Restored from commit 52be710 (checkpoint before qwen oauth + todo roller): Enhanced UI Features: - SMART FIX button with AI code analysis - APEX (Autonomous Programming EXecution) mode - SHIELD (Auto-approval) mode - MULTIX MODE multi-task pipeline interface - Live streaming token counter - Thinking indicator with bouncing dots animation Components restored: - packages/ui/src/components/chat/multi-task-chat.tsx - packages/ui/src/components/instance/instance-shell2.tsx - packages/ui/src/components/settings/OllamaCloudSettings.tsx - packages/ui/src/components/settings/QwenCodeSettings.tsx - packages/ui/src/stores/solo-store.ts - packages/ui/src/stores/task-actions.ts - packages/ui/src/stores/session-events.ts (autonomous mode) - packages/server/src/integrations/ollama-cloud.ts - packages/server/src/server/routes/ollama.ts - packages/server/src/server/routes/qwen.ts This ensures all custom features are preserved in source control.
149 lines
4.0 KiB
TypeScript
149 lines
4.0 KiB
TypeScript
import debug from "debug"
|
|
|
|
export type LoggerNamespace = "sse" | "api" | "session" | "actions" | "solo" | "multix-chat"
|
|
|
|
interface Logger {
|
|
log: (...args: unknown[]) => void
|
|
info: (...args: unknown[]) => void
|
|
warn: (...args: unknown[]) => void
|
|
error: (...args: unknown[]) => void
|
|
}
|
|
|
|
export interface NamespaceState {
|
|
name: LoggerNamespace
|
|
enabled: boolean
|
|
}
|
|
|
|
export interface LoggerControls {
|
|
listLoggerNamespaces: () => NamespaceState[]
|
|
enableLogger: (namespace: LoggerNamespace) => void
|
|
disableLogger: (namespace: LoggerNamespace) => void
|
|
enableAllLoggers: () => void
|
|
disableAllLoggers: () => void
|
|
}
|
|
|
|
const KNOWN_NAMESPACES: LoggerNamespace[] = ["sse", "api", "session", "actions", "solo", "multix-chat"]
|
|
const STORAGE_KEY = "opencode:logger:namespaces"
|
|
|
|
const namespaceLoggers = new Map<LoggerNamespace, Logger>()
|
|
const enabledNamespaces = new Set<LoggerNamespace>()
|
|
const rawConsole = typeof globalThis !== "undefined" ? globalThis.console : undefined
|
|
|
|
function applyEnabledNamespaces(): void {
|
|
if (enabledNamespaces.size === 0) {
|
|
debug.disable()
|
|
} else {
|
|
debug.enable(Array.from(enabledNamespaces).join(","))
|
|
}
|
|
}
|
|
|
|
function persistEnabledNamespaces(): void {
|
|
if (typeof window === "undefined" || !window?.localStorage) return
|
|
try {
|
|
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(Array.from(enabledNamespaces)))
|
|
} catch (error) {
|
|
rawConsole?.warn?.("Failed to persist logger namespaces", error)
|
|
}
|
|
}
|
|
|
|
function hydrateNamespacesFromStorage(): void {
|
|
if (typeof window === "undefined" || !window?.localStorage) return
|
|
try {
|
|
const stored = window.localStorage.getItem(STORAGE_KEY)
|
|
if (!stored) return
|
|
const parsed: unknown = JSON.parse(stored)
|
|
if (!Array.isArray(parsed)) return
|
|
for (const name of parsed) {
|
|
if (KNOWN_NAMESPACES.includes(name as LoggerNamespace)) {
|
|
enabledNamespaces.add(name as LoggerNamespace)
|
|
}
|
|
}
|
|
} catch (error) {
|
|
rawConsole?.warn?.("Failed to hydrate logger namespaces", error)
|
|
}
|
|
}
|
|
|
|
hydrateNamespacesFromStorage()
|
|
applyEnabledNamespaces()
|
|
|
|
function buildLogger(namespace: LoggerNamespace): Logger {
|
|
const base = debug(namespace)
|
|
const baseLogger: (...args: any[]) => void = base
|
|
const formatAndLog = (level: string, args: any[]) => {
|
|
baseLogger(level, ...args)
|
|
}
|
|
return {
|
|
log: (...args: any[]) => baseLogger(...args),
|
|
info: (...args: any[]) => baseLogger(...args),
|
|
warn: (...args: any[]) => formatAndLog("[warn]", args),
|
|
error: (...args: any[]) => formatAndLog("[error]", args),
|
|
}
|
|
}
|
|
|
|
function getLogger(namespace: string): Logger {
|
|
const ns = namespace as LoggerNamespace
|
|
if (!namespaceLoggers.has(ns)) {
|
|
namespaceLoggers.set(ns, buildLogger(ns))
|
|
}
|
|
return namespaceLoggers.get(ns)!
|
|
}
|
|
|
|
function listLoggerNamespaces(): NamespaceState[] {
|
|
return Array.from(namespaceLoggers.keys()).map((name) => ({
|
|
name,
|
|
enabled: enabledNamespaces.has(name)
|
|
}))
|
|
}
|
|
|
|
function enableLogger(namespace: string): void {
|
|
const ns = namespace as LoggerNamespace
|
|
if (enabledNamespaces.has(ns)) return
|
|
enabledNamespaces.add(ns)
|
|
persistEnabledNamespaces()
|
|
applyEnabledNamespaces()
|
|
}
|
|
|
|
function disableLogger(namespace: string): void {
|
|
const ns = namespace as LoggerNamespace
|
|
if (!enabledNamespaces.has(ns)) return
|
|
enabledNamespaces.delete(ns)
|
|
persistEnabledNamespaces()
|
|
applyEnabledNamespaces()
|
|
}
|
|
|
|
function disableAllLoggers(): void {
|
|
enabledNamespaces.clear()
|
|
persistEnabledNamespaces()
|
|
applyEnabledNamespaces()
|
|
}
|
|
|
|
function enableAllLoggers(): void {
|
|
namespaceLoggers.forEach((_, ns) => enabledNamespaces.add(ns))
|
|
persistEnabledNamespaces()
|
|
applyEnabledNamespaces()
|
|
}
|
|
|
|
const loggerControls: LoggerControls = {
|
|
listLoggerNamespaces,
|
|
enableLogger,
|
|
disableLogger,
|
|
enableAllLoggers,
|
|
disableAllLoggers,
|
|
}
|
|
|
|
function exposeLoggerControls(): void {
|
|
if (typeof window === "undefined") return
|
|
window.codenomadLogger = loggerControls
|
|
}
|
|
|
|
exposeLoggerControls()
|
|
|
|
export {
|
|
getLogger,
|
|
listLoggerNamespaces,
|
|
enableLogger,
|
|
disableLogger,
|
|
enableAllLoggers,
|
|
disableAllLoggers,
|
|
}
|