Skip to content

Commit 5874d9d

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into ocv
# Conflicts: # packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx # packages/opencode/src/cli/cmd/tui/routes/session/index.tsx # packages/opencode/src/plugin/codex.ts
2 parents 3875471 + 3c24d22 commit 5874d9d

318 files changed

Lines changed: 15258 additions & 7763 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/VOUCHED.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ ariane-emory
1616
-danieljoshuanazareth
1717
-danieljoshuanazareth
1818
-davidbernat looks to be a clawdbot that spams team and sends super weird emails, doesnt appear to be a real person
19+
dmtrkovalenko
1920
edemaine
21+
fahreddinozcan
2022
-florianleibert
2123
fwang
2224
iamdavidhill

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
- name: Build
8989
id: build
9090
run: |
91-
./packages/opencode/script/build.ts
91+
./packages/opencode/script/build.ts ${{ (github.ref_name == 'beta' && '--sourcemaps') || '' }}
9292
env:
9393
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
9494
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}

.opencode/skills/effect/SKILL.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,11 @@ Use the current Effect v4 / effect-smol source, not memory or older Effect v2/v3
2828
- In tests, prefer the repo's existing Effect test helpers and live tests for filesystem, git, child process, locks, or timing behavior.
2929
- Do not introduce `any`, non-null assertions, unchecked casts, or older Effect APIs just to satisfy types.
3030
- Do not answer from memory. Verify against `.opencode/references/effect-smol` or nearby code first.
31+
32+
## Testing Patterns
33+
34+
- Use `testEffect(...)` from `packages/opencode/test/lib/effect.ts` for tests that exercise Effect services, layers, runtime context, scoped resources, or platform integrations.
35+
- Use `it.live(...)` for filesystem, git repositories, HTTP servers, sockets, child processes, locks, real time, and other live platform behavior.
36+
- Run tests from package directories such as `packages/opencode`; never run package tests from the repo root.
37+
- Prefer explicit test layers over ad hoc managed runtimes. Keep dependency provisioning visible in the test file.
38+
- Use scoped fixtures and finalizers for resources that must be cleaned up, including temporary directories, flags, databases, fibers, servers, and global state.

bun.lock

Lines changed: 67 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nix/hashes.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"nodeModules": {
3-
"x86_64-linux": "sha256-h2T/LnUnISZZDn9ZQkZ/A59P+6+QdfOlrgl4RXK/vgM=",
4-
"aarch64-linux": "sha256-+DRohG1ZEB/2LtZU90GWoqJkeyu/sW8A8oKT3f/TtQ0=",
5-
"aarch64-darwin": "sha256-k4nsk/WduuxY8HgjRuqzGT9EjEo7V/2mAzBTYee0fZ0=",
6-
"x86_64-darwin": "sha256-3dSvfN2+5lXwOx57x8NSIWbEZ1fp6+1T6bJpAuUNPyk="
3+
"x86_64-linux": "sha256-cBfg4pJ4mjsfS4MFFASBaZZykArgIoeo/3woOcSGy1U=",
4+
"aarch64-linux": "sha256-Q6cqUwfqbscdrPW0uHcfshhQINjJi0HiyURMSdOOCf4=",
5+
"aarch64-darwin": "sha256-1AtfsD1D9YxWSEsecPJF9XsvsxsWTtVtkP5l6UW43og=",
6+
"x86_64-darwin": "sha256-YS5/8YTf9LymAUbjXVrGDfxtKVJrpZbPnnCtsGHSHoU="
77
}
88
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
"@types/cross-spawn": "6.0.6",
3535
"@octokit/rest": "22.0.0",
3636
"@hono/zod-validator": "0.4.2",
37-
"@opentui/core": "0.1.105",
38-
"@opentui/solid": "0.1.105",
37+
"@opentui/core": "0.2.0",
38+
"@opentui/solid": "0.2.0",
3939
"ulid": "3.0.1",
4040
"@kobalte/core": "0.13.11",
4141
"@types/luxon": "3.7.1",

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@opencode-ai/app",
3-
"version": "1.14.29",
3+
"version": "1.14.30",
44
"description": "",
55
"type": "module",
66
"exports": {

packages/app/src/components/settings-general.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ export const SettingsGeneral: Component = () => {
329329
label={(o) => o.label}
330330
onSelect={(option) => {
331331
if (!option) return
332+
if (option.value === currentShell()) return
332333
globalSync.updateConfig({ shell: option.value })
333334
}}
334335
variant="secondary"

packages/app/src/context/global-sync.tsx

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { SESSION_RECENT_LIMIT } from "./global-sync/types"
3333
import { formatServerError } from "@/utils/server-errors"
3434
import { queryOptions, skipToken, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/solid-query"
3535
import { createRefreshQueue } from "./global-sync/queue"
36+
import { directoryKey } from "./global-sync/utils"
3637

3738
type GlobalStore = {
3839
ready: boolean
@@ -169,18 +170,20 @@ function createGlobalSync() {
169170

170171
const queue = createRefreshQueue({
171172
paused,
173+
key: directoryKey,
172174
bootstrap: () => queryClient.fetchQuery({ queryKey: ["bootstrap"] }),
173175
bootstrapInstance,
174176
})
175177

176178
const sdkFor = (directory: string) => {
177-
const cached = sdkCache.get(directory)
179+
const key = directoryKey(directory)
180+
const cached = sdkCache.get(key)
178181
if (cached) return cached
179182
const sdk = globalSDK.createClient({
180183
directory,
181184
throwOnError: true,
182185
})
183-
sdkCache.set(directory, sdk)
186+
sdkCache.set(key, sdk)
184187
return sdk
185188
}
186189

@@ -192,23 +195,25 @@ function createGlobalSync() {
192195
void bootstrapInstance(directory)
193196
},
194197
onDispose: (directory) => {
195-
queue.clear(directory)
196-
sessionMeta.delete(directory)
197-
sdkCache.delete(directory)
198-
clearProviderRev(directory)
199-
clearSessionPrefetchDirectory(directory)
198+
const key = directoryKey(directory)
199+
queue.clear(key)
200+
sessionMeta.delete(key)
201+
sdkCache.delete(key)
202+
clearProviderRev(key)
203+
clearSessionPrefetchDirectory(key)
200204
},
201205
translate: language.t,
202206
getSdk: sdkFor,
203207
})
204208

205209
async function loadSessions(directory: string) {
206-
const pending = sessionLoads.get(directory)
210+
const key = directoryKey(directory)
211+
const pending = sessionLoads.get(key)
207212
if (pending) return pending
208213

209-
children.pin(directory)
214+
children.pin(key)
210215
const [store, setStore] = children.child(directory, { bootstrap: false })
211-
const meta = sessionMeta.get(directory)
216+
const meta = sessionMeta.get(key)
212217
if (meta && meta.limit >= store.limit) {
213218
const next = trimSessions(store.session, {
214219
limit: store.limit,
@@ -218,14 +223,14 @@ function createGlobalSync() {
218223
setStore("session", reconcile(next, { key: "id" }))
219224
cleanupDroppedSessionCaches(store, setStore, next, setSessionTodo)
220225
}
221-
children.unpin(directory)
226+
children.unpin(key)
222227
return
223228
}
224229

225230
const limit = Math.max(store.limit + SESSION_RECENT_LIMIT, SESSION_RECENT_LIMIT)
226231
const promise = queryClient
227232
.fetchQuery({
228-
...loadSessionsQuery(directory),
233+
...loadSessionsQuery(key),
229234
queryFn: () =>
230235
loadRootSessionsWithFallback({
231236
directory,
@@ -255,7 +260,7 @@ function createGlobalSync() {
255260
setStore("session", reconcile(sessions, { key: "id" }))
256261
cleanupDroppedSessionCaches(store, setStore, sessions, setSessionTodo)
257262
})
258-
sessionMeta.set(directory, { limit })
263+
sessionMeta.set(key, { limit })
259264
})
260265
.catch((err) => {
261266
console.error("Failed to load sessions", err)
@@ -270,23 +275,24 @@ function createGlobalSync() {
270275
})
271276
.then(() => {})
272277

273-
sessionLoads.set(directory, promise)
278+
sessionLoads.set(key, promise)
274279
void promise.finally(() => {
275-
sessionLoads.delete(directory)
276-
children.unpin(directory)
280+
sessionLoads.delete(key)
281+
children.unpin(key)
277282
})
278283
return promise
279284
}
280285

281286
async function bootstrapInstance(directory: string) {
282-
if (!directory) return
283-
const pending = booting.get(directory)
287+
const key = directoryKey(directory)
288+
if (!key) return
289+
const pending = booting.get(key)
284290
if (pending) return pending
285291

286-
children.pin(directory)
292+
children.pin(key)
287293
const promise = Promise.resolve().then(async () => {
288294
const child = children.ensureChild(directory)
289-
const cache = children.vcsCache.get(directory)
295+
const cache = children.vcsCache.get(key)
290296
if (!cache) return
291297
const sdk = sdkFor(directory)
292298
await bootstrapDirectory({
@@ -307,16 +313,17 @@ function createGlobalSync() {
307313
})
308314
})
309315

310-
booting.set(directory, promise)
316+
booting.set(key, promise)
311317
void promise.finally(() => {
312-
booting.delete(directory)
313-
children.unpin(directory)
318+
booting.delete(key)
319+
children.unpin(key)
314320
})
315321
return promise
316322
}
317323

318324
const unsub = globalSDK.event.listen((e) => {
319325
const directory = e.name
326+
const key = directoryKey(directory)
320327
const event = e.details
321328
const recent = bootingRoot || Date.now() - bootedAt < 1500
322329

@@ -339,9 +346,9 @@ function createGlobalSync() {
339346
return
340347
}
341348

342-
const existing = children.children[directory]
349+
const existing = children.children[key]
343350
if (!existing) return
344-
children.mark(directory)
351+
children.mark(key)
345352
const [store, setStore] = existing
346353
applyDirectoryEvent({
347354
event,
@@ -350,9 +357,9 @@ function createGlobalSync() {
350357
setStore,
351358
push: queue.push,
352359
setSessionTodo,
353-
vcsCache: children.vcsCache.get(directory),
360+
vcsCache: children.vcsCache.get(key),
354361
loadLsp: () => {
355-
void queryClient.fetchQuery(loadLspQuery(directory, sdkFor(directory)))
362+
void queryClient.fetchQuery(loadLspQuery(key, sdkFor(directory)))
356363
},
357364
})
358365
})
@@ -363,7 +370,7 @@ function createGlobalSync() {
363370
})
364371
onCleanup(() => {
365372
for (const directory of Object.keys(children.children)) {
366-
children.disposeDirectory(directory)
373+
children.disposeDirectory(directoryKey(directory))
367374
}
368375
})
369376

0 commit comments

Comments
 (0)