Skip to content

Conversation

@shuv1337
Copy link
Collaborator

@shuv1337 shuv1337 commented Dec 11, 2025

Summary

  • Merges upstream sst/opencode tag v1.0.146 into shuvcode fork
  • Resolves all merge conflicts while preserving fork-specific features (shell mode, theme/font pickers)

Changes

  • Updated sync marker to v1.0.146
  • Fixed conflicts in desktop, opencode, and UI packages
  • Added fork-specific icons (type, terminal, droplet) to upstream's icon set
  • Fixed useKittyKeyboard API change in TUI app
  • All typecheck and tests pass

Summary by CodeRabbit

  • New Features

    • Desktop app and IDE extension now available alongside terminal interface
    • Enhanced provider and model selection with a new discovery interface
    • Project colorization and improved session management
    • New routing capability for enterprise integration
  • Documentation

    • Updated messaging to reflect availability as terminal, desktop app, and IDE extension
  • UI/UX Improvements

    • New list and dialog components for better selection workflows

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

rekram1-node and others added 30 commits December 10, 2025 14:48
Co-authored-by: Ingo Fruend <ingo@oudyo.com>
- Tauri app now automatically finds an available port instead of defaulting to 4096
- Icon discovery feature is now enabled by default in the Tauri app
- Prevents port conflicts when multiple OpenCode instances are running
Frontend now receives the server port via window.__OPENCODE__.port,
allowing it to connect when using a random free port instead of hardcoded 4096
Signed-off-by: Christian Stewart <christian@aperture.us>
…co#5337)

Signed-off-by: Christian Stewart <christian@aperture.us>
AyushWalekar and others added 21 commits December 10, 2025 21:56
- Add og:image and twitter:image meta tags for better social sharing
- Generate dynamic social card URLs with session title, models, and version
- Include description meta tag for search engines
- Add og:image and twitter:image meta tags to entry-server
- Provide fallback social card image for pages without specific social cards
Resolved conflicts:
- .github/workflows/* - Keep ours (fork-specific)
- packages/desktop/src/components/prompt-input.tsx - Merged shell mode + model dialog
- packages/desktop/src/context/global-sync.tsx - Added ProviderListResponse
- packages/desktop/src/context/layout.tsx - Merged theme/font + dialog
- packages/desktop/src/pages/home.tsx - Fixed project property
- packages/opencode/src/cli/cmd/tui/routes/session/index.tsx - Fixed indentation
- packages/opencode/src/session/prompt.ts - Added error handling
- packages/ui/src/components/icon.tsx - Merged icons from both sides
- packages/ui/src/components/select-dialog.tsx - Added actions prop, kept custom props
Resolved conflicts:
- .github/workflows/* - Keep ours (fork-specific)
- packages/desktop/src/components/prompt-input.tsx - Merged shell mode + model dialog
- packages/desktop/src/context/global-sync.tsx - Added ProviderListResponse
- packages/desktop/src/context/layout.tsx - Merged theme/font + dialog
- packages/desktop/src/pages/home.tsx - Fixed project property
- packages/opencode/src/cli/cmd/tui/routes/session/index.tsx - Fixed indentation
- packages/opencode/src/cli/cmd/tui/app.tsx - Fixed useKittyKeyboard API
- packages/opencode/src/session/prompt.ts - Added error handling
- packages/ui/src/components/icon.tsx - Used upstream icons, added fork-specific (type, terminal, droplet)
- packages/ui/src/components/select-dialog.tsx - Added actions prop, kept custom props
@coderabbitai
Copy link

coderabbitai bot commented Dec 11, 2025

Walkthrough

Version 1.0.143 to 1.0.146 release: infrastructure domain updates, provider/model system refactoring in desktop app, new global server disposal endpoint, session archiving support, UI component overhauls (List, Tag, SelectDialog), console reverse proxy route, and open-source documentation updates.

Changes

Cohort / File(s) Summary
Version bumps (1.0.143 → 1.0.146)
.github/last-synced-tag, packages/console/app/package.json, packages/console/core/package.json, packages/console/function/package.json, packages/console/mail/package.json, packages/desktop/package.json, packages/extensions/zed/extension.toml, packages/function/package.json, packages/opencode/package.json, packages/plugin/package.json, packages/sdk/js/package.json, packages/slack/package.json, packages/tauri/package.json, packages/ui/package.json, packages/util/package.json, packages/web/package.json, sdks/vscode/package.json
Version bumped across all packages and platform archives.
Infrastructure & domain configuration
infra/stage.ts, infra/enterprise.ts
New shortDomain constant computed per stage; SolidStart instance renamed from enterprise to teams with updated domain configuration.
Dependency & hash updates
nix/hashes.json, package.json, packages/enterprise/package.json
nodeModules hash updated; @pierre/precision-diffs bumped to 0.6.1; js-base64 dependency added to enterprise.
Documentation & messaging
README.md, packages/console/app/src/app.tsx, packages/console/app/src/config.ts, packages/console/app/src/routes/index.tsx, packages/enterprise/src/entry-server.tsx, packages/web/...*
Messaging updated to reflect open-source availability; feature stats updated; social preview meta tags removed; provider documentation added.
Console reverse proxy
packages/console/app/src/routes/t/[...path].tsx
New reverse proxy route forwarding to enterprise.opencode.ai for all HTTP methods.
Desktop global state restructure
packages/desktop/src/context/global-sync.tsx, packages/desktop/src/context/sync.tsx
Provider data changed from Provider[] to ProviderListResponse; projects array renamed to project; storage and sync logic updated.
Desktop project & session management
packages/desktop/src/context/layout.tsx, packages/desktop/src/context/local.tsx, packages/desktop/src/context/session.tsx, packages/desktop/src/pages/home.tsx
Project colorization and enrichment added; model validity checks updated for new provider structure; session/home pages adapted to new state shape.
Desktop provider selection
packages/desktop/src/components/prompt-input.tsx, packages/desktop/src/hooks/use-providers.ts, packages/desktop/src/pages/layout.tsx
Model selection UI rewritten with dialog-driven approach; new useProviders hook for provider filtering and categorization; layout sidebar updated with provider connection workflow.
Desktop window augmentation
packages/desktop/src/app.tsx, packages/tauri/src/lib.rs, packages/tauri/src/index.tsx
Window.OPENCODE declaration moved from Tauri to desktop app; port resolution refactored with ephemeral port fallback; updater state handling preserved.
Server API expansion
packages/opencode/src/server/server.ts, packages/sdk/openapi.json
New /global/dispose endpoint; Path schema extended with home field; Session/Project schemas extended with archived timestamp.
Session & sharing
packages/opencode/src/session/index.ts, packages/opencode/src/session/compaction.ts, packages/opencode/src/session/prompt.ts, packages/opencode/src/share/share-next.ts
Session.Info.time.archived added; ShareNext now used exclusively; continuation prompt logic updated; enterprise URL resolution centralized.
CLI & TUI updates
packages/opencode/src/cli/cmd/auth.ts, packages/opencode/src/cli/cmd/tui/app.tsx, packages/opencode/src/cli/cmd/tui/context/directory.ts, packages/opencode/src/cli/cmd/tui/context/sync.tsx, packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
Plugin auth flow extracted to helper; keyboard config object format; terminal title updated; path data integration; session UI rendering enhanced with connectors.
Bus & event definitions
packages/opencode/src/bus/index.ts, packages/opencode/src/project/instance.ts
InstanceDisposed event definition refactored; GlobalBus integration on instance disposal.
Provider system
packages/opencode/src/provider/provider.ts, packages/opencode/src/provider/transform.ts, packages/opencode/src/project/project.ts, packages/opencode/src/flag/flag.ts
Cerebras loader added; reasoning_content transform bug guards added; gemini-3 thinking config refined; new OPENCODE_EXPERIMENTAL_ICON_DISCOVERY flag.
Tool documentation
packages/opencode/src/tool/bash.txt, packages/opencode/test/tool/bash.test.ts
Bash tool description now required; extended permission test suite covering patterns, denies, external directory, and git operations.
UI components — new/major
packages/ui/src/components/list.tsx, packages/ui/src/components/list.css, packages/ui/src/components/tag.tsx, packages/ui/src/components/tag.css
New List component with filtering, grouping, keyboard navigation, and active/selected state; new Tag component with size variants.
UI components — refactored
packages/ui/src/components/select-dialog.tsx, packages/ui/src/components/select-dialog.css, packages/ui/src/components/dialog.tsx, packages/ui/src/components/dialog.css
SelectDialog refactored to use List internally; dialog width reduced, margins adjusted, spacing tweaked; close button now ghost-styled.
UI component updates
packages/ui/src/components/avatar.tsx, packages/ui/src/components/button.css, packages/ui/src/components/icon.tsx, packages/ui/src/components/input.tsx, packages/ui/src/components/input.css, packages/ui/src/components/provider-icon.tsx
Avatar src extraction; button padding adjusted; icon viewBox updated, newIcons removed, icons expanded; input hidden prop added; provider-icon prop renamed name → id.
UI theme & cleanup
packages/ui/src/styles/theme.css, packages/ui/src/styles/tailwind/index.css, packages/ui/src/styles/index.css, packages/ui/index.html, packages/ui/src/demo.tsx, packages/ui/src/index.tsx, packages/ui/src/index.css
New radius tokens (--radius-xs, --radius-xl) added; component import order updated; demo file, bootstrap index, and root HTML removed; package script cleaned up.
Enterprise routes
packages/enterprise/src/routes/index.tsx, packages/enterprise/src/routes/share/[shareID].tsx, packages/enterprise/vite.config.ts
Default Hello World route added; share route extended with dynamic og:image generation, robots meta, and shareID propagation; nitro baseURL injected from env.
MCP configuration
.opencode/opencode.jsonc
MCP provider configuration block (exa.mcp, morph) removed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Provider/model state restructuring: Deep changes to global-sync, layout, local, and session contexts — verify all provider lookups transition correctly from Provider[] to ProviderListResponse structure and that filtering/selection logic is consistent across components.
  • Desktop prompt-input UI rewrite: Modal-driven approach replaces inline picker; verify dialog open/close state management, provider connection flow, and interaction with new useProviders hook are robust.
  • Server API contract changes: New /global/dispose endpoint, Path.home field addition, and time.archived fields — confirm OpenAPI schema matches implementation, migrations handle archived field, and endpoint response handling is correct.
  • Session sharing refactoring: ShareNext now exclusive path; validate that all sharing flows use new URL resolution, archived timestamp is persisted correctly, and enterprise/opncd.ai routing is consistent.
  • List/SelectDialog component interaction: New List component with grouping/filtering is now critical to model/provider selection — verify keyboard navigation, scroll behavior, active state tracking, and empty state rendering work end-to-end.
  • UI layout cascade: Dialog sizing, spacing, and margin adjustments touch multiple files; ensure responsive behavior and dark mode theming remain consistent.

Possibly related issues

Possibly related PRs

  • sync: merge upstream v1.0.129 #79: Both update .github/last-synced-tag to sync upstream version state; related via version management.
  • sync: merge upstream v1.0.130 #81: Overlaps provider/model transformation and session tooling changes (provider/transform.ts, provider.ts, session/prompt.ts); related at code level for provider system consistency.
  • sync: merge upstream v1.0.141 #103: Both update .github/last-synced-tag and share overlapping desktop sync/layout context changes (global-sync.tsx, layout.tsx); related via state management refactoring.

Poem

🐰 A rabbit hops through version land,
From 1.4.3 to 1.4.6, so grand!
Providers dance in new formations,
Dialogs bloom with fresh creations,
Desktop app bounces, open-source bright—
Three releases, one big delight! 🌟

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.03% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: merging upstream v1.0.146 into the integration branch. It is specific, action-oriented, and directly related to the changeset.
✨ 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 opencode/issue114-20251211062613

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.

@opencode-agent
Copy link

User coderabbitai[bot] does not have write permissions

github run

Copy link

@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: 17

Caution

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

⚠️ Outside diff range comments (2)
packages/web/astro.config.mjs (1)

37-40: Fix typo in Discord social link label

The label is currently "Dscord"; this will surface directly in the UI.

Here’s a minimal fix:

-        { icon: "discord", label: "Dscord", href: config.discord },
+        { icon: "discord", label: "Discord", href: config.discord },
packages/sdk/openapi.json (1)

1180-1195: Making time required in session.update request body is likely a breaking change

The PATCH body for /session/{sessionID} now has:

"properties": { "title": ..., "time": { ... } },
"required": ["time"]

This forces all callers to send a time object even when only updating title, and time.archived itself is optional. That’s a behavior change from a typical PATCH semantics and will break any existing clients that only send title.

Unless you explicitly want to require time on every update, I’d drop the "required": ["time"] here and rely on server-side validation for time.archived when present.

🧹 Nitpick comments (20)
infra/stage.ts (1)

15-19: shortDomain helper is coherent; consider reducing duplicated stage logic later

The stage → shortDomain mapping is consistent and matches the main domain pattern, just on the opncd.ai base. Over time, you may want to centralize the stage branching (e.g., a small helper that returns the dev/<stage>.dev prefix) so domain and shortDomain can’t drift if new stages are added.

packages/ui/src/components/input.tsx (1)

10-10: Consider a more robust hiding mechanism.

Setting height: 0 collapses the visual height but keeps the element in the document flow, which may cause layout issues or allow focus/interaction. Consider using a CSS class with display: none or adding aria-hidden="true" when hidden is true for better accessibility and clarity.

Apply this diff to improve the hiding behavior:

-    <Kobalte
-      data-component="input"
-      style={{ height: local.hidden ? 0 : undefined }}
-      value={local.value}
-      onChange={local.onChange}
-      onKeyDown={local.onKeyDown}
-    >
+    <Kobalte
+      data-component="input"
+      style={{ display: local.hidden ? "none" : undefined }}
+      aria-hidden={local.hidden}
+      value={local.value}
+      onChange={local.onChange}
+      onKeyDown={local.onKeyDown}
+    >

Also applies to: 18-18, 26-32

packages/opencode/src/provider/transform.ts (1)

77-87: Track the temporary bug guard for removal.

The bug guard for kimi-k2-thinking and moonshotai/Kimi-K2-Thinking is marked with TODO: rm later, indicating it's a temporary workaround. Consider creating a tracking issue to ensure this gets revisited once the underlying model issues are resolved.

packages/ui/src/components/list.css (1)

100-111: Consider removing !important declarations.

Using !important (lines 101 and 109) is typically a code smell indicating specificity conflicts. If these are needed to override inline styles or external CSS, consider restructuring the selectors or using more specific selectors instead.

         &[data-active="true"] {
           border-radius: var(--radius-md);
           background: var(--surface-raised-base-hover);
           [data-slot="list-item-active-icon"] {
             display: block;
           }
           [data-slot="list-item-extra-icon"] {
-            color: var(--icon-strong-base) !important;
+            color: var(--icon-strong-base);
           }
         }
         &:active {
           background: var(--surface-raised-base-active);
         }
         &:hover {
           [data-slot="list-item-extra-icon"] {
-            color: var(--icon-strong-base) !important;
+            color: var(--icon-strong-base);
           }
         }
packages/opencode/src/cli/cmd/auth.ts (2)

38-39: Clarify the purpose of this artificial delay.

The 10ms setTimeout wrapped in a Promise appears to be a workaround. If this is to allow the terminal to render before showing prompts, consider adding a comment explaining the intent. If it's no longer needed, it should be removed.

   // Handle prompts for all auth types
-  await new Promise((resolve) => setTimeout(resolve, 10))
+  // Brief delay to allow terminal rendering before showing prompts
+  await new Promise((resolve) => setTimeout(resolve, 10))

65-138: Consider extracting duplicated OAuth success handling.

Lines 82-101 and 114-133 contain nearly identical logic for handling OAuth success results (checking for refresh vs key, calling Auth.set). Consider extracting this to a helper function to reduce duplication.

async function saveAuthResult(result: { type: "success"; provider?: string; refresh?: string; access?: string; expires?: number; key?: string }, defaultProvider: string) {
  const saveProvider = result.provider ?? defaultProvider
  if ("refresh" in result) {
    const { type: _, provider: __, refresh, access, expires, ...extraFields } = result
    await Auth.set(saveProvider, { type: "oauth", refresh, access, expires, ...extraFields })
  }
  if ("key" in result) {
    await Auth.set(saveProvider, { type: "api", key: result.key })
  }
}
packages/ui/src/components/list.tsx (1)

72-86: Consider whether Escape should trigger onKeyEvent before returning.

Currently, pressing Escape returns early (line 74) without calling props.onKeyEvent. This means parent components cannot intercept Escape key events via the onKeyEvent callback. If this is intentional (Escape is handled at a higher level, e.g., dialog close), this is fine. Otherwise, consider:

  const handleKey = (e: KeyboardEvent) => {
    setStore("mouseActive", false)
-   if (e.key === "Escape") return
+   if (e.key === "Escape") {
+     props.onKeyEvent?.(e, undefined)
+     return
+   }
packages/desktop/src/components/prompt-input.tsx (1)

793-793: Hidden input for keyboard capture is a valid workaround but could use a comment.

This hidden input with autofocus is used to capture keyboard events for the list. Consider adding a brief comment explaining its purpose for future maintainers.

+{/* Hidden input to capture keyboard events for list navigation */}
 <Input hidden type="text" class="opacity-0 size-0" autofocus onKeyDown={handleKey} />
packages/opencode/src/server/server.ts (1)

795-798: Consider making the time object itself optional.

The time object has only optional fields, but the object itself is required by the current schema. If a client only wants to update title, they would need to pass an empty time object.

 validator(
   "json",
   z.object({
     title: z.string().optional(),
-    time: z.object({
+    time: z.object({
       archived: z.number().optional(),
-    }),
+    }).optional(),
   }),
 ),
packages/desktop/src/pages/layout.tsx (1)

600-601: TODO comment for icon cleanup should be tracked.

There's a TODO comment about cleaning up the opencode icon sizing after updating the icon in models.dev. Consider creating an issue to track this.

Would you like me to help create an issue to track this icon cleanup task?

packages/sdk/openapi.json (1)

34-58: /global/dispose endpoint response shape is consistent but lacks request parameters

The new /global/dispose POST mirrors /instance/dispose in returning a bare boolean, which is consistent. However, unlike /instance/dispose, it has no query parameters or request body at all, which means clients cannot scope or annotate the disposal call (e.g., by directory).

If the intention is truly “dispose everything regardless of directory,” this is fine. If you anticipate needing any scoping or metadata in the future, consider adding a minimal request body or query parameter now for forward compatibility.

packages/opencode/test/tool/bash.test.ts (1)

39-433: Bash permission and external_directory tests are thorough; watch for brittle message matching

The new describe("tool.bash permissions") suite does a good job covering:

  • allow/deny pattern precedence and wildcard deny
  • specific overrides (ls *, pwd*) versus general "*": "deny"
  • blocking dangerous find ... -delete/-exec forms while allowing safe find
  • differentiating git read commands from write commands
  • external_directory: "deny" for both cd outside project and workdir outside project
  • chained commands (echo && curl) where a later denied command cancels the whole sequence

Two minor nits:

  • Several expectations assert .rejects.toThrow("restricted"). If the error message text ever changes, tests will break unnecessarily. Consider relaxing these to .rejects.toThrow() or to a more specific error class if you export one from Permission.
  • The workdir: "/tmp" case assumes a POSIX‑style filesystem. If you care about Windows test runs, you may want to derive this from os.tmpdir() (or re‑use the path from tmp.path) instead of hardcoding /tmp.

Otherwise, the structure and assertions are solid and clearly aligned with BashTool’s permission model.

packages/ui/src/components/select-dialog.tsx (2)

21-35: Scroll‑into‑view effect is simple but depends on data-key contract

The effect:

if (!props.current) return
const key = props.key(props.current)
const element = document.querySelector(`[data-key="${key}"]`)
element?.scrollIntoView({ block: "center" })

is straightforward and should work as long as List consistently renders each item with a matching data-key attribute.

If you ever change List’s internal markup (e.g., different attribute name or scoping), this will silently stop working. Consider, longer‑term, delegating this to ListRef (e.g., a scrollToCurrent() method) to keep the contract type‑safe.


52-81: Header/actions and input/clear control are well‑structured

  • Conditionally rendering actions and hiding the default close button when actions exist keeps the header flexible.
  • The filter input is wired correctly to filter()/setFilter, disables browser text helpers, and the clear button is only shown when there is an active filter.

Only minor note: inputRef is never used; you can drop it unless you plan to focus or manipulate the input programmatically later.

packages/desktop/src/context/layout.tsx (6)

10-10: Type-only import for Project (optional).

Project appears to be used purely as a type. Consider switching to a type-only import (import type { Project } from "@opencode-ai/sdk/v2") to avoid pulling a runtime symbol into the bundle and keep things a bit cleaner.


12-23: Prefer theme tokens / CSS variables instead of hard-coded hex colors.

Defining PASTEL_COLORS as raw hex values bypasses the Tailwind + custom CSS-variable theme system. Consider expressing these as theme tokens (e.g., CSS variables resolved via the theme) or centralizing them in the theme so they participate in theming and remain consistent with the rest of the design system.

As per coding guidelines, prefer the Tailwind + CSS variables theme system over inline hex colors.


59-63: Color selection behavior after palette exhaustion (optional enhancement).

Once every pastel has been used, pickAvailableColor falls back to picking a random color from the full palette for newly colorized projects, which is fine but means later projects reuse colors arbitrarily. If you ever want a more controlled strategy (e.g., “least-used color” or deterministic color based on project.id/worktree), this helper would be the place to adjust it.


76-86: Avoid side effects and mutations inside the colorize memo pipeline.

colorize both mutates the project object (project.icon = …) and performs an SDK call (globalSdk.client.project.update) but is invoked from within a createMemo (enriched().flatMap(colorize)). In Solid, memoized derived values are expected to be pure; as store.projects / globalSync.data.project churn, this can cause redundant updates and makes the reactive graph harder to reason about.

Consider refactoring along these lines:

  • Keep colorize pure: return a new colorized project value without mutating the input.
  • Move the project.update side effect into a createEffect that watches list() (or enriched()) and, for entries lacking icon.color, assigns a color and calls the SDK once.
  • Optionally track which project IDs you’ve already attempted to persist to avoid double-calling update on repeated reactive runs.

This keeps derived state pure and isolates network I/O in effects, which aligns better with Solid’s reactive model.


117-118: Promise.all is unnecessary with a void-returning loadProjectSessions.

loadProjectSessions doesn’t return a Promise, so Promise.all(store.projects.map(…)) is effectively just executing the map for its side effects and wrapping an array of undefined in a Promise that you ignore.

You can simplify to:

onMount(() => {
  store.projects.forEach((project) => {
    loadProjectSessions(project.worktree)
  })
})

Or, if you actually want to await the session loads, have loadProjectSessions return the inner session.list promise and keep Promise.all.


204-214: Dialog API is clear; parameterized close is optional.

The dialog namespace (opened accessor plus open/close) keeps dialog state ephemeral and constrained to "provider" | "model", which is good. Since only one dialog can be open at a time, you could optionally simplify close to take no argument and always clear open, but the current parameterized form is also fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af6e630 and 503d678.

⛔ Files ignored due to path filters (52)
  • bun.lock is excluded by !**/*.lock
  • packages/sdk/js/src/v2/gen/sdk.gen.ts is excluded by !**/gen/**
  • packages/sdk/js/src/v2/gen/types.gen.ts is excluded by !**/gen/**
  • packages/tauri/src-tauri/icons/128x128.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/128x128@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/32x32.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/64x64.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square107x107Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square142x142Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square150x150Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square284x284Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square30x30Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square310x310Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square44x44Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square71x71Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/Square89x89Logo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/StoreLogo.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/icon.ico is excluded by !**/*.ico
  • packages/tauri/src-tauri/icons/icon.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-20x20@1x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-20x20@2x-1.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-20x20@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-20x20@3x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-29x29@1x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-29x29@2x-1.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-29x29@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-29x29@3x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-40x40@1x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-40x40@2x-1.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-40x40@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-40x40@3x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-512@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-60x60@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-60x60@3x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-76x76@1x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-76x76@2x.png is excluded by !**/*.png
  • packages/tauri/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png is excluded by !**/*.png
📒 Files selected for processing (91)
  • .github/last-synced-tag (1 hunks)
  • .opencode/opencode.jsonc (0 hunks)
  • README.md (1 hunks)
  • infra/enterprise.ts (1 hunks)
  • infra/stage.ts (1 hunks)
  • nix/hashes.json (1 hunks)
  • package.json (1 hunks)
  • packages/console/app/package.json (1 hunks)
  • packages/console/app/src/app.tsx (1 hunks)
  • packages/console/app/src/config.ts (2 hunks)
  • packages/console/app/src/routes/index.tsx (4 hunks)
  • packages/console/app/src/routes/t/[...path].tsx (1 hunks)
  • packages/console/core/package.json (1 hunks)
  • packages/console/function/package.json (1 hunks)
  • packages/console/mail/package.json (1 hunks)
  • packages/desktop/package.json (1 hunks)
  • packages/desktop/src/app.tsx (1 hunks)
  • packages/desktop/src/components/prompt-input.tsx (3 hunks)
  • packages/desktop/src/context/global-sync.tsx (5 hunks)
  • packages/desktop/src/context/layout.tsx (4 hunks)
  • packages/desktop/src/context/local.tsx (4 hunks)
  • packages/desktop/src/context/session.tsx (1 hunks)
  • packages/desktop/src/context/sync.tsx (2 hunks)
  • packages/desktop/src/hooks/use-providers.ts (1 hunks)
  • packages/desktop/src/pages/home.tsx (2 hunks)
  • packages/desktop/src/pages/layout.tsx (8 hunks)
  • packages/enterprise/package.json (2 hunks)
  • packages/enterprise/src/entry-server.tsx (0 hunks)
  • packages/enterprise/src/routes/index.tsx (1 hunks)
  • packages/enterprise/src/routes/share/[shareID].tsx (4 hunks)
  • packages/enterprise/vite.config.ts (1 hunks)
  • packages/extensions/zed/extension.toml (2 hunks)
  • packages/function/package.json (1 hunks)
  • packages/opencode/package.json (1 hunks)
  • packages/opencode/src/bus/index.ts (2 hunks)
  • packages/opencode/src/cli/cmd/auth.ts (3 hunks)
  • packages/opencode/src/cli/cmd/tui/app.tsx (2 hunks)
  • packages/opencode/src/cli/cmd/tui/context/directory.ts (1 hunks)
  • packages/opencode/src/cli/cmd/tui/context/sync.tsx (4 hunks)
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx (2 hunks)
  • packages/opencode/src/flag/flag.ts (1 hunks)
  • packages/opencode/src/project/instance.ts (2 hunks)
  • packages/opencode/src/project/project.ts (1 hunks)
  • packages/opencode/src/provider/provider.ts (1 hunks)
  • packages/opencode/src/provider/transform.ts (2 hunks)
  • packages/opencode/src/server/server.ts (8 hunks)
  • packages/opencode/src/session/compaction.ts (1 hunks)
  • packages/opencode/src/session/index.ts (2 hunks)
  • packages/opencode/src/session/prompt.ts (3 hunks)
  • packages/opencode/src/share/share-next.ts (4 hunks)
  • packages/opencode/src/tool/bash.txt (1 hunks)
  • packages/opencode/test/tool/bash.test.ts (2 hunks)
  • packages/plugin/package.json (1 hunks)
  • packages/sdk/js/package.json (1 hunks)
  • packages/sdk/openapi.json (7 hunks)
  • packages/slack/package.json (1 hunks)
  • packages/tauri/package.json (1 hunks)
  • packages/tauri/src-tauri/capabilities/default.json (1 hunks)
  • packages/tauri/src-tauri/src/lib.rs (4 hunks)
  • packages/tauri/src/index.tsx (0 hunks)
  • packages/ui/index.html (0 hunks)
  • packages/ui/package.json (1 hunks)
  • packages/ui/src/components/avatar.tsx (1 hunks)
  • packages/ui/src/components/button.css (1 hunks)
  • packages/ui/src/components/dialog.css (4 hunks)
  • packages/ui/src/components/dialog.tsx (1 hunks)
  • packages/ui/src/components/icon.tsx (2 hunks)
  • packages/ui/src/components/input.css (1 hunks)
  • packages/ui/src/components/input.tsx (1 hunks)
  • packages/ui/src/components/list.css (1 hunks)
  • packages/ui/src/components/list.tsx (1 hunks)
  • packages/ui/src/components/provider-icon.tsx (2 hunks)
  • packages/ui/src/components/select-dialog.css (2 hunks)
  • packages/ui/src/components/select-dialog.tsx (2 hunks)
  • packages/ui/src/components/tag.css (1 hunks)
  • packages/ui/src/components/tag.tsx (1 hunks)
  • packages/ui/src/demo.tsx (0 hunks)
  • packages/ui/src/index.css (0 hunks)
  • packages/ui/src/index.tsx (0 hunks)
  • packages/ui/src/styles/index.css (2 hunks)
  • packages/ui/src/styles/tailwind/index.css (1 hunks)
  • packages/ui/src/styles/theme.css (1 hunks)
  • packages/util/package.json (1 hunks)
  • packages/web/astro.config.mjs (1 hunks)
  • packages/web/package.json (1 hunks)
  • packages/web/src/content/docs/ecosystem.mdx (1 hunks)
  • packages/web/src/content/docs/index.mdx (2 hunks)
  • packages/web/src/content/docs/permissions.mdx (1 hunks)
  • packages/web/src/content/docs/providers.mdx (1 hunks)
  • packages/web/src/content/docs/sdk.mdx (2 hunks)
  • sdks/vscode/package.json (1 hunks)
💤 Files with no reviewable changes (7)
  • packages/enterprise/src/entry-server.tsx
  • packages/ui/src/index.tsx
  • packages/ui/index.html
  • packages/tauri/src/index.tsx
  • packages/ui/src/demo.tsx
  • .opencode/opencode.jsonc
  • packages/ui/src/index.css
🧰 Additional context used
📓 Path-based instructions (9)
packages/opencode/**/*.ts

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

packages/opencode/**/*.ts: Use Bun with TypeScript ESM modules as the runtime
Organize file structure using namespace-based organization (e.g., Tool.define(), Session.create())
Validate all inputs with Zod schemas
Use Log.create({ service: "name" }) pattern for logging
Use Storage namespace for persistence operations

Files:

  • packages/opencode/src/project/instance.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/provider/provider.ts
  • packages/opencode/src/cli/cmd/tui/context/directory.ts
  • packages/opencode/src/flag/flag.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/project/project.ts
  • packages/opencode/src/share/share-next.ts
  • packages/opencode/src/provider/transform.ts
  • packages/opencode/src/cli/cmd/auth.ts
  • packages/opencode/test/tool/bash.test.ts
  • packages/opencode/src/session/compaction.ts
  • packages/opencode/src/bus/index.ts
  • packages/opencode/src/server/server.ts
packages/opencode/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

packages/opencode/**/*.{ts,tsx,js,jsx}: Use relative imports for local modules, with named imports preferred
Use camelCase for variable and function names
Use PascalCase for classes and namespaces

Files:

  • packages/opencode/src/project/instance.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/provider/provider.ts
  • packages/opencode/src/cli/cmd/tui/context/directory.ts
  • packages/opencode/src/flag/flag.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  • packages/opencode/src/project/project.ts
  • packages/opencode/src/share/share-next.ts
  • packages/opencode/src/cli/cmd/tui/context/sync.tsx
  • packages/opencode/src/cli/cmd/tui/app.tsx
  • packages/opencode/src/provider/transform.ts
  • packages/opencode/src/cli/cmd/auth.ts
  • packages/opencode/test/tool/bash.test.ts
  • packages/opencode/src/session/compaction.ts
  • packages/opencode/src/bus/index.ts
  • packages/opencode/src/server/server.ts
packages/opencode/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)

packages/opencode/**/*.{ts,tsx}: Use Zod schemas for validation and TypeScript interfaces for structure
Use Result patterns for error handling; avoid throwing exceptions in tools

Files:

  • packages/opencode/src/project/instance.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/src/provider/provider.ts
  • packages/opencode/src/cli/cmd/tui/context/directory.ts
  • packages/opencode/src/flag/flag.ts
  • packages/opencode/src/session/index.ts
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  • packages/opencode/src/project/project.ts
  • packages/opencode/src/share/share-next.ts
  • packages/opencode/src/cli/cmd/tui/context/sync.tsx
  • packages/opencode/src/cli/cmd/tui/app.tsx
  • packages/opencode/src/provider/transform.ts
  • packages/opencode/src/cli/cmd/auth.ts
  • packages/opencode/test/tool/bash.test.ts
  • packages/opencode/src/session/compaction.ts
  • packages/opencode/src/bus/index.ts
  • packages/opencode/src/server/server.ts
packages/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

packages/desktop/**/*.{ts,tsx}: Use SolidJS with TypeScript as the primary framework
Use @/ alias for src/ directory imports (e.g., import Button from "@/ui/button")
Use function declarations and splitProps for SolidJS component props
Define interfaces for component props and avoid using any type
Use PascalCase for component names
Use camelCase for variable and function names

Files:

  • packages/desktop/src/pages/home.tsx
  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/app.tsx
  • packages/desktop/src/pages/layout.tsx
  • packages/desktop/src/context/local.tsx
  • packages/desktop/src/context/session.tsx
  • packages/desktop/src/context/layout.tsx
  • packages/desktop/src/context/sync.tsx
  • packages/desktop/src/components/prompt-input.tsx
  • packages/desktop/src/context/global-sync.tsx
packages/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

Apply Prettier formatting with semicolons disabled and 120 character line width

Files:

  • packages/desktop/src/pages/home.tsx
  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/app.tsx
  • packages/desktop/src/pages/layout.tsx
  • packages/desktop/src/context/local.tsx
  • packages/desktop/src/context/session.tsx
  • packages/desktop/src/context/layout.tsx
  • packages/desktop/src/context/sync.tsx
  • packages/desktop/src/components/prompt-input.tsx
  • packages/desktop/src/context/global-sync.tsx
packages/desktop/**/*.{css,ts,tsx}

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

Use TailwindCSS with custom CSS variables theme system for styling

Files:

  • packages/desktop/src/pages/home.tsx
  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/app.tsx
  • packages/desktop/src/pages/layout.tsx
  • packages/desktop/src/context/local.tsx
  • packages/desktop/src/context/session.tsx
  • packages/desktop/src/context/layout.tsx
  • packages/desktop/src/context/sync.tsx
  • packages/desktop/src/components/prompt-input.tsx
  • packages/desktop/src/context/global-sync.tsx
packages/desktop/**/*

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

Use snake_case for file names

Files:

  • packages/desktop/src/pages/home.tsx
  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/app.tsx
  • packages/desktop/src/pages/layout.tsx
  • packages/desktop/src/context/local.tsx
  • packages/desktop/src/context/session.tsx
  • packages/desktop/package.json
  • packages/desktop/src/context/layout.tsx
  • packages/desktop/src/context/sync.tsx
  • packages/desktop/src/components/prompt-input.tsx
  • packages/desktop/src/context/global-sync.tsx
packages/desktop/**/pages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

Place pages in /pages/ directory

Files:

  • packages/desktop/src/pages/home.tsx
  • packages/desktop/src/pages/layout.tsx
packages/desktop/**/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (packages/desktop/AGENTS.md)

Place higher-level components in /components/ directory

Files:

  • packages/desktop/src/components/prompt-input.tsx
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T22:11:23.578Z
Learning: Never create PRs against upstream sst/opencode repository; this is a fork of Latitudes-Dev/shuvcode
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.{ts,tsx} : Use Result patterns for error handling; avoid throwing exceptions in tools

Applied to files:

  • packages/opencode/src/session/prompt.ts
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/tools/**/*.ts : Implement tools with the `Tool.Info` interface including an `execute()` method

Applied to files:

  • packages/opencode/src/session/prompt.ts
  • packages/opencode/test/tool/bash.test.ts
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/tools/**/*.ts : Pass `sessionID` in tool context and use `App.provide()` for dependency injection

Applied to files:

  • packages/opencode/src/session/prompt.ts
  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/app.tsx
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
  • packages/opencode/test/tool/bash.test.ts
  • packages/web/src/content/docs/ecosystem.mdx
  • packages/opencode/src/server/server.ts
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.ts : Organize file structure using namespace-based organization (e.g., `Tool.define()`, `Session.create()`)

Applied to files:

  • packages/opencode/package.json
  • packages/opencode/src/cli/cmd/tui/app.tsx
  • packages/web/src/content/docs/ecosystem.mdx
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.{ts,tsx} : Use Zod schemas for validation and TypeScript interfaces for structure

Applied to files:

  • packages/opencode/package.json
  • packages/sdk/js/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.ts : Validate all inputs with Zod schemas

Applied to files:

  • packages/opencode/package.json
  • packages/sdk/js/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.ts : Use Bun with TypeScript ESM modules as the runtime

Applied to files:

  • packages/opencode/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.{ts,tsx,js,jsx} : Use PascalCase for classes and namespaces

Applied to files:

  • packages/opencode/package.json
  • packages/opencode/src/cli/cmd/tui/app.tsx
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.{ts,tsx,js,jsx} : Use relative imports for local modules, with named imports preferred

Applied to files:

  • packages/opencode/package.json
  • packages/ui/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.ts : Use `Storage` namespace for persistence operations

Applied to files:

  • packages/opencode/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Applies to packages/opencode/**/*.{ts,tsx,js,jsx} : Use camelCase for variable and function names

Applied to files:

  • packages/opencode/package.json
  • packages/opencode/src/cli/cmd/tui/app.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/*.{css,ts,tsx} : Use TailwindCSS with custom CSS variables theme system for styling

Applied to files:

  • packages/ui/src/styles/theme.css
  • packages/ui/src/styles/index.css
  • packages/ui/src/styles/tailwind/index.css
  • packages/desktop/src/context/layout.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/providers/**/*.{ts,tsx} : Place providers in `/providers/` directory

Applied to files:

  • packages/desktop/src/hooks/use-providers.ts
  • packages/desktop/src/pages/layout.tsx
  • packages/desktop/src/context/session.tsx
  • packages/desktop/src/context/sync.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/*.{ts,tsx} : Use `@/` alias for src/ directory imports (e.g., `import Button from "@/ui/button"`)

Applied to files:

  • packages/opencode/src/cli/cmd/tui/context/directory.ts
  • packages/ui/src/components/avatar.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/*.{ts,tsx} : Use function declarations and splitProps for SolidJS component props

Applied to files:

  • packages/ui/src/components/tag.tsx
  • packages/ui/src/components/avatar.tsx
  • packages/ui/src/components/list.tsx
  • packages/ui/src/components/icon.tsx
  • packages/ui/src/components/select-dialog.tsx
  • packages/desktop/src/components/prompt-input.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/*.{ts,tsx} : Use SolidJS with TypeScript as the primary framework

Applied to files:

  • packages/ui/src/components/tag.tsx
  • packages/desktop/src/components/prompt-input.tsx
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Go TUI communicates with TypeScript server via stainless SDK. When adding/modifying server endpoints in `packages/opencode/src/server/server.ts`, ask the user to generate a new client SDK before proceeding with client-side changes

Applied to files:

  • packages/console/app/src/routes/t/[...path].tsx
  • packages/opencode/src/cli/cmd/tui/app.tsx
  • packages/console/app/src/routes/index.tsx
  • packages/web/src/content/docs/sdk.mdx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/*.{ts,tsx} : Use camelCase for variable and function names

Applied to files:

  • packages/opencode/src/cli/cmd/tui/app.tsx
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Applies to packages/desktop/**/ui/**/*.{ts,tsx} : Place UI primitives in `/ui/` directory

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-12-02T19:05:23.634Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:23.634Z
Learning: Use `bun run typecheck` for type checking (or `npm run typecheck` as alternative)

Applied to files:

  • packages/ui/package.json
📚 Learning: 2025-12-02T19:05:12.128Z
Learnt from: CR
Repo: Latitudes-Dev/shuvcode PR: 0
File: packages/desktop/AGENTS.md:0-0
Timestamp: 2025-12-02T19:05:12.128Z
Learning: Use `bun run dev` to start Vite dev server on port 3000 for development

Applied to files:

  • packages/ui/package.json
🧬 Code graph analysis (16)
packages/opencode/src/project/instance.ts (1)
packages/opencode/src/bus/global.ts (1)
  • GlobalBus (3-10)
packages/opencode/src/session/prompt.ts (2)
packages/sdk/js/src/v2/gen/sdk.gen.ts (1)
  • log (1860-1896)
packages/opencode/src/tool/bash.ts (1)
  • log (23-23)
packages/desktop/src/hooks/use-providers.ts (1)
packages/util/src/encode.ts (1)
  • base64Decode (5-7)
packages/opencode/src/session/index.ts (3)
packages/sdk/js/src/v2/gen/sdk.gen.ts (1)
  • share (1062-1085)
packages/sdk/js/src/gen/sdk.gen.ts (1)
  • share (571-576)
packages/desktop/src/context/session.tsx (1)
  • id (115-117)
packages/ui/src/components/dialog.tsx (1)
packages/ui/src/components/icon-button.tsx (1)
  • IconButton (12-28)
packages/ui/src/components/list.tsx (2)
packages/ui/src/hooks/use-filtered-list.tsx (2)
  • FilteredListProps (7-16)
  • useFilteredList (18-90)
packages/ui/src/components/icon.tsx (2)
  • IconProps (54-57)
  • Icon (59-77)
packages/console/app/src/routes/t/[...path].tsx (1)
packages/opencode/src/share/share.ts (1)
  • URL (68-70)
packages/opencode/src/share/share-next.ts (3)
packages/sdk/js/src/v2/gen/types.gen.ts (1)
  • Config (1208-1412)
packages/sdk/js/src/v2/gen/core/types.gen.ts (1)
  • Config (20-74)
packages/opencode/src/session/index.ts (1)
  • share (221-234)
packages/opencode/src/cli/cmd/tui/context/sync.tsx (3)
packages/sdk/js/src/v2/gen/types.gen.ts (1)
  • Path (1424-1430)
packages/sdk/js/src/v2/gen/sdk.gen.ts (1)
  • Path (640-659)
packages/sdk/js/src/gen/types.gen.ts (1)
  • Path (1393-1398)
packages/opencode/test/tool/bash.test.ts (2)
packages/opencode/test/fixture/fixture.ts (1)
  • tmpdir (16-34)
packages/opencode/src/tool/bash.ts (1)
  • BashTool (55-369)
infra/enterprise.ts (1)
infra/stage.ts (1)
  • shortDomain (15-19)
packages/desktop/src/context/layout.tsx (2)
packages/sdk/js/src/v2/gen/types.gen.ts (1)
  • Project (21-35)
packages/sdk/js/src/gen/types.gen.ts (1)
  • Project (749-758)
packages/ui/src/components/select-dialog.tsx (1)
packages/ui/src/components/list.tsx (3)
  • ListProps (6-13)
  • ListRef (15-18)
  • List (20-142)
packages/opencode/src/server/server.ts (2)
packages/opencode/src/project/instance.ts (1)
  • Instance (16-78)
packages/opencode/src/bus/global.ts (1)
  • GlobalBus (3-10)
packages/desktop/src/components/prompt-input.tsx (9)
packages/desktop/src/hooks/use-providers.ts (2)
  • useProviders (8-31)
  • popularProviders (6-6)
packages/ui/src/components/select-dialog.tsx (1)
  • SelectDialog (21-106)
packages/desktop/src/context/layout.tsx (4)
  • open (126-130)
  • open (153-155)
  • open (169-171)
  • open (206-208)
packages/desktop/src/context/session.tsx (1)
  • open (235-237)
packages/ui/src/components/tag.tsx (1)
  • Tag (7-22)
packages/util/src/iife.ts (1)
  • iife (1-3)
packages/ui/src/components/list.tsx (2)
  • ListRef (15-18)
  • List (20-142)
packages/ui/src/components/dialog.tsx (1)
  • Dialog (86-92)
packages/ui/src/components/provider-icon.tsx (1)
  • ProviderIcon (10-24)
packages/desktop/src/context/global-sync.tsx (1)
packages/sdk/js/src/v2/gen/types.gen.ts (2)
  • ProviderListResponse (3135-3135)
  • Project (21-35)
🪛 Biome (2.1.2)
packages/ui/src/components/button.css

[error] 114-114: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

font-size is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

packages/ui/src/styles/tailwind/index.css

[error] 60-60: expected , but instead found --radius-xl

Remove --radius-xl

(parse)


[error] 60-60: Unexpected value or character.

Expected one of:

(parse)


[error] 60-60: expected , but instead found rem

Remove rem

(parse)


[error] 60-60: expected , but instead found ;

Remove ;

(parse)


[error] 60-60: Unknown type selector is not allowed.

See MDN web docs for more details.
Consider replacing the unknown type selector with valid one.

(lint/correctness/noUnknownTypeSelector)

🪛 LanguageTool
packages/web/src/content/docs/providers.mdx

[grammar] ~571-~571: Ensure spelling is correct
Context: ... txt /models --- ### Helicone Helicone is an LLM...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

packages/web/src/content/docs/index.mdx

[grammar] ~10-~10: Use a hyphen to join words.
Context: ...ig.console OpenCode is an open source AI coding agent. It's available a...

(QB_NEW_EN_HYPHEN)

packages/web/src/content/docs/permissions.mdx

[grammar] ~143-~143: Use a hyphen to join words.
Context: ...run a command in a pipeline, we use tree sitter to parse each command in the pipe...

(QB_NEW_EN_HYPHEN)

Comment on lines +3 to +13
async function handler(evt: APIEvent) {
const req = evt.request.clone()
const url = new URL(req.url)
const targetUrl = `https://enterprise.opencode.ai/${url.pathname}${url.search}`
const response = await fetch(targetUrl, {
method: req.method,
headers: req.headers,
body: req.body,
})
return response
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Add authentication, error handling, and fix URL construction.

The proxy handler has several critical issues:

  1. URL Construction Bug (Line 6): The template literal creates a double slash when url.pathname starts with /. Use https://enterprise.opencode.ai${url.pathname}${url.search} instead.

  2. Missing Authentication: No authentication or authorization checks before proxying requests to the enterprise endpoint, potentially exposing the backend to unauthorized access.

  3. No Error Handling: The fetch call lacks error handling. Network failures, timeouts, or non-2xx responses will propagate as unhandled errors.

  4. No Timeout: External calls should have timeout protection to prevent hanging request threads.

  5. Header Leakage: Blindly forwarding all headers (line 9) could leak sensitive client information (cookies, auth tokens, internal headers) to the external service.

  6. Body Streaming: For large request bodies, consider whether the body cloning approach (line 4) is appropriate or if streaming is needed.

Apply this diff to fix the URL construction:

-  const targetUrl = `https://enterprise.opencode.ai/${url.pathname}${url.search}`
+  const targetUrl = `https://enterprise.opencode.ai${url.pathname}${url.search}`

Consider adding authentication, error handling, and timeout:

async function handler(evt: APIEvent) {
  // Add authentication check
  const authHeader = evt.request.headers.get("authorization")
  if (!authHeader || !isValidAuth(authHeader)) {
    return new Response("Unauthorized", { status: 401 })
  }

  const req = evt.request.clone()
  const url = new URL(req.url)
  const targetUrl = `https://enterprise.opencode.ai${url.pathname}${url.search}`
  
  try {
    const controller = new AbortController()
    const timeout = setTimeout(() => controller.abort(), 30000) // 30s timeout
    
    const response = await fetch(targetUrl, {
      method: req.method,
      headers: sanitizeHeaders(req.headers), // Filter sensitive headers
      body: req.body,
      signal: controller.signal,
    })
    
    clearTimeout(timeout)
    return response
  } catch (error) {
    if (error instanceof Error && error.name === 'AbortError') {
      return new Response("Request timeout", { status: 504 })
    }
    return new Response("Proxy error", { status: 502 })
  }
}
🤖 Prompt for AI Agents
In packages/console/app/src/routes/t/[...path].tsx around lines 3 to 13, fix the
URL construction to avoid double slashes by using
`https://enterprise.opencode.ai${url.pathname}${url.search}` and add
authentication, header sanitization, timeout and error handling: check
evt.request.headers.get("authorization") and validate with an isValidAuth helper
returning 401 when missing/invalid; sanitize request headers to remove
cookies/internal headers before forwarding; use an AbortController with a ~30s
timeout and pass its signal to fetch; wrap fetch in try/catch and return 504 for
abort/timeouts and 502 for other errors; continue to forward the request body
but consider streaming for large payloads rather than cloning.

Comment on lines +837 to +839
onSelect={(x) => {
layout.dialog.close("model")
}}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

onSelect handler doesn't trigger provider connection.

The onSelect callback for the popular providers list only closes the dialog but doesn't actually initiate provider connection. This appears to be incomplete—users clicking a provider will see the dialog close without any action being taken.

Consider invoking the provider connection flow:

 onSelect={(x) => {
+  if (x) layout.dialog.open("provider") // or trigger specific provider auth flow
   layout.dialog.close("model")
 }}
🤖 Prompt for AI Agents
In packages/desktop/src/components/prompt-input.tsx around lines 837-839, the
onSelect handler only closes the "model" dialog and does not start the provider
connection; change the handler to pass the selected provider into the existing
provider connection flow (e.g., call the component/store action that
initiates/providerConnect or connectProvider with the selected provider
id/object), await or handle the async result, close the dialog on success (or
still close before connecting if UX requires) and add basic error
handling/feedback for failures so a click actually initiates the connection
process.

Comment on lines +864 to +869
<Button variant="ghost" class="w-full justify-start">
<div class="flex items-center gap-2">
<Icon name="plus-small" />
<div class="text-text-strong">View all providers</div>
</div>
</Button>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

"View all providers" button has no onClick handler.

This button doesn't have an onClick handler, so clicking it does nothing. Users will expect this to navigate to a provider list or open a provider dialog.

Add an onClick handler:

-<Button variant="ghost" class="w-full justify-start">
+<Button variant="ghost" class="w-full justify-start" onClick={() => layout.dialog.open("provider")}>
   <div class="flex items-center gap-2">
     <Icon name="plus-small" />
     <div class="text-text-strong">View all providers</div>
   </div>
 </Button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button variant="ghost" class="w-full justify-start">
<div class="flex items-center gap-2">
<Icon name="plus-small" />
<div class="text-text-strong">View all providers</div>
</div>
</Button>
<Button variant="ghost" class="w-full justify-start" onClick={() => layout.dialog.open("provider")}>
<div class="flex items-center gap-2">
<Icon name="plus-small" />
<div class="text-text-strong">View all providers</div>
</div>
</Button>
🤖 Prompt for AI Agents
packages/desktop/src/components/prompt-input.tsx around lines 864 to 869: the
"View all providers" Button lacks an onClick handler so it does nothing when
clicked; add an onClick prop that invokes the component's provider-opening
behavior — e.g. call an existing handler like openProviders() or
props.onOpenProviders(), or create a small handler that sets local state
(setShowProviders(true)) or routes to the providers view
(router.push('/providers')) depending on how provider UI is implemented; ensure
you import/use the correct function/prop and keep the callback memoized if
needed.

Comment on lines +148 to +157
for (const p of sync.data.provider.connected) {
if (p in sync.data.provider.default) {
return {
providerID: p,
modelID: sync.data.provider.default[p],
}
}
}

throw new Error("No default model found")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Consider graceful degradation when no default model is found.

The fallback logic throws an error if no default model can be found (line 157). While this indicates an invalid app state, throwing an uncaught error at initialization could crash the app without giving users a chance to configure providers.

Consider handling this more gracefully with a user-facing error message or fallback UI state.

Alternative implementation:

-    for (const p of sync.data.provider.connected) {
-      if (p in sync.data.provider.default) {
-        return {
-          providerID: p,
-          modelID: sync.data.provider.default[p],
-        }
-      }
-    }
-
-    throw new Error("No default model found")
+    for (const p of sync.data.provider.connected) {
+      if (p in sync.data.provider.default) {
+        return {
+          providerID: p,
+          modelID: sync.data.provider.default[p],
+        }
+      }
+    }
+
+    // Log warning and return undefined to allow app to handle gracefully
+    console.error("No default model found. Please configure a provider.")
+    return undefined

Then update the calling code to handle the undefined case with a user-friendly message or setup flow.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (const p of sync.data.provider.connected) {
if (p in sync.data.provider.default) {
return {
providerID: p,
modelID: sync.data.provider.default[p],
}
}
}
throw new Error("No default model found")
for (const p of sync.data.provider.connected) {
if (p in sync.data.provider.default) {
return {
providerID: p,
modelID: sync.data.provider.default[p],
}
}
}
// Log warning and return undefined to allow app to handle gracefully
console.error("No default model found. Please configure a provider.")
return undefined
🤖 Prompt for AI Agents
In packages/desktop/src/context/local.tsx around lines 148–157, the current
logic throws an Error("No default model found") when no provider default is
matched; change this to return undefined (or null) instead of throwing so
initialization won't crash, log a debug/warn with context (which provider list
and defaults were present), and update any callers to handle the undefined
result by showing a user-facing fallback state or setup flow (e.g., prompt to
configure providers or show a clear error UI) rather than allowing an uncaught
exception.

const load = {
project: () => sdk.client.project.current().then((x) => setStore("project", x.data!.id)),
provider: () => sdk.client.config.providers().then((x) => setStore("provider", x.data!.providers)),
provider: () => sdk.client.provider.list().then((x) => setStore("provider", x.data!)),
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f \( -name "*.json" -o -name "*.yaml" -o -name "*.yml" \) | grep -E "(openapi|swagger|schema)" | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 93


🏁 Script executed:

git ls-files | grep -E "sdk|client|api" | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 1241


🏁 Script executed:

rg "sdk\.client\.provider\.list\|sdk\.client\.config\.providers" -A 3 -B 3 --type=typescript

Repository: Latitudes-Dev/shuvcode

Length of output: 100


🏁 Script executed:

rg "provider.*list\|providers.*config" --type=json --type=typescript | head -30

Repository: Latitudes-Dev/shuvcode

Length of output: 100


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.paths | keys[] | select(contains("provider"))' 2>/dev/null | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 216


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.paths | keys[] | select(contains("config"))' 2>/dev/null | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 95


🏁 Script executed:

cat -n packages/desktop/src/context/sync.tsx | head -50

Repository: Latitudes-Dev/shuvcode

Length of output: 2565


🏁 Script executed:

cat -n packages/desktop/src/context/sdk.tsx | head -100

Repository: Latitudes-Dev/shuvcode

Length of output: 1294


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.paths["/provider"]' | head -100

Repository: Latitudes-Dev/shuvcode

Length of output: 3703


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.paths["/config/providers"]' | head -100

Repository: Latitudes-Dev/shuvcode

Length of output: 1490


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.components.schemas | keys[] | grep -i provider' 2>/dev/null

Repository: Latitudes-Dev/shuvcode

Length of output: 48


🏁 Script executed:

find packages -name "*.ts" -o -name "*.tsx" | xargs grep -l "createOpencodeClient" | head -5

Repository: Latitudes-Dev/shuvcode

Length of output: 262


🏁 Script executed:

cat packages/sdk/openapi.json | jq '.paths["/provider"].get.responses["200"].content["application/json"].schema' 2>/dev/null

Repository: Latitudes-Dev/shuvcode

Length of output: 7079


🏁 Script executed:

rg "x\.data" packages/desktop/src/context/sync.tsx -B 3 -A 3

Repository: Latitudes-Dev/shuvcode

Length of output: 1336


🏁 Script executed:

find packages -path "*/sdk*" -name "*.ts" | grep -E "client|sdk" | head -10

Repository: Latitudes-Dev/shuvcode

Length of output: 990


🏁 Script executed:

find packages -path "*/sdk*" -type f -name "*.ts" | xargs grep -l "createOpencodeClient" | head -5

Repository: Latitudes-Dev/shuvcode

Length of output: 224


🏁 Script executed:

find packages -path "*/sdk*" -type d | head -10

Repository: Latitudes-Dev/shuvcode

Length of output: 445


🏁 Script executed:

git ls-files packages/sdk | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 873


🏁 Script executed:

cat -n packages/sdk/js/src/v2/client.ts | head -100

Repository: Latitudes-Dev/shuvcode

Length of output: 1048


🏁 Script executed:

wc -l packages/sdk/js/src/v2/client.ts

Repository: Latitudes-Dev/shuvcode

Length of output: 101


🏁 Script executed:

cat -n packages/sdk/js/src/gen/sdk.gen.ts | head -150

Repository: Latitudes-Dev/shuvcode

Length of output: 4551


🏁 Script executed:

rg "ProviderListData|ProviderListResponses" packages/sdk/js/src/gen/client/types.gen.ts -A 10 | head -80

Repository: Latitudes-Dev/shuvcode

Length of output: 48


🏁 Script executed:

rg "ConfigProvidersData|ConfigProvidersResponses" packages/sdk/js/src/gen/client/types.gen.ts -A 10 | head -80

Repository: Latitudes-Dev/shuvcode

Length of output: 48


🏁 Script executed:

wc -l packages/sdk/js/src/gen/client/types.gen.ts

Repository: Latitudes-Dev/shuvcode

Length of output: 113


🏁 Script executed:

cat packages/sdk/js/src/gen/client/types.gen.ts

Repository: Latitudes-Dev/shuvcode

Length of output: 7284


🏁 Script executed:

cat packages/sdk/js/src/gen/client/index.ts | head -100

Repository: Latitudes-Dev/shuvcode

Length of output: 761


🏁 Script executed:

find packages/sdk/js/src/gen -name "*.ts" -type f | xargs wc -l | sort -rn | head -10

Repository: Latitudes-Dev/shuvcode

Length of output: 548


🏁 Script executed:

rg "type ProviderListData|type ProviderListResponses|type ConfigProvidersData|type ConfigProvidersResponses" packages/sdk/js/src/gen/types.gen.ts -A 15

Repository: Latitudes-Dev/shuvcode

Length of output: 906


🏁 Script executed:

grep -n "ProviderList\|ConfigProviders" packages/sdk/js/src/gen/types.gen.ts | head -20

Repository: Latitudes-Dev/shuvcode

Length of output: 424


🏁 Script executed:

cat -n packages/desktop/src/context/sync.tsx | sed -n '1,35p'

Repository: Latitudes-Dev/shuvcode

Length of output: 2024


Fix provider data access pattern to use the all array.

The provider data fetch has changed from sdk.client.config.providers() to sdk.client.provider.list(), with the response structure changing from { providers: [...], default: {...} } to { all: [...], default: {...}, connected: [...] }. Line 17 currently stores the entire response object via x.data!, but should store x.data!.all to match the expected data structure, similar to how session.list() extracts array data.

🤖 Prompt for AI Agents
In packages/desktop/src/context/sync.tsx around line 17, the provider fetch
stores the entire response object (x.data!) but the new API returns { all:
[...], default: {...}, connected: [...] }; change the setter to store
x.data!.all instead of x.data! so the store receives the providers array (match
the pattern used for session.list()).

Comment on lines 108 to +118
font-size: var(--font-size-small);
line-height: var(--line-height-large);
gap: 6px;

/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove duplicate property declarations in normal size button styling.

Lines 108–109 declare font-size and line-height, which are then redeclared on lines 114–117 with identical values. This duplication can cause confusion and maintenance issues.

Consolidate by removing the initial declarations:

  &[data-size="normal"] {
    height: 24px;
    padding: 0 6px;
    &[data-icon] {
      padding: 0 12px 0 4px;
    }

-   font-size: var(--font-size-small);
-   line-height: var(--line-height-large);
    gap: 6px;

    /* text-12-medium */
    font-family: var(--font-family-sans);
    font-size: var(--font-size-small);
    font-style: normal;
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-large); /* 166.667% */
    letter-spacing: var(--letter-spacing-normal);
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
font-size: var(--font-size-small);
line-height: var(--line-height-large);
gap: 6px;
/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
gap: 6px;
/* text-12-medium */
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-style: normal;
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large); /* 166.667% */
letter-spacing: var(--letter-spacing-normal);
🧰 Tools
🪛 Biome (2.1.2)

[error] 114-114: Duplicate properties can lead to unexpected behavior and may override previous declarations unintentionally.

font-size is already defined here.

Remove or rename the duplicate property to ensure consistent styling.

(lint/suspicious/noDuplicateProperties)

🤖 Prompt for AI Agents
In packages/ui/src/components/button.css around lines 108 to 118, the
normal-size button block declares font-size and line-height twice (lines 108–109
and again on 114–117); remove the earlier duplicated declarations (the ones at
lines 108–109) so each property is declared only once in the block, keeping the
semantic comment and the later detailed declarations (font-family, font-size,
font-style, font-weight, line-height, letter-spacing) intact.

Comment on lines +129 to +131
<Show when={props.activeIcon}>
{(icon) => <Icon data-slot="list-item-active-icon" name={icon()} />}
</Show>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Active icon renders for all items - should it be conditional on data-active?

The active icon currently renders for every item when props.activeIcon is provided. Based on the prop name and typical list behavior, it seems like this should only render for the currently active (keyboard-focused) item:

-                      <Show when={props.activeIcon}>
+                      <Show when={props.activeIcon && props.key(item) === active()}>
                         {(icon) => <Icon data-slot="list-item-active-icon" name={icon()} />}
                       </Show>

If the current behavior is intentional (e.g., CSS hides it via [data-active="false"] [data-slot="list-item-active-icon"]), please disregard.

🤖 Prompt for AI Agents
In packages/ui/src/components/list.tsx around lines 129-131, the active icon is
rendered whenever props.activeIcon exists rather than only for the currently
active item; change the condition so the Icon is only rendered when both
props.activeIcon is provided and the item is active (e.g., guard with
props.activeIcon && props.active or check the item's data-active state), so the
Show wrapper only produces the active-icon element for items with
data-active="true".

Comment on lines +83 to +101
<List
ref={(ref) => {
listRef = ref
}}
/>
</Show>
items={others.items}
key={others.key}
filterKeys={others.filterKeys}
current={others.current}
groupBy={others.groupBy}
sortBy={others.sortBy}
sortGroupsBy={others.sortGroupsBy}
emptyMessage={others.emptyMessage}
activeIcon={others.activeIcon}
filter={filter()}
onSelect={handleSelect}
onKeyEvent={others.onKeyEvent}
>
{others.children}
</List>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

onHighlight prop is exposed but never passed through to List

SelectDialogProps<T> defines onHighlight?: (item: T | undefined) => void, but the List invocation only passes:

<List
  ...
  emptyMessage={others.emptyMessage}
  activeIcon={others.activeIcon}
  filter={filter()}
  onSelect={handleSelect}
  onKeyEvent={others.onKeyEvent}
>
  {others.children}
</List>

There’s no onHighlight={others.onHighlight} here, so callers supplying onHighlight on SelectDialog will never see it fire. This is a behavioral regression compared to wiring FilteredList directly.

Forward onHighlight to List to restore the callback:

-            onSelect={handleSelect}
-            onKeyEvent={others.onKeyEvent}
+            onSelect={handleSelect}
+            onKeyEvent={others.onKeyEvent}
+            onHighlight={others.onHighlight}
🤖 Prompt for AI Agents
In packages/ui/src/components/select-dialog.tsx around lines 83 to 101 the
SelectDialog forwards many props to the inner List but omits the onHighlight
prop, so any onHighlight passed to SelectDialog is never forwarded; fix by
adding onHighlight={others.onHighlight} to the List props (ensure the prop is
passed through as-is and matches the List's expected signature, allowing
undefined).

Comment on lines +135 to +145
#### Scope of the `"ask"` option

When the agent asks for permission to run a particular bash command, it will
request feedback with the three options "accept", "accept always" and "deny".
The "accept always" answer applies for the rest of the current session.

In addition, command permissions are applied to the first two elements of a command. So, an "accept always" response for a command like `git log` would whitelist `git log *` but not `git commit ...`.

When an agent asks for permission to run a command in a pipeline, we use tree sitter to parse each command in the pipeline. The "accept always" permission thus applies separately to each command in the pipeline.

---
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hyphenate the tool name "tree-sitter".

The proper name of the tool should be hyphenated as "tree-sitter" rather than "tree sitter".

Apply this diff to fix the tool name:

-When an agent asks for permission to run a command in a pipeline, we use tree sitter to parse each command in the pipeline. The "accept always" permission thus applies separately to each command in the pipeline.
+When an agent asks for permission to run a command in a pipeline, we use tree-sitter to parse each command in the pipeline. The "accept always" permission thus applies separately to each command in the pipeline.
🧰 Tools
🪛 LanguageTool

[grammar] ~143-~143: Use a hyphen to join words.
Context: ...run a command in a pipeline, we use tree sitter to parse each command in the pipe...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In packages/web/src/content/docs/permissions.mdx around lines 135 to 145, the
tool name "tree sitter" is written without a hyphen; update the text to use the
correct hyphenated form "tree-sitter" (replace the occurrence "tree sitter" with
"tree-sitter") so the documentation uses the proper tool name.

Comment on lines +571 to +681
### Helicone

[Helicone](https://helicone.ai) is an LLM observability platform that provides logging, monitoring, and analytics for your AI applications. The Helicone AI Gateway routes your requests to the appropriate provider automatically based on the model.

1. Head over to [Helicone](https://helicone.ai), create an account, and generate an API key from your dashboard.

2. Run the `/connect` command and search for **Helicone**.

```txt
/connect
```

3. Enter your Helicone API key.

```txt
┌ API key
└ enter
```

4. Run the `/models` command to select a model.

```txt
/models
```

For more providers and advanced features like caching and rate limiting, check the [Helicone documentation](https://docs.helicone.ai).

#### Optional Configs

In the event you see a feature or model from Helicone that isn't configured automatically through opencode, you can always configure it yourself.

Here's [Helicone's Model Directory](https://helicone.ai/models), you'll need this to grab the IDs of the models you want to add.

```jsonc title="~/.config/opencode/opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"helicone": {
"npm": "@ai-sdk/openai-compatible",
"name": "Helicone",
"options": {
"baseURL": "https://ai-gateway.helicone.ai",
},
"models": {
"gpt-4o": {
// Model ID (from Helicone's model directory page)
"name": "GPT-4o", // Your own custom name for the model
},
"claude-sonnet-4-20250514": {
"name": "Claude Sonnet 4",
},
},
},
},
}
```

#### Custom Headers

Helicone supports custom headers for features like caching, user tracking, and session management. Add them to your provider config using `options.headers`:

```jsonc title="~/.config/opencode/opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"helicone": {
"npm": "@ai-sdk/openai-compatible",
"name": "Helicone",
"options": {
"baseURL": "https://ai-gateway.helicone.ai",
"headers": {
"Helicone-Cache-Enabled": "true",
"Helicone-User-Id": "opencode",
},
},
},
},
}
```

##### Session tracking

Helicone's [Sessions](https://docs.helicone.ai/features/sessions) feature lets you group related LLM requests together. Use the [opencode-helicone-session](https://github.com/H2Shami/opencode-helicone-session) plugin to automatically log each OpenCode conversation as a session in Helicone.

```bash
npm install -g opencode-helicone-session
```

Add it to your config.

```json title="opencode.json"
{
"plugin": ["opencode-helicone-session"]
}
```

The plugin injects `Helicone-Session-Id` and `Helicone-Session-Name` headers into your requests. In Helicone's Sessions page, you'll see each OpenCode conversation listed as a separate session.

##### Common Helicone headers

| Header | Description |
| -------------------------- | ------------------------------------------------------------- |
| `Helicone-Cache-Enabled` | Enable response caching (`true`/`false`) |
| `Helicone-User-Id` | Track metrics by user |
| `Helicone-Property-[Name]` | Add custom properties (e.g., `Helicone-Property-Environment`) |
| `Helicone-Prompt-Id` | Associate requests with prompt versions |

See the [Helicone Header Directory](https://docs.helicone.ai/helicone-headers/header-directory) for all available headers.

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Helicone AI Gateway endpoint https://ai-gateway.helicone.ai

💡 Result:

ai-gateway.helicone.ai is Helicone’s OpenAI-compatible AI Gateway — a unified proxy endpoint (https://ai-gateway.helicone.ai) that lets you call 100+ LLM providers with one API, add caching, failover, rate‑limits and observability, and use existing OpenAI SDKs by changing baseURL. Example usage: set baseURL to https://ai-gateway.helicone.ai and send OpenAI-style requests (chat/completions) with your Helicone API key. Key headers include Helicone-Auth (Bearer <HELICONE_API_KEY>) and Helicone-Target-Url (when proxying to a specific provider). Docs, blog announcement, and repo: [1][2][3][4].

Sources

  • Helicone blog: Introducing the AI Gateway. [1]
  • Helicone docs — AI Gateway overview and quickstart. [2]
  • Helicone docs — header directory (Helicone-Auth, Helicone-Target-Url). [3]
  • Helicone GitHub — ai-gateway repo (open-source). [4]

🌐 Web query:

Helicone API documentation baseURL endpoint

💡 Result:

Common Helicone API base URLs (used in docs):

Examples and header usage (from docs): set base_url to one of the above and include Helicone-Auth: Bearer <HELICONE_API_KEY> (and Helicone-Target-URL or Helicone-OpenAI-Api-Base when proxying). [1][10]

Sources: Helicone docs and quickstart. [1][2][10]


🌐 Web query:

GitHub H2Shami opencode-helicone-session plugin repository

💡 Result:

I couldn't find a GitHub repository named H2Shami/opencode-helicone-session. I searched GitHub and project docs for OpenCode and Helicone but found no matching repo or plugin by that name. Sources: OpenCode plugins docs and Helicone project pages. [1] [2]

Would you like me to:

  • search more widely (Google/GitHub again) for forks or different name variants, or
  • look for an opencode plugin that integrates with Helicone (examples or how-to)?

References:

  1. OpenCode — Plugins documentation. [1]
  2. Helicone — GitHub and sessions/docs. [2]

🌐 Web query:

Helicone documentation headers features sessions

💡 Result:

Summary — Helicone Sessions & headers

  • Purpose: Sessions group related LLM/tool/DB requests so you can trace a multi-step agent or conversation end-to-end (debugging, hierarchy/tree views, performance across flows). [1][2]

  • Required headers (add to each proxied LLM/request):

    • Helicone-Session-Id — unique session identifier (UUID recommended).
    • Helicone-Session-Path — hierarchical path using "/" to show parent→child traces (e.g. "/abstract/outline").
    • Helicone-Session-Name — human-readable session name (e.g. "Course Plan").
      Example usage shown in JavaScript/Node and curl. [1][2]
  • Path semantics: Use path segments to represent parent/child relationships so Helicone can build a trace/tree of the session. [1]

  • What sessions can include: LLM calls (OpenAI, Anthropic, etc.), vector DB queries/embeddings, tool/function calls, and any logged request sent through Helicone. [1]

  • Related/other Helicone headers & flags: authentication header Helicone-Auth; Helicone-Target-URL / Helicone-OpenAI-Api-Base for proxying; feature flags like Helicone-Omit-Response, Helicone-Omit-Request, cache headers (Helicone-Cache-Enabled, Helicone-Cache-Seed, etc.). Sessions headers are documented in the Helicone header directory. [2][3]

  • Notes: Helicone also supports realtime logging (e.g., OpenAI Realtime) and accepts the same session headers for grouping realtime conversations. [4]

Sources: Helicone Sessions docs and header directory, Helicone blog/changelog.
[1] https://docs.helicone.ai/features/sessions
[2] https://docs.helicone.ai/helicone-headers
[3] https://docs.helicone.ai/helicone-headers/header-directory
[4] https://www.helicone.ai/changelog/20250407-realtime-launch


Remove the non-existent plugin section (lines 653–670) or replace with official Helicone session setup instructions.

The GitHub repository https://github.com/H2Shami/opencode-helicone-session does not exist. The session tracking section promotes this as the recommended way to integrate Helicone sessions, but the plugin is not available. Either remove this section or replace it with direct instructions using Helicone's documented session headers (Helicone-Session-Id, Helicone-Session-Name, Helicone-Session-Path) that developers can implement manually.

The API endpoint (https://ai-gateway.helicone.ai) and all other external documentation links are correct and current.

🧰 Tools
🪛 LanguageTool

[grammar] ~571-~571: Ensure spelling is correct
Context: ... txt /models --- ### Helicone Helicone is an LLM...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
packages/web/src/content/docs/providers.mdx lines 571-681: the "Session
tracking" subsection (approx lines 653–670) references a non-existent GitHub
plugin (https://github.com/H2Shami/opencode-helicone-session); remove that
plugin installation/config snippet and instead provide instructions for manual
session tracking using Helicone's documented headers—explain that developers
should set Helicone-Session-Id, Helicone-Session-Name (and optionally
Helicone-Session-Path) on outgoing requests, show where to add those headers in
the provider options or outgoing request code, and replace the plugin link with
a link to Helicone's Sessions docs.

@opencode-agent
Copy link

User coderabbitai[bot] does not have write permissions

github run

@opencode-agent
Copy link

User coderabbitai[bot] does not have write permissions

github run

@opencode-agent
Copy link

User coderabbitai[bot] does not have write permissions

github run

@opencode-agent
Copy link

User coderabbitai[bot] does not have write permissions

github run

@shuv1337 shuv1337 closed this Dec 11, 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.