chore: upgrade Effect to beta.98 (#37498)

This commit is contained in:
Kit Langton 2026-07-17 10:31:27 -04:00 committed by GitHub
commit 44f7bb71c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 316 additions and 138 deletions

View file

@ -150,7 +150,7 @@ function expandHome(resource: string, home: string) {
function discover(fs: FSUtil.Interface, directory: string) {
return Effect.forEach(legacySources, (source) =>
fs
.glob(source.pattern, { cwd: directory, absolute: true, dot: true, symlink: true })
.scan(source.pattern, { cwd: directory, absolute: true, dot: true, symlink: true })
.pipe(
Effect.map((files) => files.toSorted().map((filepath) => ({ directory, filepath, primary: source.primary }))),
),

View file

@ -62,7 +62,7 @@ export const Plugin = define({
function loadDirectory(fs: FSUtil.Interface, directory: string) {
return Effect.gen(function* () {
const files = yield* fs
.glob("{command,commands}/**/*.md", { cwd: directory, absolute: true, dot: true, symlink: true })
.scan("{command,commands}/**/*.md", { cwd: directory, absolute: true, dot: true, symlink: true })
.pipe(Effect.catch(() => Effect.succeed([] as string[])))
return yield* Effect.forEach(files.toSorted(), (filepath) =>
fs.readFileStringSafe(filepath).pipe(

View file

@ -88,6 +88,9 @@ const make = (options: Config) =>
executeValues(query, params) {
return runValues(query, params)
},
executeValuesUnprepared(query, params) {
return runValues(query, params)
},
executeUnprepared(query, params, transformRows) {
return this.execute(query, params, transformRows)
},

View file

@ -89,6 +89,9 @@ const make = (options: Config) =>
executeValues(query, params) {
return runValues(query, params)
},
executeValuesUnprepared(query, params) {
return runValues(query, params)
},
executeUnprepared(query, params, transformRows) {
return this.execute(query, params, transformRows)
},

View file

@ -42,7 +42,7 @@ export namespace FSUtil {
readonly findUp: (target: string, start: string, stop?: string) => Effect.Effect<string[], Error>
readonly up: (options: { targets: string[]; start: string; stop?: string }) => Effect.Effect<string[], Error>
readonly globUp: (pattern: string, start: string, stop?: string) => Effect.Effect<string[], Error>
readonly glob: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>
readonly scan: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>
readonly globMatch: (pattern: string, filepath: string) => boolean
}
@ -51,7 +51,7 @@ export namespace FSUtil {
export const use = serviceUse(Service)
// Exported so simulation can wrap this layer and override the methods that
// bypass the injected FileSystem (readDirectoryEntries, glob, globUp).
// bypass the injected FileSystem (readDirectoryEntries, scan, globUp).
export const layer = Layer.effect(
Service,
Effect.gen(function* () {
@ -146,7 +146,7 @@ export namespace FSUtil {
if (mode) yield* fs.chmod(path, mode)
})
const glob = Effect.fn("FileSystem.glob")(function* (pattern: string, options?: Glob.Options) {
const scan = Effect.fn("FileSystem.scan")(function* (pattern: string, options?: Glob.Options) {
return yield* Effect.tryPromise({
try: () => Glob.scan(pattern, options),
catch: (cause) => new FileSystemError({ method: "glob", cause }),
@ -187,7 +187,7 @@ export namespace FSUtil {
const result: string[] = []
let current = start
while (true) {
const matches = yield* glob(pattern, { cwd: current, absolute: true, include: "file", dot: true }).pipe(
const matches = yield* scan(pattern, { cwd: current, absolute: true, include: "file", dot: true }).pipe(
Effect.catch(() => Effect.succeed([] as string[])),
)
result.push(...matches)
@ -214,7 +214,7 @@ export namespace FSUtil {
findUp,
up,
globUp,
glob,
scan,
globMatch: Glob.match,
})
}),

View file

@ -94,7 +94,7 @@ const configuredPlugins = Effect.fn("SkillPlugin.configuredPlugins")(function* (
}
if (entry.type !== "directory") return Effect.succeed([])
return fs
.glob("{plugin,plugins}/*.{ts,js}", {
.scan("{plugin,plugins}/*.{ts,js}", {
cwd: entry.path,
absolute: true,
include: "file",

View file

@ -184,7 +184,7 @@ const load = Effect.fn("PluginSupervisor.load")(function* (operation: Extract<Op
function discoverDirectory(fs: FSUtil.Interface, directory: string) {
return Effect.gen(function* () {
const files = yield* fs
.glob("{plugin,plugins}/*.{ts,js}", {
.scan("{plugin,plugins}/*.{ts,js}", {
cwd: directory,
absolute: true,
include: "file",

View file

@ -44,12 +44,11 @@ const retryAfter = (failure: RetryableFailure) => {
}
export const schedule = (events: EventV2.Interface, sessionID: SessionSchema.ID) =>
Schedule.exponential("2 seconds").pipe(
Schedule.take(4),
Schedule.max([Schedule.exponential("2 seconds"), Schedule.recurs(4)]).pipe(
Schedule.setInputType<RetryableFailure | SessionRunner.RunError>(),
Schedule.passthrough,
Schedule.while(({ input }) => input instanceof RetryableFailure),
Schedule.modifyDelay((failure, delay) => {
Schedule.modifyDelay(({ input: failure, duration: delay }) => {
const minimum = failure instanceof RetryableFailure ? retryAfter(failure) : undefined
return Effect.succeed(minimum === undefined ? delay : Duration.max(delay, Duration.millis(minimum)))
}),

View file

@ -109,7 +109,7 @@ const layer = Layer.effect(
const directories = source.type === "directory" ? [source.path] : yield* discovery.pull(source.url)
for (const directory of directories) {
const files = yield* fs
.glob("{*.md,**/SKILL.md}", { cwd: directory, absolute: true, include: "file", symlink: true, dot: true })
.scan("{*.md,**/SKILL.md}", { cwd: directory, absolute: true, include: "file", symlink: true, dot: true })
.pipe(Effect.catch(() => Effect.succeed([] as string[])))
for (const filepath of files.toSorted()) {
const content = yield* fs.readFileStringSafe(filepath).pipe(Effect.catch(() => Effect.succeed(undefined)))

View file

@ -84,7 +84,7 @@ export const Plugin = {
const directory = path.dirname(skill.location)
const files =
path.basename(skill.location) === "SKILL.md"
? (yield* fs.glob("**/*", { cwd: directory, absolute: true, include: "file", dot: true }))
? (yield* fs.scan("**/*", { cwd: directory, absolute: true, include: "file", dot: true }))
.filter((file) => path.basename(file) !== "SKILL.md")
.toSorted()
.slice(0, FILE_LIMIT)

View file

@ -50,11 +50,14 @@ export namespace EffectFlock {
const BASE_DELAY_MS = 100
const MAX_DELAY_MS = 2_000
const retrySchedule = (timeoutMs: number) => Schedule.exponential(BASE_DELAY_MS, 1.7).pipe(
Schedule.either(Schedule.spaced(Math.min(MAX_DELAY_MS, Math.max(BASE_DELAY_MS, Math.floor(timeoutMs / 10))))),
Schedule.jittered,
Schedule.while((meta) => meta.elapsed < timeoutMs),
)
const retrySchedule = (timeoutMs: number) =>
Schedule.min([
Schedule.exponential(BASE_DELAY_MS, 1.7),
Schedule.spaced(Math.min(MAX_DELAY_MS, Math.max(BASE_DELAY_MS, Math.floor(timeoutMs / 10)))),
]).pipe(
Schedule.jittered,
Schedule.while((meta) => meta.elapsed < timeoutMs),
)
// ---------------------------------------------------------------------------
// Lock metadata schema