Skip to content

Docs: add Workspaces guide#5

Closed
anduimagui wants to merge 21 commits intodevfrom
docs/workspaces-guide
Closed

Docs: add Workspaces guide#5
anduimagui wants to merge 21 commits intodevfrom
docs/workspaces-guide

Conversation

@anduimagui
Copy link
Copy Markdown
Owner

@anduimagui anduimagui commented Mar 19, 2026

Adds a new documentation page explaining what OpenCode workspaces are and how to create one from within a project. Also updates Mintlify navigation and the docs homepage to link to the new page.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added OAuth prompt flow for multi-step provider authentication
    • Added Workspaces feature docs and landing card
    • Go plan now surfaces MiniMax M2.7 in UI lists and limits
  • Documentation

    • Go plan docs updated across languages with new pricing (first month $5, then $10/mo)
    • Updated provider authentication guidance
  • Improvements

    • Button labels changed to "Continue"
    • Better Windows process handling and reliability
  • Chores

    • Dependency and translation updates

@github-actions
Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions
Copy link
Copy Markdown

Hey! Your PR title Docs: add Workspaces guide doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 418a8b4a-a6ba-4ccf-b363-d825824d6e4a

📥 Commits

Reviewing files that changed from the base of the PR and between ed88098 and 6db1590.

📒 Files selected for processing (1)
  • packages/app/src/components/prompt-input.tsx

📝 Walkthrough

Walkthrough

This PR adds an AppFileSystem service, refactors process/LSP spawning and shutdown, enhances OAuth prompts in the connect dialog, updates many i18n strings and Go/Zen docs to include MiniMax M2.7 and new pricing, upgrades Effect-related dependencies, and adds tests and documentation for workspaces.

Changes

Cohort / File(s) Summary
Agent & Provider Config
.opencode/agent/translator.md, packages/opencode/src/provider/schema.ts, packages/opencode/src/provider/provider.ts, packages/opencode/src/plugin/index.ts
Updated translator model to opencode/gemini-3.1-pro; added ProviderID.gitlab; removed builtin anthropic-auth plugin and adjusted anthropic loader header.
Dependency & Package Metadata
package.json, nix/hashes.json, packages/app/package.json, packages/desktop-electron/package.json, packages/opencode/package.json
Bumped Effect/catalog entries to 4.0.0-beta.35, added @effect/platform-node catalog entry, updated nix hashes, added cross-spawn and a prepare script.
Dialog Connect & OAuth Prompts
packages/app/src/components/dialog-connect-provider.tsx, packages/app/src/i18n/*.ts, packages/app/e2e/prompt/prompt-multiline.spec.ts
Added "prompt" dialog state and auth.prompt action; introduced OAuthPromptsView to gather sequential prompts and validate inputs; changed button label key to common.continue; adapted e2e test to focus/keypress flows.
i18n — "Continue" Translations
packages/app/src/i18n/\*.ts (multiple files)
Added common.continue translations across locale files.
Console Go Plan Localizations
packages/console/app/src/i18n/\*.ts (multiple files)
Updated Go plan marketing/FAQ strings across locales to include MiniMax M2.7.
Go UI & Model List
packages/console/app/src/routes/go/index.tsx, packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx
Split MiniMax into minimax-m2.7 and minimax-m2.5 entries in limits graph and promo list with updated req/duration values.
AppFileSystem Abstraction & Helpers
packages/opencode/src/filesystem/index.ts, packages/opencode/src/skill/discovery.ts, packages/opencode/src/snapshot/index.ts, packages/opencode/src/tool/truncate-effect.ts
Introduced AppFileSystem service (file/dir/json/glob/up utilities, helpers like mimeType, contains, overlaps); migrated consumers to AppFileSystem.Service and replaced direct mkdir/write flows with ensureDir/writeWithDirs.
Process, Spawn & LSP Refactor
packages/opencode/src/util/process.ts, packages/opencode/src/lsp/launch.ts, packages/opencode/src/lsp/server.ts, packages/opencode/src/lsp/index.ts, packages/opencode/src/lsp/client.ts, packages/opencode/src/ide/index.ts
Switched to cross-spawn/Process abstractions, added Process.stop() with Windows taskkill handling, introduced shared lsp.launch.spawn helper, removed synchronous kills in favor of async stop, and adjusted IDE install/run flows to use Process.run.
CLI & Session Adjustments
packages/opencode/src/cli/cmd/models.ts, packages/opencode/src/cli/cmd/pr.ts, packages/opencode/src/cli/cmd/providers.ts, packages/opencode/src/session/llm.ts, packages/opencode/src/session/message-v2.ts, packages/opencode/src/session/processor.ts
Normalized provider lookups to ProviderID, replaced raw spawn with process abstraction, simplified stream header construction, and normalized error message serialization/storage.
Prompts & System Prompt Changes
packages/opencode/src/session/prompt/anthropic-20250930.txt, packages/opencode/src/session/prompt/default.txt, packages/opencode/src/session/system.ts
Removed the anthropic prompt file, consolidated duplicate IMPORTANT blocks in default prompt, and changed default fallback prompt selection to use PROMPT_DEFAULT.
File Watcher Scoping
packages/opencode/src/file/watcher.ts, packages/opencode/test/file/watcher.test.ts
Scoped ignored protected paths to watcher root via protecteds(dir), and refactored watcher tests to use deferred-based synchronization flow.
Tests — Additions & Updates
packages/opencode/test/filesystem/filesystem.test.ts, packages/opencode/test/lsp/launch.test.ts, packages/opencode/test/provider/*.test.ts, packages/opencode/test/session/message-v2.test.ts, packages/opencode/test/util/process.test.ts
Added AppFileSystem integration tests, LSP launch test, Windows process tests; updated provider tests to use ProviderID constants and added Question.RejectedError coverage.
Docs — Workspaces & Guides
packages/docs/docs.json, packages/docs/index.mdx, packages/docs/workspaces.mdx
Added a "Workspaces" navigation group and new Workspaces documentation page describing isolated git worktrees and workflows.
Web Docs — Go & Zen Updates
packages/web/src/content/docs/**/go.mdx, packages/web/src/content/docs/zen.mdx, packages/web/src/content/docs/providers.mdx
Extensive MDX updates across locales: added MiniMax M2.7, changed pricing to $5 first month then $10/month, updated usage tables, removed per-token pricing, adjusted endpoint/SDK tables, and removed Anthropic Pro/Max setup guidance.
Layout Autoselect Guard
packages/app/src/pages/layout.tsx
Added early-return guard in autoselect resource to re-check state.autoselect after awaits, preventing stale autoselect actions.
Prompt Input Submission
packages/app/src/components/prompt-input.tsx
Prevent default on Enter, ignore repeated keydowns, and avoid submit when working with empty prompt/attachments/comments.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 I twitch my nose and tap the key,
OAuth prompts now speak to me,
MiniMax leaps to share the hill,
Files and spawns and docs all fill—
A hopping patch, so neat and spry!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/workspaces-guide

Copy link
Copy Markdown

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

🧹 Nitpick comments (13)
packages/opencode/src/session/message-v2.ts (1)

958-959: Redundant instanceof check inside case block.

Since line 958 already matches case e instanceof Error:, the ternary on line 959 is unnecessary—e is guaranteed to be an Error here.

✨ Suggested simplification
       case e instanceof Error:
-        return new NamedError.Unknown({ message: e instanceof Error ? e.message : String(e) }, { cause: e }).toObject()
+        return new NamedError.Unknown({ message: e.message }, { cause: e }).toObject()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/session/message-v2.ts` around lines 958 - 959, The case
block matching "case e instanceof Error:" contains a redundant ternary; inside
that branch `e` is already an Error, so simplify the return in the branch that
builds NamedError.Unknown by using e.message directly (i.e., replace the ternary
`e instanceof Error ? e.message : String(e)` with `e.message`) while keeping the
rest of the construction (`new NamedError.Unknown(..., { cause: e
}).toObject()`); update the code in the switch branch where `e` and
`NamedError.Unknown` are used.
packages/web/src/content/docs/providers.mdx (1)

327-328: Prefer neutral wording over policy commentary.

“support freedom of choice” is editorial. A neutral phrasing will age better and reduce perceived bias.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/providers.mdx` around lines 327 - 328, Replace
the editorial phrase "support freedom of choice" in the sentence "Other
companies support freedom of choice with developer tooling - you can use the
following subscriptions in OpenCode with zero setup:" with a neutral, factual
alternative (e.g., "offer multiple developer tooling options" or "provide a
choice of developer tooling"). Update the sentence to read plainly (for example:
"Other companies offer multiple developer tooling options — you can use the
following subscriptions in OpenCode with zero setup:") so the wording is neutral
and non-editorial.
packages/opencode/src/cli/cmd/models.ts (1)

54-60: Minor cleanup: compute ProviderID.make(args.provider) once.

This avoids duplicate conversion and keeps lookup/print paths tied to one canonical value.

✨ Small refactor
         if (args.provider) {
-          const provider = providers[ProviderID.make(args.provider)]
+          const providerID = ProviderID.make(args.provider)
+          const provider = providers[providerID]
           if (!provider) {
             UI.error(`Provider not found: ${args.provider}`)
             return
           }

-          printModels(ProviderID.make(args.provider), args.verbose)
+          printModels(providerID, args.verbose)
           return
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/cli/cmd/models.ts` around lines 54 - 60, Compute
ProviderID.make(args.provider) once and reuse it: create a local const (e.g.,
providerId = ProviderID.make(args.provider)), use providers[providerId] for the
lookup instead of calling ProviderID.make twice, keep the UI.error call and
return as-is if lookup fails, and pass providerId into printModels. Update
references to use providerId so lookup and printing use the same canonical
value.
packages/opencode/src/provider/provider.ts (1)

841-841: Prefer Partial<Record<ProviderID, Info>> over force-casting an empty object.

Line 841 currently uses an unsafe cast during incremental population/removal. Modeling this map as partial better reflects actual lifecycle and preserves stronger type checks.

♻️ Suggested type-safety refactor
-    const providers: Record<ProviderID, Info> = {} as Record<ProviderID, Info>
+    const providers: Partial<Record<ProviderID, Info>> = {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/provider/provider.ts` at line 841, The providers map is
currently created with an unsafe cast (const providers: Record<ProviderID, Info>
= {} as Record<ProviderID, Info>) which hides that entries may be added/removed
over time; change its declaration to use Partial<Record<ProviderID, Info>> so
the type accurately represents possibly-missing entries (const providers:
Partial<Record<ProviderID, Info>> = {}), and then update any code that reads
from providers (e.g., lookups by ProviderID) to handle undefined results (add
null/undefined checks or use non-null assertions only where guaranteed) so the
stronger type-safety is preserved for functions/methods that reference
providers.
packages/app/src/i18n/no.ts (1)

226-226: Consider using a distinct Norwegian label for common.continue.

Line 226 currently duplicates common.submit ("Send inn"). If this action is a step-forward CTA, "Fortsett" may be clearer UX.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/i18n/no.ts` at line 226, Replace the duplicate Norwegian
string for the key common.continue (currently "Send inn") with a distinct,
step-forward label such as "Fortsett" to avoid matching common.submit; update
the value for the constant common.continue in packages/app/src/i18n/no.ts so the
translation reflects a forward/next action and remains consistent with UX
intent.
packages/app/src/i18n/fr.ts (1)

207-207: French common.continue may be better as “Continuer”.

Line 207 maps common.continue to "Soumettre" (same as submit). If this button means step progression, "Continuer" is a better fit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/i18n/fr.ts` at line 207, Update the French translation for
the key "common.continue" in packages/app/src/i18n/fr.ts so it reads "Continuer"
instead of "Soumettre"; locate the entry for "common.continue" and replace the
value to reflect step progression wording consistent with other navigation
labels.
packages/app/src/i18n/th.ts (1)

223-223: Consider a Thai term closer to “Continue” for common.continue.

Line 223 currently mirrors submit ("ส่ง"). If this is a step-forward action, a continue-specific label would be clearer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/i18n/th.ts` at line 223, The translation for the key
common.continue currently uses the Thai word "ส่ง" (which reads like "submit");
change the value for common.continue in packages/app/src/i18n/th.ts to a Thai
term that conveys stepping forward or continuing (for example "ต่อไป" or
"ดำเนินการต่อ") so the label differentiates from submit actions and more
accurately maps to "Continue".
packages/app/src/i18n/es.ts (1)

223-223: Spanish common.continue may read better as “Continuar”.

Line 223 uses "Enviar" (same as submit). If the action is progression in a flow, "Continuar" is more precise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/i18n/es.ts` at line 223, The translation for the key
"common.continue" currently uses "Enviar" which is better suited for submit
actions; update the value of the "common.continue" entry in the es.ts
localization (the "common.continue" string) to "Continuar" so it conveys
progression in a flow rather than submission.
packages/web/src/content/docs/ja/go.mdx (1)

46-51: Mention the workspace prerequisite in the setup steps.

These instructions jump from sign-in straight to subscribing, but the note below says Go is workspace-scoped. A brief “create/select a workspace first” link to the new Workspaces guide here would make the flow self-serve.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/ja/go.mdx` around lines 46 - 51, Update the
setup steps in the Go guide to require creating or selecting a workspace before
subscribing: modify the numbered list (the step that currently reads "OpenCode
Zenにサインインし、GoをサブスクライブしてAPIキーをコピーします") to split into two steps — first instruct
users to create or select a workspace (include a link to the new Workspaces
guide), then instruct them to subscribe to OpenCode Go and copy the API key;
ensure the subsequent instructions referencing the TUI commands `/connect` and
`/models` still follow and mention selecting the same workspace when connecting.
packages/web/src/content/docs/tr/go.mdx (2)

56-81: Same model ordering inconsistency as in the Spanish version.

The bullet list (lines 56-59) shows MiniMax M2.5 before M2.7, while the table (lines 77-81) shows M2.7 before M2.5. Align the ordering for consistency across localized documentation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/tr/go.mdx` around lines 56 - 81, The localized
Turkish doc has inconsistent model ordering: the bullet list lines with model
names (GLM-5, Kimi K2.5, MiniMax M2.5, MiniMax M2.7) does not match the table
order (GLM-5, Kimi K2.5, MiniMax M2.7, MiniMax M2.5); update the bullet list so
the MiniMax entries appear in the same order as the table (change the list to
GLM-5, Kimi K2.5, MiniMax M2.7, MiniMax M2.5) to ensure consistent ordering
across the document.

79-81: Table row label may be ambiguous in Turkish.

The label "5 saatte bir istek" could be interpreted as "one request per 5 hours" rather than the intended "requests per 5-hour window." Consider rephrasing for clarity, e.g., "5 saatlik istek" or "5 saat içinde istek sayısı" to better convey that these are totals.

📝 Suggested fix
-| 5 saatte bir istek | 1.150 | 1.850     | 14.000       | 20.000       |
-| haftalık istek     | 2.880 | 4.630     | 35.000       | 50.000       |
-| aylık istek        | 5.750 | 9.250     | 70.000       | 100.000      |
+| 5 saatlik istek    | 1.150 | 1.850     | 14.000       | 20.000       |
+| haftalık istek     | 2.880 | 4.630     | 35.000       | 50.000       |
+| aylık istek        | 5.750 | 9.250     | 70.000       | 100.000      |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/tr/go.mdx` around lines 79 - 81, Update the
ambiguous Turkish table label "5 saatte bir istek" to a clearer phrasing that
conveys a total over a 5-hour window; replace the string "5 saatte bir istek"
with one of the suggested alternatives such as "5 saatlik istek" or "5 saat
içinde istek sayısı" in the table row so readers understand it represents
requests in a 5-hour period.
packages/web/src/content/docs/es/go.mdx (1)

66-91: Model ordering inconsistency between list and table.

The bullet list (lines 66-69) orders the MiniMax models as M2.5 then M2.7, but the table (lines 87-91) orders them as M2.7 then M2.5. Consider using consistent ordering throughout the document for clarity.

📝 Suggested fix to align ordering

Either update the bullet list to match the table order:

 - **GLM-5**
 - **Kimi K2.5**
-- **MiniMax M2.5**
 - **MiniMax M2.7**
+- **MiniMax M2.5**

Or update the table to match the bullet list order (swap M2.7 and M2.5 columns).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/es/go.mdx` around lines 66 - 91, The document
shows inconsistent ordering of the MiniMax models: the bullet list lists
"MiniMax M2.5" then "MiniMax M2.7" while the table columns are "MiniMax M2.7"
then "MiniMax M2.5"; pick one ordering and make both places match by either
swapping the two MiniMax entries in the bullet list or rearranging the table
columns so the sequence of model names ("GLM-5", "Kimi K2.5", "MiniMax M2.7",
"MiniMax M2.5" or the alternative with M2.5 before M2.7) is identical in the
list and the table to ensure consistent presentation.
packages/opencode/test/filesystem/filesystem.test.ts (1)

2-4: Use the exported defaultLayer in this suite.

This is duplicating the production composition verbatim. Pointing the tests at AppFileSystem.defaultLayer keeps the setup in sync with the public wiring and makes regressions in that export visible here.

♻️ Proposed cleanup
-import { Effect, Layer } from "effect"
-import { NodeFileSystem } from "@effect/platform-node"
+import { Effect } from "effect"
 import { AppFileSystem } from "../../src/filesystem"
 ...
-const live = AppFileSystem.layer.pipe(Layer.provide(NodeFileSystem.layer))
+const live = AppFileSystem.defaultLayer

Also applies to: 8-9

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/filesystem/filesystem.test.ts` around lines 2 - 4,
Tests are duplicating the production composition; replace the manual composition
that imports and constructs Layer/NodeFileSystem with the exported public wiring
by using AppFileSystem.defaultLayer in the test suite (referencing the symbol
AppFileSystem.defaultLayer) so the tests consume the same Layer as production;
locate the setup that currently imports NodeFileSystem and builds a Layer/Effect
and swap it to use AppFileSystem.defaultLayer and update any references to the
old variable names accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.opencode/agent/translator.md:
- Line 4: The model entry "opencode/gemini-3.1-pro" in
.opencode/agent/translator.md is not in the documented model glossary and
appears to be an out-of-scope docs-only change; either revert this model ID or
add documentation and justification for its addition: confirm that
"opencode/gemini-3.1-pro" is a supported model, update the Do-Not-Translate
glossary to include it, and add a short PR description explaining why this docs
change is necessary (or remove the line to revert to the previous documented
model).

In `@packages/app/src/components/dialog-connect-provider.tsx`:
- Around line 261-271: The onSelect handler mutates formStore with
setFormStore("value", ...) before reading item(), which can change the reactive
item() result; fix by capturing the current prompt/index from item() and/or
select() into local constants (e.g., const currentItem = item(); const idx =
currentItem?.index; const prompt = select();) before calling setFormStore,
validate they exist, then compute nextValue, call setFormStore, and finally call
next(idx, nextValue) using the previously captured idx so the index can't change
due to the state update.

In `@packages/console/app/src/routes/go/index.tsx`:
- Around line 50-51: The CSS selector targeting MiniMax graph points still looks
for data-model="minimax" but the model IDs in the code were changed to
"minimax-m2.7" and "minimax-m2.5"; update the selector(s) in index.css (the rule
that uses [data-model="minimax"]) to match the new IDs or use a prefix selector
like [data-model^="minimax"] so both "minimax-m2.7" and "minimax-m2.5" get the
MiniMax-specific styling.

In `@packages/docs/workspaces.mdx`:
- Line 11: Replace the inconsistent phrase "working tree" in the sentence "Each
workspace has its own git branch and directory, so you can experiment without
disturbing your main working tree." with the consistent term "worktree" to match
the rest of the page; update that sentence to read "...without disturbing your
main worktree." and ensure no other occurrences on the page use "working tree."

In `@packages/opencode/src/filesystem/index.ts`:
- Around line 48-50: The JSON parsing/stringifying in readJson and writeJson
must be wrapped so parse/stringify exceptions are converted into the library's
FileSystemError and propagated through the Effect error channel; update the
generator bodies of readJson and writeJson to catch synchronous errors from
JSON.parse and JSON.stringify (and other serialization issues like
BigInt/circular refs), construct a FileSystemError containing the original error
and path context, and propagate it via the Effect failure mechanism (so the
functions no longer throw synchronously or return undefined but fail with
AppFileSystem.Error). Ensure you reference and use the existing FileSystemError
type when creating the error and propagate it from the readJson and writeJson
implementations.
- Around line 188-195: The relative-based boundary checks in contains() and
overlaps() are incorrect because they treat any segment that starts with ".." as
an escape; add a small helper (e.g., isChildOf(parent, child)) that computes rel
= relative(parent, child) and returns true if rel === "" or the first path
segment is not exactly ".." (use rel.split(sep)[0] with path.sep from node's
path); then rewrite contains(parent, child) to call isChildOf(parent, child) and
overlaps(a,b) to use isChildOf(a,b) || isChildOf(b,a) (keep function names
contains and overlaps as-is to locate changes).

In `@packages/opencode/src/lsp/launch.ts`:
- Around line 1-18: The exported spawn's declared return type overstates
guarantees: change the function signature and overloads to return Process.Child
intersected with an object type that explicitly declares non-null stdin, stdout,
and stderr (e.g., Process.Child & { stdin: NodeJS.WritableStream; stdout:
NodeJS.ReadableStream; stderr: NodeJS.ReadableStream }) and tighten opts to
Omit<Process.Options, "stdio"> so callers cannot override stdio; keep the
runtime null-check (if (!proc.stdin || ... ) throw) and cast proc to the
narrowed return type after that check, and update any callers expecting
ChildProcessWithoutNullStreams to use the new narrowed type (symbols: spawn,
Process.spawn, Process.Child, Child).

In `@packages/opencode/src/session/system.ts`:
- Line 29: The change to SystemPrompt.provider that returns [PROMPT_DEFAULT]
alters runtime fallback behavior in production; revert this change in
packages/opencode/src/session/system.ts so SystemPrompt.provider preserves the
original fallback selection (undo the return [PROMPT_DEFAULT] modification) and
either open a separate PR for the behavioral change or update this PR’s
description to explicitly include the runtime change so reviewers know it’s
intentional.

In `@packages/opencode/src/util/process.ts`:
- Around line 146-158: The stop function currently calls proc.kill() (and the
taskkill branch) then returns without waiting for the process to actually exit,
causing races; update export async function stop(proc: ChildProcess) to await
the process termination by returning a Promise that resolves on
proc.once('exit'/'close') (or using a wrapped promise) after calling proc.kill()
or after taskkill finishes, and handle the case where proc.pid is falsy or the
process has already exited (resolve immediately); ensure both the non-Windows
branch (proc.kill()) and the Windows branch (after run([...taskkill...])) wait
for the exit event before resolving so callers in lsp/index.ts and lsp/client.ts
reliably observe a terminated process.

In `@packages/web/src/content/docs/da/go.mdx`:
- Around line 117-121: The "Endpoints" section header and the table header row
are in English; change the header "Endpoints" to a Danish heading like
"Endepunkter" (or "API-endpoints") and translate the table column headers "Model
ID", "Endpoint", and "AI SDK Package" to Danish (suggested: "Model-id",
"Endepunkt", "AI SDK-pakke") so the section remains fully localized; update the
header text and the table header row in the Go docs (the lines containing the
"Endpoints" heading and the table header cells) accordingly.

In `@packages/web/src/content/docs/fr/go.mdx`:
- Around line 77-87: Update the numeric formatting in the table and bullet list
in go.mdx to use French thousands separators (spaces) instead of commas: replace
values like "1,150", "14,000", "20,000", "2,880", "4,630", "35,000", "50,000",
"5,750", "9,250", "70,000", "100,000" and the token/cache figures "52,000",
"55,000" with "1 150", "14 000", "20 000", "2 880", "4 630", "35 000", "50 000",
"5 750", "9 250", "70 000", "100 000", "52 000", "55 000" respectively (prefer
non‑breaking spaces if supported) so the table rows and the bullet points (the
GLM-5, Kimi K2.5, MiniMax lines) use French grouping for thousands.

In `@packages/web/src/content/docs/it/zen.mdx`:
- Line 118: The pricing table lists "Qwen3 Coder 480B" with rates but there is
no corresponding entry in the Endpoint table and the model is marked deprecated
since February 6, 2026; either remove "Qwen3 Coder 480B" from the pricing table
to reflect its deprecated/unavailable status, or add a matching Endpoint table
row for "Qwen3 Coder 480B" (including the endpoint name, input/output formats,
and availability/deprecation note) so the pricing and Endpoint sections stay
consistent; locate the model name "Qwen3 Coder 480B" in the pricing table and
the Endpoint table section to apply the chosen fix.
- Around line 200-202: The Italian docs contain a duplicate privacy entry
"MiniMax M2.5 Free"—replace the second occurrence with "MiMo V2 Flash Free" so
the free-trial models list matches the free models section; update the privacy
sentence for the new entry to the same format used for "MiniMax M2.5 Free" and
"Nemotron 3 Super Free" (i.e., "MiMo V2 Flash Free: durante il periodo gratuito,
i dati raccolti potrebbero essere usati per migliorare il modello.").

In `@packages/web/src/content/docs/providers.mdx`:
- Around line 330-332: Update the product name casing in the providers list:
change "Github Copilot" to "GitHub Copilot" and "Gitlab Duo" to "GitLab Duo" so
user-facing docs use the official casing; locate the list containing "ChatGPT
Plus", "Github Copilot", "Gitlab Duo" and replace those two strings accordingly
to preserve consistency and searchability.
- Around line 321-333: The Anthropic setup steps that instruct users to choose
"Claude Pro/Max" are now contradictory with the note that Anthropic is
prohibited; update the earlier Anthropic connect instructions so step 2
instructs the user to "Select Manually enter API Key and paste your Anthropic
API key" instead of selecting Claude Pro/Max, adjust the example auth-selection
ASCII block to show "Manually enter API Key", and change step 3 wording to "Run
`/models` to select an Anthropic model" so the flow matches the new guidance;
locate and edit the Anthropic setup section text that currently references
"Claude Pro/Max" and replace those phrases and the example snippet accordingly.

In `@packages/web/src/content/docs/th/go.mdx`:
- Line 22: Replace the remaining English section headings on the page (the
"Background" heading at line 22 and the other section titles left in English at
lines 42, 65, 99, 120 and 128) with their Thai equivalents so the page and its
TOC/navigation are fully localized; update the MDX headings themselves (the
H2/H3 lines) and any corresponding anchors or explicit IDs used for the
table-of-contents so the localized headings and links remain in sync.

---

Nitpick comments:
In `@packages/app/src/i18n/es.ts`:
- Line 223: The translation for the key "common.continue" currently uses
"Enviar" which is better suited for submit actions; update the value of the
"common.continue" entry in the es.ts localization (the "common.continue" string)
to "Continuar" so it conveys progression in a flow rather than submission.

In `@packages/app/src/i18n/fr.ts`:
- Line 207: Update the French translation for the key "common.continue" in
packages/app/src/i18n/fr.ts so it reads "Continuer" instead of "Soumettre";
locate the entry for "common.continue" and replace the value to reflect step
progression wording consistent with other navigation labels.

In `@packages/app/src/i18n/no.ts`:
- Line 226: Replace the duplicate Norwegian string for the key common.continue
(currently "Send inn") with a distinct, step-forward label such as "Fortsett" to
avoid matching common.submit; update the value for the constant common.continue
in packages/app/src/i18n/no.ts so the translation reflects a forward/next action
and remains consistent with UX intent.

In `@packages/app/src/i18n/th.ts`:
- Line 223: The translation for the key common.continue currently uses the Thai
word "ส่ง" (which reads like "submit"); change the value for common.continue in
packages/app/src/i18n/th.ts to a Thai term that conveys stepping forward or
continuing (for example "ต่อไป" or "ดำเนินการต่อ") so the label differentiates
from submit actions and more accurately maps to "Continue".

In `@packages/opencode/src/cli/cmd/models.ts`:
- Around line 54-60: Compute ProviderID.make(args.provider) once and reuse it:
create a local const (e.g., providerId = ProviderID.make(args.provider)), use
providers[providerId] for the lookup instead of calling ProviderID.make twice,
keep the UI.error call and return as-is if lookup fails, and pass providerId
into printModels. Update references to use providerId so lookup and printing use
the same canonical value.

In `@packages/opencode/src/provider/provider.ts`:
- Line 841: The providers map is currently created with an unsafe cast (const
providers: Record<ProviderID, Info> = {} as Record<ProviderID, Info>) which
hides that entries may be added/removed over time; change its declaration to use
Partial<Record<ProviderID, Info>> so the type accurately represents
possibly-missing entries (const providers: Partial<Record<ProviderID, Info>> =
{}), and then update any code that reads from providers (e.g., lookups by
ProviderID) to handle undefined results (add null/undefined checks or use
non-null assertions only where guaranteed) so the stronger type-safety is
preserved for functions/methods that reference providers.

In `@packages/opencode/src/session/message-v2.ts`:
- Around line 958-959: The case block matching "case e instanceof Error:"
contains a redundant ternary; inside that branch `e` is already an Error, so
simplify the return in the branch that builds NamedError.Unknown by using
e.message directly (i.e., replace the ternary `e instanceof Error ? e.message :
String(e)` with `e.message`) while keeping the rest of the construction (`new
NamedError.Unknown(..., { cause: e }).toObject()`); update the code in the
switch branch where `e` and `NamedError.Unknown` are used.

In `@packages/opencode/test/filesystem/filesystem.test.ts`:
- Around line 2-4: Tests are duplicating the production composition; replace the
manual composition that imports and constructs Layer/NodeFileSystem with the
exported public wiring by using AppFileSystem.defaultLayer in the test suite
(referencing the symbol AppFileSystem.defaultLayer) so the tests consume the
same Layer as production; locate the setup that currently imports NodeFileSystem
and builds a Layer/Effect and swap it to use AppFileSystem.defaultLayer and
update any references to the old variable names accordingly.

In `@packages/web/src/content/docs/es/go.mdx`:
- Around line 66-91: The document shows inconsistent ordering of the MiniMax
models: the bullet list lists "MiniMax M2.5" then "MiniMax M2.7" while the table
columns are "MiniMax M2.7" then "MiniMax M2.5"; pick one ordering and make both
places match by either swapping the two MiniMax entries in the bullet list or
rearranging the table columns so the sequence of model names ("GLM-5", "Kimi
K2.5", "MiniMax M2.7", "MiniMax M2.5" or the alternative with M2.5 before M2.7)
is identical in the list and the table to ensure consistent presentation.

In `@packages/web/src/content/docs/ja/go.mdx`:
- Around line 46-51: Update the setup steps in the Go guide to require creating
or selecting a workspace before subscribing: modify the numbered list (the step
that currently reads "OpenCode Zenにサインインし、GoをサブスクライブしてAPIキーをコピーします") to split
into two steps — first instruct users to create or select a workspace (include a
link to the new Workspaces guide), then instruct them to subscribe to OpenCode
Go and copy the API key; ensure the subsequent instructions referencing the TUI
commands `/connect` and `/models` still follow and mention selecting the same
workspace when connecting.

In `@packages/web/src/content/docs/providers.mdx`:
- Around line 327-328: Replace the editorial phrase "support freedom of choice"
in the sentence "Other companies support freedom of choice with developer
tooling - you can use the following subscriptions in OpenCode with zero setup:"
with a neutral, factual alternative (e.g., "offer multiple developer tooling
options" or "provide a choice of developer tooling"). Update the sentence to
read plainly (for example: "Other companies offer multiple developer tooling
options — you can use the following subscriptions in OpenCode with zero setup:")
so the wording is neutral and non-editorial.

In `@packages/web/src/content/docs/tr/go.mdx`:
- Around line 56-81: The localized Turkish doc has inconsistent model ordering:
the bullet list lines with model names (GLM-5, Kimi K2.5, MiniMax M2.5, MiniMax
M2.7) does not match the table order (GLM-5, Kimi K2.5, MiniMax M2.7, MiniMax
M2.5); update the bullet list so the MiniMax entries appear in the same order as
the table (change the list to GLM-5, Kimi K2.5, MiniMax M2.7, MiniMax M2.5) to
ensure consistent ordering across the document.
- Around line 79-81: Update the ambiguous Turkish table label "5 saatte bir
istek" to a clearer phrasing that conveys a total over a 5-hour window; replace
the string "5 saatte bir istek" with one of the suggested alternatives such as
"5 saatlik istek" or "5 saat içinde istek sayısı" in the table row so readers
understand it represents requests in a 5-hour period.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 18de2dac-62c8-4d21-8034-83fa40708123

📥 Commits

Reviewing files that changed from the base of the PR and between c3ddc85 and ed88098.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (101)
  • .opencode/agent/translator.md
  • nix/hashes.json
  • package.json
  • packages/app/e2e/prompt/prompt-multiline.spec.ts
  • packages/app/package.json
  • packages/app/src/components/dialog-connect-provider.tsx
  • packages/app/src/i18n/ar.ts
  • packages/app/src/i18n/br.ts
  • packages/app/src/i18n/bs.ts
  • packages/app/src/i18n/da.ts
  • packages/app/src/i18n/de.ts
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/es.ts
  • packages/app/src/i18n/fr.ts
  • packages/app/src/i18n/ja.ts
  • packages/app/src/i18n/ko.ts
  • packages/app/src/i18n/no.ts
  • packages/app/src/i18n/pl.ts
  • packages/app/src/i18n/ru.ts
  • packages/app/src/i18n/th.ts
  • packages/app/src/i18n/tr.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/i18n/zht.ts
  • packages/app/src/pages/layout.tsx
  • packages/console/app/src/i18n/ar.ts
  • packages/console/app/src/i18n/br.ts
  • packages/console/app/src/i18n/da.ts
  • packages/console/app/src/i18n/de.ts
  • packages/console/app/src/i18n/en.ts
  • packages/console/app/src/i18n/es.ts
  • packages/console/app/src/i18n/fr.ts
  • packages/console/app/src/i18n/it.ts
  • packages/console/app/src/i18n/ja.ts
  • packages/console/app/src/i18n/ko.ts
  • packages/console/app/src/i18n/no.ts
  • packages/console/app/src/i18n/pl.ts
  • packages/console/app/src/i18n/ru.ts
  • packages/console/app/src/i18n/th.ts
  • packages/console/app/src/i18n/tr.ts
  • packages/console/app/src/i18n/zh.ts
  • packages/console/app/src/i18n/zht.ts
  • packages/console/app/src/routes/go/index.tsx
  • packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx
  • packages/desktop-electron/package.json
  • packages/docs/docs.json
  • packages/docs/index.mdx
  • packages/docs/workspaces.mdx
  • packages/opencode/package.json
  • packages/opencode/src/cli/cmd/models.ts
  • packages/opencode/src/cli/cmd/pr.ts
  • packages/opencode/src/cli/cmd/providers.ts
  • packages/opencode/src/file/watcher.ts
  • packages/opencode/src/filesystem/index.ts
  • packages/opencode/src/ide/index.ts
  • packages/opencode/src/lsp/client.ts
  • packages/opencode/src/lsp/index.ts
  • packages/opencode/src/lsp/launch.ts
  • packages/opencode/src/lsp/server.ts
  • packages/opencode/src/plugin/index.ts
  • packages/opencode/src/provider/provider.ts
  • packages/opencode/src/provider/schema.ts
  • packages/opencode/src/session/llm.ts
  • packages/opencode/src/session/message-v2.ts
  • packages/opencode/src/session/processor.ts
  • packages/opencode/src/session/prompt/anthropic-20250930.txt
  • packages/opencode/src/session/prompt/default.txt
  • packages/opencode/src/session/system.ts
  • packages/opencode/src/skill/discovery.ts
  • packages/opencode/src/snapshot/index.ts
  • packages/opencode/src/tool/truncate-effect.ts
  • packages/opencode/src/util/eventloop.ts
  • packages/opencode/src/util/process.ts
  • packages/opencode/test/file/watcher.test.ts
  • packages/opencode/test/filesystem/filesystem.test.ts
  • packages/opencode/test/lsp/launch.test.ts
  • packages/opencode/test/provider/amazon-bedrock.test.ts
  • packages/opencode/test/provider/gitlab-duo.test.ts
  • packages/opencode/test/provider/provider.test.ts
  • packages/opencode/test/session/message-v2.test.ts
  • packages/opencode/test/util/process.test.ts
  • packages/web/src/content/docs/ar/go.mdx
  • packages/web/src/content/docs/bs/go.mdx
  • packages/web/src/content/docs/da/go.mdx
  • packages/web/src/content/docs/de/go.mdx
  • packages/web/src/content/docs/es/go.mdx
  • packages/web/src/content/docs/fr/go.mdx
  • packages/web/src/content/docs/go.mdx
  • packages/web/src/content/docs/it/go.mdx
  • packages/web/src/content/docs/it/zen.mdx
  • packages/web/src/content/docs/ja/go.mdx
  • packages/web/src/content/docs/ko/go.mdx
  • packages/web/src/content/docs/nb/go.mdx
  • packages/web/src/content/docs/pl/go.mdx
  • packages/web/src/content/docs/providers.mdx
  • packages/web/src/content/docs/pt-br/go.mdx
  • packages/web/src/content/docs/ru/go.mdx
  • packages/web/src/content/docs/th/go.mdx
  • packages/web/src/content/docs/tr/go.mdx
  • packages/web/src/content/docs/zen.mdx
  • packages/web/src/content/docs/zh-cn/go.mdx
  • packages/web/src/content/docs/zh-tw/go.mdx
💤 Files with no reviewable changes (4)
  • packages/opencode/src/util/eventloop.ts
  • packages/opencode/src/cli/cmd/providers.ts
  • packages/opencode/src/plugin/index.ts
  • packages/opencode/src/session/prompt/anthropic-20250930.txt

description: Translate content for a specified locale while preserving technical terms
mode: subagent
model: opencode/gemini-3-pro
model: opencode/gemini-3.1-pro
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify where model IDs are defined/referenced and whether this new ID appears elsewhere.

rg -n -C2 'opencode/gemini-3\.1-pro|opencode/gemini-3-pro|model:\s*opencode/' .

Repository: anduimagui/opencode

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check the git diff for this specific file to see what changed
git diff HEAD -- .opencode/agent/translator.md | head -30

Repository: anduimagui/opencode

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Search for model configuration definitions, registries, or documentation
rg -n 'model|gemini|opencode' '.opencode/' -t md -t yaml -t json | head -20

Repository: anduimagui/opencode

Length of output: 2278


🏁 Script executed:

#!/bin/bash
# Look for any documentation or config files that list supported models
find . -type f \( -name "*.md" -o -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) | xargs rg -l 'model|opencode' | head -10

Repository: anduimagui/opencode

Length of output: 415


🏁 Script executed:

#!/bin/bash
# Check git status and history of this specific file
git status .opencode/agent/translator.md
echo "---"
git log --oneline -5 -- .opencode/agent/translator.md
echo "---"
git show HEAD:.opencode/agent/translator.md 2>/dev/null || echo "File not in HEAD"

Repository: anduimagui/opencode

Length of output: 16520


🏁 Script executed:

#!/bin/bash
# Search for model definitions, catalogs, or validation logic
rg -n 'gemini|claude|kimi' . -t md -t json -t yaml -t js | grep -i 'model\|catalog\|support\|registry' | head -15

Repository: anduimagui/opencode

Length of output: 1455


🏁 Script executed:

#!/bin/bash
# Look for any .opencode configuration or schema documentation
cat .opencode/agent/translator.md
echo "---"
ls -la .opencode/agent/ | head -10

Repository: anduimagui/opencode

Length of output: 16757


Confirm this model ID is supported and document why it changes for a docs-only PR.

The model opencode/gemini-3.1-pro does not appear in the official model registry (the Do-Not-Translate glossary in this file lists all documented models) and is not used in any other agent config files. Other agents use models like opencode/claude-haiku-4-5 and opencode/kimi-k2 which are both in configs and in the glossary. This change is also out of scope for a Workspaces-docs PR unless explicitly documented in the PR description.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/agent/translator.md at line 4, The model entry
"opencode/gemini-3.1-pro" in .opencode/agent/translator.md is not in the
documented model glossary and appears to be an out-of-scope docs-only change;
either revert this model ID or add documentation and justification for its
addition: confirm that "opencode/gemini-3.1-pro" is a supported model, update
the Do-Not-Translate glossary to include it, and add a short PR description
explaining why this docs change is necessary (or remove the line to revert to
the previous documented model).

Comment on lines +261 to +271
onSelect={(value) => {
if (!value) return
const prompt = select()
if (!prompt) return
const nextValue = {
...formStore.value,
[prompt.key]: value.value,
}
setFormStore("value", prompt.key, value.value)
void next(item()!.index, nextValue)
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential reactive state timing issue in select prompt handler.

After calling setFormStore("value", ...) on line 269, the item() accessor may return a different prompt (or undefined) because current() depends on formStore.value. Capturing the index before the state update would be safer.

Suggested fix
                  onSelect={(value) => {
                    if (!value) return
                    const prompt = select()
                    if (!prompt) return
+                   const currentIndex = item()!.index
                    const nextValue = {
                      ...formStore.value,
                      [prompt.key]: value.value,
                    }
                    setFormStore("value", prompt.key, value.value)
-                   void next(item()!.index, nextValue)
+                   void next(currentIndex, nextValue)
                  }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/app/src/components/dialog-connect-provider.tsx` around lines 261 -
271, The onSelect handler mutates formStore with setFormStore("value", ...)
before reading item(), which can change the reactive item() result; fix by
capturing the current prompt/index from item() and/or select() into local
constants (e.g., const currentItem = item(); const idx = currentItem?.index;
const prompt = select();) before calling setFormStore, validate they exist, then
compute nextValue, call setFormStore, and finally call next(idx, nextValue)
using the previously captured idx so the index can't change due to the state
update.

Comment on lines +50 to +51
{ id: "minimax-m2.7", name: "MiniMax M2.7", req: 14000, d: "330ms" },
{ id: "minimax-m2.5", name: "MiniMax M2.5", req: 20000, d: "360ms" },
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update MiniMax CSS selectors to match new model IDs.

Line 50 and Line 51 changed model IDs to versioned values, but packages/console/app/src/routes/go/index.css (Line 664) still targets data-model="minimax". This breaks MiniMax-specific styling for the graph points.

💡 Proposed fix
- [data-point][data-kind="go"][data-model="minimax"] {
+ [data-point][data-kind="go"][data-model^="minimax-"] {
    fill: var(--color-go-3);
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/console/app/src/routes/go/index.tsx` around lines 50 - 51, The CSS
selector targeting MiniMax graph points still looks for data-model="minimax" but
the model IDs in the code were changed to "minimax-m2.7" and "minimax-m2.5";
update the selector(s) in index.css (the rule that uses [data-model="minimax"])
to match the new IDs or use a prefix selector like [data-model^="minimax"] so
both "minimax-m2.7" and "minimax-m2.5" get the MiniMax-specific styling.

- The project’s main worktree is the **local** workspace.
- Additional worktrees are **sandbox** workspaces (extra directories tracked on the project).

Each workspace has its own git branch and directory, so you can experiment without disturbing your main working tree.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use consistent git terminology (“worktree” vs “working tree”).

This line switches to “working tree” while the rest of the page uses “worktree.” Keep one term throughout for clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/docs/workspaces.mdx` at line 11, Replace the inconsistent phrase
"working tree" in the sentence "Each workspace has its own git branch and
directory, so you can experiment without disturbing your main working tree."
with the consistent term "worktree" to match the rest of the page; update that
sentence to read "...without disturbing your main worktree." and ensure no other
occurrences on the page use "working tree."

Comment on lines +48 to +50
const readJson = Effect.fn("FileSystem.readJson")(function* (path: string) {
const text = yield* fs.readFileString(path)
return JSON.parse(text)
Copy link
Copy Markdown

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:

#!/bin/bash
node <<'NODE'
try {
  JSON.parse("{")
} catch (err) {
  console.log("parse:", err.name)
}

console.log("stringify undefined:", JSON.stringify(undefined))

try {
  JSON.stringify({ n: 1n })
} catch (err) {
  console.log("bigint:", err.name)
}

const cyclic = {}
cyclic.self = cyclic
try {
  JSON.stringify(cyclic)
} catch (err) {
  console.log("cyclic:", err.name)
}
NODE

Repository: anduimagui/opencode

Length of output: 148


🏁 Script executed:

# Check if the file exists and examine the readJson and writeJson implementations
cat packages/opencode/src/filesystem/index.ts | head -100

Repository: anduimagui/opencode

Length of output: 4389


🏁 Script executed:

# Read more to see the complete readJson and writeJson implementations
sed -n '48,60p' packages/opencode/src/filesystem/index.ts

Repository: anduimagui/opencode

Length of output: 657


🏁 Script executed:

# Verify Effect.try usage pattern and FileSystemError definition
grep -n "Effect.try" packages/opencode/src/filesystem/index.ts

Repository: anduimagui/opencode

Length of output: 107


🏁 Script executed:

# Check if Effect.try is available in the codebase or used elsewhere
rg "Effect\.try" packages/opencode/src/ -A 2

Repository: anduimagui/opencode

Length of output: 2011


🏁 Script executed:

# Check what happens when JSON.stringify returns undefined and how it might affect writeFileString
node <<'EOF'
// Test what JSON.stringify returns for edge cases
console.log("undefined:", JSON.stringify(undefined))
console.log("function:", JSON.stringify(() => {}))
console.log("symbol:", JSON.stringify(Symbol('test')))

// These throw
const tests = [
  { name: "bigint", obj: { n: 1n } },
  { name: "cyclic", obj: (() => { const o = {}; o.self = o; return o; })() },
];

for (const test of tests) {
  try {
    JSON.stringify(test.obj);
  } catch (e) {
    console.log(`${test.name} throws: ${e.constructor.name}`)
  }
}
EOF

Repository: anduimagui/opencode

Length of output: 171


Wrap JSON parse/stringify failures in FileSystemError.

Invalid JSON, BigInt, circular data, and unsupported top-level values currently escape as synchronous throws or undefined, violating the API signature that advertises AppFileSystem.Error. The readJson and writeJson implementations lack error handling to channel these failures through the Effect error layer.

Proposed fix
       const readJson = Effect.fn("FileSystem.readJson")(function* (path: string) {
         const text = yield* fs.readFileString(path)
-        return JSON.parse(text)
+        return yield* Effect.try({
+          try: () => JSON.parse(text),
+          catch: (cause) => new FileSystemError({ method: "readJson", cause }),
+        })
       })

       const writeJson = Effect.fn("FileSystem.writeJson")(function* (path: string, data: unknown, mode?: number) {
-        const content = JSON.stringify(data, null, 2)
+        const content = yield* Effect.try({
+          try: () => JSON.stringify(data, null, 2),
+          catch: (cause) => new FileSystemError({ method: "writeJson", cause }),
+        })
+        if (content === undefined) {
+          yield* Effect.fail(new FileSystemError({ method: "writeJson" }))
+        }
         yield* fs.writeFileString(path, content)
         if (mode) yield* fs.chmod(path, mode)
       })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/src/filesystem/index.ts` around lines 48 - 50, The JSON
parsing/stringifying in readJson and writeJson must be wrapped so
parse/stringify exceptions are converted into the library's FileSystemError and
propagated through the Effect error channel; update the generator bodies of
readJson and writeJson to catch synchronous errors from JSON.parse and
JSON.stringify (and other serialization issues like BigInt/circular refs),
construct a FileSystemError containing the original error and path context, and
propagate it via the Effect failure mechanism (so the functions no longer throw
synchronously or return undefined but fail with AppFileSystem.Error). Ensure you
reference and use the existing FileSystemError type when creating the error and
propagate it from the readJson and writeJson implementations.

| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 |
| GLM 5 | $1.00 | $3.20 | $0.20 | - |
| Kimi K2.5 | $0.60 | $3.00 | $0.10 | - |
| Qwen3 Coder 480B | $0.45 | $1.50 | - | - |
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistency: Qwen3 Coder 480B has pricing but no endpoint entry.

This model appears in the pricing table but is missing from the Endpoint table (lines 56-89). Additionally, it's listed as deprecated since February 6, 2026 (line 191). Consider either:

  1. Removing it from the pricing table since it's deprecated and has no endpoint, or
  2. Adding it to the endpoint table if it should still be available.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/it/zen.mdx` at line 118, The pricing table
lists "Qwen3 Coder 480B" with rates but there is no corresponding entry in the
Endpoint table and the model is marked deprecated since February 6, 2026; either
remove "Qwen3 Coder 480B" from the pricing table to reflect its
deprecated/unavailable status, or add a matching Endpoint table row for "Qwen3
Coder 480B" (including the endpoint name, input/output formats, and
availability/deprecation note) so the pricing and Endpoint sections stay
consistent; locate the model name "Qwen3 Coder 480B" in the pricing table and
the Endpoint table section to apply the chosen fix.

Comment on lines 200 to +202
- MiniMax M2.5 Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
- OpenAI APIs: le richieste vengono conservate per 30 giorni in conformita alle [OpenAI's Data Policies](https://platform.openai.com/docs/guides/your-data).
- Anthropic APIs: le richieste vengono conservate per 30 giorni in conformita alle [Anthropic's Data Policies](https://docs.anthropic.com/en/docs/claude-code/data-usage).
- MiniMax M2.5 Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
- Nemotron 3 Super Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Duplicate privacy exception entry — likely missing MiMo V2 Flash Free.

Line 200 and 201 both list "MiniMax M2.5 Free". Based on the free models section (lines 156-159), line 201 should likely be "MiMo V2 Flash Free" instead, as it's one of the free trial models but is missing its privacy disclosure.

Proposed fix
 - Big Pickle: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
 - MiniMax M2.5 Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
-- MiniMax M2.5 Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
+- MiMo V2 Flash Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
 - Nemotron 3 Super Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati per migliorare il modello.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/it/zen.mdx` around lines 200 - 202, The Italian
docs contain a duplicate privacy entry "MiniMax M2.5 Free"—replace the second
occurrence with "MiMo V2 Flash Free" so the free-trial models list matches the
free models section; update the privacy sentence for the new entry to the same
format used for "MiniMax M2.5 Free" and "Nemotron 3 Super Free" (i.e., "MiMo V2
Flash Free: durante il periodo gratuito, i dati raccolti potrebbero essere usati
per migliorare il modello.").

Comment on lines +321 to +333
There are plugins that allow you to use your Claude Pro/Max models with
OpenCode. Anthropic explicitly prohibits this.

##### Using API keys
Previous versions of OpenCode came bundled with these plugins but that is no
longer the case as of 1.3.0

You can also select **Create an API Key** if you don't have a Pro/Max subscription. It'll also open your browser and ask you to login to Anthropic and give you a code you can paste in your terminal.
Other companies support freedom of choice with developer tooling - you can use
the following subscriptions in OpenCode with zero setup:

Or if you already have an API key, you can select **Manually enter API Key** and paste it in your terminal.
- ChatGPT Plus
- Github Copilot
- Gitlab Duo
:::
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Resolve the Anthropic setup contradiction in this section.

This new note conflicts with earlier Anthropic steps (Line 304–315), which still tell users to pick Claude Pro/Max in /connect. That creates a broken flow for readers.

🔧 Suggested doc fix
 ### Anthropic

 1. Once you've signed up, run the `/connect` command and select Anthropic.

    ```txt
    /connect
    ```

-2. Here you can select the **Claude Pro/Max** option and it'll open your browser
-   and ask you to authenticate.
+2. Select **Manually enter API Key** and paste your Anthropic API key.

    ```txt
    ┌ Select auth method
    │
-   │ Manually enter API Key
+   │ Manually enter API Key
    └
    ```

-3. Now all the Anthropic models should be available when you use the `/models` command.
+3. Run `/models` to select an Anthropic model.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/providers.mdx` around lines 321 - 333, The
Anthropic setup steps that instruct users to choose "Claude Pro/Max" are now
contradictory with the note that Anthropic is prohibited; update the earlier
Anthropic connect instructions so step 2 instructs the user to "Select Manually
enter API Key and paste your Anthropic API key" instead of selecting Claude
Pro/Max, adjust the example auth-selection ASCII block to show "Manually enter
API Key", and change step 3 wording to "Run `/models` to select an Anthropic
model" so the flow matches the new guidance; locate and edit the Anthropic setup
section text that currently references "Claude Pro/Max" and replace those
phrases and the example snippet accordingly.

Comment on lines +330 to +332
- ChatGPT Plus
- Github Copilot
- Gitlab Duo
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix product name capitalization in user-facing docs.

Use official casing for consistency and searchability:

  • GitHub Copilot (not Github Copilot)
  • GitLab Duo (not Gitlab Duo)
✏️ Suggested copy edit
-- Github Copilot
-- Gitlab Duo
+- GitHub Copilot
+- GitLab Duo
📝 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
- ChatGPT Plus
- Github Copilot
- Gitlab Duo
- ChatGPT Plus
- GitHub Copilot
- GitLab Duo
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/providers.mdx` around lines 330 - 332, Update
the product name casing in the providers list: change "Github Copilot" to
"GitHub Copilot" and "Gitlab Duo" to "GitLab Duo" so user-facing docs use the
official casing; locate the list containing "ChatGPT Plus", "Github Copilot",
"Gitlab Duo" and replace those two strings accordingly to preserve consistency
and searchability.

---

## ความเป็นมา
## Background
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Translate the edited section headings into Thai.

The section titles on Lines 22, 42, 65, 99, 120, and 128 are still English on an otherwise Thai page, so the localized TOC/navigation remains partially untranslated.

Also applies to: 42-42, 65-65, 99-99, 120-120, 128-128

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web/src/content/docs/th/go.mdx` at line 22, Replace the remaining
English section headings on the page (the "Background" heading at line 22 and
the other section titles left in English at lines 42, 65, 99, 120 and 128) with
their Thai equivalents so the page and its TOC/navigation are fully localized;
update the MDX headings themselves (the H2/H3 lines) and any corresponding
anchors or explicit IDs used for the table-of-contents so the localized headings
and links remain in sync.

@github-actions
Copy link
Copy Markdown

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants