Skip to content

Conversation

@rafavalls
Copy link
Collaborator

@rafavalls rafavalls commented Nov 14, 2025

Direct access to all project resources through Home, while created resources automatically appear in the Pinned section for easy access. This is a step that introduces Projects as a scoped App until we get MCPs in our organization.

Screenshot 2025-11-14 at 09 10 12

Summary by CodeRabbit

  • New Features

    • Home tab to view/manage project resources by type (documents, tools, workflows, views, agents)
    • Copy-to-clipboard for tool inputs
    • Auto-pin newly created resources for quick access
  • UI Updates

    • Sidebar reorganized: Home replaces New Thread; MCPs replaces Apps; New Thread moved to Threads
    • Pinned section only shows when tabs exist, with lock/unlock toggle
  • Chores / Migration

    • Removed old default pinned tabs; existing pins migrated/filtered on load

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 14, 2025

Walkthrough

Adds a ProjectHome UI and routes "home://self" to it, restructures the sidebar (HOME and MCPs buttons), introduces optional auto-pinning when opening/creating resources, adds copy-to-clipboard and create-aware auto-open logic in tool messages, and migrates old default pinned tabs to an empty default.

Changes

Cohort / File(s) Summary
ProjectHome & routing
apps/web/src/components/project/home.tsx, apps/web/src/components/canvas/canvas-tab-content.tsx, apps/web/src/components/decopilot/thread-provider.tsx
New ProjectHome component; CanvasTabContent now renders ProjectHome for protocol === "home"; parseResourceUri recognizes home://self and returns { protocol: "home" }.
Sidebar restructuring
apps/web/src/components/sidebar/index.tsx
HOME button now opens home://self detail tab; MCPs button opens apps list; PINNED section renders only when there are pinned tabs; THREADS header/controls reorganized and New thread button present.
Auto-pinning plumbing
apps/web/src/hooks/use-pinned-tabs.ts, apps/web/src/utils/resource-tabs.ts, apps/web/src/components/resources-v2/list.tsx
DEFAULT_PINNED_TABS set to empty with migration of old URIs; openResourceTab gained optional pinTab and shouldPin to auto-pin created/opened tabs; ResourcesV2List calls pinTab after creating new resources.
Tool message enhancements
apps/web/src/components/chat/tool-message.tsx
Adds useSDK/usePinnedTabs usage, detects CREATE ops, passes isCreateOperation/pinTab into auto-open flow, and adds a copy-to-clipboard button with feedback in the header.
Styling tweak
apps/web/src/components/home/project-home.tsx
Adds bg-sidebar class to the chat ResizablePanel for consistent sidebar background styling.

Sequence Diagram(s)

sequenceDiagram
  participant Tool as Tool UI (tool-message)
  participant Utils as openResourceTab
  participant Tabs as Tabs Store (addTab / setActiveTab)
  participant Pins as pinTab (usePinnedTabs)

  Note over Tool: User or auto flow triggers resource open
  Tool->>Utils: openResourceTab(resourceUri, setActiveTab, pinTab?, shouldPin?)
  alt shouldPin == true and pinTab provided
    Utils->>Tabs: addTab({resourceUri, title, type})
    Tabs-->>Utils: tabCreated
    Utils->>Pins: pinTab({resourceUri, title, type:"detail", icon?})
    Pins-->>Tabs: pinned
  else no pin
    Utils->>Tabs: addTab({resourceUri, title, type})
  end
  Utils->>Tabs: setActiveTab(tabId)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas to review closely:

  • Interaction between openResourceTab, the new pinTab/shouldPin parameters, and ResourcesV2List create-success branches.
  • Tool-message changes: create-op detection, auto-open dependency array, and copy-to-clipboard UI/behavior.
  • Sidebar conditional rendering for PINNED and new HOME/MCPs behavior.
  • parseResourceUri addition for home://self and CanvasTabContent routing to ProjectHome.

Possibly related PRs

Suggested reviewers

  • viktormarinho
  • tlgimenes

Poem

🐇 A rabbit hops to open Home,
Pins a tab where new seeds roam,
Copies quick with one small cheer,
New MCPs and threads appear —
Hoppy code, now neatly grown!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The description provides context and motivation but lacks adherence to the required template structure with missing checklist items and no explicit sections for testing/documentation details. Complete the Review Checklist section by checking off applicable items or noting why they don't apply, and add explicit sections for testing confirmation and documentation updates if applicable.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main changes: introducing a Home view for project resources and auto-pinning functionality for created resources.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch valls/pinned-resources

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96ae072 and 9543244.

📒 Files selected for processing (9)
  • apps/web/src/components/canvas/canvas-tab-content.tsx (2 hunks)
  • apps/web/src/components/chat/tool-message.tsx (5 hunks)
  • apps/web/src/components/decopilot/thread-provider.tsx (1 hunks)
  • apps/web/src/components/home/project-home.tsx (1 hunks)
  • apps/web/src/components/project/home.tsx (1 hunks)
  • apps/web/src/components/resources-v2/list.tsx (6 hunks)
  • apps/web/src/components/sidebar/index.tsx (3 hunks)
  • apps/web/src/hooks/use-pinned-tabs.ts (1 hunks)
  • apps/web/src/utils/resource-tabs.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/web/src/components/decopilot/thread-provider.tsx
  • apps/web/src/components/project/home.tsx
  • apps/web/src/components/resources-v2/list.tsx
  • apps/web/src/components/home/project-home.tsx
🧰 Additional context used
🧬 Code graph analysis (3)
apps/web/src/components/chat/tool-message.tsx (3)
packages/sdk/src/hooks/store.tsx (1)
  • useSDK (36-44)
apps/web/src/hooks/use-pinned-tabs.ts (1)
  • usePinnedTabs (50-156)
apps/web/src/utils/resource-tabs.ts (1)
  • openResourceTab (58-112)
apps/web/src/components/sidebar/index.tsx (2)
apps/web/src/hooks/analytics.ts (1)
  • trackEvent (48-61)
apps/web/src/components/decopilot/thread-provider.tsx (1)
  • buildAppsListUri (1011-1013)
apps/web/src/components/canvas/canvas-tab-content.tsx (1)
apps/web/src/components/project/home.tsx (1)
  • ProjectHome (46-117)
🪛 GitHub Actions: Tests
apps/web/src/components/sidebar/index.tsx

[warning] 255-255: ESLint: 'searchParams' is declared but never used. Unused variables should start with a '_'.


[warning] 255-255: ESLint: 'setSearchParams' is declared but never used. Unused variables should start with a '_'.

🔇 Additional comments (18)
apps/web/src/components/canvas/canvas-tab-content.tsx (2)

19-19: LGTM!

The lazy import for ProjectHome follows the established pattern and is appropriate for code-splitting.


305-307: LGTM!

The HOME protocol routing is correctly integrated into the existing routing chain and follows the established pattern.

apps/web/src/components/sidebar/index.tsx (4)

489-509: LGTM!

The HOME button implementation correctly creates a detail tab with home://self URI, which aligns with the new routing in canvas-tab-content.tsx. The tracking event and mobile behavior are properly handled.


511-535: LGTM!

The MCPs button correctly reuses the existing apps list infrastructure while updating the user-facing label and tracking. The implementation is consistent with the HOME button pattern.


537-569: LGTM!

The conditional rendering of the PINNED section is appropriate given the migration to empty default pinned tabs. This creates a cleaner UI when users haven't pinned anything yet.


571-612: LGTM!

The THREADS section reorganization maintains the "New thread" functionality while accommodating the new HOME button. The tracking event and behavior are correctly preserved.

apps/web/src/utils/resource-tabs.ts (3)

69-75: LGTM!

The optional pinTab callback and shouldPin flag parameters maintain backward compatibility and follow good design patterns. The default value of false for shouldPin prevents unexpected auto-pinning.


92-92: LGTM!

Extracting the title into a variable for reuse is a good refactor and maintains the existing logic.


102-110: LGTM!

The auto-pin logic correctly checks both conditions and provides consistent tab information to pinTab. The placement after addTab ensures proper tab creation order.

apps/web/src/components/chat/tool-message.tsx (6)

1-1: LGTM!

The new imports are necessary for the pinning functionality and are used appropriately in the component.

Also applies to: 29-29


694-695: LGTM!

The hooks are correctly placed and chained. Using the locator from useSDK ensures project-specific pinned tab storage.


779-805: LGTM!

The auto-open effect correctly handles the resource tab opening flow with proper guards against duplicate opens. The dependency array is comprehensive and includes all referenced values.


808-828: LGTM!

The distinction between automatic pinning (on creation) and manual clicks (no pinning) is well-documented and intentional. This provides a good user experience where only newly created resources are auto-pinned.


741-745: LGTM!

The copy-to-clipboard implementation follows established patterns and provides good user feedback with the tooltip and icon change. The conditional rendering ensures the button only appears when there's input to copy.

Also applies to: 830-855


773-776: Code pattern is well-established and correctly verified.

The _CREATE suffix is consistently used across all CREATE operations in the codebase (e.g., DECO_CHAT_RESOURCES_CREATE, PROJECTS_CREATE, AGENTS_CREATE, DECO_RESOURCE_TOOL_CREATE). This naming convention is documented in the SDK and uniformly applied in tool registration, making the isCreateOperation detection reliable.

apps/web/src/hooks/use-pinned-tabs.ts (3)

31-42: LGTM!

The OLD_DEFAULT_NATIVE_URIS constant is well-documented and appropriately scoped for migration purposes. This allows clean removal of old defaults while preserving the migration path.


44-48: LGTM!

The migration to an empty default aligns with the PR objectives of making pinning fully user-controlled. The documentation clearly explains the intentional behavior change.


52-66: LGTM!

The migration logic cleanly removes old default native view pins while preserving any user-pinned tabs. This provides a smooth upgrade path without requiring manual user intervention.


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
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 (6)
apps/web/src/utils/resource-tabs.ts (1)

92-92: Potential undefined title fallback.

The .pop() method can return undefined if the array is empty. While this is unlikely for a resource URI, the fallback to "Resource" only happens when the result is falsy, not specifically undefined.

Consider making the fallback more explicit:

-    const title = resourceUri.split("/").pop() || "Resource";
+    const title = resourceUri.split("/").pop() ?? "Resource";

Using the nullish coalescing operator (??) makes it clearer that you're handling undefined.

apps/web/src/components/project/home.tsx (1)

91-93: Consider handling more connection types.

The current implementation only handles connection.type === "HTTP" and falls back to "Unknown connection" for all other types. If other connection types (e.g., WebSocket, SSE) are valid and expected, consider handling them explicitly.

If other types are expected, consider:

-                      {selfIntegration.connection?.type === "HTTP"
-                        ? selfIntegration.connection.url
-                        : "Unknown connection"}
+                      {selfIntegration.connection?.type === "HTTP" && selfIntegration.connection.url
+                        ? selfIntegration.connection.url
+                        : selfIntegration.connection?.type === "STDIO"
+                        ? "Standard I/O"
+                        : "Unknown connection"}
apps/web/src/components/sidebar/index.tsx (4)

488-507: Avoid opening duplicate Home tabs; reuse existing tab when possible

The Home button always calls addTab with resourceUri: "home://self" without checking for an existing Home tab, unlike renderPinnedTab, which reuses existing tabs by resourceUri. This can lead to multiple identical Home tabs.

Consider reusing an existing Home tab before creating a new one, e.g.:

onClick={() => {
  const existingTab = tabs.find((t) => t.resourceUri === "home://self");
  if (existingTab) {
    setActiveTab(existingTab.id);
  } else {
    addTab({
      type: "detail",
      resourceUri: "home://self",
      title: "Home",
      icon: "home",
    });
  }
  trackEvent("sidebar_navigation_click", { item: "Home" });
  isMobile && toggleSidebar();
}}

510-534: Apply the same “reuse existing tab” pattern for MCPs

Similar to Home, the MCPs button always creates a new list tab for buildAppsListUri(). Given that buildAppsListUri returns a stable URI, repeated clicks may create duplicate MCPs tabs.

Consider mirroring the pattern used in renderPinnedTab (and the suggested Home change) by checking tabs for an existing MCPs tab by resourceUri and calling setActiveTab instead of always addTab.


536-567: Pinned section conditional rendering looks good; minor a11y enhancement possible

The conditional pinnedTabs.length > 0 plus the drag‑mode toggle is a clean improvement—no empty “Pinned” section and a clear affordance for reordering.

You might optionally add aria-pressed={isDragMode} to the drag toggle <button> so assistive tech recognizes it as a stateful toggle, but the current implementation is otherwise solid.


599-611: Close sidebar on mobile after creating a new thread

The New thread button creates a thread and tracks the click but does not close the sidebar on mobile, unlike navigation actions such as Home and MCPs that call isMobile && toggleSidebar().

For consistency and a smoother mobile UX, consider:

onClick={() => {
  createThread();
  trackEvent("sidebar_new_thread_click");
  isMobile && toggleSidebar();
}}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b7708c and 96ae072.

📒 Files selected for processing (9)
  • apps/web/src/components/canvas/canvas-tab-content.tsx (2 hunks)
  • apps/web/src/components/chat/tool-message.tsx (5 hunks)
  • apps/web/src/components/decopilot/thread-provider.tsx (1 hunks)
  • apps/web/src/components/home/project-home.tsx (1 hunks)
  • apps/web/src/components/project/home.tsx (1 hunks)
  • apps/web/src/components/resources-v2/list.tsx (6 hunks)
  • apps/web/src/components/sidebar/index.tsx (3 hunks)
  • apps/web/src/hooks/use-pinned-tabs.ts (1 hunks)
  • apps/web/src/utils/resource-tabs.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
apps/web/src/components/resources-v2/list.tsx (1)
apps/web/src/hooks/use-pinned-tabs.ts (1)
  • usePinnedTabs (50-156)
apps/web/src/components/project/home.tsx (4)
packages/sdk/src/mcp/schema.ts (1)
  • integrations (351-363)
packages/sdk/src/hooks/mcp.ts (1)
  • useIntegrations (141-175)
apps/web/src/components/integrations/common.tsx (1)
  • IntegrationIcon (19-35)
apps/web/src/components/resources-v2/list.tsx (1)
  • ResourcesV2List (1695-1747)
apps/web/src/components/canvas/canvas-tab-content.tsx (2)
apps/web/src/components/project/home.tsx (1)
  • ProjectHome (46-117)
packages/sdk/src/lazy.ts (1)
  • lazy (1-9)
apps/web/src/components/chat/tool-message.tsx (3)
packages/sdk/src/hooks/store.tsx (1)
  • useSDK (36-44)
apps/web/src/hooks/use-pinned-tabs.ts (1)
  • usePinnedTabs (50-156)
apps/web/src/utils/resource-tabs.ts (1)
  • openResourceTab (58-112)
apps/web/src/components/sidebar/index.tsx (3)
apps/web/src/hooks/analytics.ts (1)
  • trackEvent (48-61)
apps/web/src/components/decopilot/thread-provider.tsx (1)
  • buildAppsListUri (1011-1013)
packages/ai/src/agent.ts (1)
  • createThread (899-925)
⏰ 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). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (15)
apps/web/src/components/decopilot/thread-provider.tsx (1)

172-177: LGTM!

The home URI parsing is correctly placed and follows the same pattern as other URI checks. The placement before the agents list check maintains proper precedence.

apps/web/src/components/canvas/canvas-tab-content.tsx (2)

19-19: LGTM!

Lazy loading the ProjectHome component is appropriate and follows the established pattern for other components in this file.


305-307: LGTM!

The routing branch for the home protocol is correctly implemented and follows the same pattern as other protocol handlers.

apps/web/src/components/home/project-home.tsx (1)

72-72: Added background styling to chat panel.

The bg-sidebar class addition provides visual consistency for the chat panel. No functional concerns.

apps/web/src/components/resources-v2/list.tsx (2)

873-881: Auto-pinning newly created documents.

The implementation correctly pins newly created resources only after successful tab creation. The pattern is consistent and appropriate.


973-981: Consistent auto-pinning across all creation flows.

The auto-pinning logic is consistently applied across document templates, AI PRD templates, and generic resource creation. Each flow correctly checks for successful tab creation before pinning.

Also applies to: 1044-1052, 1152-1160

apps/web/src/components/chat/tool-message.tsx (4)

773-776: CREATE operation detection logic.

The detection of CREATE operations using toolName?.includes("_CREATE") is straightforward and aligns with the naming convention used in the codebase.


786-805: Auto-pin on resource creation with proper dependencies.

The effect correctly auto-opens and auto-pins newly created resources. The dependency array includes all necessary values, and the hasOpenedTabRef ensures the effect runs only once per tool call.


812-812: Intentional behavior: Manual clicks don't auto-pin.

The comment correctly clarifies that manual clicks should not trigger auto-pinning, only automatic opens after creation. This is the right UX decision.


830-855: Copy-to-clipboard functionality.

The copy button implementation is clean and uses proper tooltip feedback. The useCopy hook handles the clipboard interaction and state management.

apps/web/src/components/project/home.tsx (1)

46-117: Well-structured ProjectHome component.

The component is cleanly organized with:

  • Proper hook usage and memoization
  • Clear separation of header and content sections
  • Graceful handling of missing integration data
  • Appropriate use of ResourcesV2List for resource management
apps/web/src/hooks/use-pinned-tabs.ts (3)

35-42: Migration constant for old default pins.

The OLD_DEFAULT_NATIVE_URIS constant properly documents the old default pinned tabs that need to be removed during migration.


54-65: Migration removes old default pins on first load.

The migration logic correctly filters out old default native URIs while preserving user-created pins. This runs once when the hook initializes with existing data.

Note: This migration is permanent - once a user loads the updated code, the old defaults are removed from localStorage and won't return even if they revert to an older version. This is typically the desired behavior for this type of migration.


48-48: Design change: Empty default pinned tabs.

The shift from auto-populated defaults to an empty array means users start with a clean slate and manually pin what they want. This aligns with the PR's goal of auto-pinning created resources instead.

apps/web/src/components/sidebar/index.tsx (1)

570-597: Threads section label & structure are consistent with new sidebar UX

Renaming the header to “Threads” and keeping the thread selector action under it aligns well with the new structure and doesn’t introduce any behavioral changes.

@rafavalls rafavalls force-pushed the valls/pinned-resources branch from 96ae072 to 9543244 Compare November 14, 2025 12:23
@cloudflare-workers-and-pages
Copy link

Deploying decocms-admin-frontend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9543244
Status: ✅  Deploy successful!
Preview URL: https://e94e03e0.admin-decocms-frontend.pages.dev
Branch Preview URL: https://valls-pinned-resources.admin-decocms-frontend.pages.dev

View logs

@rafavalls rafavalls closed this Dec 30, 2025
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.

2 participants