refactor(core): replace legacy logger with Effect logging (#31310)
This commit is contained in:
@@ -4,7 +4,6 @@ import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } fr
|
||||
import { withTransientReadRetry } from "@/util/effect-http-client"
|
||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
|
||||
const skillConcurrency = 4
|
||||
const fileConcurrency = 8
|
||||
@@ -27,7 +26,6 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/Sk
|
||||
export const layer: Layer.Layer<Service, never, FSUtil.Service | Path.Path | HttpClient.HttpClient> = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const log = Log.create({ service: "skill-discovery" })
|
||||
const fs = yield* FSUtil.Service
|
||||
const path = yield* Path.Path
|
||||
const http = HttpClient.filterStatusOk(withTransientReadRetry(yield* HttpClient.HttpClient))
|
||||
@@ -42,10 +40,7 @@ export const layer: Layer.Layer<Service, never, FSUtil.Service | Path.Path | Htt
|
||||
Effect.flatMap((body) => fs.writeWithDirs(dest, new Uint8Array(body))),
|
||||
Effect.as(true),
|
||||
Effect.catch((err) =>
|
||||
Effect.sync(() => {
|
||||
log.error("failed to download", { url, err })
|
||||
return false
|
||||
}),
|
||||
Effect.logError("failed to download", { url: url, error: err }).pipe(Effect.as(false)),
|
||||
),
|
||||
)
|
||||
})
|
||||
@@ -55,29 +50,27 @@ export const layer: Layer.Layer<Service, never, FSUtil.Service | Path.Path | Htt
|
||||
const index = new URL("index.json", base).href
|
||||
const host = base.slice(0, -1)
|
||||
|
||||
log.info("fetching index", { url: index })
|
||||
yield* Effect.logInfo("fetching index", { url: index })
|
||||
|
||||
const data = yield* HttpClientRequest.get(index).pipe(
|
||||
HttpClientRequest.acceptJson,
|
||||
http.execute,
|
||||
Effect.flatMap(HttpClientResponse.schemaBodyJson(Index)),
|
||||
Effect.catch((err) =>
|
||||
Effect.sync(() => {
|
||||
log.error("failed to fetch index", { url: index, err })
|
||||
return null
|
||||
}),
|
||||
Effect.logError("failed to fetch index", { url: index, error: err }).pipe(Effect.as(null)),
|
||||
),
|
||||
)
|
||||
|
||||
if (!data) return []
|
||||
|
||||
const list = data.skills.filter((skill) => {
|
||||
if (!skill.files.includes("SKILL.md")) {
|
||||
log.warn("skill entry missing SKILL.md", { url: index, skill: skill.name })
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
const missing = data.skills.filter((skill) => !skill.files.includes("SKILL.md"))
|
||||
yield* Effect.forEach(
|
||||
missing,
|
||||
(skill) =>
|
||||
Effect.logWarning("skill entry missing SKILL.md", { url: index, skill: skill.name }),
|
||||
{ discard: true },
|
||||
)
|
||||
const list = data.skills.filter((skill) => skill.files.includes("SKILL.md"))
|
||||
|
||||
const dirs = yield* Effect.forEach(
|
||||
list,
|
||||
|
||||
@@ -14,11 +14,9 @@ import { FrontmatterError } from "@opencode-ai/core/v1/config/error"
|
||||
import { ConfigMarkdown } from "@/config/markdown"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import { Glob } from "@opencode-ai/core/util/glob"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import { Discovery } from "./discovery"
|
||||
import { isRecord } from "@/util/record"
|
||||
|
||||
const log = Log.create({ service: "skill" })
|
||||
const CLAUDE_EXTERNAL_DIR = ".claude"
|
||||
const AGENTS_EXTERNAL_DIR = ".agents"
|
||||
const EXTERNAL_SKILL_PATTERN = "skills/**/SKILL.md"
|
||||
@@ -113,7 +111,7 @@ const add = Effect.fnUntraced(function* (state: State, match: string, events: Ev
|
||||
const message = FrontmatterError.isInstance(err) ? err.data.message : `Failed to parse skill ${match}`
|
||||
const { Session } = yield* Effect.promise(() => import("@/session/session"))
|
||||
yield* events.publish(Session.Event.Error, { error: new NamedError.Unknown({ message }).toObject() })
|
||||
log.error("failed to load skill", { skill: match, err })
|
||||
yield* Effect.logError("failed to load skill", { skill: match, error: err })
|
||||
return undefined
|
||||
}),
|
||||
),
|
||||
@@ -124,11 +122,7 @@ const add = Effect.fnUntraced(function* (state: State, match: string, events: Ev
|
||||
if (!isSkillFrontmatter(md.data)) return
|
||||
|
||||
if (state.skills[md.data.name]) {
|
||||
log.warn("duplicate skill name", {
|
||||
name: md.data.name,
|
||||
existing: state.skills[md.data.name].location,
|
||||
duplicate: match,
|
||||
})
|
||||
yield* Effect.logWarning("duplicate skill name", { name: md.data.name, existing: state.skills[md.data.name].location, duplicate: match })
|
||||
}
|
||||
|
||||
state.dirs.add(path.dirname(match))
|
||||
@@ -159,8 +153,7 @@ const scan = Effect.fnUntraced(function* (
|
||||
}).pipe(
|
||||
Effect.catch((error) => {
|
||||
if (!opts?.scope) return Effect.die(error)
|
||||
log.error(`failed to scan ${opts.scope} skills`, { dir: root, error })
|
||||
return Effect.succeed([] as string[])
|
||||
return Effect.logError(`failed to scan ${opts.scope} skills`, { dir: root, error: error }).pipe(Effect.as([] as string[]))
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -212,7 +205,7 @@ const discoverSkills = Effect.fnUntraced(function* (
|
||||
const expanded = item.startsWith("~/") ? path.join(global.home, item.slice(2)) : item
|
||||
const dir = path.isAbsolute(expanded) ? expanded : path.join(directory, expanded)
|
||||
if (!(yield* fsys.isDir(dir))) {
|
||||
log.warn("skill path not found", { path: dir })
|
||||
yield* Effect.logWarning("skill path not found", { path: dir })
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -242,7 +235,7 @@ const loadSkills = Effect.fnUntraced(function* (
|
||||
discard: true,
|
||||
})
|
||||
|
||||
log.info("init", { count: Object.keys(state.skills).length })
|
||||
yield* Effect.logInfo("init", { count: Object.keys(state.skills).length })
|
||||
})
|
||||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/Skill") {}
|
||||
|
||||
Reference in New Issue
Block a user