Skip to content

Commit 94ff3f0

Browse files
committed
fix - skip arborist plugin deps install in tests; bump snapshot revert timeout
Root cause of all 7 test timeouts: config.ts fires a background @npmcli/arborist.reify() for @opencode-ai/plugin in every .opencode/ directory it discovers. plugin/index.ts and tool/registry.ts then call waitForDependencies() which joins that fiber before loading plugins or custom tools. On Blacksmith ARM64, a cold arborist fetch takes 10-30 s per test. Running in parallel across a 4-vCPU runner saturates CPU/IO and starves even unrelated tests (session.processor, snapshot.revert) past their 30 s limit. Fixes: - flag.ts: add OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL flag - config.ts: guard the npmSvc.install() + deps.push() block with the new flag - preload.ts: set OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL=true for all tests (safe: bun resolves @opencode-ai/plugin from the workspace node_modules; tests do not author plugins that import the SDK at runtime) - snapshot.test.ts: raise timeout on the 280-file revert test to 60 s (git operations across 280 files can push past 30 s on ARM64)
1 parent b9810c4 commit 94ff3f0

4 files changed

Lines changed: 37 additions & 23 deletions

File tree

packages/opencode/src/config/config.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -542,28 +542,30 @@ export const layer = Layer.effect(
542542

543543
yield* ensureGitignore(dir).pipe(Effect.orDie)
544544

545-
const dep = yield* npmSvc
546-
.install(dir, {
547-
add: [
548-
{
549-
name: "@opencode-ai/plugin",
550-
version: InstallationLocal ? undefined : InstallationVersion,
551-
},
552-
],
553-
})
554-
.pipe(
555-
Effect.exit,
556-
Effect.tap((exit) =>
557-
Exit.isFailure(exit)
558-
? Effect.sync(() => {
559-
log.warn("background dependency install failed", { dir, error: String(exit.cause) })
560-
})
561-
: Effect.void,
562-
),
563-
Effect.asVoid,
564-
Effect.forkDetach,
565-
)
566-
deps.push(dep)
545+
if (!Flag.OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL) {
546+
const dep = yield* npmSvc
547+
.install(dir, {
548+
add: [
549+
{
550+
name: "@opencode-ai/plugin",
551+
version: InstallationLocal ? undefined : InstallationVersion,
552+
},
553+
],
554+
})
555+
.pipe(
556+
Effect.exit,
557+
Effect.tap((exit) =>
558+
Exit.isFailure(exit)
559+
? Effect.sync(() => {
560+
log.warn("background dependency install failed", { dir, error: String(exit.cause) })
561+
})
562+
: Effect.void,
563+
),
564+
Effect.asVoid,
565+
Effect.forkDetach,
566+
)
567+
deps.push(dep)
568+
}
567569

568570
result.command = mergeDeep(result.command ?? {}, yield* Effect.promise(() => ConfigCommand.load(dir)))
569571
result.agent = mergeDeep(result.agent ?? {}, yield* Effect.promise(() => ConfigAgent.load(dir)))

packages/opencode/src/flag/flag.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ export const Flag = {
4444
OPENCODE_DISABLE_AUTOCOMPACT: truthy("OPENCODE_DISABLE_AUTOCOMPACT"),
4545
OPENCODE_DISABLE_MODELS_FETCH: truthy("OPENCODE_DISABLE_MODELS_FETCH"),
4646
OPENCODE_DISABLE_MOUSE: truthy("OPENCODE_DISABLE_MOUSE"),
47+
// Skip the background @npmcli/arborist install of @opencode-ai/plugin into
48+
// .opencode/ directories. In production this ensures the plugin SDK is
49+
// available for user-authored plugins. In test environments bun resolves
50+
// @opencode-ai/plugin from the workspace node_modules directly, so the
51+
// install is unnecessary and causes test timeouts on slower CI runners.
52+
OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL: truthy("OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL"),
4753
OPENCODE_DISABLE_CLAUDE_CODE,
4854
OPENCODE_DISABLE_CLAUDE_CODE_PROMPT: OPENCODE_DISABLE_CLAUDE_CODE || truthy("OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"),
4955
OPENCODE_DISABLE_CLAUDE_CODE_SKILLS,

packages/opencode/test/preload.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ process.env["OPENCODE_TEST_HOME"] = testHome
4545
const testManagedConfigDir = path.join(dir, "managed")
4646
process.env["OPENCODE_TEST_MANAGED_CONFIG_DIR"] = testManagedConfigDir
4747
process.env["OPENCODE_DISABLE_DEFAULT_PLUGINS"] = "true"
48+
// Skip the background @npmcli/arborist install of @opencode-ai/plugin into
49+
// .opencode/ dirs. Tests don't need the runtime npm install because bun
50+
// resolves @opencode-ai/plugin from the monorepo workspace node_modules.
51+
// Without this, plugin/tool tests trigger a full npm network fetch per test,
52+
// consuming 10-30 s on Blacksmith ARM64 CI and causing timeouts.
53+
process.env["OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL"] = "true"
4854

4955
// Write the cache version file to prevent global/index.ts from clearing the cache
5056
const cacheDir = path.join(dir, "cache", "opencode")

packages/opencode/test/snapshot/snapshot.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,4 +1528,4 @@ test("revert handles large mixed batches across chunk boundaries", async () => {
15281528
)
15291529
},
15301530
})
1531-
})
1531+
}, 60_000) // 280 files + multiple git operations can exceed 30 s on slower ARM64 CI runners

0 commit comments

Comments
 (0)