mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
Introduce a primaryWorktree Effect that queries Git plumbing commands to locate the main checkout from any linked worktree. Integrate it into config loading so .kilo directory settings from the primary checkout act as local-scoped fallbacks beneath the active worktree and KILO_CONFIG_DIR overrides. Wire primaryPaths into skill discovery so project skills installed in the primary checkout appear as fallbacks unless overridden locally. Refactor session family matching to consider sandbox directories and filter out nested Git repositories when resolving worktree roots. Convert baselineDirectory in indexing to an Effect that delegates to primaryWorktree instead of reading Instance.project.worktree directly. Restore the content() signal usage in the TUI text part renderer. Provide Git.defaultLayer across all affected test layers and add coverage for linked worktrees, submodules, paths with spaces, sandbox project matching, and primary config directory precedence.
122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
import { describe, expect } from "bun:test"
|
|
import { Effect, Layer } from "effect"
|
|
import { FetchHttpClient } from "effect/unstable/http"
|
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
|
import { EffectFlock } from "@opencode-ai/core/util/effect-flock"
|
|
import path from "path"
|
|
import { pathToFileURL } from "url"
|
|
import { Bus } from "../../src/bus"
|
|
import { Config } from "../../src/config/config"
|
|
import { Env } from "../../src/env"
|
|
import { Git } from "../../src/git" // kilocode_change
|
|
import { RuntimeFlags } from "../../src/effect/runtime-flags"
|
|
import { Plugin } from "../../src/plugin/index"
|
|
import { ModelID, ProviderID } from "../../src/provider/schema"
|
|
import { provideTmpdirInstance } from "../fixture/fixture"
|
|
import { testEffect } from "../lib/effect"
|
|
import { AccountTest } from "../fake/account"
|
|
import { AuthTest } from "../fake/auth"
|
|
import { NpmTest } from "../fake/npm"
|
|
|
|
const configLayer = Config.layer.pipe(
|
|
Layer.provide(Git.defaultLayer), // kilocode_change
|
|
Layer.provide(EffectFlock.defaultLayer),
|
|
Layer.provide(AppFileSystem.defaultLayer),
|
|
Layer.provide(Env.defaultLayer),
|
|
Layer.provide(AuthTest.empty),
|
|
Layer.provide(AccountTest.empty),
|
|
Layer.provide(NpmTest.noop),
|
|
Layer.provide(FetchHttpClient.layer),
|
|
)
|
|
const it = testEffect(
|
|
Layer.mergeAll(
|
|
Plugin.layer.pipe(
|
|
Layer.provide(Bus.layer),
|
|
Layer.provide(configLayer),
|
|
Layer.provide(RuntimeFlags.layer({ disableDefaultPlugins: true })),
|
|
),
|
|
CrossSpawnSpawner.defaultLayer,
|
|
),
|
|
)
|
|
const systemHook = "experimental.chat.system.transform"
|
|
|
|
function withProject<A, E, R>(source: string, self: Effect.Effect<A, E, R>) {
|
|
return provideTmpdirInstance((dir) =>
|
|
Effect.gen(function* () {
|
|
const file = path.join(dir, "plugin.ts")
|
|
yield* Effect.all(
|
|
[
|
|
Effect.promise(() => Bun.write(file, source)),
|
|
Effect.promise(() =>
|
|
Bun.write(
|
|
path.join(dir, "opencode.json"),
|
|
JSON.stringify(
|
|
{
|
|
$schema: "https://opencode.ai/config.json",
|
|
plugin: [pathToFileURL(file).href],
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
{ discard: true, concurrency: 2 },
|
|
)
|
|
return yield* self
|
|
}),
|
|
)
|
|
}
|
|
|
|
const triggerSystemTransform = Effect.fn("PluginTriggerTest.triggerSystemTransform")(function* () {
|
|
const plugin = yield* Plugin.Service
|
|
const out = { system: [] as string[] }
|
|
yield* plugin.trigger(
|
|
systemHook,
|
|
{
|
|
model: {
|
|
providerID: ProviderID.anthropic,
|
|
modelID: ModelID.make("claude-sonnet-4-6"),
|
|
},
|
|
},
|
|
out,
|
|
)
|
|
return out.system
|
|
})
|
|
|
|
describe("plugin.trigger", () => {
|
|
it.live("runs synchronous hooks without crashing", () =>
|
|
withProject(
|
|
[
|
|
"export default async () => ({",
|
|
` ${JSON.stringify(systemHook)}: (_input, output) => {`,
|
|
' output.system.unshift("sync")',
|
|
" },",
|
|
"})",
|
|
"",
|
|
].join("\n"),
|
|
Effect.gen(function* () {
|
|
expect(yield* triggerSystemTransform()).toEqual(["sync"])
|
|
}),
|
|
),
|
|
)
|
|
|
|
it.live("awaits asynchronous hooks", () =>
|
|
withProject(
|
|
[
|
|
"export default async () => ({",
|
|
` ${JSON.stringify(systemHook)}: async (_input, output) => {`,
|
|
" await Bun.sleep(1)",
|
|
' output.system.unshift("async")',
|
|
" },",
|
|
"})",
|
|
"",
|
|
].join("\n"),
|
|
Effect.gen(function* () {
|
|
expect(yield* triggerSystemTransform()).toEqual(["async"])
|
|
}),
|
|
),
|
|
)
|
|
})
|