Add structured logging and ensure CLI shuts down cleanly

This commit is contained in:
Shantur Rathore
2025-11-17 20:21:39 +00:00
parent 08d81f8bb5
commit 719a9c9c74
13 changed files with 255 additions and 55 deletions

View File

@@ -7,9 +7,14 @@ import {
import { ConfigStore } from "./store"
import { EventBus } from "../events/bus"
import type { ConfigFileUpdate } from "./schema"
import { Logger } from "../logger"
export class BinaryRegistry {
constructor(private readonly configStore: ConfigStore, private readonly eventBus?: EventBus) {}
constructor(
private readonly configStore: ConfigStore,
private readonly eventBus: EventBus | undefined,
private readonly logger: Logger,
) {}
list(): BinaryRecord[] {
return this.mapRecords()
@@ -18,12 +23,14 @@ export class BinaryRegistry {
resolveDefault(): BinaryRecord {
const binaries = this.mapRecords()
if (binaries.length === 0) {
this.logger.warn("No configured binaries found, falling back to opencode")
return this.buildFallbackRecord("opencode")
}
return binaries.find((binary) => binary.isDefault) ?? binaries[0]
}
create(request: BinaryCreateRequest): BinaryRecord {
this.logger.info({ path: request.path }, "Registering OpenCode binary")
const entry = {
path: request.path,
version: undefined,
@@ -49,6 +56,7 @@ export class BinaryRegistry {
}
update(id: string, updates: BinaryUpdateRequest): BinaryRecord {
this.logger.info({ id }, "Updating OpenCode binary")
const config = this.configStore.get()
const updatedEntries = config.opencodeBinaries.map((binary) =>
binary.path === id ? { ...binary, label: updates.label ?? binary.label } : binary,
@@ -69,6 +77,7 @@ export class BinaryRegistry {
}
remove(id: string) {
this.logger.info({ id }, "Removing OpenCode binary")
const config = this.configStore.get()
const remaining = config.opencodeBinaries.filter((binary) => binary.path !== id)
const update: ConfigFileUpdate = { opencodeBinaries: remaining }
@@ -82,6 +91,7 @@ export class BinaryRegistry {
}
validatePath(path: string): BinaryValidationResult {
this.logger.debug({ path }, "Validating OpenCode binary path")
return this.validateRecord({
id: path,
path,
@@ -119,6 +129,7 @@ export class BinaryRegistry {
}
private emitChange() {
this.logger.debug("Emitting binaries changed event")
this.eventBus?.publish({ type: "config.binariesChanged", binaries: this.mapRecords() })
}

View File

@@ -1,6 +1,7 @@
import fs from "fs"
import path from "path"
import { EventBus } from "../events/bus"
import { Logger } from "../logger"
import {
AgentModelSelections,
ConfigFile,
@@ -14,7 +15,11 @@ export class ConfigStore {
private cache: ConfigFile = DEFAULT_CONFIG
private loaded = false
constructor(private readonly configPath: string, private readonly eventBus?: EventBus) {}
constructor(
private readonly configPath: string,
private readonly eventBus: EventBus | undefined,
private readonly logger: Logger,
) {}
load(): ConfigFile {
if (this.loaded) {
@@ -27,11 +32,13 @@ export class ConfigStore {
const content = fs.readFileSync(resolved, "utf-8")
const parsed = JSON.parse(content)
this.cache = ConfigFileSchema.parse(parsed)
this.logger.debug({ resolved }, "Loaded existing config file")
} else {
this.cache = DEFAULT_CONFIG
this.logger.info({ resolved }, "No config file found, using defaults")
}
} catch (error) {
console.warn("Failed to load config", error)
this.logger.warn({ err: error }, "Failed to load config, using defaults")
this.cache = DEFAULT_CONFIG
}
@@ -52,6 +59,7 @@ export class ConfigStore {
this.cache = ConfigFileSchema.parse(merged)
this.persist()
this.eventBus?.publish({ type: "config.appChanged", config: this.cache })
this.logger.info("Config updated")
}
private mergeConfig(current: ConfigFile, partial: ConfigFile | ConfigFileUpdate): ConfigFile {
@@ -97,8 +105,9 @@ export class ConfigStore {
const resolved = this.resolvePath(this.configPath)
fs.mkdirSync(path.dirname(resolved), { recursive: true })
fs.writeFileSync(resolved, JSON.stringify(this.cache, null, 2), "utf-8")
this.logger.debug({ resolved }, "Persisted config file")
} catch (error) {
console.warn("Failed to persist config", error)
this.logger.warn({ err: error }, "Failed to persist config")
}
}