fix(core): preserve global instructions across read races
This commit is contained in:
parent
7456598cde
commit
1bbe16b93e
2 changed files with 41 additions and 2 deletions
|
|
@ -66,7 +66,10 @@ export const layer = (options?: Options) => Layer.effect(
|
||||||
fs.resolve,
|
fs.resolve,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
const paths = Array.dedupe([yield* fs.resolve(join(global.config, "AGENTS.md")), ...discovered])
|
const globalPath = yield* fs.resolve(join(global.config, "AGENTS.md"))
|
||||||
|
const observed = new Set(discovered)
|
||||||
|
if (yield* fs.exists(globalPath)) observed.add(globalPath)
|
||||||
|
const paths = Array.dedupe([globalPath, ...discovered])
|
||||||
const files = yield* Effect.forEach(
|
const files = yield* Effect.forEach(
|
||||||
paths,
|
paths,
|
||||||
(path) =>
|
(path) =>
|
||||||
|
|
@ -79,7 +82,7 @@ export const layer = (options?: Options) => Layer.effect(
|
||||||
),
|
),
|
||||||
{ concurrency: "unbounded" },
|
{ concurrency: "unbounded" },
|
||||||
)
|
)
|
||||||
if (files.some((file, index) => file === undefined && discovered.has(paths[index])))
|
if (files.some((file, index) => file === undefined && observed.has(paths[index])))
|
||||||
return Instructions.unavailable
|
return Instructions.unavailable
|
||||||
return files.filter((file): file is File => file !== undefined)
|
return files.filter((file): file is File => file !== undefined)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,42 @@ describe("InstructionDiscovery", () => {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it.effect("preserves admitted instructions when the global file disappears before read", () =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const file = AbsolutePath.make("/global/AGENTS.md")
|
||||||
|
const racingFS = Layer.effect(
|
||||||
|
FSUtil.Service,
|
||||||
|
FSUtil.Service.pipe(
|
||||||
|
Effect.map((fs) =>
|
||||||
|
FSUtil.Service.of({
|
||||||
|
...fs,
|
||||||
|
exists: () => Effect.succeed(true),
|
||||||
|
up: () => Effect.succeed([]),
|
||||||
|
readFileStringSafe: () => Effect.succeed(undefined),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).pipe(Layer.provide(LayerNode.compile(FSUtil.node)))
|
||||||
|
const context = yield* InstructionDiscovery.Service.pipe(
|
||||||
|
Effect.flatMap((service) => service.load()),
|
||||||
|
Effect.provide(
|
||||||
|
instructionLayer({
|
||||||
|
config: "/global",
|
||||||
|
filesystemLayer: racingFS,
|
||||||
|
locationServiceLayer: Layer.succeed(
|
||||||
|
Location.Service,
|
||||||
|
Location.Service.of(location({ directory: AbsolutePath.make("/repo") })),
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
(yield* readUpdate(context, state({ "core/instructions": [{ path: file, content: "old" }] }))).changed,
|
||||||
|
).toBe(false)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
it.effect("canonicalizes upward discovery boundaries", () =>
|
it.effect("canonicalizes upward discovery boundaries", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
let observed: { targets: string[]; start: string; stop?: string } | undefined
|
let observed: { targets: string[]; start: string; stop?: string } | undefined
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue