feat(opencode): add optional runtime overlay#3761
feat(opencode): add optional runtime overlay#3761Danigm-dev wants to merge 33 commits intosimstudioai:stagingfrom
Conversation
PR SummaryMedium Risk Overview Introduces new server routes for OpenCode metadata ( Bundles a new OpenCode client/service layer (backed by Separately hardens shared Written by Cursor Bugbot for commit 9bb48d0. This will update automatically on new commits. Configure here. |
|
@Danigm-dev is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
...Id]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx
Outdated
Show resolved
Hide resolved
Greptile SummaryThis PR introduces OpenCode as an optional Sim capability — a new workflow block, a suite of API routes, a library client/service layer, async dropdown/combobox support, and Docker Compose overlays — while leaving the default Sim deployment path completely unchanged. The implementation is well-structured: the OpenCode block is hidden behind Key changes at a glance:
Minor findings:
Confidence Score: 5/5Safe to merge — all remaining findings are P2 style suggestions with no correctness or data-integrity impact. The PR is well-implemented: auth is enforced at every route, the memory table upsert relies on a verified unique index, stale-session retry logic is correct and covered by tests, previously flagged issues (existsSync caching, unpinned Docker image, GitHub token leakage) are resolved, and the default Sim path is demonstrably unchanged. The two open findings are minor efficiency and validation nits (P2) that do not affect production correctness. docker/opencode/entrypoint.sh (port range validation) and apps/sim/blocks/blocks/opencode.ts (fetchOptionById efficiency) have minor P2 suggestions, but neither blocks merge. Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as Browser / Block UI
participant DiscoveryAPI as /api/opencode/*
participant ToolAPI as /api/tools/opencode/prompt
participant Service as lib/opencode/service.ts
participant Client as lib/opencode/client.ts
participant OC as OpenCode Server
participant DB as memory table
Note over UI,OC: Block configuration — async dropdown loading
UI->>DiscoveryAPI: GET /api/opencode/repos?workspaceId=...
DiscoveryAPI->>Service: listOpenCodeRepositories()
Service->>Client: createOpenCodeClient()
Client->>OC: project.list()
OC-->>Client: Project[]
Client-->>Service: projects
Service-->>DiscoveryAPI: OpenCodeRepositoryOption[]
DiscoveryAPI-->>UI: {data: [...repos]}
UI->>DiscoveryAPI: GET /api/opencode/providers?workspaceId=&repository=...
DiscoveryAPI->>Service: listOpenCodeProviders(repository)
Service->>OC: config.providers({ directory })
OC-->>Service: Provider[]
Service-->>DiscoveryAPI: OpenCodeProviderOption[]
DiscoveryAPI-->>UI: {data: [...providers]}
Note over UI,DB: Workflow execution — prompt tool
UI->>ToolAPI: POST /api/tools/opencode/prompt {repository, prompt, ...}
ToolAPI->>Service: resolveOpenCodeRepositoryOption(repository)
Service->>OC: project.list()
OC-->>Service: repo option
ToolAPI->>DB: getStoredOpenCodeSession(workspaceId, memoryKey)
DB-->>ToolAPI: storedSession | null
alt No stored session or repository mismatch
ToolAPI->>Service: createOpenCodeSession(repositoryOption, title)
Service->>OC: session.create({ directory })
OC-->>Service: {id: sessionId}
end
ToolAPI->>Service: promptOpenCodeSession({sessionId, prompt, ...})
Service->>OC: session.prompt({id, body})
OC-->>Service: SessionPromptResponse
Service-->>ToolAPI: OpenCodePromptResult
alt Stale session error + reusableStoredThread
ToolAPI->>Service: createOpenCodeSession() [fresh]
Service->>OC: session.create()
OC-->>Service: {id: freshSessionId}
ToolAPI->>Service: promptOpenCodeSession({freshSessionId, ...})
Service->>OC: session.prompt()
OC-->>Service: result
end
ToolAPI->>DB: storeOpenCodeSession(workspaceId, memoryKey, {sessionId, repository})
ToolAPI-->>UI: {success: true, output: {content, threadId, cost?}}
Reviews (2): Last reviewed commit: "Merge branch 'staging' into feat/opencod..." | Re-trigger Greptile |
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Outdated
Show resolved
Hide resolved
|
Addressed the actionable Greptile findings in the latest branch state.
Validation run after these changes:
Latest fix commit: |
...Id]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx
Outdated
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Outdated
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Outdated
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Outdated
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Outdated
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Show resolved
Hide resolved
...Id]/components/panel/components/editor/components/sub-block/components/combobox/combobox.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| (open: boolean) => { | ||
| if (open) { | ||
| void fetchOptionsIfNeeded() | ||
| void fetchOptionsIfNeeded(true) |
There was a problem hiding this comment.
Every dropdown open triggers unnecessary API refetch
Medium Severity
handleOpenChange now calls fetchOptionsIfNeeded(true) with force=true every time any async-loading dropdown or combobox is opened. This bypasses the hasAttemptedOptionsFetchRef guard, causing a full API refetch even when options were already successfully loaded. The intent was to enable retry after fetch errors, but the fix also triggers redundant refetches on every open for all async dropdowns app-wide (including the existing Agent block selectors), causing unnecessary network traffic and loading-spinner flicker.


Summary
Adds OpenCode as an optional Sim capability without changing the default Sim deployment path or base UX.
This PR introduces:
OPENCODE_REPOSITORY_ROOTcontract so Sim can also target compatible external OpenCode deploymentsThe default Sim experience remains unchanged:
docker-compose.local.ymlis unchangeddocker-compose.prod.ymlis unchangedNEXT_PUBLIC_OPENCODE_ENABLED=trueType of Change
Testing
timeout 90s bunx vitest run blocks/blocks.test.tsfromapps/simbunx vitest run lib/opencode/service.test.ts app/api/opencode/repos/route.test.ts app/api/tools/opencode/prompt/route.test.tsfromapps/simdocker compose -f docker-compose.local.yml -f docker-compose.opencode.local.yml configenv OPENCODE_SERVER_PASSWORD=change-me docker compose -f docker-compose.prod.yml -f docker-compose.opencode.yml configReviewer focus:
OPENCODE_REPOSITORY_ROOThandling for external deploymentsChecklist
Screenshots/Videos
Not included. The OpenCode block is hidden by default and only appears when
NEXT_PUBLIC_OPENCODE_ENABLED=true. Manual validation covered both states and a successful prompt execution flow.