Skip to content

Develop#198

Merged
Diplow merged 20 commits into
mainfrom
develop
Jan 2, 2026
Merged

Develop#198
Diplow merged 20 commits into
mainfrom
develop

Conversation

@Diplow
Copy link
Copy Markdown
Owner

@Diplow Diplow commented Jan 2, 2026

Summary by CodeRabbit

  • New Features

    • Tiles gain semantic types (Organizational, Context, System); editors show a type selector for non-root tiles and API/agent prompts include tile type.
    • Chat now surfaces generated prompts via a collapsible prompt view and streaming prompt updates.
  • Data Migration

    • Existing tiles migrated to semantic categories (BASE → CONTEXT where applicable).
  • Documentation

    • Added docs and READMEs for tile types and agent templates.
  • Tests & Tools

    • Updated tests and helpers covering itemType behavior and template-driven prompt generation.

✏️ Tip: You can customize this high-level summary in your review settings.

Diplow and others added 15 commits January 1, 2026 15:57
…ONAL, CONTEXT, SYSTEM)

This is phase 1 of the tile type classification feature. Changes include:

Schema changes:
- Extend MapItemType enum with ORGANIZATIONAL, CONTEXT, SYSTEM values
- Remove deprecated BASE type
- Add migration (0014) to convert existing BASE tiles:
  - Favorited tiles + descendants → 'system'
  - All other BASE tiles → 'context'
  - USER tiles unchanged

Code updates:
- Replace all MapItemType.BASE references with MapItemType.CONTEXT (23+ files)
- Update error message from BASE_ITEM_MUST_HAVE_PARENT to NON_USER_ITEM_MUST_HAVE_PARENT
- Add comprehensive TDD tests for type classification

The new types enable type-aware agent behavior:
- organizational: Navigation structure (always visible)
- context: Reference material (explore on-demand)
- system: Executable capability (invoke via hexecute)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace 'module' variable name with 'toolsModule' to avoid Next.js warning
- Use nullish coalescing operator instead of logical OR for safer defaults
- Add eslint-disable comment for typeof import() pattern (necessary for dynamic import typing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add documentation for itemType support in MCP tools:
- Table showing type values and their semantic meanings
- Which tools support itemType (addItem, updateItem, GET tools)
- How agents should interpret each type

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Write tests BEFORE implementation (TDD red phase):
- TypeSelectorField component tests (rendering, interaction, disabled state)
- TileForm integration tests with type selector
- useTileState hook tests for itemType state management

Tests define expected behavior:
- Dropdown with Organizational/Context/System options
- Hidden for USER type tiles (root tiles)
- itemType included in save callback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add itemType support to the tile creation and editing UI:

- Create _TypeSelectorField component with dropdown for type selection
- Update useTileState hook to track editItemType state
- Integrate TypeSelectorField into TileForm
- Update _handleSave to include itemType in save callback
- Pass itemType through TileWidget props to TileForm

Type options: Organizational, Context (default), System
Hidden for USER type tiles (root tiles cannot change type)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove HTMLSelectElement type assertion that ESLint flagged as unnecessary.
Use toBeDisabled() matcher instead of checking .disabled property.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add documentation for itemType support in the tile editing UI:
- Table showing type values and their UI behavior
- Key behaviors for type selector visibility and defaults
- Updated responsibilities to include type editing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document the new MapItemType enum values and their semantic meanings:

CLAUDE.md:
- Add Tile Types section explaining USER, ORGANIZATIONAL, CONTEXT, SYSTEM
- Document agent behavior expectations for each type
- Add migration note about BASE → split types

UBIQUITOUS.md:
- Add comprehensive definitions for each tile type
- Explain semantic classification purpose
- Document when agents should explore vs invoke tiles

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The itemType field was not being passed from UI dropdown changes through
to the API mutation, causing updates to not persist after page reload.

Changes:
- Add itemType to UpdateMapItemAttrsSchema in parameters.ts
- Add toItemTypeEnum converter in mutation-callbacks.ts
- Thread itemType through MutationCoordinator and mutation wrappers
- Include itemType in TileData adapt function and tile handlers
- Update all test files to include mandatory itemType in mock TileData

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Make itemType required in API schema (map-schemas.ts) instead of optional
- Remove default fallback in service layer (_item-crud.service.ts)
- Add itemType to all callers: agentic.ts, execute-task route, MCP tools
- Thread itemType through frontend mutation coordinator chain
- Create createTestItem factory helper with sensible defaults for tests
- Update 38 test files to use factory instead of direct addItemToMap calls

This ensures itemType is always explicitly passed in application code while
tests can use the factory's default (CONTEXT) when they don't care about
the specific type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add NonUserMapItemType, NonUserMapItemTypeString, VisibilityString types
- Replace hardcoded string unions with proper types across ~15 files
- Add structural constraints for tile type hierarchies:
  - SYSTEM tiles must have SYSTEM structural descendants
  - CONTEXT tiles must have CONTEXT structural descendants
  - ORGANIZATIONAL tiles can only be under USER or ORGANIZATIONAL parents
- Add batchUpdateItemTypeWithStructuralDescendants SQL query for cascade updates
- When updating to SYSTEM/CONTEXT, cascade to structural descendants (1-6)
- Skip hexplans (direction 0) and composition children (-1 to -6)
- Add comprehensive integration tests for hierarchy validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…used import

- Extend test file ESLint override to disable no-unsafe-* rules
- ESLint's TypeScript parser fails to resolve types from test helper
  factories, causing 320 false positive errors (pnpm typecheck passes)
- Remove unused MapItemCreateAttributes import from _mutation-wrappers.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 2, 2026

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

Project Deployment Review Updated (UTC)
hexframe Ready Ready Preview, Comment Jan 2, 2026 6:28pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 2, 2026

📝 Walkthrough

Walkthrough

Replaces legacy BASE tile type with semantic itemTypes (USER, ORGANIZATIONAL, CONTEXT, SYSTEM), threads itemType and a typed VisibilityString through DB, services, API, cache, mutations, and UI, adds a SQL migration to reclassify tiles, introduces a Mustache-based agentic templates subsystem and prompt events, and adds test helpers (createTestItem) with broad test updates.

Changes

Cohort / File(s) Summary
Core domain types & objects
src/lib/domains/mapping/_objects/map-item.ts, src/lib/domains/mapping/_objects/index.ts, src/lib/domains/mapping/types/errors.ts, src/lib/domains/mapping/types/item-attributes.ts, src/lib/domains/mapping/types/parameters.ts, src/lib/domains/mapping/utils/index.ts
Introduces semantic MapItemType (USER, ORGANIZATIONAL, CONTEXT, SYSTEM), NonUser* and VisibilityString aliases, replaces BASE-related error with NON_USER_ITEM_MUST_HAVE_PARENT, and surfaces itemType in types/schemas.
DB migration
drizzle/migrations/0014_migrate_item_types.sql
New migration: computes favorited items + descendants, sets them to SYSTEM, and converts remaining BASE→CONTEXT (with notices and verification query).
Repository & write queries
src/lib/domains/mapping/_repositories/map-item.ts, src/lib/domains/mapping/infrastructure/map-item/db.ts, src/lib/domains/mapping/infrastructure/map-item/queries/write-queries.ts
Adds updateItemType and batchUpdateItemTypeWithStructuralDescendants, switches create attrs to use baseItemId (no nested ref).
Service layer (CRUD & validation)
src/lib/domains/mapping/services/_item-services/_item-crud.service.ts, _item-management.service.ts
addItemToMap now requires non-USER itemType; updateItem accepts optional itemType with hierarchical validation and cascading update helpers; new validators and _isStructuralChild helper.
API routers & schemas
src/server/api/routers/map/map-schemas.ts, src/server/api/routers/map/map-items.ts, src/server/api/routers/agentic/agentic.ts
Adds public itemType enum/schema (required on create, optional on update); router converts strings→MapItemType; agentic hexplan creation and prompt payloads now include itemType: SYSTEM.
MCP tools & handlers
src/app/services/mcp/handlers/tools.ts, src/app/services/mcp/services/map-items.ts, src/app/services/mcp/__tests__/mcp-itemtype.test.ts, src/app/services/mcp/README.md
MCP add/update tools accept/validate itemType (enum); handlers forward itemType to map operations; tests assert schema and consistency.
Cache, mutation coordinator & types
src/app/map/Cache/Lifecycle/MutationCoordinator/*, src/app/map/Cache/types/*, _mutation-wrappers.ts
Threads itemType through optimistic create/update flows and mutation wrappers; visibility typing moved to VisibilityString; public hook signatures accept itemType.
TileData & cache handlers
src/app/map/types/tile-data.ts, src/app/map/Cache/Handlers/.../tile-converter.ts, ancestor-loader.ts, prefetch-operations.ts
Adds data.itemType to TileData and propagates it through converters, ancestor loader, and sibling prefetch.
UI: Tile widget, form & selector
src/app/map/Chat/Timeline/Widgets/TileWidget/*, _internals/form/_TypeSelectorField.tsx, useTileState.tsx
New TypeSelectorField component; TileForm/TileWidget/useTileState accept and expose editable itemType (defaults to 'context'); onSave/onItemTypeChange signatures extended.
Widget integration & handlers
src/app/map/Chat/Timeline/_components/_renderers/*, _utils/creation-handlers.ts, _utils/tile-handlers.ts
Propagates itemType into widget rendering and create/update handlers; handlers updated to accept itemType and VisibilityString.
Agentic templates & prompt builder
src/lib/domains/agentic/templates/_prompt-builder.ts, _system-template.ts, index.ts, README.md, dependencies.json
New Mustache-based templates subsystem; public buildPrompt(data: PromptData) and PromptData (includes itemType); SYSTEM template implemented; mustache dependency added.
Agentic execution & streaming
src/lib/domains/agentic/services/task-execution.service.ts, src/app/api/stream/execute-task/route.ts, src/lib/domains/agentic/types/stream.types.ts, streaming callbacks/events
Adds TaskExecutionCallbacks (onPromptBuilt), emits prompt_generated events in streaming route and agentic types; streaming callbacks and event guards added.
Test helpers & fixtures
src/lib/domains/mapping/services/__tests__/helpers/_test-item-factory.ts, _test-utilities.ts, many __tests__/*, src/app/map/Cache/__tests__/test-fixtures.ts
Adds createTestItem and specialized test factories; many tests updated to use helper and replace BASE→CONTEXT in fixtures; new createMockTileData helper exported.
Mapping infra & mappers
src/lib/domains/mapping/infrastructure/map-item/mappers.ts, db.ts, README.md
Mappers use baseItemId instead of nested ref; DB repo implements itemType update methods; README examples updated to CONTEXT.
Numerous test updates
src/**/__tests__/*, drizzle/__tests__/*, src/server/**/__tests__/*
Tests updated to import MapItemType, set many itemType values to CONTEXT, replace addItemToMap calls with createTestItem, and add itemType-focused integration tests.
Chat UI: prompt plumbing
src/app/map/Chat/_hooks/_streaming-chat-callbacks.ts, _streaming-utils.ts, _state/*, MessageActorRenderer, CollapsiblePrompt
Adds streaming prompt events/handlers, stores prompt on streaming message state, and displays prompts via a new CollapsiblePrompt component in actor renderer.
ESLint, tooling & deps
.eslintrc.cjs, package.json
ESLint test globs extended and unsafe-* rules disabled for tests; added mustache and @types/mustache in package.json.
Docs & READMEs
CLAUDE.md, UBIQUITOUS.md, src/server/README.md, .claude/commands/hexrun.md, widget README
Documentation added/updated for Tile Types, migration notes, execution directions, templates subsystem, and minor formatting fixes in examples.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    rect rgb(250,250,255)
    participant User as User (UI)
    participant TileWidget as TileWidget
    participant UseTileState as useTileState
    end
    rect rgb(245,245,245)
    participant MutationCoordinator as MutationCoordinator
    participant Cache as Map Cache
    end
    rect rgb(240,255,240)
    participant TRPC as TRPC Router
    participant DB as Database
    end

    User->>TileWidget: edit title + select itemType
    TileWidget->>UseTileState: set editItemType
    User->>TileWidget: click Save
    TileWidget->>MutationCoordinator: createItemOptimistic(coords, title, itemType)
    MutationCoordinator->>Cache: _createOptimisticItem(..., itemType)
    Cache-->>User: show optimistic UI (item with itemType)
    MutationCoordinator->>TRPC: addItem mutation (payload includes itemType)
    TRPC->>TRPC: toMapItemTypeEnum(itemType)
    TRPC->>DB: insert map_item (item_type = enum)
    DB-->>TRPC: created MapItem (with itemType)
    TRPC-->>MutationCoordinator: return MapItemContract (itemType)
    MutationCoordinator->>Cache: finalize item with server data (itemType)
    Cache-->>User: UI updated (persisted itemType)
Loading
sequenceDiagram
    autonumber
    participant Migration as SQL Migration
    participant Favorites as tile_favorites
    participant Items as map_items
    participant Write as writeQueries

    Migration->>Favorites: select favorited map items
    Migration->>Items: recursive CTE → compute descendants
    Migration->>Write: batch update favorites+descendants → item_type = SYSTEM
    Migration->>Write: update remaining BASE → CONTEXT
    Migration->>Items: leave USER rows unchanged
    Write-->>Migration: report counts / notices
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Develop #152: Overlaps agentic prompt-building and hexplan creation changes; likely touches buildPrompt/PromptData and hexecute flows.
  • Develop #170: Related to prompt-building/execution and template integration (templates subsystem and buildPrompt wiring).
  • Develop #181: Related to hexplan/hexecute flow and propagation of hexplan/task itemType through agentic execution.

Poem

🐰 I hopped through enums and SQL rows bright,

Swapped BASE for CONTEXT, made types take flight.
SYSTEMs now hum, ORGANIZATIONALs stand tall,
Context tiles scatter their seeds for all.
A carrot-cheer for maps, neat and right!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'Develop' is vague and non-descriptive, failing to convey any meaningful information about the changes in the pull request. Replace with a specific, descriptive title that summarizes the main change, such as 'Add itemType field to map items and implement tile type classification' or 'Implement semantic tile type system (itemType) with SYSTEM, CONTEXT, ORGANIZATIONAL types'.
Docstring Coverage ⚠️ Warning Docstring coverage is 67.24% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
src/lib/domains/mapping/types/__tests__/parameters-negative-directions.test.ts (1)

307-322: Update test descriptions to reflect CONTEXT type.

The test descriptions at lines 307 and 324 still reference "BASE items" but the code now uses MapItemType.CONTEXT. Update the descriptions for accuracy:

  • Line 307: "should work with BASE items having composed children paths" → "should work with CONTEXT items having composed children paths"
  • Line 324: "should work with BASE items at composition" → "should work with CONTEXT items at composition"
🔎 Suggested description updates
-  it("should work with BASE items having composed children paths", () => {
+  it("should work with CONTEXT items having composed children paths", () => {
     const params: CreateMapItemParams = {
       itemType: MapItemType.CONTEXT,
-  it("should work with BASE items at composition (direction 0)", () => {
+  it("should work with CONTEXT items at composition (direction 0)", () => {
     const params: CreateMapItemParams = {
       itemType: MapItemType.CONTEXT,

Also applies to: 324-339

src/lib/domains/mapping/types/__tests__/contracts.test.ts (1)

286-304: Update comments to reflect CONTEXT type.

The inline comments at lines 297 and 367 still reference "BASE items" but the code now uses MapItemType.CONTEXT. Update these comments for accuracy:

// parentId - BASE items need a parent

should be:

// parentId - CONTEXT items need a parent
🔎 Suggested comment updates
-      999 // parentId - BASE items need a parent
+      999 // parentId - CONTEXT items need a parent

Also applies to: 356-378

src/lib/domains/mapping/services/__tests__/item-crud.integration.test.ts (1)

47-47: Update test description to reflect CONTEXT default.

The test description mentions "BASE item" but the implementation now defaults to MapItemType.CONTEXT via the createTestItem helper. This is correctly asserted at line 99, but the description should be updated for consistency.

🔎 Suggested fix
-    it("should add a child BASE item to a root USER item", async () => {
+    it("should add a child CONTEXT item to a root USER item", async () => {
src/app/map/Cache/Lifecycle/MutationCoordinator/mutation-coordinator.test.ts (1)

299-316: Update mock responses to use valid MapItemType enum values.

The mock mutation responses use itemType: "BASE" as const, but "BASE" is not a valid enum value—it's a legacy type that has been split into ORGANIZATIONAL, CONTEXT, SYSTEM, and USER. The test fixtures correctly use MapItemType.CONTEXT. Update the mocks to either:

  • Use MapItemType.CONTEXT to match the fixtures, or
  • Use null to represent unclassified legacy tiles per the migration note

This ensures the mocked server responses represent realistic current-state data.

src/lib/domains/mapping/services/__tests__/helpers/item-crud/_item-add-helpers.ts (1)

17-30: Validation mismatch: hardcoded CONTEXT vs. optional itemType parameter.

The function accepts an optional itemType parameter (line 14) and uses it when creating the item (line 20), but the validation at line 30 hardcodes MapItemType.CONTEXT. If a caller passes a different itemType (e.g., ORGANIZATIONAL), the test will fail unexpectedly.

🔎 Proposed fix
-  expect(childItemContract.itemType).toBe(MapItemType.CONTEXT);
+  expect(childItemContract.itemType).toBe(addItemArgs.itemType ?? MapItemType.CONTEXT);
src/app/map/Cache/Lifecycle/MutationCoordinator/mutation-coordinator.ts (1)

1254-1269: Use tile.data.itemType instead of hardcoding MapItemType.CONTEXT in _reconstructApiData.

The method ignores tile.data.itemType (which TileData already stores) and always reconstructs items as MapItemType.CONTEXT. Since _reconstructApiData is used throughout rollback operations (delete, move, copy, visibility updates, etc.), items with other types (e.g., ORGANIZATIONAL) will be restored with incorrect types, causing data loss.

Change line 1264 from:

itemType: MapItemType.CONTEXT,

to:

itemType: tile.data.itemType,
🧹 Nitpick comments (21)
drizzle/migrations/0014_migrate_item_types.sql (1)

19-22: Remove unused variable descendant_ids.

The descendant_ids variable is declared but never assigned or used. The recursive CTE result is stored directly in all_system_ids instead.

🔎 Proposed fix
 DECLARE
   favorited_map_item_ids INTEGER[];
-  descendant_ids INTEGER[];
   all_system_ids INTEGER[];
 BEGIN
src/app/map/Canvas/Tile/Item/_internals/hooks/__tests__/use-item-state.test.tsx (1)

69-69: Test mock correctly updated with semantic item type.

The addition of itemType: MapItemType.CONTEXT aligns the test fixture with the new TileData schema. Using CONTEXT is appropriate since these tests focus on drag behavior rather than item-type-specific logic.

Optional: Improve readability by placing properties on separate lines
-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,
src/lib/domains/mapping/_objects/map-item.ts (1)

64-73: Clarify the distinction between ref.itemType and itemType.

Having two fields with similar names (ref.itemType on Line 68 and itemType on Line 71) but different purposes creates confusion:

  • ref.itemType is described as a "reference marker"
  • itemType is the "semantic tile type"

This naming collision makes the codebase harder to understand and maintain. Consider either:

  1. Renaming ref.itemType to something more distinctive (e.g., ref.marker or ref.category)
  2. Adding a detailed comment explaining why both fields exist and when each should be used
  3. Consolidating if both aren't truly necessary
src/app/map/Chat/Timeline/Widgets/TileWidget/_internals/form/_TypeSelectorField.tsx (2)

3-3: Import ItemTypeValue from domain layer instead of duplicating.

Line 3 defines a local ItemTypeValue type that duplicates NonUserMapItemTypeString from ~/lib/domains/mapping/utils. This creates maintenance risk if the types diverge.

🔎 Proposed fix to import from domain
+'use client';
+
+import type { NonUserMapItemTypeString } from '~/lib/domains/mapping/utils';
+
-type ItemTypeValue = 'organizational' | 'context' | 'system';
+type ItemTypeValue = NonUserMapItemTypeString;

24-36: Add label-input association for accessibility.

The <label> (Line 24) and <select> (Line 27) are not properly associated. For better accessibility, add an id to the select element and a matching htmlFor attribute to the label.

🔎 Proposed fix
     <div>
-      <label className="text-xs text-muted-foreground mb-1 block">
+      <label htmlFor="tile-type-selector" className="text-xs text-muted-foreground mb-1 block">
         Type
       </label>
       <select
+        id="tile-type-selector"
         value={value}
         onChange={(e) => {
src/app/map/Canvas/Menu/__tests__/items-builder-history.test.ts (1)

6-6: LGTM! Test data properly updated with itemType.

The test has been correctly updated to include itemType: MapItemType.CONTEXT in the mock data, aligning with the new semantic type system.

Optional: Line 24 has both visibility and itemType on the same line. Consider splitting for better readability:

-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,

Also applies to: 24-24

src/app/map/Cache/Handlers/__tests__/navigation-handler.test.ts (1)

13-13: LGTM! Test fixtures updated to include semantic item type.

The addition of itemType: MapItemType.CONTEXT correctly aligns the test data with the new tile schema. Using CONTEXT is appropriate for general test fixtures representing non-user tiles.

Optional: Improve readability by placing properties on separate lines

For better readability, consider formatting multi-property objects with one property per line:

           visibility: Visibility.PRIVATE,
-          itemType: MapItemType.CONTEXT,
+          itemType: MapItemType.CONTEXT,

Currently on lines 70 and 97, both visibility and itemType appear inline which is valid but slightly harder to scan.

Also applies to: 70-70, 97-97

src/app/map/Canvas/Tile/Item/_components/__tests__/item-tile-content-favorites.test.tsx (1)

8-8: LGTM! Test data correctly updated with semantic item type.

The test fixture now includes the required itemType field with an appropriate value for the test context.

Optional: Format properties on separate lines

Line 57 has two properties on a single line, which reduces readability:

       color: "zinc-50",
-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,

Also applies to: 57-57

src/app/map/Canvas/__tests__/TileContextMenu-composition.test.tsx (1)

8-8: LGTM! Test fixture extended with semantic item type.

The mock tile data correctly includes the new itemType field, maintaining consistency with the updated schema.

Optional: Format properties on separate lines

Line 31 combines two properties on one line:

       color: 'primary',
-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,

Also applies to: 31-31

src/app/map/Canvas/Tile/Base/__tests__/BaseComponents.test.tsx (1)

8-8: LGTM! Test fixtures updated with semantic item type.

Both test cases now include the required itemType field, correctly aligning with the new tile data schema.

Optional: Format properties on separate lines

Lines 30 and 67 have two properties on single lines:

       color: "zinc-500",
-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,

And similarly at line 67:

       color: "amber-400",
-      visibility: Visibility.PRIVATE, itemType: MapItemType.CONTEXT,
+      visibility: Visibility.PRIVATE,
+      itemType: MapItemType.CONTEXT,

Also applies to: 30-30, 67-67

src/app/map/Cache/State/__tests__/reducer.test.ts (1)

20-696: LGTM! Cache reducer tests properly updated with itemType field.

The test fixtures now include itemType: MapItemType.CONTEXT, correctly reflecting the expanded TileData.data shape. The migration is consistent across all test scenarios including region loading, item children, and edge cases.

Minor formatting note: Some lines have trailing blank lines after the itemType addition (lines 24, 39, 167, 646). Consider removing these for consistency, though this is purely cosmetic.

src/app/map/Cache/Lifecycle/MutationCoordinator/__tests__/copy-item.test.ts (1)

323-325: Formatting inconsistency.

The visibility and itemType properties have inconsistent indentation compared to other properties in the object. This appears to be a formatting issue.

Suggested fix
         color: "#000000",
-        visibility: Visibility.PRIVATE,
-      itemType: MapItemType.CONTEXT,
+          visibility: Visibility.PRIVATE,
+          itemType: MapItemType.CONTEXT,
         },
src/lib/domains/mapping/infrastructure/map-item/queries/write-queries.ts (1)

268-280: Consider adding a comment explaining the SQL path arithmetic.

The SUBSTRING(... FROM pathLen + 2) and SPLIT_PART(..., ',', 1) logic is non-obvious. The +2 accounts for the parent path length plus the comma separator.

          // Filter: tile itself OR first direction after parent is positive (1-6)
          pathString === ""
            ? sql`(${mapItems.path} = '' OR ${mapItems.path} ~ '^[1-6](,.*)?$')`
            : sql`(
                ${mapItems.path} = ${pathString}
                OR (
+                  -- pathLen + 2 skips parent path + comma to get first child direction
                  LENGTH(${mapItems.path}) > ${sql.raw(String(pathLen))}
                  AND CAST(SPLIT_PART(SUBSTRING(${mapItems.path} FROM ${sql.raw(String(pathLen + 2))}), ',', 1) AS INTEGER) > 0
                )
              )`
src/lib/domains/mapping/services/__tests__/item-deep-copy-negative-directions.test.ts (1)

8-8: Refactoring to createTestItem improves consistency.

The migration from direct addItemToMap calls to the createTestItem helper centralizes test item creation and provides consistent defaults. The helper defaults itemType to MapItemType.CONTEXT (per the helper implementation in _test-item-factory.ts).

Optional: Consider explicit itemType for test clarity

For tests where the itemType might affect deep-copy behavior or assertions, consider explicitly specifying it even when using the default. This makes test intent clearer:

 const parentItem = await createTestItem(testEnv, {
   parentId: rootMap.id,
   coords: _createTestCoordinates({
     userId: setupParams.userId,
     groupId: setupParams.groupId,
     path: [Direction.East],
   }),
   title: "Parent Item",
   content: "Parent content",
+  itemType: MapItemType.CONTEXT,
 });

This is particularly useful for tests verifying type-specific behavior.

Also applies to: 28-37, 40-49, 51-60

src/app/services/mcp/__tests__/mcp-itemtype.test.ts (1)

28-39: Consider extracting repeated type casting to a helper.

The type assertion pattern for itemTypeProperty is repeated across multiple tests. A helper function would reduce duplication and improve maintainability.

🔎 Proposed helper extraction
// Add after line 14
function getToolItemTypeProperty(toolName: string) {
  const tool = mcpTools.find(t => t.name === toolName);
  return tool?.inputSchema.properties?.itemType as {
    type?: string;
    enum?: string[];
    description?: string;
  } | undefined;
}

function getUpdateToolItemTypeProperty(toolName: string) {
  const tool = mcpTools.find(t => t.name === toolName);
  const updates = tool?.inputSchema.properties?.updates as {
    properties?: { itemType?: { type?: string; enum?: string[]; description?: string } };
  };
  return updates?.properties?.itemType;
}
src/app/map/Chat/Timeline/Widgets/TileWidget/useTileState.tsx (1)

32-37: Consider extracting the itemType validation logic to reduce duplication.

The same conditional check for valid editable item types appears in both the initial state (lines 33-36) and the sync effect (lines 69-71). Extracting this to a helper would improve maintainability.

🔎 Proposed refactor
+const isEditableItemType = (
+  type: ItemTypeValue
+): type is 'organizational' | 'context' | 'system' =>
+  type === 'organizational' || type === 'context' || type === 'system';
+
+const getEditableItemType = (itemType: ItemTypeValue): 'organizational' | 'context' | 'system' =>
+  isEditableItemType(itemType) ? itemType : 'context';
+
 // Default to 'context' if itemType is null/undefined
-const [editItemType, setEditItemType] = useState<'organizational' | 'context' | 'system'>(
-  (itemType === 'organizational' || itemType === 'context' || itemType === 'system')
-    ? itemType
-    : 'context'
-);
+const [editItemType, setEditItemType] = useState<'organizational' | 'context' | 'system'>(
+  getEditableItemType(itemType)
+);

Then use getEditableItemType(itemType) in the useEffect as well.

Also applies to: 68-73

src/app/map/Chat/Timeline/Widgets/TileWidget/_internals/_handlers.ts (1)

16-17: Consider consolidating the EditableItemType type definition.

This same type alias is defined in multiple files (useTileState.tsx, TileForm.tsx, and here). Consider exporting it from a shared location to ensure consistency and reduce duplication.

🔎 Proposed approach

Create a shared types file or export from a central location:

// In a shared types file, e.g., ~/app/map/Chat/Timeline/Widgets/TileWidget/types.ts
export type EditableItemType = 'organizational' | 'context' | 'system';
export type ItemTypeValue = EditableItemType | 'user' | null;

Then import from that location in all three files.

src/lib/domains/mapping/_objects/__tests__/map-item-type-classification.test.ts (1)

53-65: Consider the maintenance implications of asserting exact enum count.

While this test ensures BASE is removed, the assertion expect(enumValues).toHaveLength(4) may cause test failures if new valid types are added in the future. Consider documenting this expectation or using a more flexible approach.

🔎 Alternative approach
 it("should have exactly 4 enum values", () => {
   const enumValues = Object.values(MapItemType);
-  expect(enumValues).toHaveLength(4);
+  // Explicitly verify the expected types exist; update count if new types are added
+  const expectedTypes = ["user", "organizational", "context", "system"];
+  expect(enumValues).toHaveLength(expectedTypes.length);
   expect(enumValues).toContain("user");
   expect(enumValues).toContain("organizational");
   expect(enumValues).toContain("context");
   expect(enumValues).toContain("system");
 });
src/lib/domains/mapping/services/__tests__/helpers/_test-item-factory.ts (1)

76-98: Consider documenting the direction validation expectation.

The shorthands createTestStructuralChild and createTestComposedChild set itemType defaults but don't validate that the coords.path ends with an appropriate direction (1-6 for structural, -1 to -6 for composed). This is likely intentional for test flexibility, but consider adding a brief comment noting that callers are responsible for providing coords with the correct direction.

src/app/services/mcp/handlers/tools.ts (1)

325-325: Consider adding runtime validation for itemType in updates.

The updates object is cast to include itemType?: NonUserMapItemTypeString, but unlike addItem, there's no validation that the provided itemType value (if present) is one of the valid enum values. While TypeScript types help at compile time, MCP clients send arbitrary JSON. Consider validating updates.itemType if provided.

🔎 Example validation
const validItemTypes = ["organizational", "context", "system"];
if (updates.itemType && !validItemTypes.includes(updates.itemType)) {
  throw new Error(`Invalid itemType: ${updates.itemType}. Must be one of: ${validItemTypes.join(", ")}`);
}
src/lib/domains/mapping/services/_item-services/_item-crud.service.ts (1)

539-542: Consider logging when parent is not found during update validation.

The silent return when catching an error during parent lookup could mask data integrity issues. If the parent should exist but doesn't, this might indicate orphaned tiles or corrupted data.

🔎 Suggested improvement
     } catch {
-      // Parent not found, skip validation
+      // Parent not found - log for observability but don't block the update
+      // This can happen with orphaned tiles or during concurrent operations
+      console.warn(`Parent not found at ${JSON.stringify(parentCoords)} during itemType update validation for coords ${JSON.stringify(coords)}`);
       return;
     }

Comment thread src/app/map/Cache/Handlers/__tests__/stale-closure.test.ts Outdated
Comment thread src/lib/domains/mapping/_actions/_map-item-copy-helpers.ts Outdated
Diplow and others added 2 commits January 2, 2026 17:13
- Create dedicated templates subsystem at lib/domains/agentic/templates/
- Move template logic from prompt-builder.ts to _prompt-builder.ts
- Add _system-template.ts with SYSTEM tile template constants
- Add dependencies.json declaring mustache and mapping dependencies
- Clean index.ts to only re-export public API (buildPrompt, PromptData)
- Make itemType required in PromptData (remove fallback behavior)
- Fix cross-domain imports to use public mapping API
- Add README.md documenting subsystem responsibilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
refactor(agentic): extract templates subsystem with encapsulated API
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/lib/domains/agentic/templates/_system-template.ts (1)

67-87: Consider surfacing blocked steps even when pending steps exist.

The template shows three mutually exclusive states: hexplanBlocked, hexplanComplete, and hexplanPending. However, the state detection logic (in _prompt-builder.ts lines 152-177) prioritizes hexplanPending when 📋 exists, which means blocked (🔴) steps are silently ignored if any pending step remains.

This could mask important blockers from the agent. Consider either:

  1. Adding a warning about blocked steps within the hexplanPending block, or
  2. Making hexplanBlocked take precedence over hexplanPending

Based on learnings, 🔴 BLOCKED indicates tasks that need intervention, so surfacing them promptly seems important.

src/lib/domains/agentic/templates/_prompt-builder.ts (1)

152-177: Emoji-based status detection may produce false positives.

Using data.hexPlan.includes('📋') and includes('🔴') could match emoji appearing in user content, not just status markers. Consider checking for line-start patterns like /^📋/m or using more structured status tracking.

Additionally, the state priority means blocked steps are hidden when pending steps exist (as noted in the template review).

🔎 More robust pattern matching
- const hasPendingSteps = data.hexPlan.includes('📋')
- const hasBlockedSteps = data.hexPlan.includes('🔴')
+ const hasPendingSteps = /^📋/m.test(data.hexPlan)
+ const hasBlockedSteps = /^🔴/m.test(data.hexPlan)
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23cef3e and bef6784.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • package.json
  • src/lib/domains/agentic/dependencies.json
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/templates/README.md
  • src/lib/domains/agentic/templates/_prompt-builder.ts
  • src/lib/domains/agentic/templates/_system-template.ts
  • src/lib/domains/agentic/templates/dependencies.json
  • src/lib/domains/agentic/templates/index.ts
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
  • src/server/api/routers/agentic/agentic.ts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/domains/agentic/templates/README.md
  • src/lib/domains/agentic/templates/dependencies.json
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use absolute imports with ~/ prefix instead of relative imports (./ or ../) - this is enforced by ESLint no-restricted-imports rule

Files:

  • src/lib/domains/agentic/templates/_system-template.ts
  • src/lib/domains/agentic/templates/_prompt-builder.ts
  • src/lib/domains/agentic/templates/index.ts
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
  • src/server/api/routers/agentic/agentic.ts
src/lib/domains/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

src/lib/domains/**/*.{ts,tsx}: Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)
Use Domain-Driven Design in src/lib/domains/ with clear boundaries between mapping, IAM, and other domains

Files:

  • src/lib/domains/agentic/templates/_system-template.ts
  • src/lib/domains/agentic/templates/_prompt-builder.ts
  • src/lib/domains/agentic/templates/index.ts
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
src/lib/domains/agentic/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Files:

  • src/lib/domains/agentic/templates/_system-template.ts
  • src/lib/domains/agentic/templates/_prompt-builder.ts
  • src/lib/domains/agentic/templates/index.ts
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest for tests (not Jest)

Files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
src/server/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use tRPC for type-safe API with server-side caching and optimizations in the backend

Files:

  • src/server/api/routers/agentic/agentic.ts
🧠 Learnings (4)
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/agentic/**/*.{ts,tsx} : Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Applied to files:

  • src/lib/domains/agentic/templates/_system-template.ts
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
  • src/server/api/routers/agentic/agentic.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use Vitest for tests (not Jest)

Applied to files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/**/*.{ts,tsx} : Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)

Applied to files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
  • src/lib/domains/agentic/utils/prompt-builder.ts
  • src/server/api/routers/agentic/agentic.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: A tile is either a leaf (does concrete work with no subtask children) or a parent (orchestrates children), never both. Leaf tiles describe WHAT to do and WHY, while parent tiles only orchestrate children

Applied to files:

  • src/lib/domains/agentic/utils/prompt-builder.ts
🧬 Code graph analysis (3)
src/lib/domains/agentic/templates/_prompt-builder.ts (1)
src/lib/domains/agentic/templates/_system-template.ts (4)
  • ANCESTOR_INTRO (133-133)
  • SYSTEM_TEMPLATE (46-118)
  • SystemTemplateData (12-40)
  • HEXRUN_INTRO (123-128)
src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts (1)
src/lib/domains/agentic/templates/_prompt-builder.ts (2)
  • PromptData (13-42)
  • buildPrompt (204-213)
src/server/api/routers/agentic/agentic.ts (3)
src/lib/domains/mapping/utils/index.ts (1)
  • MapItemType (29-29)
src/lib/domains/mapping/services/__tests__/helpers/_test-utilities.ts (1)
  • MapItemType (13-13)
src/lib/domains/mapping/types/contracts.ts (1)
  • MapItemType (30-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Tests - Phase 2 (React Components)
  • GitHub Check: Build
  • GitHub Check: Type Check
  • GitHub Check: Tests - Phase 1 (Main Suite)
  • GitHub Check: ESLint
🔇 Additional comments (21)
src/lib/domains/agentic/dependencies.json (1)

13-14: LGTM! Templates subsystem correctly registered.

The addition of the templates subsystem aligns with the new itemType-aware prompt generation infrastructure introduced in this PR.

src/lib/domains/agentic/services/task-execution.service.ts (1)

140-142: LGTM! ItemType correctly propagated to prompt builder.

The itemType field from the task is correctly passed through to the buildPrompt function, enabling template selection based on tile semantics.

src/lib/domains/agentic/templates/index.ts (1)

1-11: LGTM! Clean public API design.

The public entry point follows best practices with clear documentation and proper encapsulation of the internal _prompt-builder module. The absolute import path correctly uses the ~/ prefix as per coding guidelines.

src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts (2)

3-3: LGTM! ItemType properly integrated into test data.

The MapItemType import and default value (SYSTEM) correctly establish the foundation for itemType-aware testing throughout the suite.

Also applies to: 15-15


543-571: Error handling implementation is correct and well-tested.

The error throwing logic is properly implemented in _getTemplateByItemType() function, with error messages defined in TEMPLATE_LOOKUP_ERRORS. All three unsupported itemTypes (ORGANIZATIONAL, USER, CONTEXT) correctly throw the expected errors. Tests use Vitest as required and accurately verify the error handling behavior.

package.json (1)

92-92: Mustache library is current and has no known vulnerabilities. The package.json already specifies version ^4.2.0, which is the latest stable release as of January 2026. No security advisories are associated with the mustache package.

src/server/api/routers/agentic/agentic.ts (4)

6-6: LGTM!

Import correctly uses absolute path with ~/ prefix as per coding guidelines, and MapItemType is properly imported alongside other mapping utilities.


61-62: LGTM!

Setting itemType: MapItemType.SYSTEM for hexplan tiles is correct. Per the domain conventions, hexplan tiles (direction-0 children) are system-generated execution state trackers, making SYSTEM the appropriate item type.


510-512: LGTM!

Propagating itemType from the task context to the prompt builder enables template selection based on tile type. The pattern is consistent with the hexecute endpoint below.


663-665: LGTM!

Consistent with the executeTask endpoint - itemType is correctly propagated to the prompt builder for template selection.

src/lib/domains/agentic/templates/_system-template.ts (3)

12-40: LGTM!

The SystemTemplateData interface provides a clean contract for template rendering with appropriate flags for conditional sections and pre-rendered content blocks.


88-118: Execution instructions align with domain conventions.

The step-by-step instructions correctly reference the emoji status markers (📋 for completion, 🔴 BLOCKED for failures) and follow the "execute one step, then return" pattern for iterative execution. The parent/leaf tile distinction using isParentTile is well-implemented.


123-133: LGTM!

Static intro constants provide clear context for the HEXRUN execution model and ancestor relationships.

src/lib/domains/agentic/templates/_prompt-builder.ts (5)

7-9: LGTM!

Imports correctly use absolute paths with ~/ prefix as per coding guidelines.


13-42: LGTM!

The PromptData interface provides a clean API for prompt generation, with itemType enabling template selection. The separation of composedChildren (context tiles with content) and structuralChildren (subtask tiles with previews) aligns with the domain model.


46-57: LGTM!

XML escaping covers all standard entities, and the _hasContent helper provides consistent empty-string handling.


116-139: Exhaustive switch is good practice.

The never type check ensures compile-time errors if new MapItemType values are added without handling them here. The explicit error messages for unimplemented types are helpful.


204-212: Minor: Template data preparation is hardcoded to SYSTEM.

_prepareSystemTemplateData is called unconditionally, but _getTemplateByItemType validates the type first. When USER/CONTEXT templates are implemented, this will need a corresponding data preparation function. This is acceptable for now since only SYSTEM is supported.

src/lib/domains/agentic/utils/prompt-builder.ts (3)

11-12: LGTM!

Clean re-export from templates subsystem using absolute import path. This maintains backward compatibility while centralizing prompt-building logic.


25-52: LGTM!

generateParentHexplanContent correctly uses the emoji status markers per domain conventions:

  • 🟡 STARTED for task execution began
  • 📋 prefix for pending steps (display only)

The dual-mode handling (flat leaf tasks for root tiles vs. direct children for intermediate parents) supports the execution tracking model.


58-74: LGTM!

generateLeafHexplanContent creates a simple execution plan for leaf tiles with the correct 🟡 STARTED marker and 📋 pending step. The optional instruction inclusion is a nice touch.

Remove redundant nested ref structure from MapItem attrs. The old
`ref: { itemType: MapItemType; itemId: number }` was premature
abstraction - itemType was always CONTEXT, never stored in DB,
and never read anywhere.

Simplified to `baseItemId: number` which directly represents the
foreign key to BaseItem. The actual BaseItem object remains
accessible via `mapItem.ref` (the RelatedItems property).

Changes:
- Attrs interface: ref → baseItemId
- Constructor: simplified default logic
- Infrastructure: mappers, db.ts, write-queries.ts
- Domain helpers: creation, copy, management services
- Tests: updated all ref constructions

No database migration needed - DB already stored just refItemId.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PromptGeneratedEvent SSE event type to stream the hexecute prompt
- Emit prompt before LLM streaming starts via onPromptBuilt callback
- Store prompt in streaming message state and persist after finalization
- Create CollapsiblePrompt component with MarkdownRenderer for display
- Show prompt in chat messages (collapsed by default, before thinking indicator)
- Remove XML escaping from content fields in prompt builder to preserve
  intentional XML structure in tile content (keeps escaping for attributes)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx (1)

15-17: Consider dynamic summary text for better UX.

The summary text remains static as "Show the prompt" whether the details are open or closed. For improved user experience, consider updating the text to reflect the current state (e.g., "Show the prompt" when collapsed, "Hide the prompt" when expanded).

🔎 Optional refinement with dynamic text
-      <summary className="cursor-pointer text-muted-foreground hover:text-foreground transition-colors">
-        Show the prompt
-      </summary>
+      <summary className="cursor-pointer text-muted-foreground hover:text-foreground transition-colors [&[open]]:before:content-['Hide_the_prompt'] before:content-['Show_the_prompt']">
+      </summary>

Alternatively, use React state with the onToggle event:

import { MarkdownRenderer } from '~/app/map/Chat/Timeline/_components/MarkdownRenderer'
import { useState } from 'react'

interface CollapsiblePromptProps {
  prompt: string
}

export function CollapsiblePrompt({ prompt }: CollapsiblePromptProps) {
  const [isOpen, setIsOpen] = useState(false)
  
  return (
    <details 
      className="mb-2 text-xs" 
      onToggle={(e) => setIsOpen((e.target as HTMLDetailsElement).open)}
    >
      <summary className="cursor-pointer text-muted-foreground hover:text-foreground transition-colors">
        {isOpen ? 'Hide the prompt' : 'Show the prompt'}
      </summary>
      <div className="mt-2 p-3 bg-muted/50 rounded-md overflow-x-auto max-h-96 overflow-y-auto">
        <MarkdownRenderer content={prompt} isSystemMessage={false} />
      </div>
    </details>
  )
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between deffe6e and 468ea45.

📒 Files selected for processing (15)
  • src/app/api/stream/execute-task/route.ts
  • src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx
  • src/app/map/Chat/Timeline/_components/MessageActorRenderer.tsx
  • src/app/map/Chat/_hooks/_streaming-chat-callbacks.ts
  • src/app/map/Chat/_hooks/_streaming-utils.ts
  • src/app/map/Chat/_state/_events/_creators/streaming-creators.ts
  • src/app/map/Chat/_state/_events/event.creators.ts
  • src/app/map/Chat/_state/_events/event.types.ts
  • src/app/map/Chat/_state/_events/index.ts
  • src/app/map/Chat/_state/_operations/message-operations.ts
  • src/app/map/Chat/_state/_selectors/streaming-message-handlers.ts
  • src/lib/domains/agentic/index.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/lib/domains/agentic/templates/_prompt-builder.ts
  • src/lib/domains/agentic/types/stream.types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/domains/agentic/templates/_prompt-builder.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use absolute imports with ~/ prefix instead of relative imports (./ or ../) - this is enforced by ESLint no-restricted-imports rule

Files:

  • src/app/map/Chat/_hooks/_streaming-utils.ts
  • src/app/map/Chat/_state/_events/_creators/streaming-creators.ts
  • src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx
  • src/app/map/Chat/_state/_operations/message-operations.ts
  • src/app/map/Chat/Timeline/_components/MessageActorRenderer.tsx
  • src/app/map/Chat/_state/_events/index.ts
  • src/lib/domains/agentic/types/stream.types.ts
  • src/lib/domains/agentic/index.ts
  • src/app/api/stream/execute-task/route.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
  • src/app/map/Chat/_hooks/_streaming-chat-callbacks.ts
  • src/app/map/Chat/_state/_events/event.creators.ts
  • src/app/map/Chat/_state/_selectors/streaming-message-handlers.ts
  • src/app/map/Chat/_state/_events/event.types.ts
src/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Next.js 15 App Router with progressive enhancement following Static → Progressive → Dynamic component patterns

Files:

  • src/app/map/Chat/_hooks/_streaming-utils.ts
  • src/app/map/Chat/_state/_events/_creators/streaming-creators.ts
  • src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx
  • src/app/map/Chat/_state/_operations/message-operations.ts
  • src/app/map/Chat/Timeline/_components/MessageActorRenderer.tsx
  • src/app/map/Chat/_state/_events/index.ts
  • src/app/api/stream/execute-task/route.ts
  • src/app/map/Chat/_hooks/_streaming-chat-callbacks.ts
  • src/app/map/Chat/_state/_events/event.creators.ts
  • src/app/map/Chat/_state/_selectors/streaming-message-handlers.ts
  • src/app/map/Chat/_state/_events/event.types.ts
src/lib/domains/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

src/lib/domains/**/*.{ts,tsx}: Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)
Use Domain-Driven Design in src/lib/domains/ with clear boundaries between mapping, IAM, and other domains

Files:

  • src/lib/domains/agentic/types/stream.types.ts
  • src/lib/domains/agentic/index.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
src/lib/domains/agentic/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Files:

  • src/lib/domains/agentic/types/stream.types.ts
  • src/lib/domains/agentic/index.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
🧠 Learnings (3)
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/agentic/**/*.{ts,tsx} : Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Applied to files:

  • src/lib/domains/agentic/index.ts
  • src/app/api/stream/execute-task/route.ts
  • src/lib/domains/agentic/services/task-execution.service.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/**/*.{ts,tsx} : Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)

Applied to files:

  • src/lib/domains/agentic/index.ts
  • src/app/api/stream/execute-task/route.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/**/*.{ts,tsx} : Use Domain-Driven Design in src/lib/domains/ with clear boundaries between mapping, IAM, and other domains

Applied to files:

  • src/app/api/stream/execute-task/route.ts
🧬 Code graph analysis (7)
src/app/map/Chat/_state/_events/_creators/streaming-creators.ts (3)
src/app/map/Chat/_state/_events/event.creators.ts (1)
  • createStreamingMessagePromptEvent (35-35)
src/app/map/Chat/_state/_events/index.ts (2)
  • createStreamingMessagePromptEvent (44-44)
  • ChatEvent (11-11)
src/app/map/Chat/_state/_events/event.types.ts (1)
  • ChatEvent (31-37)
src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx (1)
src/app/map/Chat/Timeline/_components/MarkdownRenderer.tsx (1)
  • MarkdownRenderer (10-21)
src/app/map/Chat/_state/_operations/message-operations.ts (1)
src/app/map/Chat/_state/_events/_creators/streaming-creators.ts (1)
  • createStreamingMessagePromptEvent (50-58)
src/app/map/Chat/Timeline/_components/MessageActorRenderer.tsx (1)
src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx (1)
  • CollapsiblePrompt (12-23)
src/lib/domains/agentic/services/task-execution.service.ts (1)
src/lib/domains/agentic/index.ts (6)
  • TaskExecutionCallbacks (92-92)
  • executeTaskStreaming (89-89)
  • TaskExecutionInput (91-91)
  • AgenticService (8-8)
  • StreamChunk (29-29)
  • LLMResponse (28-28)
src/app/map/Chat/_state/_selectors/streaming-message-handlers.ts (2)
src/app/map/Chat/_state/_events/event.types.ts (1)
  • StreamingMessagePromptPayload (147-150)
src/app/map/Chat/_state/_events/index.ts (1)
  • StreamingMessagePromptPayload (28-28)
src/app/map/Chat/_state/_events/event.types.ts (1)
src/app/map/Chat/_state/_events/index.ts (1)
  • StreamingMessagePromptPayload (28-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Tests - Phase 1 (Main Suite)
  • GitHub Check: Tests - Phase 2 (React Components)
  • GitHub Check: Build
  • GitHub Check: ESLint
🔇 Additional comments (26)
src/app/map/Chat/Timeline/_components/MessageActorRenderer.tsx (2)

8-8: LGTM!

The import follows the coding guidelines by using an absolute import with the ~/ prefix.


135-135: Message type correctly includes the optional prompt property.

The Message interface in src/app/map/Chat/_state/_events/event.types.ts defines prompt?: string, and the conditional rendering correctly guards access to it.

src/app/map/Chat/Timeline/_components/CollapsiblePrompt.tsx (1)

1-23: LGTM!

The component implementation is clean and follows best practices:

  • Uses absolute imports with ~/ prefix per coding guidelines
  • Leverages native HTML <details>/<summary> elements for progressive enhancement
  • Provides good accessibility out of the box
  • Integrates seamlessly with the existing MarkdownRenderer
src/lib/domains/agentic/services/task-execution.service.ts (2)

140-141: LGTM! itemType propagation is correct.

The addition of itemType: task.itemType to the buildPrompt call properly threads semantic item typing through the prompt-building pipeline, consistent with the PR's objectives.


189-217: LGTM! Lifecycle callback implementation is sound.

The TaskExecutionCallbacks interface and its integration into executeTaskStreaming is well-implemented:

  • Properly documented with JSDoc
  • Correctly uses optional chaining for safe callback invocation
  • Prompt extraction safely handles empty messages array with fallback to empty string
  • Timing is appropriate (after prompt building, before streaming)
src/app/map/Chat/_state/_events/index.ts (1)

28-28: LGTM! Event type and creator exports are consistent.

The additions of StreamingMessagePromptPayload and createStreamingMessagePromptEvent maintain consistency with the existing event export patterns.

Also applies to: 44-44

src/app/map/Chat/_state/_events/_creators/streaming-creators.ts (1)

46-58: LGTM! Event creator follows established patterns.

The createStreamingMessagePromptEvent function is correctly implemented:

  • Consistent with existing streaming event creators in this file
  • Proper JSDoc documentation
  • Appropriate payload structure with streamId and prompt fields
  • Uses the same ID generation pattern as other creators
src/app/map/Chat/_hooks/_streaming-utils.ts (2)

16-16: LGTM! Callback signature is appropriate.

The onPromptGenerated callback addition to StreamingCallbacks is well-typed and consistent with other callbacks in the interface.


62-64: LGTM! Event handling is correct.

The prompt_generated event handling is properly implemented:

  • Uses optional chaining for safe callback invocation
  • Correctly returns shouldClose: false to continue streaming
  • Follows the pattern of other non-terminal event handlers
src/lib/domains/agentic/index.ts (1)

61-61: LGTM! Public API exports are complete and consistent.

The additions properly expose the new types and type guards through the domain's public API:

  • PromptGeneratedEvent alongside other stream event types
  • isPromptGeneratedEvent alongside other event type guards
  • TaskExecutionCallbacks alongside other task execution types

Also applies to: 75-75, 92-92

src/app/map/Chat/_state/_operations/message-operations.ts (1)

9-9: LGTM! Clean addition of prompt event.

The setMessagePrompt method follows the same pattern as other streaming operations and correctly uses the absolute import with ~/ prefix. The implementation is straightforward and type-safe.

Also applies to: 42-44

src/app/map/Chat/_state/_events/event.types.ts (1)

25-25: LGTM! Type definitions are well-structured.

The new event type, payload interface, and optional Message.prompt field are correctly defined and documented. The changes integrate cleanly with the existing event type system.

Also applies to: 50-51, 147-150

src/app/api/stream/execute-task/route.ts (4)

38-38: LGTM! Imports follow conventions.

The imports correctly use absolute paths with ~/ prefix and add necessary types for the new prompt generation flow.

Also applies to: 44-45


149-152: LGTM! SSE helper follows existing pattern.

The _emitPromptGenerated helper is consistent with other SSE emission functions (_emitTextDelta, _emitDone) and correctly constructs the PromptGeneratedEvent.


214-215: The addItemToMap method signature correctly accepts the itemType parameter.

The method in src/lib/domains/mapping/services/_item-services/_item-crud.service.ts (line 44+) has itemType: MapItemType as a required parameter in its signature. The code at lines 214-215 correctly passes itemType: MapItemType.SYSTEM when creating the Hexplan item.


308-313: Remove this comment - the code is correct.

The executeTaskStreaming function signature expects 4 parameters: input, agenticService, onChunk, and callbacks?: TaskExecutionCallbacks. The code correctly passes onPromptBuilt as a property of the fourth parameter (callbacks object), not the third parameter. The fourth parameter is properly typed as TaskExecutionCallbacks, which has onPromptBuilt?: (prompt: string) => void defined in the interface.

Likely an incorrect or invalid review comment.

src/app/map/Chat/_state/_events/event.creators.ts (1)

35-35: LGTM! Export addition is consistent.

The createStreamingMessagePromptEvent re-export follows the existing pattern and correctly uses absolute imports.

src/app/map/Chat/_hooks/_streaming-chat-callbacks.ts (1)

40-42: LGTM! Callback implementation is correct.

The onPromptGenerated callback correctly uses the getStreamId() helper to avoid stale closures and follows the same pattern as other callbacks in this function. The implementation properly bridges the streaming event to the chat state.

src/lib/domains/agentic/types/stream.types.ts (3)

32-40: LGTM! Clean event interface definition.

The PromptGeneratedEvent interface follows the established discriminated union pattern and is well-documented. The comment clarifying "full XML prompt" provides helpful context for consumers.


158-166: LGTM! Proper union type extension.

The PromptGeneratedEvent is correctly integrated into the discriminated union, maintaining type safety for event handling.


185-190: LGTM! Type guard follows established pattern.

The type guard implementation is consistent with other guards in the file and properly enables type-safe event handling.

src/app/map/Chat/_state/_selectors/streaming-message-handlers.ts (5)

1-8: LGTM! Proper absolute import usage.

The import follows the coding guideline requirement for absolute imports with ~/ prefix.


13-20: LGTM! Consistent state extension.

The optional prompt field follows the same pattern as the model field and is appropriately documented.


64-74: LGTM! Consistent event handling pattern.

The prompt event handler follows the established defensive pattern used by other streaming event handlers, with proper payload validation and state updates.


87-96: LGTM! Prompt properly included in finalized messages.

The prompt is correctly threaded through from streaming state to the finalized message using optional chaining.


114-124: LGTM! Prompt properly included in streaming messages.

The prompt is consistently included in in-progress streaming messages, maintaining parity with finalized message structure.

Tests now correctly expect that only XML attributes are escaped,
while content bodies preserve raw text for LLM processing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 468ea45 and 4390e49.

📒 Files selected for processing (1)
  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use absolute imports with ~/ prefix instead of relative imports (./ or ../) - this is enforced by ESLint no-restricted-imports rule

Files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
src/lib/domains/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

src/lib/domains/**/*.{ts,tsx}: Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)
Use Domain-Driven Design in src/lib/domains/ with clear boundaries between mapping, IAM, and other domains

Files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
src/lib/domains/agentic/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Vitest for tests (not Jest)

Files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
🧠 Learnings (3)
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use Vitest for tests (not Jest)

Applied to files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/agentic/**/*.{ts,tsx} : Hexplan tiles (direction-0 children) track execution state using exact emoji-prefixed status markers: 🟡 STARTED (task execution began), ✅ COMPLETED (task finished successfully), 🔴 BLOCKED (task stuck, needs intervention). Steps without prefix are pending (📋 for display only)

Applied to files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
📚 Learning: 2026-01-01T14:56:07.704Z
Learnt from: CR
Repo: Diplow/hexframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-01T14:56:07.704Z
Learning: Applies to src/lib/domains/**/*.{ts,tsx} : Use direction values: positive 1-6 for subtask children, negative -1 to -6 for context children, and direction 0 for hexplan (execution state and progress tracking)

Applied to files:

  • src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts
🧬 Code graph analysis (1)
src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts (2)
src/lib/domains/agentic/templates/_prompt-builder.ts (2)
  • PromptData (13-42)
  • buildPrompt (204-213)
src/lib/domains/agentic/utils/prompt-builder.ts (2)
  • PromptData (12-12)
  • buildPrompt (12-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: ESLint
  • GitHub Check: Build
  • GitHub Check: Tests - Phase 1 (Main Suite)
  • GitHub Check: Tests - Phase 2 (React Components)
🔇 Additional comments (3)
src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts (3)

3-3: LGTM!

The import uses the required absolute path with ~/ prefix, consistent with the project's coding guidelines.


7-18: LGTM!

The test helper with the default itemType: MapItemType.SYSTEM properly aligns with the updated PromptData interface and provides a sensible default for test scenarios.


189-191: Implementation correctly handles XML escaping as tested.

Verification confirms the buildPrompt implementation properly implements the escaping policy: XML attributes are escaped via _escapeXML() while content bodies preserve raw text for LLM processing. This behavior is consistently applied across all sections (composed children contexts, subtask previews, task content, and hexplan) and matches all test expectations exactly.

Comment on lines +547 to +575
// ==================== UNSUPPORTED ITEM TYPES ====================
describe('buildPrompt error handling for unsupported itemTypes', () => {
it('should throw error for ORGANIZATIONAL itemType', () => {
const data = createTestData({
task: { title: 'Test', content: 'Content', coords: 'userId,0:1' },
itemType: MapItemType.ORGANIZATIONAL
})

expect(() => buildPrompt(data)).toThrow('ORGANIZATIONAL tiles cannot be executed')
})

it('should throw error for USER itemType', () => {
const data = createTestData({
task: { title: 'Test', content: 'Content', coords: 'userId,0:1' },
itemType: MapItemType.USER
})

expect(() => buildPrompt(data)).toThrow('USER tile templates not yet implemented')
})

it('should throw error for CONTEXT itemType', () => {
const data = createTestData({
task: { title: 'Test', content: 'Content', coords: 'userId,0:1' },
itemType: MapItemType.CONTEXT
})

expect(() => buildPrompt(data)).toThrow('CONTEXT tile templates not yet implemented')
})
})
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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find the buildPrompt implementation and error handling
rg -n 'ORGANIZATIONAL tiles cannot be executed|USER tile templates not yet implemented|CONTEXT tile templates not yet implemented' src/lib/domains/agentic/ -A 2 -B 2

Repository: Diplow/hexframe

Length of output: 2089


🏁 Script executed:

# Look for buildPrompt implementation
fd prompt-builder.ts src/lib/domains/agentic/ | grep -v test

Repository: Diplow/hexframe

Length of output: 159


🏁 Script executed:

# Search for MapItemType enum definition
rg -n 'enum MapItemType|type MapItemType' src/lib/ -A 15

Repository: Diplow/hexframe

Length of output: 4053


🏁 Script executed:

# Find where these errors are thrown in the implementation
rg -n 'throw.*ORGANIZATIONAL|throw.*USER|throw.*CONTEXT' src/lib/domains/agentic/ -B 3 -A 1

Repository: Diplow/hexframe

Length of output: 1671


🏁 Script executed:

# Verify MapItemType enum definition to understand CONTEXT itemType
cat -n src/lib/domains/mapping/_objects/map-item.ts | sed -n '31,45p'

Repository: Diplow/hexframe

Length of output: 534


🏁 Script executed:

# Check how error throwing is implemented in buildPrompt
rg -n 'organizationalNotSupported|userNotImplemented|contextNotImplemented' src/lib/domains/agentic/ -B 2 -A 1

Repository: Diplow/hexframe

Length of output: 1676


Fix ORGANIZATIONAL error message test to verify complete error string.

The ORGANIZATIONAL test on line 555 only checks for a partial error message. The implementation throws 'ORGANIZATIONAL tiles cannot be executed - they are structural groupings only', but the test expects 'ORGANIZATIONAL tiles cannot be executed'. While the partial match passes with Vitest's .toThrow(), the test is incomplete and doesn't verify the full error message.

Update line 555 to:

expect(() => buildPrompt(data)).toThrow('ORGANIZATIONAL tiles cannot be executed - they are structural groupings only')

The USER and CONTEXT tests correctly match their implementation error messages.

Note: MapItemType.CONTEXT (the enum value) does not conflict with the coding guideline's "CONTEXT" for context children with negative directions—they are separate concepts used in different contexts.

🤖 Prompt for AI Agents
In src/lib/domains/agentic/utils/__tests__/prompt-builder.test.ts around lines
547 to 575, update the ORGANIZATIONAL error-message assertion to check the full
error string thrown by buildPrompt; replace the current partial expectation on
line 555 with one that expects "ORGANIZATIONAL tiles cannot be executed - they
are structural groupings only" so the test verifies the complete error message.

@Diplow Diplow merged commit da552f6 into main Jan 2, 2026
16 of 18 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jan 19, 2026
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