@cdoing/opentuicli 0.1.21 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../node_modules/zustand/esm/vanilla.mjs", "../../../node_modules/zustand/esm/react.mjs", "../../../node_modules/zustand/esm/index.mjs", "../../../node_modules/zustand/esm/middleware.mjs", "../src/store/settings.ts", "../src/context/theme.tsx", "../src/context/sdk.tsx", "../src/components/toast.tsx", "../src/lib/autocomplete.ts", "../src/components/input-area.tsx", "../src/routes/home.tsx", "../src/components/message-list.tsx", "../src/components/permission-prompt.tsx", "../src/components/loading-spinner.tsx", "../src/lib/terminal-title.ts", "../src/lib/history.ts", "../src/lib/context-providers.ts", "../src/routes/session.tsx", "../src/components/status-bar.tsx", "../src/components/session-header.tsx", "../src/components/session-footer.tsx", "../src/components/sidebar.tsx", "../src/components/dialog-model.tsx", "../src/components/dialog-command.tsx", "../src/components/dialog-help.tsx", "../src/components/dialog-theme.tsx", "../src/components/session-browser.tsx", "../src/components/setup-wizard.tsx", "../src/components/dialog-status.tsx", "../src/app.tsx", "../src/index.ts"],
4
- "sourcesContent": ["const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n", "import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n", "export * from 'zustand/vanilla';\nexport * from 'zustand/react';\n", "const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst findCallerName = (stack) => {\n var _a, _b;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return (_b = /.+ (.+) .+/.exec(callerLine)) == null ? void 0 : _b[1];\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n", "/**\n * Settings Store \u2014 Zustand + persist (file-backed)\n *\n * Persists user preferences to ~/.cdoing/tui-settings.json so they\n * survive across sessions: theme, mode, provider, model, sidebar, etc.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { create } from \"zustand\";\nimport { persist, createJSONStorage, type StateStorage } from \"zustand/middleware\";\n\n// \u2500\u2500 File-backed storage adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst SETTINGS_PATH = path.join(os.homedir(), \".cdoing\", \"tui-settings.json\");\n\nconst fileStorage: StateStorage = {\n getItem: (name: string): string | null => {\n try {\n if (!fs.existsSync(SETTINGS_PATH)) return null;\n const data = JSON.parse(fs.readFileSync(SETTINGS_PATH, \"utf-8\"));\n return JSON.stringify(data[name] ?? null);\n } catch {\n return null;\n }\n },\n setItem: (name: string, value: string): void => {\n try {\n const dir = path.dirname(SETTINGS_PATH);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n let data: Record<string, unknown> = {};\n try {\n if (fs.existsSync(SETTINGS_PATH)) {\n data = JSON.parse(fs.readFileSync(SETTINGS_PATH, \"utf-8\"));\n }\n } catch {}\n data[name] = JSON.parse(value);\n fs.writeFileSync(SETTINGS_PATH, JSON.stringify(data, null, 2), \"utf-8\");\n } catch {}\n },\n removeItem: (name: string): void => {\n try {\n if (!fs.existsSync(SETTINGS_PATH)) return;\n const data = JSON.parse(fs.readFileSync(SETTINGS_PATH, \"utf-8\"));\n delete data[name];\n fs.writeFileSync(SETTINGS_PATH, JSON.stringify(data, null, 2), \"utf-8\");\n } catch {}\n },\n};\n\n// \u2500\u2500 Settings State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SettingsState {\n // Appearance\n themeId: string;\n mode: \"dark\" | \"light\";\n syncTerminalBg: boolean;\n sidebarMode: \"auto\" | \"show\" | \"hide\";\n\n // Provider / model\n provider: string;\n model: string;\n\n // Actions\n setThemeId: (id: string) => void;\n setMode: (mode: \"dark\" | \"light\") => void;\n setSyncTerminalBg: (sync: boolean) => void;\n setSidebarMode: (mode: \"auto\" | \"show\" | \"hide\") => void;\n setProvider: (provider: string) => void;\n setModel: (model: string) => void;\n}\n\nexport const useSettingsStore = create<SettingsState>()(\n persist(\n (set) => ({\n // Defaults\n themeId: \"vercel\",\n mode: \"dark\",\n syncTerminalBg: true,\n sidebarMode: \"auto\",\n provider: \"anthropic\",\n model: \"\",\n\n // Actions\n setThemeId: (themeId) => set({ themeId }),\n setMode: (mode) => set({ mode }),\n setSyncTerminalBg: (syncTerminalBg) => set({ syncTerminalBg }),\n setSidebarMode: (sidebarMode) => set({ sidebarMode }),\n setProvider: (provider) => set({ provider }),\n setModel: (model) => set({ model }),\n }),\n {\n name: \"tui-settings\",\n storage: createJSONStorage(() => fileStorage),\n // Only persist these keys (not actions)\n partialize: (state) => ({\n themeId: state.themeId,\n mode: state.mode,\n syncTerminalBg: state.syncTerminalBg,\n sidebarMode: state.sidebarMode,\n provider: state.provider,\n model: state.model,\n }),\n },\n ),\n);\n", "/**\n * Theme Context \u2014 Multi-theme system for the TUI\n *\n * Supports 15+ built-in themes inspired by popular editor themes.\n * Each theme has dark and light variants with full color palettes.\n *\n * Detection:\n * 1. OSC 11 escape sequence (queries terminal directly)\n * 2. COLORFGBG environment variable (fallback)\n * 3. Defaults to dark mode\n */\n\nimport { RGBA, rgbToHex, SyntaxStyle } from \"@opentui/core\";\nimport { createContext, useContext, useState, useEffect, useRef, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useSettingsStore } from \"../store/settings\";\n\nexport interface Theme {\n text: RGBA;\n textMuted: RGBA;\n textDim: RGBA;\n primary: RGBA;\n secondary: RGBA;\n success: RGBA;\n error: RGBA;\n warning: RGBA;\n info: RGBA;\n border: RGBA;\n borderFocused: RGBA;\n bg: RGBA;\n bgSubtle: RGBA;\n // Roles\n userText: RGBA;\n assistantText: RGBA;\n systemText: RGBA;\n toolText: RGBA;\n // Tool status\n toolRunning: RGBA;\n toolDone: RGBA;\n toolError: RGBA;\n // Diff\n diffAdd: RGBA;\n diffRemove: RGBA;\n diffHunk: RGBA;\n}\n\n// \u2500\u2500 Theme Definitions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface ThemeDef {\n name: string;\n dark: Theme;\n light: Theme;\n}\n\nfunction t(hex: string): RGBA {\n return RGBA.fromHex(hex);\n}\n\n/** Helper to build a full theme from a minimal palette */\nfunction buildTheme(p: {\n bg: string; bgSubtle: string; text: string; textMuted: string; textDim: string;\n primary: string; secondary: string; success: string; error: string;\n warning: string; info: string; border: string;\n diffAdd?: string; diffRemove?: string;\n}): Theme {\n return {\n text: t(p.text), textMuted: t(p.textMuted), textDim: t(p.textDim),\n primary: t(p.primary), secondary: t(p.secondary),\n success: t(p.success), error: t(p.error), warning: t(p.warning), info: t(p.info),\n border: t(p.border), borderFocused: t(p.primary),\n bg: t(p.bg), bgSubtle: t(p.bgSubtle),\n userText: t(p.success), assistantText: t(p.text),\n systemText: t(p.warning), toolText: t(p.textMuted),\n toolRunning: t(p.warning), toolDone: t(p.success), toolError: t(p.error),\n diffAdd: t(p.diffAdd || p.success), diffRemove: t(p.diffRemove || p.error),\n diffHunk: t(p.info),\n };\n}\n\n// \u2500\u2500 Built-in Themes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const THEMES: Record<string, ThemeDef> = {\n default: {\n name: \"Default\",\n dark: buildTheme({\n bg: \"#000000\", bgSubtle: \"#111111\", text: \"#e5e7eb\", textMuted: \"#9ca3af\", textDim: \"#6b7280\",\n primary: \"#06b6d4\", secondary: \"#8b5cf6\", success: \"#22c55e\", error: \"#ef4444\",\n warning: \"#eab308\", info: \"#3b82f6\", border: \"#374151\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f3f4f6\", text: \"#1f2937\", textMuted: \"#6b7280\", textDim: \"#9ca3af\",\n primary: \"#0891b2\", secondary: \"#7c3aed\", success: \"#16a34a\", error: \"#dc2626\",\n warning: \"#ca8a04\", info: \"#2563eb\", border: \"#d1d5db\",\n }),\n },\n catppuccin: {\n name: \"Catppuccin\",\n dark: buildTheme({\n bg: \"#1e1e2e\", bgSubtle: \"#313244\", text: \"#cdd6f4\", textMuted: \"#a6adc8\", textDim: \"#6c7086\",\n primary: \"#89b4fa\", secondary: \"#cba6f7\", success: \"#a6e3a1\", error: \"#f38ba8\",\n warning: \"#f9e2af\", info: \"#74c7ec\", border: \"#45475a\",\n }),\n light: buildTheme({\n bg: \"#eff1f5\", bgSubtle: \"#e6e9ef\", text: \"#4c4f69\", textMuted: \"#6c6f85\", textDim: \"#9ca0b0\",\n primary: \"#1e66f5\", secondary: \"#8839ef\", success: \"#40a02b\", error: \"#d20f39\",\n warning: \"#df8e1d\", info: \"#04a5e5\", border: \"#ccd0da\",\n }),\n },\n dracula: {\n name: \"Dracula\",\n dark: buildTheme({\n bg: \"#282a36\", bgSubtle: \"#44475a\", text: \"#f8f8f2\", textMuted: \"#6272a4\", textDim: \"#44475a\",\n primary: \"#bd93f9\", secondary: \"#ff79c6\", success: \"#50fa7b\", error: \"#ff5555\",\n warning: \"#f1fa8c\", info: \"#8be9fd\", border: \"#44475a\",\n }),\n light: buildTheme({\n bg: \"#f8f8f2\", bgSubtle: \"#e6e6e6\", text: \"#282a36\", textMuted: \"#6272a4\", textDim: \"#999999\",\n primary: \"#7c3aed\", secondary: \"#d946ef\", success: \"#16a34a\", error: \"#dc2626\",\n warning: \"#ca8a04\", info: \"#0891b2\", border: \"#d1d5db\",\n }),\n },\n nord: {\n name: \"Nord\",\n dark: buildTheme({\n bg: \"#2e3440\", bgSubtle: \"#3b4252\", text: \"#eceff4\", textMuted: \"#d8dee9\", textDim: \"#4c566a\",\n primary: \"#88c0d0\", secondary: \"#b48ead\", success: \"#a3be8c\", error: \"#bf616a\",\n warning: \"#ebcb8b\", info: \"#81a1c1\", border: \"#434c5e\",\n }),\n light: buildTheme({\n bg: \"#eceff4\", bgSubtle: \"#e5e9f0\", text: \"#2e3440\", textMuted: \"#4c566a\", textDim: \"#7b88a1\",\n primary: \"#5e81ac\", secondary: \"#b48ead\", success: \"#a3be8c\", error: \"#bf616a\",\n warning: \"#ebcb8b\", info: \"#81a1c1\", border: \"#d8dee9\",\n }),\n },\n tokyonight: {\n name: \"Tokyo Night\",\n dark: buildTheme({\n bg: \"#1a1b26\", bgSubtle: \"#24283b\", text: \"#c0caf5\", textMuted: \"#a9b1d6\", textDim: \"#565f89\",\n primary: \"#7aa2f7\", secondary: \"#bb9af7\", success: \"#9ece6a\", error: \"#f7768e\",\n warning: \"#e0af68\", info: \"#7dcfff\", border: \"#3b4261\",\n }),\n light: buildTheme({\n bg: \"#d5d6db\", bgSubtle: \"#cbccd1\", text: \"#343b58\", textMuted: \"#565a6e\", textDim: \"#9699a3\",\n primary: \"#34548a\", secondary: \"#5a4a78\", success: \"#485e30\", error: \"#8c4351\",\n warning: \"#8f5e15\", info: \"#0f4b6e\", border: \"#b4b5b9\",\n }),\n },\n gruvbox: {\n name: \"Gruvbox\",\n dark: buildTheme({\n bg: \"#282828\", bgSubtle: \"#3c3836\", text: \"#ebdbb2\", textMuted: \"#a89984\", textDim: \"#665c54\",\n primary: \"#fabd2f\", secondary: \"#d3869b\", success: \"#b8bb26\", error: \"#fb4934\",\n warning: \"#fe8019\", info: \"#83a598\", border: \"#504945\",\n }),\n light: buildTheme({\n bg: \"#fbf1c7\", bgSubtle: \"#f2e5bc\", text: \"#3c3836\", textMuted: \"#7c6f64\", textDim: \"#a89984\",\n primary: \"#b57614\", secondary: \"#8f3f71\", success: \"#79740e\", error: \"#9d0006\",\n warning: \"#af3a03\", info: \"#427b58\", border: \"#d5c4a1\",\n }),\n },\n rosepine: {\n name: \"Ros\u00E9 Pine\",\n dark: buildTheme({\n bg: \"#191724\", bgSubtle: \"#1f1d2e\", text: \"#e0def4\", textMuted: \"#908caa\", textDim: \"#6e6a86\",\n primary: \"#c4a7e7\", secondary: \"#ebbcba\", success: \"#31748f\", error: \"#eb6f92\",\n warning: \"#f6c177\", info: \"#9ccfd8\", border: \"#26233a\",\n }),\n light: buildTheme({\n bg: \"#faf4ed\", bgSubtle: \"#f2e9e1\", text: \"#575279\", textMuted: \"#797593\", textDim: \"#9893a5\",\n primary: \"#907aa9\", secondary: \"#d7827e\", success: \"#286983\", error: \"#b4637a\",\n warning: \"#ea9d34\", info: \"#56949f\", border: \"#dfdad9\",\n }),\n },\n monokai: {\n name: \"Monokai\",\n dark: buildTheme({\n bg: \"#272822\", bgSubtle: \"#3e3d32\", text: \"#f8f8f2\", textMuted: \"#75715e\", textDim: \"#49483e\",\n primary: \"#66d9ef\", secondary: \"#ae81ff\", success: \"#a6e22e\", error: \"#f92672\",\n warning: \"#e6db74\", info: \"#66d9ef\", border: \"#49483e\",\n }),\n light: buildTheme({\n bg: \"#fafafa\", bgSubtle: \"#f0f0f0\", text: \"#272822\", textMuted: \"#75715e\", textDim: \"#b0b0b0\",\n primary: \"#0096d1\", secondary: \"#7c3aed\", success: \"#629e25\", error: \"#c4265e\",\n warning: \"#b5a21d\", info: \"#0096d1\", border: \"#d0d0d0\",\n }),\n },\n solarized: {\n name: \"Solarized\",\n dark: buildTheme({\n bg: \"#002b36\", bgSubtle: \"#073642\", text: \"#839496\", textMuted: \"#657b83\", textDim: \"#586e75\",\n primary: \"#268bd2\", secondary: \"#6c71c4\", success: \"#859900\", error: \"#dc322f\",\n warning: \"#b58900\", info: \"#2aa198\", border: \"#073642\",\n }),\n light: buildTheme({\n bg: \"#fdf6e3\", bgSubtle: \"#eee8d5\", text: \"#657b83\", textMuted: \"#839496\", textDim: \"#93a1a1\",\n primary: \"#268bd2\", secondary: \"#6c71c4\", success: \"#859900\", error: \"#dc322f\",\n warning: \"#b58900\", info: \"#2aa198\", border: \"#eee8d5\",\n }),\n },\n amoled: {\n name: \"AMOLED\",\n dark: buildTheme({\n bg: \"#000000\", bgSubtle: \"#0a0a0a\", text: \"#ffffff\", textMuted: \"#888888\", textDim: \"#555555\",\n primary: \"#00e5ff\", secondary: \"#e040fb\", success: \"#00e676\", error: \"#ff1744\",\n warning: \"#ffea00\", info: \"#40c4ff\", border: \"#222222\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f5f5f5\", text: \"#000000\", textMuted: \"#666666\", textDim: \"#aaaaaa\",\n primary: \"#0097a7\", secondary: \"#7b1fa2\", success: \"#2e7d32\", error: \"#c62828\",\n warning: \"#f9a825\", info: \"#0277bd\", border: \"#e0e0e0\",\n }),\n },\n github: {\n name: \"GitHub\",\n dark: buildTheme({\n bg: \"#0d1117\", bgSubtle: \"#161b22\", text: \"#e6edf3\", textMuted: \"#8b949e\", textDim: \"#484f58\",\n primary: \"#58a6ff\", secondary: \"#bc8cff\", success: \"#3fb950\", error: \"#f85149\",\n warning: \"#d29922\", info: \"#58a6ff\", border: \"#30363d\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f6f8fa\", text: \"#1f2328\", textMuted: \"#656d76\", textDim: \"#8c959f\",\n primary: \"#0969da\", secondary: \"#8250df\", success: \"#1a7f37\", error: \"#cf222e\",\n warning: \"#9a6700\", info: \"#0969da\", border: \"#d0d7de\",\n }),\n },\n material: {\n name: \"Material\",\n dark: buildTheme({\n bg: \"#263238\", bgSubtle: \"#37474f\", text: \"#eeffff\", textMuted: \"#b0bec5\", textDim: \"#546e7a\",\n primary: \"#82aaff\", secondary: \"#c792ea\", success: \"#c3e88d\", error: \"#ff5370\",\n warning: \"#ffcb6b\", info: \"#89ddff\", border: \"#37474f\",\n }),\n light: buildTheme({\n bg: \"#fafafa\", bgSubtle: \"#eeeeee\", text: \"#90a4ae\", textMuted: \"#546e7a\", textDim: \"#b0bec5\",\n primary: \"#6182b8\", secondary: \"#7c4dff\", success: \"#91b859\", error: \"#e53935\",\n warning: \"#f76d47\", info: \"#39adb5\", border: \"#d0d0d0\",\n }),\n },\n synthwave: {\n name: \"Synthwave '84\",\n dark: buildTheme({\n bg: \"#262335\", bgSubtle: \"#34294f\", text: \"#ffffff\", textMuted: \"#bbbbbb\", textDim: \"#6d5da0\",\n primary: \"#ff7edb\", secondary: \"#36f9f6\", success: \"#72f1b8\", error: \"#fe4450\",\n warning: \"#fede5d\", info: \"#36f9f6\", border: \"#495495\",\n }),\n light: buildTheme({\n bg: \"#f5f0ff\", bgSubtle: \"#e8e0f0\", text: \"#262335\", textMuted: \"#6d5da0\", textDim: \"#a090c0\",\n primary: \"#b03090\", secondary: \"#108888\", success: \"#308050\", error: \"#c03030\",\n warning: \"#a08000\", info: \"#207080\", border: \"#d0c8e0\",\n }),\n },\n everforest: {\n name: \"Everforest\",\n dark: buildTheme({\n bg: \"#2d353b\", bgSubtle: \"#343f44\", text: \"#d3c6aa\", textMuted: \"#859289\", textDim: \"#5c6a72\",\n primary: \"#a7c080\", secondary: \"#d699b6\", success: \"#a7c080\", error: \"#e67e80\",\n warning: \"#dbbc7f\", info: \"#7fbbb3\", border: \"#475258\",\n }),\n light: buildTheme({\n bg: \"#fdf6e3\", bgSubtle: \"#f3efda\", text: \"#5c6a72\", textMuted: \"#829181\", textDim: \"#a6b0a0\",\n primary: \"#8da101\", secondary: \"#df69ba\", success: \"#8da101\", error: \"#f85552\",\n warning: \"#dfa000\", info: \"#35a77c\", border: \"#e0dcc7\",\n }),\n },\n cobalt2: {\n name: \"Cobalt2\",\n dark: buildTheme({\n bg: \"#193549\", bgSubtle: \"#1f4662\", text: \"#ffffff\", textMuted: \"#8db0cc\", textDim: \"#4d7ea0\",\n primary: \"#ffc600\", secondary: \"#ff9d00\", success: \"#3ad900\", error: \"#ff628c\",\n warning: \"#ffc600\", info: \"#80fcff\", border: \"#2a5a7a\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f0f0f0\", text: \"#193549\", textMuted: \"#4d7ea0\", textDim: \"#8db0cc\",\n primary: \"#b88d00\", secondary: \"#cc7a00\", success: \"#2ba600\", error: \"#cc4e70\",\n warning: \"#b88d00\", info: \"#0090a0\", border: \"#d0d0d0\",\n }),\n },\n kanagawa: {\n name: \"Kanagawa\",\n dark: buildTheme({\n bg: \"#1F1F28\", bgSubtle: \"#2A2A37\", text: \"#DCD7BA\", textMuted: \"#727169\", textDim: \"#54546D\",\n primary: \"#7E9CD8\", secondary: \"#957FB8\", success: \"#98BB6C\", error: \"#E82424\",\n warning: \"#D7A657\", info: \"#76946A\", border: \"#54546D\",\n }),\n light: buildTheme({\n bg: \"#F2E9DE\", bgSubtle: \"#EAE4D7\", text: \"#54433A\", textMuted: \"#9E9389\", textDim: \"#B8AFA6\",\n primary: \"#2D4F67\", secondary: \"#957FB8\", success: \"#98BB6C\", error: \"#E82424\",\n warning: \"#D7A657\", info: \"#76946A\", border: \"#D4CBBF\",\n }),\n },\n nightowl: {\n name: \"Night Owl\",\n dark: buildTheme({\n bg: \"#011627\", bgSubtle: \"#0b2942\", text: \"#d6deeb\", textMuted: \"#637777\", textDim: \"#44596b\",\n primary: \"#82aaff\", secondary: \"#c792ea\", success: \"#addb67\", error: \"#ef5350\",\n warning: \"#ffcb8b\", info: \"#7fdbca\", border: \"#1d3b53\",\n }),\n light: buildTheme({\n bg: \"#fbfbfb\", bgSubtle: \"#f0f0f0\", text: \"#403f53\", textMuted: \"#989fb1\", textDim: \"#c0c0c0\",\n primary: \"#4876d6\", secondary: \"#994cc3\", success: \"#4d804e\", error: \"#de3d3b\",\n warning: \"#e0af68\", info: \"#0c969b\", border: \"#d9d9d9\",\n }),\n },\n onedark: {\n name: \"One Dark\",\n dark: buildTheme({\n bg: \"#282c34\", bgSubtle: \"#2c313c\", text: \"#abb2bf\", textMuted: \"#636d83\", textDim: \"#4b5263\",\n primary: \"#61afef\", secondary: \"#c678dd\", success: \"#98c379\", error: \"#e06c75\",\n warning: \"#e5c07b\", info: \"#56b6c2\", border: \"#3e4451\",\n }),\n light: buildTheme({\n bg: \"#fafafa\", bgSubtle: \"#f0f0f0\", text: \"#383a42\", textMuted: \"#a0a1a7\", textDim: \"#c0c0c0\",\n primary: \"#4078f2\", secondary: \"#a626a4\", success: \"#50a14f\", error: \"#e45649\",\n warning: \"#c18401\", info: \"#0184bc\", border: \"#d3d3d3\",\n }),\n },\n matrix: {\n name: \"Matrix\",\n dark: buildTheme({\n bg: \"#0a0e0a\", bgSubtle: \"#0e130d\", text: \"#62ff94\", textMuted: \"#8ca391\", textDim: \"#3d4a44\",\n primary: \"#2eff6a\", secondary: \"#00efff\", success: \"#62ff94\", error: \"#ff4b4b\",\n warning: \"#e6ff57\", info: \"#30b3ff\", border: \"#1e2a1b\",\n }),\n light: buildTheme({\n bg: \"#eef3ea\", bgSubtle: \"#e4ebe1\", text: \"#203022\", textMuted: \"#748476\", textDim: \"#a0b0a5\",\n primary: \"#1cc24b\", secondary: \"#24f6d9\", success: \"#1cc24b\", error: \"#ff4b4b\",\n warning: \"#e6ff57\", info: \"#30b3ff\", border: \"#748476\",\n }),\n },\n flexoki: {\n name: \"Flexoki\",\n dark: buildTheme({\n bg: \"#100f0f\", bgSubtle: \"#1c1b1a\", text: \"#cecdc3\", textMuted: \"#878580\", textDim: \"#575653\",\n primary: \"#4385be\", secondary: \"#8b7ec8\", success: \"#879a39\", error: \"#d14d41\",\n warning: \"#da702c\", info: \"#3aa99f\", border: \"#343331\",\n }),\n light: buildTheme({\n bg: \"#fffcf0\", bgSubtle: \"#f2f0e5\", text: \"#100f0f\", textMuted: \"#878580\", textDim: \"#b7b5ac\",\n primary: \"#205ea6\", secondary: \"#5e409d\", success: \"#66800b\", error: \"#af3029\",\n warning: \"#bc5215\", info: \"#24837b\", border: \"#e6e4d9\",\n }),\n },\n cursor: {\n name: \"Cursor\",\n dark: buildTheme({\n bg: \"#1e1e1e\", bgSubtle: \"#252526\", text: \"#d4d4d4\", textMuted: \"#808080\", textDim: \"#5a5a5a\",\n primary: \"#007acc\", secondary: \"#c586c0\", success: \"#6a9955\", error: \"#f44747\",\n warning: \"#cca700\", info: \"#4ec9b0\", border: \"#333333\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#f3f3f3\", text: \"#1e1e1e\", textMuted: \"#808080\", textDim: \"#b0b0b0\",\n primary: \"#007acc\", secondary: \"#af00db\", success: \"#388a34\", error: \"#cd3131\",\n warning: \"#bf8803\", info: \"#16825d\", border: \"#e5e5e5\",\n }),\n },\n vercel: {\n name: \"Vercel\",\n dark: buildTheme({\n bg: \"#000000\", bgSubtle: \"#111111\", text: \"#ededed\", textMuted: \"#888888\", textDim: \"#444444\",\n primary: \"#ffffff\", secondary: \"#888888\", success: \"#0070f3\", error: \"#ee0000\",\n warning: \"#f5a623\", info: \"#0070f3\", border: \"#333333\",\n }),\n light: buildTheme({\n bg: \"#ffffff\", bgSubtle: \"#fafafa\", text: \"#000000\", textMuted: \"#666666\", textDim: \"#999999\",\n primary: \"#000000\", secondary: \"#666666\", success: \"#0070f3\", error: \"#ee0000\",\n warning: \"#f5a623\", info: \"#0070f3\", border: \"#eaeaea\",\n }),\n },\n \"osaka-jade\": {\n name: \"Osaka Jade\",\n dark: buildTheme({\n bg: \"#111c18\", bgSubtle: \"#1a2520\", text: \"#C1C497\", textMuted: \"#53685B\", textDim: \"#3d4a44\",\n primary: \"#2DD5B7\", secondary: \"#D2689C\", success: \"#549e6a\", error: \"#FF5345\",\n warning: \"#E5C736\", info: \"#2DD5B7\", border: \"#3d4a44\",\n }),\n light: buildTheme({\n bg: \"#F6F5DD\", bgSubtle: \"#E8E7CC\", text: \"#111c18\", textMuted: \"#53685B\", textDim: \"#A8A78C\",\n primary: \"#1faa90\", secondary: \"#a8527a\", success: \"#3d7a52\", error: \"#c7392d\",\n warning: \"#b5a020\", info: \"#1faa90\", border: \"#A8A78C\",\n }),\n },\n};\n\n/** Get sorted list of theme IDs */\nexport function getThemeIds(): string[] {\n return Object.keys(THEMES).sort((a, b) => {\n if (a === \"default\") return -1;\n if (b === \"default\") return 1;\n return a.localeCompare(b);\n });\n}\n\n/** Get theme by ID and mode */\nexport function getThemeColors(themeId: string, mode: \"dark\" | \"light\"): Theme {\n const def = THEMES[themeId] || THEMES[\"default\"];\n return mode === \"light\" ? def.light : def.dark;\n}\n\n// \u2500\u2500 Terminal detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction luminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const s = c / 255;\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction queryTerminalBackground(): Promise<{ r: number; g: number; b: number } | null> {\n return new Promise((resolve) => {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n resolve(null);\n return;\n }\n const timeout = setTimeout(() => { cleanup(); resolve(null); }, 500);\n let buf = \"\";\n const onData = (data: Buffer) => {\n buf += data.toString();\n const match = buf.match(\n /\\x1b\\]11;rgb:([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})/\n );\n if (match) {\n cleanup();\n const parse = (hex: string) =>\n hex.length <= 2 ? parseInt(hex, 16) : Math.round((parseInt(hex, 16) / 65535) * 255);\n resolve({ r: parse(match[1]), g: parse(match[2]), b: parse(match[3]) });\n }\n };\n const cleanup = () => {\n clearTimeout(timeout);\n process.stdin.removeListener(\"data\", onData);\n if (wasRaw === false) process.stdin.setRawMode(false);\n };\n const wasRaw = process.stdin.isRaw;\n try { process.stdin.setRawMode(true); } catch { resolve(null); return; }\n process.stdin.on(\"data\", onData);\n process.stdout.write(\"\\x1b]11;?\\x07\");\n });\n}\n\nfunction detectThemeFromEnv(): \"dark\" | \"light\" {\n const bg = process.env.COLORFGBG;\n if (bg) {\n const parts = bg.split(\";\");\n const bgVal = parseInt(parts[parts.length - 1] || \"0\", 10);\n if (bgVal > 8) return \"light\";\n }\n return \"dark\";\n}\n\nlet _detectedMode: \"dark\" | \"light\" | null = null;\n\nexport async function detectTerminalTheme(): Promise<\"dark\" | \"light\"> {\n if (_detectedMode) return _detectedMode;\n const rgb = await queryTerminalBackground();\n if (rgb) {\n const lum = luminance(rgb.r, rgb.g, rgb.b);\n _detectedMode = lum > 0.5 ? \"light\" : \"dark\";\n } else {\n _detectedMode = detectThemeFromEnv();\n }\n return _detectedMode;\n}\n\nexport function setTerminalBackground(color: RGBA): void {\n if (!process.stdout.isTTY) return;\n const hex = rgbToHex(color);\n process.stdout.write(`\\x1b]11;${hex}\\x07`);\n}\n\nexport function restoreTerminalBackground(): void {\n if (!process.stdout.isTTY) return;\n process.stdout.write(\"\\x1b]111;\\x07\");\n}\n\n// \u2500\u2500 Syntax Style Generation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction generateSyntaxStyle(theme: Theme): SyntaxStyle {\n return SyntaxStyle.fromStyles({\n // Default text\n \"default\": { fg: theme.text },\n // Markdown-specific scopes (used by <markdown> component)\n \"markup.heading.1\": { fg: theme.primary, bold: true },\n \"markup.heading.2\": { fg: theme.primary, bold: true },\n \"markup.heading.3\": { fg: theme.info, bold: true },\n \"markup.heading.4\": { fg: theme.info, bold: true },\n \"markup.heading.5\": { fg: theme.info },\n \"markup.heading.6\": { fg: theme.info },\n \"markup.bold\": { bold: true },\n \"markup.italic\": { italic: true },\n \"markup.list\": { fg: theme.warning },\n \"markup.link\": { fg: theme.info, underline: true },\n \"markup.raw\": { fg: theme.warning },\n \"markup.quote\": { fg: theme.textMuted, italic: true },\n // Code block syntax highlighting\n \"keyword\": { fg: theme.secondary, bold: true },\n \"keyword.control\": { fg: theme.secondary, bold: true },\n \"keyword.operator\": { fg: theme.secondary },\n \"string\": { fg: theme.success },\n \"string.quoted\": { fg: theme.success },\n \"comment\": { fg: theme.textDim, italic: true },\n \"comment.line\": { fg: theme.textDim, italic: true },\n \"comment.block\": { fg: theme.textDim, italic: true },\n \"constant\": { fg: theme.warning },\n \"constant.numeric\": { fg: theme.warning },\n \"number\": { fg: theme.warning },\n \"variable\": { fg: theme.text },\n \"variable.parameter\": { fg: theme.text },\n \"function\": { fg: theme.info },\n \"entity.name.function\": { fg: theme.info },\n \"support.function\": { fg: theme.info },\n \"type\": { fg: theme.primary },\n \"entity.name.type\": { fg: theme.primary },\n \"support.type\": { fg: theme.primary },\n \"operator\": { fg: theme.textMuted },\n \"punctuation\": { fg: theme.textMuted },\n });\n}\n\n// \u2500\u2500 Theme Context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ThemeContext = createContext<{\n theme: Theme;\n themeId: string;\n mode: \"dark\" | \"light\";\n syntaxStyle: SyntaxStyle;\n customBg: string | null;\n setThemeId: (id: string) => void;\n setMode: (m: \"dark\" | \"light\") => void;\n setCustomBg: (hex: string | null) => void;\n syncTerminalBg: boolean;\n setSyncTerminalBg: (sync: boolean) => void;\n} | undefined>(undefined);\n\nexport function ThemeProvider(props: {\n mode?: string;\n themeId?: string;\n syncTerminalBg?: boolean;\n detectedMode?: \"dark\" | \"light\";\n children: ReactNode;\n}) {\n const initialMode: \"dark\" | \"light\" =\n props.mode === \"light\" ? \"light\"\n : props.mode === \"auto\" ? (props.detectedMode || \"dark\")\n : \"dark\";\n\n const initialThemeId = props.themeId || \"vercel\";\n\n const [themeId, setThemeIdState] = useState(initialThemeId);\n const [currentMode, setCurrentMode] = useState<\"dark\" | \"light\">(initialMode);\n const [theme, setTheme] = useState<Theme>(getThemeColors(initialThemeId, initialMode));\n const [syncBg, setSyncBg] = useState(props.syncTerminalBg ?? false);\n const [customBg, setCustomBgState] = useState<string | null>(null);\n\n // Refs to avoid stale closures \u2014 always read current values\n const syncBgRef = useRef(syncBg);\n syncBgRef.current = syncBg;\n const customBgRef = useRef(customBg);\n customBgRef.current = customBg;\n const modeRef = useRef(currentMode);\n modeRef.current = currentMode;\n const themeIdRef = useRef(themeId);\n themeIdRef.current = themeId;\n\n /** Apply terminal background to match theme \u2014 always call after setTheme */\n const applyTerminalBg = (colors: Theme) => {\n if (!syncBgRef.current) return;\n if (customBgRef.current) {\n setTerminalBackground(RGBA.fromHex(customBgRef.current));\n } else {\n setTerminalBackground(colors.bg);\n }\n };\n\n const setThemeId = (id: string) => {\n setThemeIdState(id);\n themeIdRef.current = id;\n const colors = getThemeColors(id, modeRef.current);\n setTheme(colors);\n applyTerminalBg(colors);\n useSettingsStore.getState().setThemeId(id);\n };\n\n const setMode = (m: \"dark\" | \"light\") => {\n setCurrentMode(m);\n modeRef.current = m;\n const colors = getThemeColors(themeIdRef.current, m);\n setTheme(colors);\n applyTerminalBg(colors);\n useSettingsStore.getState().setMode(m);\n };\n\n const setCustomBg = (hex: string | null) => {\n setCustomBgState(hex);\n customBgRef.current = hex;\n if (!syncBgRef.current) return;\n if (hex) {\n setTerminalBackground(RGBA.fromHex(hex));\n } else {\n setTerminalBackground(getThemeColors(themeIdRef.current, modeRef.current).bg);\n }\n };\n\n const setSyncTerminalBg = (sync: boolean) => {\n setSyncBg(sync);\n syncBgRef.current = sync;\n if (sync) {\n const colors = getThemeColors(themeIdRef.current, modeRef.current);\n applyTerminalBg(colors);\n } else {\n restoreTerminalBackground();\n }\n useSettingsStore.getState().setSyncTerminalBg(sync);\n };\n\n // Sync terminal bg on mount \u2014 force it immediately\n useEffect(() => {\n if (syncBgRef.current) {\n const colors = getThemeColors(initialThemeId, initialMode);\n applyTerminalBg(colors);\n }\n return () => {\n if (syncBgRef.current) restoreTerminalBackground();\n };\n }, []);\n\n const syntaxStyle = useMemo(() => generateSyntaxStyle(theme), [theme]);\n\n return (\n <ThemeContext.Provider value={{ theme, themeId, mode: currentMode, syntaxStyle, customBg, setThemeId, setMode, setCustomBg, syncTerminalBg: syncBg, setSyncTerminalBg }}>\n {props.children}\n </ThemeContext.Provider>\n );\n}\n\nexport function useTheme() {\n const ctx = useContext(ThemeContext);\n if (!ctx) throw new Error(\"useTheme must be used within ThemeProvider\");\n return ctx;\n}\n", "/**\n * SDK Context \u2014 wraps AgentRunner, ToolRegistry, PermissionManager,\n * and exposes callbacks for runtime model/provider changes and agent rebuild.\n */\n\nimport { createContext, useContext } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { AgentRunner } from \"@cdoing/ai\";\nimport type { ToolRegistry, PermissionManager } from \"@cdoing/core\";\n\nexport interface SDKState {\n agent: AgentRunner;\n registry: ToolRegistry;\n permissionManager: PermissionManager;\n workingDir: string;\n provider: string;\n model: string;\n /** Request a permission decision from the UI */\n requestPermission?: (toolName: string, message: string) => Promise<\"allow\" | \"always\" | \"deny\">;\n /** Rebuild the agent after model/provider change */\n rebuildAgent?: (provider: string, model: string, apiKey?: string) => void;\n /** Change working directory */\n setWorkingDir?: (dir: string) => void;\n}\n\nconst SDKContext = createContext<SDKState | undefined>(undefined);\n\nexport function SDKProvider(props: { value: SDKState; children: ReactNode }) {\n return (\n <SDKContext.Provider value={props.value}>\n {props.children}\n </SDKContext.Provider>\n );\n}\n\nexport function useSDK() {\n const ctx = useContext(SDKContext);\n if (!ctx) throw new Error(\"useSDK must be used within SDKProvider\");\n return ctx;\n}\n", "/**\n * Toast Notification System \u2014 transient notifications for the TUI\n *\n * Provides a ToastProvider context and useToast hook for showing\n * auto-dismissing notifications with type-based styling.\n */\n\nimport { createContext, useContext, useState, useEffect, useCallback, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useTheme } from \"../context/theme\";\nimport type { Theme } from \"../context/theme\";\nimport type { RGBA } from \"@opentui/core\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ToastType = \"info\" | \"success\" | \"warning\" | \"error\";\n\ninterface ToastItem {\n id: number;\n type: ToastType;\n message: string;\n duration: number;\n}\n\ninterface ToastContextValue {\n toast: (type: ToastType, message: string, duration?: number) => void;\n}\n\n// \u2500\u2500 Icons & Colors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOAST_ICONS: Record<ToastType, string> = {\n info: \"\\u2139\", // i\n success: \"\\u2713\", // checkmark\n warning: \"\\u26A0\", // warning sign\n error: \"\\u2717\", // x mark\n};\n\nfunction getToastColor(type: ToastType, theme: Theme): RGBA {\n switch (type) {\n case \"info\": return theme.info;\n case \"success\": return theme.success;\n case \"warning\": return theme.warning;\n case \"error\": return theme.error;\n }\n}\n\n// \u2500\u2500 Context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\nconst DEFAULT_DURATION = 3000;\nconst MAX_VISIBLE = 3;\n\n// \u2500\u2500 Provider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function ToastProvider(props: { children: ReactNode }) {\n const { theme } = useTheme();\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const idRef = useRef(0);\n const timersRef = useRef<Map<number, ReturnType<typeof setTimeout>>>(new Map());\n\n const removeToast = useCallback((id: number) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const toast = useCallback((type: ToastType, message: string, duration?: number) => {\n const id = ++idRef.current;\n const dur = duration ?? DEFAULT_DURATION;\n const item: ToastItem = { id, type, message, duration: dur };\n\n setToasts((prev) => {\n const next = [...prev, item];\n // Keep only the most recent MAX_VISIBLE toasts\n if (next.length > MAX_VISIBLE) {\n const removed = next.splice(0, next.length - MAX_VISIBLE);\n // Clean up timers for removed toasts\n for (const r of removed) {\n const timer = timersRef.current.get(r.id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(r.id);\n }\n }\n }\n return next;\n });\n\n // Set auto-dismiss timer\n const timer = setTimeout(() => {\n removeToast(id);\n }, dur);\n timersRef.current.set(id, timer);\n }, [removeToast]);\n\n // Clean up all timers on unmount\n useEffect(() => {\n return () => {\n for (const timer of timersRef.current.values()) {\n clearTimeout(timer);\n }\n timersRef.current.clear();\n };\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast }}>\n {props.children}\n {/* Toast overlay \u2014 positioned at the bottom, above status bar */}\n {toasts.length > 0 && (\n <box flexDirection=\"column\" alignItems=\"flex-end\">\n {toasts.map((t) => {\n const color = getToastColor(t.type, theme);\n const icon = TOAST_ICONS[t.type];\n return (\n <box key={t.id} height={1} flexDirection=\"row\" justifyContent=\"flex-end\">\n <text fg={color}>{` ${icon} `}</text>\n <text fg={theme.text}>{t.message}</text>\n <text fg={theme.textDim}>{\" \"}</text>\n </box>\n );\n })}\n </box>\n )}\n </ToastContext.Provider>\n );\n}\n\n// \u2500\u2500 Hook \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within ToastProvider\");\n return ctx;\n}\n", "/**\n * Autocomplete engine \u2014 slash commands, @mentions, path completion, tool subcommands\n *\n * Ported from @cdoing/cli UserInput.tsx logic for the OpenTUI terminal.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n// \u2500\u2500 Slash Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface SlashCommand {\n name: string;\n description: string;\n}\n\nexport const SLASH_COMMANDS: SlashCommand[] = [\n { name: \"/help\", description: \"Show available commands\" },\n { name: \"/clear\", description: \"Clear chat history\" },\n { name: \"/new\", description: \"Start new conversation\" },\n { name: \"/model\", description: \"Show/change model\" },\n { name: \"/provider\", description: \"Show/change provider\" },\n { name: \"/mode\", description: \"Cycle permission mode\" },\n { name: \"/usage\", description: \"Show token usage & cost\" },\n { name: \"/compact\", description: \"Compress context\" },\n { name: \"/config\", description: \"Show/set configuration\" },\n { name: \"/dir\", description: \"Change working directory\" },\n { name: \"/history\", description: \"Browse past sessions\" },\n { name: \"/ls\", description: \"List conversations\" },\n { name: \"/resume\", description: \"Resume conversation by ID\" },\n { name: \"/view\", description: \"View a conversation\" },\n { name: \"/fork\", description: \"Fork current conversation\" },\n { name: \"/delete\", description: \"Delete a conversation\" },\n { name: \"/plan\", description: \"Plan mode (approve/reject/show/off)\" },\n { name: \"/plan approve\", description: \"Approve plan and start building\" },\n { name: \"/plan reject\", description: \"Reject plan\" },\n { name: \"/plan show\", description: \"Show current plan\" },\n { name: \"/plan off\", description: \"Cancel plan mode\" },\n { name: \"/tasks\", description: \"Show active tasks\" },\n { name: \"/memory\", description: \"Show agent memory\" },\n { name: \"/permissions\", description: \"Show permission rules\" },\n { name: \"/hooks\", description: \"Show configured hooks\" },\n { name: \"/rules\", description: \"Show project rules\" },\n { name: \"/mcp\", description: \"MCP server management\" },\n { name: \"/context\", description: \"Show context providers\" },\n { name: \"/effort\", description: \"Set effort level\" },\n { name: \"/theme\", description: \"Switch theme\" },\n { name: \"/bg\", description: \"Run in background\" },\n { name: \"/jobs\", description: \"Show background jobs\" },\n { name: \"/login\", description: \"OAuth login\" },\n { name: \"/logout\", description: \"OAuth logout\" },\n { name: \"/setup\", description: \"Run setup wizard\" },\n { name: \"/doctor\", description: \"Check system health\" },\n { name: \"/init\", description: \"Initialize project config\" },\n { name: \"/exit\", description: \"Quit the TUI\" },\n { name: \"/quit\", description: \"Quit the TUI\" },\n { name: \"/btw\", description: \"Ask without adding to history\" },\n { name: \"/auth-status\", description: \"Show authentication status\" },\n { name: \"/queue\", description: \"Show message queue\" },\n];\n\n// \u2500\u2500 @Mention Providers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MentionProvider {\n trigger: string;\n description: string;\n}\n\nexport const MENTION_PROVIDERS: MentionProvider[] = [\n { trigger: \"@terminal\", description: \"Recent terminal output\" },\n { trigger: \"@url\", description: \"Fetch URL content\" },\n { trigger: \"@tree\", description: \"Project file tree\" },\n { trigger: \"@codebase\", description: \"Full codebase context\" },\n { trigger: \"@clip\", description: \"Clipboard content\" },\n { trigger: \"@file\", description: \"Include a file\" },\n];\n\n// \u2500\u2500 Tool Subcommands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst TOOL_SUBCOMMANDS: Record<string, string[]> = {\n npm: [\"install\", \"run\", \"test\", \"start\", \"build\", \"init\", \"publish\", \"uninstall\", \"update\", \"ls\", \"audit\", \"ci\"],\n yarn: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"start\", \"dev\", \"upgrade\", \"info\", \"why\"],\n pnpm: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"dev\", \"update\", \"store\"],\n bun: [\"install\", \"add\", \"remove\", \"run\", \"build\", \"test\", \"dev\", \"init\", \"create\"],\n git: [\"status\", \"add\", \"commit\", \"push\", \"pull\", \"fetch\", \"checkout\", \"branch\", \"merge\", \"rebase\", \"log\", \"diff\", \"stash\", \"reset\", \"clone\", \"remote\", \"tag\", \"cherry-pick\", \"bisect\", \"show\", \"blame\", \"reflog\"],\n docker: [\"build\", \"run\", \"exec\", \"ps\", \"images\", \"pull\", \"push\", \"stop\", \"rm\", \"logs\", \"compose\"],\n python: [\"-m\", \"-c\", \"--version\", \"manage.py\"],\n python3: [\"-m\", \"-c\", \"--version\", \"manage.py\"],\n pip: [\"install\", \"uninstall\", \"freeze\", \"list\", \"show\"],\n cargo: [\"build\", \"run\", \"test\", \"check\", \"clippy\", \"fmt\", \"new\", \"init\", \"add\", \"publish\"],\n go: [\"build\", \"run\", \"test\", \"get\", \"mod\", \"fmt\", \"vet\", \"install\", \"generate\"],\n make: [\"build\", \"test\", \"clean\", \"install\", \"all\"],\n kubectl: [\"get\", \"describe\", \"apply\", \"delete\", \"logs\", \"exec\", \"port-forward\", \"scale\"],\n gh: [\"pr\", \"issue\", \"repo\", \"run\", \"release\", \"api\", \"auth\", \"browse\"],\n turbo: [\"build\", \"dev\", \"test\", \"lint\", \"run\"],\n npx: [\"tsc\", \"ts-node\", \"eslint\", \"prettier\", \"jest\", \"vitest\", \"playwright\"],\n};\n\n// \u2500\u2500 Suggestion Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Suggestion {\n text: string;\n description?: string;\n type: \"command\" | \"mention\" | \"file\" | \"subcommand\";\n}\n\n// \u2500\u2500 Autocomplete Logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getCompletions(input: string, workingDir: string): Suggestion[] {\n if (!input) return [];\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n return SLASH_COMMANDS\n .filter((c) => c.name.startsWith(input))\n .map((c) => ({ text: c.name, description: c.description, type: \"command\" as const }));\n }\n\n // @mentions\n if (input.startsWith(\"@\") || input.includes(\" @\")) {\n const atIdx = input.lastIndexOf(\"@\");\n const query = input.substring(atIdx);\n\n const results: Suggestion[] = [];\n\n // Provider matches\n for (const p of MENTION_PROVIDERS) {\n if (p.trigger.startsWith(query)) {\n results.push({ text: p.trigger, description: p.description, type: \"mention\" });\n }\n }\n\n // File matches for @file or bare @\n if (query === \"@\" || query.startsWith(\"@file \") || query.startsWith(\"@f\")) {\n const fileQuery = query.startsWith(\"@file \") ? query.substring(6) : \"\";\n const files = getProjectFiles(workingDir, fileQuery);\n for (const f of files.slice(0, 10)) {\n results.push({ text: `@file ${f}`, description: \"\", type: \"file\" });\n }\n }\n\n return results;\n }\n\n // Tool subcommands (e.g. \"npm \" \u2192 show npm subcommands)\n const parts = input.split(\" \");\n if (parts.length >= 1) {\n const tool = parts[0];\n const subcommands = TOOL_SUBCOMMANDS[tool];\n if (subcommands && parts.length <= 2) {\n const sub = parts[1] || \"\";\n return subcommands\n .filter((s) => s.startsWith(sub))\n .map((s) => ({ text: `${tool} ${s}`, description: \"\", type: \"subcommand\" as const }));\n }\n }\n\n // Path completion for shell commands (cd, ls, cat, etc.)\n if (parts.length >= 2) {\n const pathResults = getPathCompletions(input, workingDir);\n if (pathResults.length > 0) {\n const prefix = parts.slice(0, -1).join(\" \") + \" \";\n return pathResults.map((p) => ({\n text: prefix + p,\n description: p.endsWith(\"/\") ? \"directory\" : \"file\",\n type: \"file\" as const,\n }));\n }\n }\n\n return [];\n}\n\n// \u2500\u2500 Ghost Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getGhostText(input: string, workingDir: string): string {\n if (!input) return \"\";\n\n // Slash command ghost\n if (input.startsWith(\"/\")) {\n const match = SLASH_COMMANDS.find((c) => c.name.startsWith(input) && c.name !== input);\n return match ? match.name.substring(input.length) : \"\";\n }\n\n // @mention ghost\n const atIdx = input.lastIndexOf(\"@\");\n if (atIdx >= 0 && atIdx === input.length - input.substring(atIdx).length) {\n const query = input.substring(atIdx);\n const match = MENTION_PROVIDERS.find((p) => p.trigger.startsWith(query) && p.trigger !== query);\n return match ? match.trigger.substring(query.length) : \"\";\n }\n\n return \"\";\n}\n\n// \u2500\u2500 Path Completion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function getPathCompletions(input: string, workingDir: string): string[] {\n // Detect path context: commands like cd, ls, cat, etc.\n const pathCommands = [\"cd\", \"ls\", \"cat\", \"head\", \"tail\", \"less\", \"more\", \"vim\", \"nano\", \"code\", \"open\", \"rm\", \"cp\", \"mv\", \"mkdir\", \"touch\", \"chmod\"];\n const parts = input.split(\" \");\n if (parts.length < 2) return [];\n\n const cmd = parts[0];\n if (!pathCommands.includes(cmd)) return [];\n\n const partial = parts[parts.length - 1] || \"\";\n return readPathEntries(workingDir, partial);\n}\n\nfunction readPathEntries(workingDir: string, partial: string): string[] {\n try {\n const dir = partial.includes(\"/\")\n ? path.resolve(workingDir, partial.substring(0, partial.lastIndexOf(\"/\") + 1))\n : workingDir;\n const prefix = partial.includes(\"/\") ? partial.substring(partial.lastIndexOf(\"/\") + 1) : partial;\n\n if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return [];\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n const base = partial.includes(\"/\") ? partial.substring(0, partial.lastIndexOf(\"/\") + 1) : \"\";\n\n return entries\n .filter((e) => !e.name.startsWith(\".\") || partial.startsWith(\".\"))\n .filter((e) => e.name.toLowerCase().startsWith(prefix.toLowerCase()))\n .sort((a, b) => {\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n })\n .slice(0, 20)\n .map((e) => base + e.name + (e.isDirectory() ? \"/\" : \"\"));\n } catch {\n return [];\n }\n}\n\nfunction getProjectFiles(workingDir: string, query: string): string[] {\n const results: string[] = [];\n const lower = query.toLowerCase();\n const skipDirs = new Set([\"node_modules\", \".git\", \"dist\", \"build\", \"__pycache__\", \".cache\", \"coverage\"]);\n\n const walk = (dir: string, rel: string, depth: number) => {\n if (depth > 3 || results.length >= 15) return;\n try {\n const entries = fs.readdirSync(path.join(workingDir, dir), { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || skipDirs.has(e.name)) continue;\n if (results.length >= 15) break;\n const p = rel ? `${rel}/${e.name}` : e.name;\n if (e.isDirectory()) {\n if (!query || p.toLowerCase().includes(lower)) results.push(p + \"/\");\n walk(path.join(dir, e.name), p, depth + 1);\n } else {\n if (!query || p.toLowerCase().includes(lower)) results.push(p);\n }\n }\n } catch { /* skip */ }\n };\n\n walk(\"\", \"\", 0);\n return results;\n}\n", "/**\n * InputArea \u2014 rich input with autocomplete, ghost text, image paste\n *\n * Features:\n * - Slash command autocomplete dropdown (/ prefix)\n * - @mention autocomplete dropdown (@ prefix)\n * - Tool subcommand suggestions (npm, git, etc.)\n * - Ghost text inline completion (Tab/\u2192 to accept)\n * - Ctrl+V paste text or images (macOS clipboard)\n * - Ctrl+U clear line, Ctrl+W delete word\n * - Up/Down navigate suggestions, Enter to select\n * - Escape to close dropdown\n */\n\nimport { TextAttributes, RGBA } from \"@opentui/core\";\nimport { useState, useRef, useMemo } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { execSync } from \"child_process\";\nimport { useTheme } from \"../context/theme\";\nimport { getCompletions, getGhostText } from \"../lib/autocomplete\";\nimport type { ImageAttachment } from \"@cdoing/ai\";\n\nexport type AgentMode = \"build\" | \"plan\";\n\nexport interface InputAreaProps {\n onSubmit: (text: string, images?: ImageAttachment[]) => void;\n placeholder?: string;\n disabled?: boolean;\n /** When true, all keyboard input is suppressed (e.g. dialog is open) */\n suppressInput?: boolean;\n workingDir: string;\n /** Current agent mode (build/plan). If provided, shows mode tabs. */\n mode?: AgentMode;\n /** Callback when mode changes via Tab key */\n onModeChange?: (mode: AgentMode) => void;\n /** Model name to display in the tab bar */\n modelLabel?: string;\n}\n\nfunction readClipboard(): string {\n try {\n if (process.platform === \"darwin\") return execSync(\"pbpaste\", { encoding: \"utf-8\" });\n try { return execSync(\"xclip -selection clipboard -o\", { encoding: \"utf-8\" }); }\n catch { return execSync(\"xsel --clipboard --output\", { encoding: \"utf-8\" }); }\n } catch { return \"\"; }\n}\n\nfunction readClipboardImage(): ImageAttachment | null {\n if (process.platform !== \"darwin\") return null;\n try {\n const hasImage = execSync(\n `osascript -e 'clipboard info' 2>/dev/null | grep -q \"TIFF\\\\|PNG\\\\|JPEG\" && echo \"yes\" || echo \"no\"`,\n { encoding: \"utf-8\", timeout: 1000 },\n ).trim();\n if (hasImage !== \"yes\") return null;\n const base64 = execSync(\n `osascript -e 'set theImage to the clipboard as \u00ABclass PNGf\u00BB' -e 'return theImage' 2>/dev/null | base64`,\n { encoding: \"utf-8\", timeout: 3000, maxBuffer: 20 * 1024 * 1024 },\n ).trim();\n if (base64 && base64.length > 100) return { data: base64, mimeType: \"image/png\" };\n } catch {}\n return null;\n}\n\nconst MAX_VISIBLE = 6;\n\nexport function InputArea(props: InputAreaProps) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const [value, setValue] = useState(\"\");\n const [pendingImages, setPendingImages] = useState<ImageAttachment[]>([]);\n const [selectedIdx, setSelectedIdx] = useState(0);\n const [dropdownOpen, setDropdownOpen] = useState(false);\n const valueRef = useRef(value);\n valueRef.current = value;\n const imageCountRef = useRef(0);\n\n // Compute suggestions based on current input, with a leading \"(none)\" option for path completions\n const suggestions = useMemo(() => {\n if (!value) return [];\n const completions = getCompletions(value, props.workingDir);\n // Add a \"none\" option at the top for file/subcommand completions so user can submit as-is\n if (completions.length > 0 && completions[0].type === \"file\") {\n return [{ text: value, description: \"submit as typed\", type: \"file\" as const }, ...completions];\n }\n return completions;\n }, [value, props.workingDir]);\n\n // Compute ghost text\n const ghost = useMemo(() => {\n if (dropdownOpen && suggestions.length > 0) return \"\";\n return getGhostText(value, props.workingDir);\n }, [value, props.workingDir, dropdownOpen, suggestions.length]);\n\n // Auto-open dropdown when suggestions exist\n const showDropdown = dropdownOpen && suggestions.length > 0;\n\n useKeyboard((key: any) => {\n // Suppress all input when a dialog overlay is open\n if (props.suppressInput) return;\n\n // Allow typing even when disabled (streaming) \u2014 submit handler decides what to do\n\n // \u2500\u2500 Tab \u2014 always switch mode (build \u2194 plan) \u2500\u2500\n if (key.name === \"tab\" && props.onModeChange && props.mode) {\n props.onModeChange(props.mode === \"build\" ? \"plan\" : \"build\");\n return;\n }\n\n // \u2500\u2500 Dropdown navigation \u2500\u2500\n if (showDropdown) {\n if (key.name === \"up\") {\n setSelectedIdx((i) => (i <= 0 ? suggestions.length - 1 : i - 1));\n return;\n }\n if (key.name === \"down\") {\n setSelectedIdx((i) => (i >= suggestions.length - 1 ? 0 : i + 1));\n return;\n }\n if (key.name === \"return\") {\n const s = suggestions[selectedIdx];\n if (s) {\n const text = s.text.trim();\n if (text) {\n props.onSubmit(text, pendingImages.length > 0 ? [...pendingImages] : undefined);\n setValue(\"\");\n setPendingImages([]);\n }\n setDropdownOpen(false);\n setSelectedIdx(0);\n }\n return;\n }\n if (key.name === \"escape\") {\n setDropdownOpen(false);\n return;\n }\n // Arrow right \u2014 accept selected autocomplete suggestion\n if (key.name === \"right\") {\n const s = suggestions[selectedIdx];\n if (s) {\n setValue(s.text + \" \");\n setDropdownOpen(false);\n setSelectedIdx(0);\n }\n return;\n }\n }\n\n // \u2500\u2500 Ghost text accept (arrow right) \u2500\u2500\n if (ghost && key.name === \"right\") {\n setValue((v) => v + ghost);\n return;\n }\n\n // Ctrl+V \u2014 paste image or text\n if (key.ctrl && key.name === \"v\") {\n const img = readClipboardImage();\n if (img) {\n imageCountRef.current += 1;\n setPendingImages((prev) => [...prev, img]);\n setValue((v) => v + `[Image #${imageCountRef.current}] `);\n return;\n }\n const clip = readClipboard().trim();\n if (clip) {\n const firstLine = clip.split(\"\\n\")[0] || \"\";\n setValue((v) => v + firstLine);\n }\n return;\n }\n\n // Ctrl+U \u2014 clear line\n if (key.ctrl && key.name === \"u\") {\n setValue(\"\");\n setPendingImages([]);\n setDropdownOpen(false);\n return;\n }\n\n // Ctrl+W \u2014 delete last word\n if (key.ctrl && key.name === \"w\") {\n setValue((v) => v.replace(/\\S+\\s*$/, \"\"));\n return;\n }\n\n // Enter \u2014 submit\n if (key.name === \"return\" && !key.shift) {\n const text = valueRef.current.trim();\n if (text || pendingImages.length > 0) {\n props.onSubmit(text || \"Describe this image.\", pendingImages.length > 0 ? [...pendingImages] : undefined);\n setValue(\"\");\n setPendingImages([]);\n setDropdownOpen(false);\n }\n return;\n }\n\n // Backspace\n if (key.name === \"backspace\") {\n setValue((v) => {\n const next = v.slice(0, -1);\n // Re-evaluate dropdown\n if (next.startsWith(\"/\") || next.includes(\"@\") || getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n } else {\n setDropdownOpen(false);\n }\n return next;\n });\n return;\n }\n\n // Escape \u2014 only consume if dropdown is open\n if (key.name === \"escape\" && dropdownOpen) {\n setDropdownOpen(false);\n return;\n }\n\n // Space\n if (key.name === \"space\") {\n setValue((v) => {\n const next = v + \" \";\n // Close dropdown on space for slash commands, but check for path completions\n if (v.startsWith(\"/\")) {\n setDropdownOpen(false);\n } else if (getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n }\n return next;\n });\n return;\n }\n\n // Regular character\n if (key.name && key.name.length === 1 && !key.ctrl && !key.meta) {\n setValue((v) => {\n const next = v + key.name;\n // Auto-open dropdown for /, @, and path completions\n if (next.startsWith(\"/\") || next.includes(\"@\")) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n } else if (getCompletions(next, props.workingDir).length > 0) {\n setDropdownOpen(true);\n setSelectedIdx(0);\n }\n return next;\n });\n }\n });\n\n const isSlashCommand = value.startsWith(\"/\");\n\n // Window the suggestions for display\n const windowStart = Math.max(0, Math.min(selectedIdx - Math.floor(MAX_VISIBLE / 2), suggestions.length - MAX_VISIBLE));\n const visibleSuggestions = suggestions.slice(windowStart, windowStart + MAX_VISIBLE);\n const hasAbove = windowStart > 0;\n const hasBelow = windowStart + MAX_VISIBLE < suggestions.length;\n\n const bgColor = customBg ? RGBA.fromHex(customBg) : t.bg;\n\n return (\n <box flexDirection=\"column\" flexShrink={0} backgroundColor={bgColor}>\n {/* Autocomplete dropdown (above input) */}\n {showDropdown && (\n <box flexDirection=\"column\" paddingX={1} backgroundColor={bgColor}>\n {hasAbove && (\n <box><text fg={t.textDim}>{` \u25B2 ${windowStart} more`}</text></box>\n )}\n {visibleSuggestions.map((s, i) => {\n const realIdx = windowStart + i;\n const isSelected = realIdx === selectedIdx;\n const color = s.type === \"command\" ? t.warning\n : s.type === \"mention\" ? t.info\n : s.type === \"file\" ? t.success\n : t.textMuted;\n return (\n <box key={s.text} flexDirection=\"row\">\n <text fg={isSelected ? t.primary : color} attributes={isSelected ? TextAttributes.BOLD : undefined}>\n {isSelected ? \" \u276F \" : \" \"}\n </text>\n <text fg={isSelected ? t.text : color}>{s.text}</text>\n {s.description ? (\n <text fg={t.textDim}>{` ${s.description}`}</text>\n ) : null}\n </box>\n );\n })}\n {hasBelow && (\n <box><text fg={t.textDim}>{` \u25BC ${suggestions.length - windowStart - MAX_VISIBLE} more`}</text></box>\n )}\n </box>\n )}\n\n {/* Pending images indicator */}\n {pendingImages.length > 0 && (\n <box height={1} paddingX={1}>\n <text fg={t.primary}>\n {` \uD83D\uDDBC ${pendingImages.length} image${pendingImages.length > 1 ? \"s\" : \"\"} attached`}\n </text>\n </box>\n )}\n\n {/* Input box */}\n <box\n height={3}\n borderStyle=\"single\"\n borderColor={t.borderFocused}\n backgroundColor={bgColor}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingX={1}\n >\n <text\n fg={isSlashCommand ? t.warning : t.primary}\n attributes={TextAttributes.BOLD}\n >\n {isSlashCommand ? \" / \" : \" > \"}\n </text>\n\n {value ? (\n <>\n <text fg={t.text}>{value}</text>\n {ghost ? (\n <text fg={t.textDim}>{ghost}</text>\n ) : (\n <text fg={t.primary}>{\"\u258A\"}</text>\n )}\n </>\n ) : (\n <text fg={t.textDim}>\n {props.placeholder || \"Type a message... (^V paste, / commands, @ context, \u2192 accept)\"}\n </text>\n )}\n </box>\n\n {/* Mode tab bar (Build / Plan) + model label + shortcuts */}\n {props.mode && (\n <box height={1} flexDirection=\"row\" backgroundColor={bgColor} paddingX={1}>\n {/* Build tab */}\n <box backgroundColor={props.mode === \"build\" ? t.primary : undefined}>\n <text\n fg={props.mode === \"build\" ? t.bg : t.textMuted}\n attributes={props.mode === \"build\" ? TextAttributes.BOLD : undefined}\n >\n {\" Build \"}\n </text>\n </box>\n <text fg={t.textDim}>{\" \"}</text>\n {/* Plan tab */}\n <box backgroundColor={props.mode === \"plan\" ? t.secondary : undefined}>\n <text\n fg={props.mode === \"plan\" ? t.bg : t.textMuted}\n attributes={props.mode === \"plan\" ? TextAttributes.BOLD : undefined}\n >\n {\" Plan \"}\n </text>\n </box>\n\n {/* Model label */}\n {props.modelLabel && (\n <>\n <text fg={t.textDim}>{\" \"}</text>\n <text fg={t.textMuted} attributes={TextAttributes.ITALIC}>\n {props.modelLabel}\n </text>\n </>\n )}\n\n {/* Right-aligned shortcut hints */}\n <box flexGrow={1} />\n <text fg={t.textDim}>{\"tab mode \"}</text>\n <text fg={t.textDim}>{\"ctrl+p commands\"}</text>\n </box>\n )}\n </box>\n );\n}\n", "/**\n * Home Route \u2014 landing screen with logo, project info, shortcuts, and quick actions\n *\n * Responsive: adapts layout based on terminal dimensions.\n * - Small terminals (< 60 cols or < 20 rows): compact layout, no logo\n * - Medium terminals: smaller logo, condensed info\n * - Large terminals: full figlet logo, spacious layout\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { InputArea } from \"../components/input-area\";\nimport type { ImageAttachment } from \"@cdoing/ai\";\n\n// Full figlet logo (ANSI Shadow)\nconst LOGO_FULL = [\n \" \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \",\n \"\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\",\n \"\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\",\n \"\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\",\n \" \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \",\n];\n\n// Compact logo for smaller terminals\nconst LOGO_COMPACT = [\n \"\u250C\u2500\u2510\u250C\u2510 \u250C\u2500\u2510\u252C\u250C\u2510\u250C\u250C\u2500\u2510\",\n \"\u2502 \u2502\u2502\u2502 \u2502\u2502\u2502\u2502\u2502\u2502\u2502\u2502 \u252C\",\n \"\u2514\u2500\u2518\u2514\u2518\u2514\u2500\u2518\u2514\u2500\u2518\u2518\u2514\u2518\u2514\u2500\u2518\",\n];\n\nexport function Home(props: {\n provider: string;\n model: string;\n workingDir: string;\n themeId: string;\n onAction?: (action: string) => void;\n onSubmit?: (text: string, images?: ImageAttachment[]) => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n const w = dims.width || 80;\n const h = dims.height || 24;\n\n const shortDir = () => {\n const home = process.env.HOME || \"\";\n const d = props.workingDir;\n return home && d.startsWith(home) ? \"~\" + d.slice(home.length) : d;\n };\n\n const subtitle = \"Multi-provider AI coding assistant\";\n const version = \"v0.1.1\";\n\n // Determine layout size\n const isSmall = w < 60 || h < 20;\n const isMedium = !isSmall && (w < 80 || h < 30);\n\n // Pick logo\n const logo = isSmall ? null : isMedium ? LOGO_COMPACT : LOGO_FULL;\n\n // Build info lines\n const infoLines = [\n [\"Provider\", props.provider],\n [\"Model\", props.model],\n [\"Theme\", props.themeId],\n [\"Directory\", shortDir()],\n ];\n const maxKeyLen = Math.max(...infoLines.map(([k]) => k.length));\n\n // Quick actions\n const actions = [\n { key: \"Enter\", label: \"Send message / start session\", id: \"start\" },\n { key: \"Ctrl+P\", label: \"Command palette\", id: \"commands\" },\n { key: \"Ctrl+O\", label: \"Switch model\", id: \"model\" },\n { key: \"Ctrl+T\", label: \"Change theme\", id: \"theme\" },\n { key: \"Ctrl+N\", label: \"New session\", id: \"new\" },\n { key: \"Ctrl+S\", label: \"Browse sessions\", id: \"sessions\" },\n { key: \"/setup\", label: \"Setup wizard\", id: \"setup\" },\n { key: \"Ctrl+C\", label: \"Quit\", id: \"quit\" },\n ];\n const maxActionKey = Math.max(...actions.map((a) => a.key.length));\n\n return (\n <box flexDirection=\"column\" flexGrow={1} flexShrink={1} overflow=\"hidden\">\n <box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" flexGrow={1}>\n {/* Logo */}\n {logo && logo.map((line, i) => (\n <text key={`logo-${i}`} fg={t.primary} attributes={TextAttributes.BOLD}>\n {line}\n </text>\n ))}\n\n {/* Subtitle + version */}\n <text fg={t.textDim}>\n {subtitle}\n </text>\n <text fg={t.textMuted}>\n {version}\n </text>\n\n <text>{\"\"}</text>\n\n {/* Info section */}\n {infoLines.map(([key, val], i) => {\n const line = `${key.padStart(maxKeyLen)} ${val}`;\n return (\n <text key={`info-${i}`} fg={t.textDim}>\n {line}\n </text>\n );\n })}\n\n <text>{\"\"}</text>\n\n {/* Actions */}\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Actions\"}\n </text>\n {actions.map((action, i) => {\n const line = `${action.key.padStart(maxActionKey)} ${action.label}`;\n return (\n <text key={`act-${i}`} fg={t.textMuted}>\n {line}\n </text>\n );\n })}\n\n <text>{\"\"}</text>\n\n {/* Footer */}\n <text fg={t.textDim}>\n {\"Powered by @opentui/react + @cdoing/ai\"}\n </text>\n </box>\n\n {/* Input bar at bottom \u2014 user can start typing immediately */}\n {props.onSubmit && (\n <InputArea\n onSubmit={props.onSubmit}\n workingDir={props.workingDir}\n placeholder=\"Start typing to begin a session... (/ commands, @ context)\"\n />\n )}\n </box>\n );\n}\n", "/**\n * MessageList \u2014 renders chat messages with tool calls, streaming, and markdown\n *\n * Uses a custom inline markdown renderer for assistant messages (matching the CLI's\n * RenderMarkdown approach) with OpenTUI's <markdown> component for fenced code blocks.\n * The scrollbox is managed by the parent (session.tsx) to ensure proper flex height\n * calculation (matching OpenCode's pattern).\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme, type Theme } from \"../context/theme\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Message {\n id: string;\n role: \"user\" | \"assistant\" | \"system\" | \"tool\";\n content: string;\n toolName?: string;\n toolStatus?: \"running\" | \"done\" | \"error\";\n toolInput?: Record<string, any>;\n isError?: boolean;\n timestamp: number;\n}\n\n// \u2500\u2500 Tool Config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ToolConfig {\n label: string;\n icon: string;\n verb: string;\n}\n\nconst TOOL_CONFIG: Record<string, ToolConfig> = {\n file_read: { label: \"Read\", icon: \"\u25C7\", verb: \"Reading\" },\n file_write: { label: \"Write\", icon: \"\u25C8\", verb: \"Writing\" },\n file_edit: { label: \"Edit\", icon: \"\u25C8\", verb: \"Editing\" },\n multi_edit: { label: \"MultiEdit\", icon: \"\u25C8\", verb: \"Editing\" },\n apply_patch: { label: \"Patch\", icon: \"\u25C8\", verb: \"Patching\" },\n shell_exec: { label: \"Bash\", icon: \"$\", verb: \"Running\" },\n file_run: { label: \"Run\", icon: \"\u25B6\", verb: \"Running\" },\n glob_search: { label: \"Search files\", icon: \"\u25CE\", verb: \"Searching\" },\n grep_search: { label: \"Search\", icon: \"\u25CE\", verb: \"Searching\" },\n codebase_search: { label: \"Codebase\", icon: \"\u25CE\", verb: \"Searching\" },\n web_fetch: { label: \"Fetch\", icon: \"\u25CC\", verb: \"Fetching\" },\n web_search: { label: \"Web Search\", icon: \"\u25CC\", verb: \"Searching\" },\n sub_agent: { label: \"Agent\", icon: \"\u25C6\", verb: \"Running\" },\n todo: { label: \"Todo\", icon: \"\u2610\", verb: \"Updating\" },\n list_dir: { label: \"List Dir\", icon: \"\u251C\", verb: \"Listing\" },\n view_diff: { label: \"Diff\", icon: \"\u00B1\", verb: \"Viewing\" },\n view_repo_map: { label: \"Repo Map\", icon: \"\u229E\", verb: \"Mapping\" },\n code_verify: { label: \"Verify\", icon: \"\u2713\", verb: \"Verifying\" },\n system_info: { label: \"System Info\", icon: \"i\", verb: \"Checking\" },\n ast_edit: { label: \"AST Edit\", icon: \"\u2325\", verb: \"Editing\" },\n notebook_edit: { label: \"Notebook\", icon: \"\u22A1\", verb: \"Editing\" },\n};\n\n// \u2500\u2500 Inline Markdown Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Strip markdown inline syntax markers: **bold** \u2192 bold, *italic* \u2192 italic, `code` \u2192 code */\nfunction stripInlineMarkdown(text: string): string {\n return text\n .replace(/`([^`]+)`/g, \"$1\")\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\")\n .replace(/(?<!\\w)\\*([^*]+)\\*(?!\\w)/g, \"$1\");\n}\n\n// \u2500\u2500 Custom Markdown Renderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Renders markdown content using OpenTUI primitives with proper styling.\n// Strips markdown syntax (##, **, *, `, ---) and renders styled text.\n// Uses <markdown> component only for fenced code blocks (syntax highlighting).\n\nfunction RenderMarkdown(props: { text: string; theme: Theme }) {\n const t = props.theme;\n const { syntaxStyle } = useTheme();\n const lines = props.text.split(\"\\n\");\n\n const rendered: React.ReactNode[] = [];\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i];\n\n // \u2500\u2500 Fenced code block \u2014 use OpenTUI <markdown> for syntax highlighting \u2500\u2500\n if (line.startsWith(\"```\")) {\n const codeLines: string[] = [line];\n i++;\n while (i < lines.length) {\n codeLines.push(lines[i]);\n if (lines[i].startsWith(\"```\")) {\n i++;\n break;\n }\n i++;\n }\n const codeBlock = codeLines.join(\"\\n\");\n rendered.push(\n <box key={`code-${i}`} marginY={0}>\n <markdown\n syntaxStyle={syntaxStyle}\n streaming={false}\n content={codeBlock}\n conceal={true}\n />\n </box>\n );\n continue;\n }\n\n // \u2500\u2500 Headers \u2500\u2500\n if (line.startsWith(\"### \")) {\n rendered.push(\n <text key={i} fg={t.info} attributes={TextAttributes.BOLD}>\n {` \u25B8 ${stripInlineMarkdown(line.slice(4))}`}\n </text>\n );\n i++;\n continue;\n }\n if (line.startsWith(\"## \")) {\n rendered.push(\n <text key={i} fg={t.primary} attributes={TextAttributes.BOLD}>\n {` \u25B8\u25B8 ${stripInlineMarkdown(line.slice(3))}`}\n </text>\n );\n i++;\n continue;\n }\n if (line.startsWith(\"# \")) {\n rendered.push(\n <text key={i} fg={t.primary} attributes={TextAttributes.BOLD}>\n {`\u25B8\u25B8\u25B8 ${stripInlineMarkdown(line.slice(2))}`}\n </text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Horizontal rule \u2500\u2500\n if (/^---+$/.test(line) || /^===+$/.test(line) || /^\\*\\*\\*+$/.test(line)) {\n rendered.push(\n <text key={i} fg={t.textDim}>{\"\u2500\".repeat(40)}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Bullet list \u2500\u2500\n const bulletMatch = line.match(/^(\\s*)[-*] (.*)/);\n if (bulletMatch) {\n const indent = bulletMatch[1] || \"\";\n const content = stripInlineMarkdown(bulletMatch[2]);\n rendered.push(\n <text key={i}>{`${indent}\u25CF ${content}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Numbered list \u2500\u2500\n const numMatch = line.match(/^(\\s*)(\\d+)\\. (.*)/);\n if (numMatch) {\n const content = stripInlineMarkdown(numMatch[3]);\n rendered.push(\n <text key={i}>{`${numMatch[1]}${numMatch[2]}. ${content}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Blockquote \u2500\u2500\n if (line.startsWith(\"> \")) {\n rendered.push(\n <text key={i} fg={t.textMuted}>{`\u2502 ${stripInlineMarkdown(line.slice(2))}`}</text>\n );\n i++;\n continue;\n }\n\n // \u2500\u2500 Empty line \u2500\u2500\n if (!line.trim()) {\n rendered.push(<text key={i}>{\" \"}</text>);\n i++;\n continue;\n }\n\n // \u2500\u2500 Plain text \u2014 strip markdown syntax \u2500\u2500\n rendered.push(\n <text key={i}>{stripInlineMarkdown(line)}</text>\n );\n i++;\n }\n\n return <box flexDirection=\"column\">{rendered}</box>;\n}\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction formatTimestamp(ts: number): string {\n const d = new Date(ts);\n let h = d.getHours();\n const m = d.getMinutes();\n const ampm = h >= 12 ? \"PM\" : \"AM\";\n h = h % 12 || 12;\n return `${h}:${m.toString().padStart(2, \"0\")} ${ampm}`;\n}\n\n/**\n * Renders message content only (no scrollbox wrapper).\n * Parent should wrap this in a <scrollbox> for proper flex height.\n */\nexport function MessageList(props: {\n messages: Message[];\n streamingText?: string;\n isStreaming?: boolean;\n showTimestamps?: boolean;\n}) {\n const { theme } = useTheme();\n const t = theme;\n\n return (\n <>\n {/* Empty state */}\n {props.messages.length === 0 && !props.isStreaming && (\n <box paddingX={2} paddingY={1}>\n <text fg={t.textMuted}>\n {\"Type a message to start chatting. Use / for commands, @ for context.\"}\n </text>\n </box>\n )}\n\n {/* Messages */}\n {props.messages.map((msg) => {\n if (msg.role === \"user\") {\n return (\n <box key={msg.id} paddingX={1} paddingY={0} flexDirection=\"row\">\n <text fg={t.userText} attributes={TextAttributes.BOLD}>\n {\"\u276F \"}\n </text>\n <text fg={t.userText} flexGrow={1}>{msg.content}</text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n );\n }\n\n if (msg.role === \"assistant\") {\n return (\n <box key={msg.id} paddingLeft={1} marginTop={1} flexShrink={0} flexDirection=\"column\">\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"\u25C6 \"}\n </text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n <box paddingLeft={2}>\n <RenderMarkdown text={msg.content.trim()} theme={t} />\n </box>\n </box>\n );\n }\n\n if (msg.role === \"system\") {\n return (\n <box key={msg.id} paddingX={1} flexDirection=\"row\">\n <text fg={t.systemText} flexGrow={1}>{`\u26A1 ${msg.content}`}</text>\n {props.showTimestamps && msg.timestamp && (\n <text fg={t.textDim}>{` ${formatTimestamp(msg.timestamp)}`}</text>\n )}\n </box>\n );\n }\n\n if (msg.role === \"tool\") {\n return (\n <ToolCallRow\n key={msg.id}\n name={msg.toolName || \"unknown\"}\n content={msg.content}\n status={msg.toolStatus || (msg.isError ? \"error\" : \"done\")}\n input={msg.toolInput}\n />\n );\n }\n\n return null;\n })}\n\n {/* Streaming indicator */}\n {props.isStreaming && (\n <box paddingLeft={1} marginTop={1} flexShrink={0} flexDirection=\"column\">\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"\u25C6 \"}\n </text>\n <text fg={t.primary}>{\"\u258A\"}</text>\n </box>\n {(props.streamingText || \"\").trim() && (\n <box paddingLeft={2}>\n <RenderMarkdown text={(props.streamingText || \"\").trim()} theme={t} />\n </box>\n )}\n </box>\n )}\n </>\n );\n}\n\n// \u2500\u2500 Tool Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction trimText(s: string, max: number): string {\n const first = s.split(\"\\n\")[0] || \"\";\n return first.length > max ? first.substring(0, max) + \"\u2026\" : first;\n}\n\nfunction shortPath(p: string): string {\n const home = process.env.HOME || \"\";\n let s = (home && p.startsWith(home)) ? \"~\" + p.slice(home.length) : p;\n // Show last 2 segments if too long\n if (s.length > 50) {\n const parts = s.split(\"/\");\n s = \"\u2026/\" + parts.slice(-2).join(\"/\");\n }\n return s;\n}\n\nfunction countLines(s: string): number {\n return s ? s.split(\"\\n\").length : 0;\n}\n\n/** Extract a short description from tool input, per tool type */\nfunction getToolDescription(name: string, input?: Record<string, any>): string {\n if (!input) return \"\";\n switch (name) {\n case \"file_read\":\n return input.file_path ? shortPath(input.file_path) : \"\";\n case \"file_write\":\n return input.file_path ? shortPath(input.file_path) : \"\";\n case \"file_edit\":\n case \"multi_edit\":\n case \"apply_patch\":\n return input.file_path ? shortPath(input.file_path) : \"\";\n case \"shell_exec\":\n return input.command ? trimText(input.command, 55) : \"\";\n case \"file_run\":\n return input.file_path ? shortPath(input.file_path) : \"\";\n case \"glob_search\":\n return input.pattern ? `\"${trimText(input.pattern, 40)}\"` : \"\";\n case \"grep_search\":\n return input.pattern ? `\"${trimText(input.pattern, 30)}\"${input.path ? ` in ${shortPath(input.path)}` : \"\"}` : \"\";\n case \"codebase_search\":\n return input.query ? `\"${trimText(input.query, 40)}\"` : \"\";\n case \"web_fetch\":\n return input.url ? trimText(input.url, 50) : \"\";\n case \"web_search\":\n return input.query ? `\"${trimText(input.query, 40)}\"` : \"\";\n case \"sub_agent\":\n return input.description ? trimText(input.description, 50) : \"\";\n case \"list_dir\":\n return input.path ? shortPath(input.path) : \"\";\n default:\n return input.description || \"\";\n }\n}\n\n/** Get a summary of the output for the collapsed view */\nfunction getOutputSummary(name: string, output: string, isError?: boolean): string {\n if (!output) return \"\";\n if (isError) return trimText(output, 50);\n\n const lines = countLines(output);\n switch (name) {\n case \"file_read\":\n return `${lines} lines`;\n case \"shell_exec\":\n case \"file_run\":\n return lines > 1 ? `${lines} lines` : trimText(output, 40);\n case \"grep_search\":\n case \"glob_search\":\n case \"codebase_search\": {\n const results = output.split(\"\\n\").filter((l) => l.trim()).length;\n return `${results} result${results !== 1 ? \"s\" : \"\"}`;\n }\n case \"file_write\":\n case \"file_edit\":\n case \"multi_edit\":\n case \"apply_patch\":\n return output.includes(\"+\") || output.includes(\"-\") ? trimText(output, 40) : \"done\";\n default:\n return lines > 1 ? `${lines} lines` : trimText(output, 40);\n }\n}\n\n// \u2500\u2500 Tool Call Row \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction ToolCallRow(props: {\n name: string;\n content: string;\n status: \"running\" | \"done\" | \"error\";\n input?: Record<string, any>;\n}) {\n const { theme } = useTheme();\n const t = theme;\n\n const config = TOOL_CONFIG[props.name] || { label: props.name.replace(/_/g, \" \"), icon: \"\u2699\", verb: \"Running\" };\n const isRunning = props.status === \"running\";\n const isError = props.status === \"error\";\n\n // Status indicator\n const statusIcon = isRunning ? \"\u27F3\" : isError ? \"\u2717\" : \"\u2713\";\n const statusColor = isRunning ? t.toolRunning : isError ? t.toolError : t.toolDone;\n\n // Description from input args\n const description = getToolDescription(props.name, props.input);\n\n // Output summary (shown after \u2192 arrow)\n const outputSummary = !isRunning ? getOutputSummary(props.name, props.content, isError) : \"\";\n\n // For shell commands, show the command inline\n const isShell = props.name === \"shell_exec\" || props.name === \"file_run\";\n const shellCmd = isShell && props.input?.command ? trimText(props.input.command, 55) : \"\";\n\n // For file ops, show the path\n const isFileOp = [\"file_read\", \"file_write\", \"file_edit\", \"multi_edit\", \"apply_patch\"].includes(props.name);\n const filePath = isFileOp && props.input?.file_path ? shortPath(props.input.file_path) : \"\";\n\n // For search ops, show the pattern\n const isSearch = [\"grep_search\", \"glob_search\", \"codebase_search\"].includes(props.name);\n const searchPattern = isSearch && (props.input?.pattern || props.input?.query) ?\n trimText(props.input?.pattern || props.input?.query, 35) : \"\";\n\n // Diff preview for edits\n const hasEditDiff = (props.name === \"file_edit\" || props.name === \"multi_edit\") &&\n props.input?.old_string && props.input?.new_string;\n const oldStr = hasEditDiff ? trimText(props.input!.old_string, 50) : \"\";\n const newStr = hasEditDiff ? trimText(props.input!.new_string, 50) : \"\";\n\n // Output content lines (for expanded view)\n const outputLines = props.content ? props.content.split(\"\\n\") : [];\n const maxPreviewLines = 6;\n const previewLines = outputLines.slice(0, maxPreviewLines);\n const hasMoreLines = outputLines.length > maxPreviewLines;\n\n return (\n <box flexDirection=\"column\" paddingLeft={2} paddingRight={1}>\n {/* \u2500\u2500 Header row: status + icon + label + description + output summary \u2500\u2500 */}\n <box flexDirection=\"row\" height={1}>\n <text fg={statusColor} attributes={isRunning ? TextAttributes.BOLD : undefined}>\n {`${statusIcon} `}\n </text>\n <text fg={t.textMuted}>{`${config.icon} `}</text>\n <text fg={isRunning ? t.toolRunning : t.text} attributes={TextAttributes.BOLD}>\n {isRunning ? `${config.verb}...` : config.label}\n </text>\n\n {/* Inline detail: file path, command, or search pattern */}\n {filePath && !isRunning ? (\n <text fg={t.info}>{` ${filePath}`}</text>\n ) : shellCmd ? (\n <text fg={isRunning ? t.textDim : t.textMuted}>{` $ ${shellCmd}`}</text>\n ) : searchPattern ? (\n <text fg={t.warning}>{` \"${searchPattern}\"`}</text>\n ) : description && !filePath && !shellCmd ? (\n <text fg={t.textDim}>{` ${description}`}</text>\n ) : null}\n\n {/* Output summary after arrow */}\n {outputSummary && !isRunning ? (\n <>\n <text fg={t.textDim}>{\" \u2192 \"}</text>\n <text fg={isError ? t.error : t.toolDone}>{outputSummary}</text>\n </>\n ) : null}\n </box>\n\n {/* \u2500\u2500 Edit diff preview (for file_edit) \u2500\u2500 */}\n {hasEditDiff && !isRunning && (\n <box flexDirection=\"column\" paddingLeft={3}>\n <box flexDirection=\"row\" height={1}>\n <text fg={t.diffRemove}>{` - ${oldStr}`}</text>\n </box>\n <box flexDirection=\"row\" height={1}>\n <text fg={t.diffAdd}>{` + ${newStr}`}</text>\n </box>\n </box>\n )}\n\n {/* \u2500\u2500 Shell output preview (for bash/run) \u2500\u2500 */}\n {isShell && !isRunning && previewLines.length > 0 && (\n <box flexDirection=\"column\" paddingLeft={3}>\n <box height={1}>\n <text fg={t.border}>{\" \u250C\" + \"\u2500\".repeat(40)}</text>\n </box>\n {previewLines.map((line, i) => (\n <box key={i} height={1}>\n <text fg={t.textDim}>{` \u2502 ${trimText(line, 55)}`}</text>\n </box>\n ))}\n {hasMoreLines && (\n <box height={1}>\n <text fg={t.textDim}>{` \u2502 \u2026 ${outputLines.length - maxPreviewLines} more lines`}</text>\n </box>\n )}\n <box height={1}>\n <text fg={t.border}>{\" \u2514\" + \"\u2500\".repeat(40)}</text>\n </box>\n </box>\n )}\n\n {/* \u2500\u2500 Search results preview \u2500\u2500 */}\n {isSearch && !isRunning && previewLines.length > 0 && (\n <box flexDirection=\"column\" paddingLeft={3}>\n {previewLines.slice(0, 4).map((line, i) => (\n <box key={i} height={1}>\n <text fg={t.textDim}>{` ${trimText(line, 60)}`}</text>\n </box>\n ))}\n {outputLines.length > 4 && (\n <box height={1}>\n <text fg={t.textDim}>{` \u2026 ${outputLines.length - 4} more`}</text>\n </box>\n )}\n </box>\n )}\n\n {/* \u2500\u2500 Error output \u2500\u2500 */}\n {isError && props.content && (\n <box flexDirection=\"column\" paddingLeft={3}>\n <box height={1}>\n <text fg={t.error}>{` \u2717 ${trimText(props.content, 70)}`}</text>\n </box>\n </box>\n )}\n\n {/* \u2500\u2500 Running indicator for shell commands \u2500\u2500 */}\n {isShell && isRunning && (\n <box paddingLeft={3} height={1}>\n <text fg={t.toolRunning}>{\" \u258A Executing command...\"}</text>\n </box>\n )}\n </box>\n );\n}\n", "/**\n * PermissionPrompt \u2014 asks user to allow/deny a tool action\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface PermissionPromptProps {\n toolName: string;\n message: string;\n onDecision: (decision: \"allow\" | \"always\" | \"deny\") => void;\n}\n\nconst OPTIONS = [\n { key: \"1\", label: \"Allow once\", value: \"allow\" as const },\n { key: \"2\", label: \"Always allow\", value: \"always\" as const },\n { key: \"3\", label: \"Deny\", value: \"deny\" as const },\n];\n\nexport function PermissionPrompt(props: PermissionPromptProps) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const [selected, setSelected] = useState(0);\n\n useKeyboard((key: any) => {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelected((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelected((s) => Math.min(OPTIONS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n props.onDecision(OPTIONS[selected].value);\n } else if (key.name === \"1\") {\n props.onDecision(\"allow\");\n } else if (key.name === \"2\") {\n props.onDecision(\"always\");\n } else if (key.name === \"3\") {\n props.onDecision(\"deny\");\n }\n });\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.warning}\n backgroundColor={customBg || t.bg}\n paddingX={1}\n paddingY={0}\n flexDirection=\"column\"\n >\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {\"\uD83D\uDD10 Permission Required\"}\n </text>\n <text fg={t.text}>\n {` ${props.toolName}: ${props.message}`}\n </text>\n <text fg={t.textDim}>{\"\"}</text>\n {OPTIONS.map((opt, i) => (\n <box key={opt.key}>\n <text\n fg={selected === i ? t.primary : t.textMuted}\n attributes={selected === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selected === i ? \"\u276F\" : \" \"} [${opt.key}] ${opt.label}`}\n </text>\n </box>\n ))}\n <text fg={t.textDim}>{\"\\n \u2191\u2193 Navigate Enter Select 1-3 Quick pick\"}</text>\n </box>\n );\n}\n", "/**\n * LoadingSpinner \u2014 animated thinking/tool indicator\n */\n\nimport { useState, useEffect } from \"react\";\nimport { useTheme } from \"../context/theme\";\n\nconst FRAMES = [\"\u280B\", \"\u2819\", \"\u2839\", \"\u2838\", \"\u283C\", \"\u2834\", \"\u2826\", \"\u2827\", \"\u2807\", \"\u280F\"];\n\nexport function LoadingSpinner(props: { label?: string }) {\n const { theme } = useTheme();\n const t = theme;\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const interval = setInterval(() => {\n setFrame((f) => (f + 1) % FRAMES.length);\n }, 80);\n return () => clearInterval(interval);\n }, []);\n\n return (\n <box paddingX={1} height={1} flexDirection=\"row\">\n <text fg={t.primary}>{FRAMES[frame]}</text>\n <text fg={t.textMuted}>{` ${props.label || \"Thinking...\"}`}</text>\n </box>\n );\n}\n", "/**\n * Terminal Title \u2014 set/reset the terminal window title via escape sequences\n */\n\nexport function setTerminalTitle(title: string): void {\n if (process.stdout.isTTY) {\n process.stdout.write(`\\x1b]0;${title}\\x07`);\n }\n}\n\nexport function resetTerminalTitle(): void {\n if (process.stdout.isTTY) {\n process.stdout.write(`\\x1b]0;\\x07`);\n }\n}\n", "/**\n * Conversation History Manager for TUI\n *\n * Saves conversations to ~/.cdoing/conversations/ as JSON files.\n * Mirrors the base CLI implementation for full compatibility.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\n\nconst CONV_DIR = path.join(os.homedir(), \".cdoing\", \"conversations\");\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\" | \"tool\";\n content: string;\n toolName?: string;\n timestamp: number;\n}\n\nexport interface Conversation {\n id: string;\n title: string;\n createdAt: number;\n updatedAt: number;\n provider: string;\n model: string;\n messages: ChatMessage[];\n}\n\nfunction ensureDir(): void {\n if (!fs.existsSync(CONV_DIR)) fs.mkdirSync(CONV_DIR, { recursive: true });\n}\n\nfunction generateId(): string {\n const now = Date.now().toString(36);\n const rand = Math.random().toString(36).slice(2, 6);\n return `${now}-${rand}`;\n}\n\nfunction deriveTitle(message: string): string {\n const clean = message.replace(/\\n/g, \" \").trim();\n return clean.length > 60 ? clean.substring(0, 57) + \"...\" : clean;\n}\n\nexport function createConversation(provider: string, model: string): Conversation {\n ensureDir();\n return {\n id: generateId(),\n title: \"New conversation\",\n createdAt: Date.now(),\n updatedAt: Date.now(),\n provider,\n model,\n messages: [],\n };\n}\n\nexport function addMessage(\n conv: Conversation,\n role: \"user\" | \"assistant\" | \"tool\",\n content: string,\n toolName?: string\n): void {\n conv.messages.push({ role, content, timestamp: Date.now(), toolName });\n conv.updatedAt = Date.now();\n\n if (role === \"user\" && conv.title === \"New conversation\") {\n conv.title = deriveTitle(content);\n }\n\n saveConversation(conv);\n}\n\nexport function saveConversation(conv: Conversation): void {\n ensureDir();\n const filePath = path.join(CONV_DIR, `${conv.id}.json`);\n fs.writeFileSync(filePath, JSON.stringify(conv, null, 2), \"utf-8\");\n}\n\nexport function loadConversation(id: string): Conversation | null {\n // Support partial IDs\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const match = files.find((f) => f.startsWith(id) || f.replace(\".json\", \"\") === id);\n if (!match) return null;\n\n const filePath = path.join(CONV_DIR, match);\n try {\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function listConversations(): Conversation[] {\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const convs: Conversation[] = [];\n\n for (const file of files) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(CONV_DIR, file), \"utf-8\"));\n convs.push(data);\n } catch {}\n }\n\n return convs.sort((a, b) => b.updatedAt - a.updatedAt);\n}\n\nexport function loadLastConversation(): Conversation | null {\n const all = listConversations();\n return all.length > 0 ? all[0] : null;\n}\n\nexport function deleteConversation(id: string): boolean {\n ensureDir();\n const files = fs.readdirSync(CONV_DIR).filter((f) => f.endsWith(\".json\"));\n const match = files.find((f) => f.startsWith(id) || f.replace(\".json\", \"\") === id);\n if (match) {\n fs.unlinkSync(path.join(CONV_DIR, match));\n return true;\n }\n return false;\n}\n\nexport function forkConversation(idOrConv: string | Conversation): Conversation | null {\n const original =\n typeof idOrConv === \"string\" ? loadConversation(idOrConv) : idOrConv;\n if (!original) return null;\n\n ensureDir();\n const forked: Conversation = {\n ...original,\n id: generateId(),\n title: `Fork of: ${original.title}`,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n messages: original.messages.map((m) => ({ ...m })),\n };\n saveConversation(forked);\n return forked;\n}\n\nexport function updateConversationTitle(id: string, title: string): void {\n const conv = loadConversation(id);\n if (!conv) return;\n conv.title = title.length > 80 ? title.substring(0, 77) + \"...\" : title;\n conv.updatedAt = Date.now();\n saveConversation(conv);\n}\n\nexport function formatRelativeDate(timestamp: number): string {\n const diff = Date.now() - timestamp;\n const seconds = Math.floor(diff / 1000);\n if (seconds < 60) return \"just now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n if (days < 30) return `${days}d ago`;\n return new Date(timestamp).toLocaleDateString();\n}\n", "/**\n * Context Provider Expansion \u2014 resolves @mentions in user messages\n *\n * Detects @terminal, @url, @tree, @codebase, @clip, @file triggers\n * and expands them into the actual content before sending to the agent.\n */\n\nimport {\n ContextProviderRegistry,\n TerminalContextProvider,\n UrlContextProvider,\n TreeContextProvider,\n CodebaseContextProvider,\n ClipboardContextProvider,\n FileIncludeContextProvider,\n} from \"@cdoing/core\";\n\nlet registry: ContextProviderRegistry | null = null;\nlet terminalProvider: TerminalContextProvider | null = null;\n\nfunction getRegistry(): ContextProviderRegistry {\n if (!registry) {\n registry = new ContextProviderRegistry();\n terminalProvider = new TerminalContextProvider();\n registry.register(terminalProvider);\n registry.register(new UrlContextProvider());\n registry.register(new TreeContextProvider());\n registry.register(new CodebaseContextProvider());\n registry.register(new ClipboardContextProvider());\n registry.register(new FileIncludeContextProvider());\n }\n return registry;\n}\n\n/** Update terminal provider with recent shell output */\nexport function pushTerminalOutput(output: string): void {\n getRegistry();\n if (terminalProvider && typeof (terminalProvider as any).push === \"function\") {\n (terminalProvider as any).push(output);\n }\n}\n\n/** Known @mention triggers */\nconst TRIGGERS = [\"@terminal\", \"@url\", \"@tree\", \"@codebase\", \"@clip\", \"@file\"];\n\n/**\n * Resolve all @mention providers in a message.\n * Returns the expanded message with provider content appended.\n */\nexport async function resolveContextProviders(\n message: string,\n workingDir: string\n): Promise<string> {\n const reg = getRegistry();\n let expandedMessage = message;\n const appendSections: string[] = [];\n\n for (const trigger of TRIGGERS) {\n const idx = expandedMessage.indexOf(trigger);\n if (idx === -1) continue;\n\n // Extract the trigger + argument\n const afterTrigger = expandedMessage.substring(idx + trigger.length);\n const endIdx = afterTrigger.search(/\\s@|\\n|$/);\n const arg = afterTrigger.substring(0, endIdx === -1 ? afterTrigger.length : endIdx).trim();\n\n // Remove trigger from message\n const fullTrigger = trigger + (arg ? \" \" + arg : \"\");\n expandedMessage = expandedMessage.replace(fullTrigger, \"\").trim();\n\n // Resolve\n const providerName = trigger.substring(1); // strip @\n const provider = reg.get(providerName);\n if (!provider) continue;\n\n try {\n const result = await provider.resolve(arg, { workingDir });\n if (result) {\n appendSections.push(`--- ${trigger} ---\\n${result}`);\n }\n } catch {\n // Silently skip failed providers\n }\n }\n\n if (appendSections.length > 0) {\n expandedMessage = expandedMessage + \"\\n\\n\" + appendSections.join(\"\\n\\n\");\n }\n\n return expandedMessage;\n}\n\n/**\n * Check if a message contains any @mention triggers.\n */\nexport function hasContextMentions(message: string): boolean {\n return TRIGGERS.some((t) => message.includes(t));\n}\n", "/**\n * Session Route \u2014 active chat session with full agent integration\n *\n * Wires up the AgentRunner with streaming callbacks to display:\n * - Token-by-token streaming with cursor\n * - Tool call display with status icons\n * - Permission prompts (via SDK context)\n * - Token usage tracking\n * - Full slash command handling\n * - Session persistence (save/resume/fork/delete)\n * - @mention context expansion\n * - Background jobs (/bg, /jobs)\n * - One-shot questions (/btw)\n * - Shell command auto-detection\n * - OAuth status (/auth-status)\n * - /config set support\n */\n\nimport { useState, useRef, useEffect } from \"react\";\nimport { TextAttributes } from \"@opentui/core\";\nimport { useKeyboard } from \"@opentui/react\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { MessageList, type Message } from \"../components/message-list\";\nimport { InputArea, type AgentMode } from \"../components/input-area\";\nimport { PermissionPrompt } from \"../components/permission-prompt\";\nimport { LoadingSpinner } from \"../components/loading-spinner\";\nimport { useSDK } from \"../context/sdk\";\nimport { useTheme } from \"../context/theme\";\nimport { useToast } from \"../components/toast\";\nimport { setTerminalTitle } from \"../lib/terminal-title\";\nimport { execSync } from \"child_process\";\nimport type { AgentCallbacks, ImageAttachment } from \"@cdoing/ai\";\nimport {\n createConversation,\n addMessage as addHistoryMessage,\n listConversations,\n loadConversation,\n deleteConversation,\n forkConversation,\n formatRelativeDate,\n type Conversation,\n} from \"../lib/history\";\nimport {\n resolveContextProviders,\n hasContextMentions,\n pushTerminalOutput,\n} from \"../lib/context-providers\";\n\n// \u2500\u2500 Shell Command Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst SHELL_COMMANDS = new Set([\n \"ls\", \"ll\", \"la\", \"pwd\", \"cd\", \"mkdir\", \"rmdir\", \"rm\", \"cp\", \"mv\",\n \"cat\", \"head\", \"tail\", \"touch\", \"echo\", \"env\",\n \"git\", \"npm\", \"yarn\", \"pnpm\", \"npx\", \"node\", \"ts-node\",\n \"python\", \"python3\", \"pip\", \"pip3\",\n \"docker\", \"docker-compose\",\n \"grep\", \"find\", \"which\", \"whereis\",\n \"curl\", \"wget\",\n \"chmod\", \"chown\", \"ln\",\n \"ps\", \"kill\", \"df\", \"du\",\n \"open\", \"code\",\n \"vim\", \"vi\", \"nano\", \"less\", \"more\", \"man\", \"top\", \"htop\",\n]);\n\nfunction detectShellCommand(input: string): string | null {\n const trimmed = input.trim();\n const firstWord = trimmed.split(/\\s+/)[0].toLowerCase();\n return SHELL_COMMANDS.has(firstWord) ? trimmed : null;\n}\n\n// \u2500\u2500 Background Job \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface BackgroundJob {\n id: string;\n prompt: string;\n status: \"running\" | \"done\" | \"error\";\n result?: string;\n error?: string;\n startedAt: number;\n completedAt?: number;\n}\n\n// \u2500\u2500 Interrupt/Queue Prompt \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction InterruptPrompt(props: {\n message: string;\n onInterrupt: () => void;\n onQueue: () => void;\n onCancel: () => void;\n}) {\n const { theme } = useTheme();\n const t = theme;\n const [selected, setSelected] = useState(0);\n const options = [\n { label: \"Interrupt \u2014 stop current response and send new message\", action: props.onInterrupt },\n { label: \"Queue \u2014 wait for current response, then send\", action: props.onQueue },\n { label: \"Cancel \u2014 discard new message\", action: props.onCancel },\n ];\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\") { props.onCancel(); return; }\n if (key.name === \"up\" || key.name === \"k\") { setSelected((s) => Math.max(0, s - 1)); return; }\n if (key.name === \"down\" || key.name === \"j\") { setSelected((s) => Math.min(options.length - 1, s + 1)); return; }\n if (key.name === \"return\") { options[selected].action(); return; }\n // Quick keys\n if (key.sequence === \"1\" || key.sequence === \"i\") { props.onInterrupt(); return; }\n if (key.sequence === \"2\" || key.sequence === \"q\") { props.onQueue(); return; }\n if (key.sequence === \"3\") { props.onCancel(); return; }\n });\n\n const preview = props.message.length > 50 ? props.message.slice(0, 47) + \"...\" : props.message;\n\n return (\n <box flexDirection=\"column\" flexShrink={0} paddingX={1}>\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {\" Agent is streaming. What to do with your message?\"}\n </text>\n <text fg={t.textDim}>{` \"${preview}\"`}</text>\n <text>{\"\"}</text>\n {options.map((opt, i) => (\n <text key={i} fg={i === selected ? t.primary : t.textMuted} attributes={i === selected ? TextAttributes.BOLD : undefined}>\n {` ${i === selected ? \"\u276F\" : \" \"} ${i + 1}. ${opt.label}`}\n </text>\n ))}\n <text fg={t.textDim}>{\" \u2191\u2193 Navigate Enter Select i/q/Esc Quick keys\"}</text>\n </box>\n );\n}\n\n// \u2500\u2500 Session View \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function SessionView(props: {\n onStatus: (s: string) => void;\n onTokens: (input: number, output: number) => void;\n onActiveTool: (tool: string | undefined) => void;\n onContextPercent: (pct: number) => void;\n onOpenDialog?: (dialog: string) => void;\n initialMessage?: { text: string; images?: ImageAttachment[] } | null;\n dialogOpen?: boolean;\n}) {\n const sdk = useSDK();\n const { setMode } = useTheme();\n const { toast } = useToast();\n\n // Set terminal title to indicate active session\n setTerminalTitle(\"cdoing - session\");\n\n const [messages, setMessages] = useState<Message[]>([]);\n const [streamingText, setStreamingText] = useState(\"\");\n const streamingTextRef = useRef(streamingText);\n streamingTextRef.current = streamingText;\n const [isStreaming, setIsStreaming] = useState(false);\n const [agentMode, setAgentMode] = useState<AgentMode>(\"build\");\n\n // Wire mode change to permission manager's agentType\n const handleModeChange = (mode: AgentMode) => {\n setAgentMode(mode);\n sdk.permissionManager.setAgentType(mode);\n };\n const [activeTool, setActiveTool] = useState<string | undefined>();\n const [pendingPermission, setPendingPermission] = useState<{\n toolName: string;\n message: string;\n resolve: (decision: \"allow\" | \"always\" | \"deny\") => void;\n } | null>(null);\n\n // Interrupt/queue prompt state\n const [pendingInterrupt, setPendingInterrupt] = useState<{\n text: string;\n images?: ImageAttachment[];\n } | null>(null);\n const queuedMessagesRef = useRef<string[]>([]);\n\n const totalInputRef = useRef(0);\n const totalOutputRef = useRef(0);\n const msgIdCounterRef = useRef(0);\n const conversationRef = useRef<Conversation | null>(null);\n const backgroundJobsRef = useRef<BackgroundJob[]>([]);\n const bgIdCounterRef = useRef(0);\n const planPendingRef = useRef(false);\n const planSummaryRef = useRef(\"\");\n\n // Initialize conversation on first render\n if (!conversationRef.current) {\n conversationRef.current = createConversation(sdk.provider, sdk.model);\n }\n\n const addMessage = (role: Message[\"role\"], content: string, extra?: Partial<Message>) => {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role,\n content,\n timestamp: Date.now(),\n ...extra,\n };\n setMessages((prev) => [...prev, msg]);\n\n // Persist to conversation history\n if (conversationRef.current && (role === \"user\" || role === \"assistant\")) {\n addHistoryMessage(conversationRef.current, role, content);\n }\n\n return msg.id;\n };\n\n const updateMessage = (id: string, updates: Partial<Message>) => {\n setMessages((prev) =>\n prev.map((m) => (m.id === id ? { ...m, ...updates } : m))\n );\n };\n\n // \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const loadStoredConfig = (): Record<string, any> => {\n try {\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n if (fs.existsSync(configPath)) {\n return JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n return {};\n };\n\n const saveConfigKey = (key: string, value: any): void => {\n const configDir = path.join(os.homedir(), \".cdoing\");\n const configPath = path.join(configDir, \"config.json\");\n let config: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n config[key] = value;\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n };\n\n const loadProjectSettings = (): Record<string, any> => {\n try {\n const settingsPath = path.join(sdk.workingDir, \".cdoing\", \"settings.json\");\n if (fs.existsSync(settingsPath)) {\n return JSON.parse(fs.readFileSync(settingsPath, \"utf-8\"));\n }\n const claudePath = path.join(sdk.workingDir, \".claude\", \"settings.json\");\n if (fs.existsSync(claudePath)) {\n return JSON.parse(fs.readFileSync(claudePath, \"utf-8\"));\n }\n } catch {}\n return {};\n };\n\n // \u2500\u2500 Background Jobs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const runBackgroundJob = (prompt: string) => {\n const job: BackgroundJob = {\n id: `bg-${++bgIdCounterRef.current}`,\n prompt,\n status: \"running\",\n startedAt: Date.now(),\n };\n backgroundJobsRef.current = [...backgroundJobsRef.current, job];\n addMessage(\"system\", `Background job ${job.id} started: ${prompt.substring(0, 60)}${prompt.length > 60 ? \"...\" : \"\"}`);\n\n // Run in background with a separate callback set\n let bgResult = \"\";\n const bgCallbacks: AgentCallbacks = {\n onToken: (token) => { bgResult += token; },\n onToolCall: () => {},\n onToolResult: () => {},\n onComplete: () => {\n job.status = \"done\";\n job.result = bgResult.trim();\n job.completedAt = Date.now();\n backgroundJobsRef.current = [...backgroundJobsRef.current];\n addMessage(\"system\", `Background job ${job.id} completed. Use /jobs ${job.id} to see results.`);\n },\n onError: (error) => {\n job.status = \"error\";\n job.error = error.message;\n job.completedAt = Date.now();\n backgroundJobsRef.current = [...backgroundJobsRef.current];\n addMessage(\"system\", `Background job ${job.id} failed: ${error.message}`);\n },\n };\n\n // Fire and forget\n sdk.agent.run(prompt, bgCallbacks).catch((err) => {\n job.status = \"error\";\n job.error = err instanceof Error ? err.message : String(err);\n job.completedAt = Date.now();\n });\n };\n\n // \u2500\u2500 Slash Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const handleSlashCommand = (cmd: string) => {\n const [command, ...args] = cmd.split(\" \");\n const arg = args.join(\" \").trim();\n\n switch (command) {\n case \"/clear\":\n setMessages([]);\n sdk.agent.clearHistory();\n addMessage(\"system\", \"Chat cleared.\");\n toast(\"success\", \"Chat cleared\");\n break;\n\n case \"/new\":\n setMessages([]);\n sdk.agent.clearHistory();\n totalInputRef.current = 0;\n totalOutputRef.current = 0;\n props.onTokens(0, 0);\n props.onContextPercent(0);\n conversationRef.current = createConversation(sdk.provider, sdk.model);\n addMessage(\"system\", \"New conversation started.\");\n toast(\"success\", \"New conversation started\");\n break;\n\n case \"/model\": {\n if (arg && sdk.rebuildAgent) {\n sdk.rebuildAgent(sdk.provider, arg);\n addMessage(\"system\", `Model switched to: ${arg}`);\n toast(\"info\", `Model: ${arg}`);\n } else if (arg) {\n addMessage(\"system\", \"Model switching not available.\");\n toast(\"warning\", \"Model switching not available\");\n } else {\n addMessage(\"system\", `Current model: ${sdk.model}`);\n }\n break;\n }\n\n case \"/provider\": {\n if (arg && sdk.rebuildAgent) {\n const { getDefaultModel } = require(\"@cdoing/ai\");\n const defaultModel = getDefaultModel(arg) || sdk.model;\n sdk.rebuildAgent(arg, defaultModel);\n addMessage(\"system\", `Provider switched to: ${arg} (model: ${defaultModel})`);\n toast(\"info\", `Provider: ${arg} (${defaultModel})`);\n } else if (arg) {\n addMessage(\"system\", \"Provider switching not available.\");\n toast(\"warning\", \"Provider switching not available\");\n } else {\n addMessage(\"system\", `Current provider: ${sdk.provider}`);\n }\n break;\n }\n\n case \"/mode\": {\n const currentMode = (sdk.permissionManager as any)?.mode || \"ask\";\n addMessage(\"system\", `Permission mode: ${currentMode}\\nAvailable: ask, auto-edit, auto`);\n break;\n }\n\n case \"/dir\": {\n if (arg) {\n const resolved = path.resolve(sdk.workingDir, arg);\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n if (sdk.setWorkingDir) sdk.setWorkingDir(resolved);\n addMessage(\"system\", `Working directory changed to: ${resolved}`);\n } else {\n addMessage(\"system\", `Directory not found: ${resolved}`);\n }\n } else {\n addMessage(\"system\", `Working directory: ${sdk.workingDir}`);\n }\n break;\n }\n\n case \"/config\": {\n if (arg.startsWith(\"set \")) {\n const setParts = arg.substring(4).trim().split(/\\s+/);\n if (setParts.length >= 2) {\n const [key, ...valParts] = setParts;\n const value = valParts.join(\" \");\n if (key === \"api-key\") {\n const config = loadStoredConfig();\n if (!config.apiKeys) config.apiKeys = {};\n config.apiKeys[sdk.provider] = value;\n saveConfigKey(\"apiKeys\", config.apiKeys);\n addMessage(\"system\", `API key saved for ${sdk.provider}.`);\n } else if (key === \"api-key-helper\") {\n saveConfigKey(\"apiKeyHelper\", value);\n addMessage(\"system\", `API key helper set to: ${value}`);\n } else {\n saveConfigKey(key, value);\n addMessage(\"system\", `Config ${key} set to: ${value}`);\n }\n } else {\n addMessage(\"system\", \"Usage: /config set <key> <value>\");\n }\n } else if (arg === \"show\" || !arg) {\n const config = loadStoredConfig();\n const lines = Object.entries(config)\n .filter(([k]) => k !== \"apiKeys\")\n .map(([k, v]) => ` ${k}: ${typeof v === \"object\" ? JSON.stringify(v) : v}`);\n addMessage(\"system\", lines.length > 0 ? \"Configuration:\\n\" + lines.join(\"\\n\") : \"No configuration found. Run /setup to configure.\");\n } else {\n addMessage(\"system\", \"Usage: /config [show | set <key> <value>]\");\n }\n break;\n }\n\n case \"/theme\": {\n const validModes = [\"dark\", \"light\"] as const;\n if (arg && (validModes as readonly string[]).includes(arg)) {\n setMode(arg as \"dark\" | \"light\");\n addMessage(\"system\", `Theme mode switched to: ${arg}`);\n toast(\"success\", `Mode: ${arg}`);\n } else {\n addMessage(\"system\", \"Usage: /theme dark | light (or Ctrl+T for theme picker)\");\n toast(\"warning\", \"Usage: /theme dark | light\");\n }\n break;\n }\n\n case \"/compact\":\n if ((sdk.agent as any).compressContext) {\n (sdk.agent as any).compressContext();\n addMessage(\"system\", \"Context compressed.\");\n toast(\"success\", \"Context compressed\");\n } else {\n addMessage(\"system\", \"Context compression not available.\");\n toast(\"warning\", \"Context compression not available\");\n }\n break;\n\n case \"/effort\": {\n const levels = [\"low\", \"medium\", \"high\", \"max\"];\n if (arg && levels.includes(arg)) {\n addMessage(\"system\", `Effort level set to: ${arg}`);\n toast(\"info\", `Effort: ${arg}`);\n } else {\n addMessage(\"system\", `Usage: /effort <${levels.join(\"|\")}>`);\n }\n break;\n }\n\n case \"/plan\": {\n // Helper: rebuild agent with fresh system prompt, preserving history\n const rebuildWithHistory = () => {\n if (sdk.rebuildAgent) {\n const history = sdk.agent.getHistory();\n sdk.rebuildAgent(sdk.provider, sdk.model);\n if (history.length > 0) {\n sdk.agent.setHistory(history);\n }\n }\n };\n\n if (arg === \"off\" || arg === \"cancel\") {\n planPendingRef.current = false;\n sdk.permissionManager.setMode(\"default\" as any);\n rebuildWithHistory();\n addMessage(\"system\", \"Plan mode cancelled. Switched to build mode.\");\n } else if (arg === \"show\") {\n addMessage(\"system\", planSummaryRef.current || \"No active plan.\");\n } else if (arg === \"approve\" || arg === \"yes\") {\n if (!planPendingRef.current) {\n addMessage(\"system\", \"No plan to approve. Use /plan <request> to create one.\");\n break;\n }\n planPendingRef.current = false;\n sdk.permissionManager.setMode(\"default\" as any);\n rebuildWithHistory();\n addMessage(\"system\", \"Plan approved! Switched to build mode. Executing...\");\n const buildPrompt = [\n \"[MODE SWITCH: Plan \u2192 Build]\",\n \"Your operational mode has changed from plan to build.\",\n \"You now have full access to write files, run commands, and execute tools.\",\n \"\",\n \"## Approved Plan\",\n planSummaryRef.current || \"Execute the plan you created.\",\n \"\",\n \"## Instructions\",\n \"Execute the plan step by step. If a step fails, explain why and suggest alternatives.\",\n ].join(\"\\n\");\n sendMessage(buildPrompt);\n } else if (arg === \"reject\" || arg === \"no\") {\n planPendingRef.current = false;\n sdk.permissionManager.setMode(\"default\" as any);\n rebuildWithHistory();\n addMessage(\"system\", \"Plan rejected. Switched to build mode.\");\n } else if (!arg) {\n const isActive = planPendingRef.current;\n if (isActive) {\n planPendingRef.current = false;\n sdk.permissionManager.setMode(\"default\" as any);\n rebuildWithHistory();\n addMessage(\"system\", \"Plan mode OFF. Switched to build mode.\");\n } else {\n sdk.permissionManager.setMode(\"plan\" as any);\n rebuildWithHistory();\n addMessage(\"system\", \"Plan mode ON (read-only). Send a message to start planning.\\nUse /plan approve to execute, /plan reject to cancel.\");\n }\n } else {\n // /plan <request>\n sdk.permissionManager.setMode(\"plan\" as any);\n rebuildWithHistory();\n planPendingRef.current = true;\n addMessage(\"system\", \"Plan mode ON (read-only). Generating plan...\\nUse /plan approve when ready, /plan reject to cancel.\");\n const planPrompt = [\n \"[PLAN MODE \u2014 Read-only]\",\n \"Analyze this request and create a detailed step-by-step implementation plan.\",\n \"You are in read-only mode \u2014 you can read files, search code, and explore, but CANNOT write or execute.\",\n \"When your plan is complete, call plan_exit with a summary.\",\n \"\",\n `Request: ${arg}`,\n ].join(\"\\n\");\n sendMessage(planPrompt);\n }\n break;\n }\n\n case \"/permissions\": {\n const settings = loadProjectSettings();\n const allow = settings?.allow || [];\n const deny = settings?.deny || [];\n const lines: string[] = [\"Permission rules:\"];\n if (deny.length > 0) lines.push(\" Deny: \" + deny.join(\", \"));\n if (allow.length > 0) lines.push(\" Allow: \" + allow.join(\", \"));\n if (deny.length === 0 && allow.length === 0) lines.push(\" No custom rules configured.\");\n addMessage(\"system\", lines.join(\"\\n\"));\n break;\n }\n\n case \"/hooks\": {\n try {\n const hooksPath = path.join(sdk.workingDir, \".cdoing\", \"hooks.json\");\n if (fs.existsSync(hooksPath)) {\n const hooks = JSON.parse(fs.readFileSync(hooksPath, \"utf-8\"));\n const keys = Object.keys(hooks);\n addMessage(\"system\", keys.length > 0\n ? \"Configured hooks:\\n\" + keys.map((k) => ` ${k}: ${JSON.stringify(hooks[k])}`).join(\"\\n\")\n : \"No hooks configured.\");\n } else {\n addMessage(\"system\", \"No hooks file found (.cdoing/hooks.json).\");\n }\n } catch {\n addMessage(\"system\", \"No hooks configured.\");\n }\n break;\n }\n\n case \"/rules\": {\n try {\n const rulesDir = path.join(sdk.workingDir, \".cdoing\", \"rules\");\n if (fs.existsSync(rulesDir)) {\n const files = fs.readdirSync(rulesDir).filter((f: string) => f.endsWith(\".md\"));\n addMessage(\"system\", files.length > 0\n ? \"Project rules:\\n\" + files.map((f: string) => ` ${f}`).join(\"\\n\")\n : \"No rules found in .cdoing/rules/.\");\n } else {\n addMessage(\"system\", \"No rules directory found (.cdoing/rules/).\");\n }\n } catch {\n addMessage(\"system\", \"No rules configured.\");\n }\n break;\n }\n\n case \"/memory\":\n addMessage(\"system\", \"Memory store: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/tasks\":\n addMessage(\"system\", \"Task list: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/context\":\n addMessage(\"system\", [\n \"Context providers (use @ to invoke):\",\n \" @terminal \u2014 Recent terminal output\",\n \" @url \u2014 Fetch URL content\",\n \" @tree \u2014 Project file tree\",\n \" @codebase \u2014 Full codebase context\",\n \" @clip \u2014 Clipboard content\",\n \" @file \u2014 Include a file\",\n ].join(\"\\n\"));\n break;\n\n case \"/mcp\":\n addMessage(\"system\", \"MCP server management: not yet implemented in TUI. Coming soon.\");\n break;\n\n case \"/history\":\n case \"/ls\": {\n const convs = listConversations().slice(0, 20);\n if (convs.length > 0) {\n const lines = convs.map((c) => {\n const id = c.id.substring(0, 12);\n const date = formatRelativeDate(c.updatedAt);\n const msgCount = c.messages.filter((m) => m.role === \"user\").length;\n return ` ${id} ${date.padEnd(10)} (${msgCount} msgs) ${c.title}`;\n });\n addMessage(\"system\", \"Conversations:\\n\" + lines.join(\"\\n\") + \"\\n\\nUse /resume <id> to continue. Ctrl+S for interactive browser.\");\n } else {\n addMessage(\"system\", \"No saved conversations found.\");\n }\n break;\n }\n\n case \"/resume\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /resume <conversation-id>\");\n break;\n }\n const conv = loadConversation(arg);\n if (!conv) {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n break;\n }\n // Restore conversation\n conversationRef.current = conv;\n setMessages([]);\n sdk.agent.clearHistory();\n totalInputRef.current = 0;\n totalOutputRef.current = 0;\n // Replay messages into UI\n for (const m of conv.messages) {\n if (m.role === \"user\" || m.role === \"assistant\") {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: m.role,\n content: m.content,\n timestamp: m.timestamp,\n };\n setMessages((prev) => [...prev, msg]);\n }\n }\n addMessage(\"system\", `Resumed conversation: ${conv.title}`);\n break;\n }\n\n case \"/view\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /view <conversation-id>\");\n break;\n }\n const conv = loadConversation(arg);\n if (!conv) {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n break;\n }\n const viewMsgs = conv.messages\n .filter((m) => m.role !== \"tool\")\n .slice(-20)\n .map((m) => {\n const prefix = m.role === \"user\" ? \"\u276F\" : \"\u25C6\";\n const content = m.content.length > 100 ? m.content.substring(0, 97) + \"...\" : m.content;\n return ` ${prefix} ${content.replace(/\\n/g, \" \")}`;\n });\n addMessage(\"system\", `Conversation: ${conv.title}\\n\\n${viewMsgs.join(\"\\n\")}`);\n break;\n }\n\n case \"/fork\": {\n const sourceConv = arg ? loadConversation(arg) : conversationRef.current;\n if (!sourceConv) {\n addMessage(\"system\", arg ? `Conversation not found: ${arg}` : \"No active conversation to fork.\");\n break;\n }\n const forked = forkConversation(sourceConv);\n if (forked) {\n addMessage(\"system\", `Forked conversation: ${forked.id.substring(0, 12)} \u2014 \"${forked.title}\"`);\n } else {\n addMessage(\"system\", \"Failed to fork conversation.\");\n }\n break;\n }\n\n case \"/delete\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /delete <conversation-id>\");\n break;\n }\n if (deleteConversation(arg)) {\n addMessage(\"system\", `Conversation deleted: ${arg}`);\n } else {\n addMessage(\"system\", `Conversation not found: ${arg}`);\n }\n break;\n }\n\n case \"/bg\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /bg <prompt>\");\n break;\n }\n runBackgroundJob(arg);\n break;\n }\n\n case \"/jobs\": {\n const jobs = backgroundJobsRef.current;\n if (arg) {\n // Show specific job\n const job = jobs.find((j) => j.id === arg);\n if (job) {\n const elapsed = job.completedAt\n ? `${((job.completedAt - job.startedAt) / 1000).toFixed(1)}s`\n : `${((Date.now() - job.startedAt) / 1000).toFixed(1)}s (running)`;\n const result = job.result\n ? job.result.length > 500 ? job.result.substring(0, 497) + \"...\" : job.result\n : job.error || \"(no output)\";\n addMessage(\"system\", `Job ${job.id} [${job.status}] (${elapsed}):\\n Prompt: ${job.prompt}\\n Result: ${result}`);\n } else {\n addMessage(\"system\", `Job not found: ${arg}`);\n }\n } else if (jobs.length > 0) {\n const lines = jobs.map((j) => {\n const icon = j.status === \"running\" ? \"\u23F3\" : j.status === \"done\" ? \"\u2713\" : \"\u2717\";\n return ` ${icon} ${j.id} ${j.status} ${j.prompt.substring(0, 50)}${j.prompt.length > 50 ? \"...\" : \"\"}`;\n });\n addMessage(\"system\", \"Background jobs:\\n\" + lines.join(\"\\n\"));\n } else {\n addMessage(\"system\", \"No background jobs.\");\n }\n break;\n }\n\n case \"/btw\": {\n if (!arg) {\n addMessage(\"system\", \"Usage: /btw <question>\");\n break;\n }\n // Ephemeral question \u2014 don't add to conversation history\n const btwMsg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: \"user\",\n content: `(btw) ${arg}`,\n timestamp: Date.now(),\n };\n setMessages((prev) => [...prev, btwMsg]);\n setIsStreaming(true);\n setStreamingText(\"\");\n props.onStatus(\"Processing...\");\n\n let btwResult = \"\";\n const btwCallbacks: AgentCallbacks = {\n onToken: (token) => {\n btwResult += token;\n setStreamingText((prev) => prev + token);\n },\n onToolCall: () => {},\n onToolResult: () => {},\n onComplete: () => {\n if (btwResult.trim()) {\n const msg: Message = {\n id: `msg-${++msgIdCounterRef.current}`,\n role: \"assistant\",\n content: btwResult.trim(),\n timestamp: Date.now(),\n };\n setMessages((prev) => [...prev, msg]);\n setStreamingText(\"\");\n }\n setIsStreaming(false);\n props.onStatus(\"Ready\");\n },\n onError: (error) => {\n addMessage(\"system\", `Error: ${error.message}`);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n },\n };\n\n sdk.agent.run(arg, btwCallbacks).catch((err) => {\n addMessage(\"system\", `Error: ${err instanceof Error ? err.message : String(err)}`);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n });\n break;\n }\n\n case \"/login\":\n case \"/setup\":\n if (props.onOpenDialog) {\n props.onOpenDialog(\"setup\");\n } else {\n addMessage(\"system\", \"Setup wizard: configure via ~/.cdoing/config.json or run the base CLI with --login.\");\n }\n break;\n\n case \"/logout\": {\n try {\n const { fullLogout } = require(\"@cdoing/core\");\n const msg = fullLogout(sdk.provider);\n\n // Invalidate the in-memory agent so it can't make further API calls\n sdk.agent.invalidate();\n\n addMessage(\"system\", msg);\n } catch {\n addMessage(\"system\", \"OAuth logout not available.\");\n }\n break;\n }\n\n case \"/auth-status\": {\n const config = loadStoredConfig();\n const lines: string[] = [\"Authentication Status:\", \"\"];\n\n // OAuth status\n try {\n const { getAllOAuthStatuses } = require(\"@cdoing/core\");\n const oauthStatuses = getAllOAuthStatuses();\n lines.push(\"OAuth:\");\n let hasOAuth = false;\n for (const s of oauthStatuses) {\n if (s.status === \"none\") continue;\n hasOAuth = true;\n const icon = s.status === \"active\" ? \"\u2713\" : \"\u2717\";\n const label = s.status === \"active\" ? \"active\" : \"expired\";\n const expires = s.expiresAt ? new Date(s.expiresAt).toLocaleString() : \"unknown\";\n lines.push(` ${icon} ${s.name}: ${label}`);\n if (s.expiresAt) lines.push(` Expires: ${expires}`);\n }\n if (!hasOAuth) lines.push(\" None\");\n } catch {\n lines.push(\"OAuth: unavailable\");\n }\n\n // API keys\n lines.push(\"\");\n lines.push(\"Stored API keys:\");\n if (config.apiKeys && Object.keys(config.apiKeys).length > 0) {\n for (const [prov, key] of Object.entries(config.apiKeys)) {\n const k = String(key);\n const masked = k.slice(0, 8) + \"...\" + k.slice(-4);\n lines.push(` \u2713 ${prov}: ${masked}`);\n }\n } else {\n lines.push(\" None\");\n }\n\n lines.push(\"\");\n lines.push(\"Environment variables:\");\n const envVars: [string, string | undefined][] = [\n [\"ANTHROPIC_API_KEY\", process.env.ANTHROPIC_API_KEY],\n [\"OPENAI_API_KEY\", process.env.OPENAI_API_KEY],\n [\"GOOGLE_API_KEY\", process.env.GOOGLE_API_KEY],\n ];\n let hasEnvKey = false;\n for (const [name, value] of envVars) {\n if (value) {\n hasEnvKey = true;\n const masked = value.slice(0, 8) + \"...\" + value.slice(-4);\n lines.push(` \u2713 ${name}: ${masked}`);\n }\n }\n if (!hasEnvKey) lines.push(\" None\");\n\n addMessage(\"system\", lines.join(\"\\n\"));\n break;\n }\n\n case \"/doctor\": {\n const checks: string[] = [\"System health check:\"];\n const config = loadStoredConfig();\n const envKey = process.env[`${sdk.provider.toUpperCase()}_API_KEY`];\n let hasAuth = !!(config.apiKeys?.[sdk.provider] || envKey);\n if (!hasAuth) {\n try {\n const { getOAuthStatus } = require(\"@cdoing/core\");\n hasAuth = getOAuthStatus(sdk.provider).status === \"active\";\n } catch {}\n }\n checks.push(` Provider: ${sdk.provider} ${hasAuth ? \"\u2713 Authenticated\" : \"\u2717 No API key or OAuth token\"}`);\n checks.push(` Model: ${sdk.model}`);\n checks.push(` Working dir: ${sdk.workingDir} ${fs.existsSync(sdk.workingDir) ? \"\u2713\" : \"\u2717\"}`);\n const hasCdoing = fs.existsSync(path.join(sdk.workingDir, \".cdoing\"));\n const hasClaude = fs.existsSync(path.join(sdk.workingDir, \".claude\"));\n checks.push(` Project config: ${hasCdoing ? \".cdoing/ \u2713\" : hasClaude ? \".claude/ \u2713\" : \"\u2717 none\"}`);\n checks.push(` Node: ${process.version}`);\n checks.push(` Platform: ${process.platform} ${process.arch}`);\n\n // Check conversation history\n const convs = listConversations();\n checks.push(` Conversations: ${convs.length} saved`);\n\n // Check background jobs\n const runningJobs = backgroundJobsRef.current.filter((j) => j.status === \"running\");\n if (runningJobs.length > 0) {\n checks.push(` Background jobs: ${runningJobs.length} running`);\n }\n\n addMessage(\"system\", checks.join(\"\\n\"));\n break;\n }\n\n case \"/init\": {\n const cdoingDir = path.join(sdk.workingDir, \".cdoing\");\n if (fs.existsSync(cdoingDir)) {\n addMessage(\"system\", \"Project already initialized (.cdoing/ exists).\");\n } else {\n try {\n fs.mkdirSync(cdoingDir, { recursive: true });\n fs.mkdirSync(path.join(cdoingDir, \"rules\"), { recursive: true });\n fs.writeFileSync(\n path.join(cdoingDir, \"config.md\"),\n \"# Project Configuration\\n\\nDescribe your project here for the AI assistant.\\n\",\n \"utf-8\"\n );\n addMessage(\"system\", \"Project initialized. Created .cdoing/ with config.md and rules/.\");\n } catch (err) {\n addMessage(\"system\", `Failed to initialize: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n break;\n }\n\n case \"/queue\":\n addMessage(\"system\", \"Message queue is empty.\");\n break;\n\n case \"/help\":\n addMessage(\"system\", [\n \"Available commands:\",\n \"\",\n \" Session\",\n \" /clear Clear chat history\",\n \" /new Start new conversation\",\n \" /compact Compress context window\",\n \" /btw <question> Ask without adding to history\",\n \"\",\n \" Configuration\",\n \" /model [name] Show/change model\",\n \" /provider [name] Show/change provider\",\n \" /mode Show permission mode\",\n \" /dir [path] Show/change working directory\",\n \" /config Show configuration\",\n \" /config set k v Set a config value\",\n \" /theme <mode> Switch theme (dark/light/auto)\",\n \" /effort <level> Set effort (low/medium/high/max)\",\n \" /plan <on|off> Toggle plan mode\",\n \"\",\n \" History\",\n \" /history, /ls List saved conversations\",\n \" /resume <id> Resume conversation\",\n \" /view <id> View conversation messages\",\n \" /fork [id] Fork current/specified conversation\",\n \" /delete <id> Delete conversation\",\n \"\",\n \" Background\",\n \" /bg <prompt> Run prompt in background\",\n \" /jobs [id] List/inspect background jobs\",\n \"\",\n \" System\",\n \" /permissions Show permission rules\",\n \" /hooks Show configured hooks\",\n \" /rules Show project rules\",\n \" /context Show context providers\",\n \" /mcp MCP server management\",\n \" /doctor System health check\",\n \" /usage Show token usage\",\n \" /auth-status Show authentication status\",\n \"\",\n \" /setup Run setup wizard\",\n \" /login Open setup wizard\",\n \" /logout Clear OAuth tokens\",\n \" /init Initialize project config\",\n \" /exit Quit\",\n \"\",\n \"Keyboard shortcuts:\",\n \" Ctrl+V Paste text or image\",\n \" Ctrl+U Clear input line\",\n \" Ctrl+W Delete last word\",\n \" Ctrl+P Command palette\",\n \" Ctrl+O Model picker\",\n \" Ctrl+N New session\",\n \" Ctrl+S Session browser\",\n \" Tab Switch mode (Build/Plan)\",\n \" \u2192 Accept autocomplete\",\n \" \u2191/\u2193 Navigate suggestions\",\n \" Escape Close dropdown\",\n \"\",\n \"Shell: prefix with ! or type commands directly (ls, git, npm, etc.)\",\n \"Context: use @terminal, @url, @tree, @codebase, @clip, @file in messages\",\n ].join(\"\\n\"));\n break;\n\n case \"/usage\":\n addMessage(\"system\", `Tokens: ${totalInputRef.current.toLocaleString()}\u2192${totalOutputRef.current.toLocaleString()} (${(totalInputRef.current + totalOutputRef.current).toLocaleString()} total)`);\n break;\n\n case \"/exit\":\n case \"/quit\":\n process.exit(0);\n break;\n\n default:\n addMessage(\"system\", `Unknown command: ${command}. Type /help for available commands.`);\n toast(\"error\", `Unknown command: ${command}`);\n }\n };\n\n // \u2500\u2500 Shell Commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const runShellCommand = (shellCmd: string) => {\n addMessage(\"user\", `!${shellCmd}`);\n let output = \"\";\n let errorMsg = \"\";\n try {\n output = execSync(shellCmd, {\n cwd: sdk.workingDir,\n env: { ...process.env },\n encoding: \"utf-8\",\n timeout: 120000,\n maxBuffer: 10 * 1024 * 1024,\n });\n } catch (err: any) {\n if (err.stdout) output = String(err.stdout);\n if (err.stderr) errorMsg = String(err.stderr);\n if (err.status !== undefined && err.status !== 0) {\n errorMsg += `\\n[exited with code ${err.status}]`;\n } else if (!err.stdout && !err.stderr && err.message) {\n errorMsg = err.message;\n }\n }\n const result = (output + (errorMsg ? `\\n${errorMsg}` : \"\")).trim();\n addMessage(\"system\", `$ ${shellCmd}\\n${result || \"(no output)\"}`);\n\n // Push to terminal context provider\n pushTerminalOutput(`$ ${shellCmd}\\n${result}`);\n };\n\n // \u2500\u2500 Interrupt: stop streaming, flush partial, send new message with context \u2500\u2500\n\n const handleInterrupt = (text: string, images?: ImageAttachment[]) => {\n // Capture partial response and interrupt \u2014 adds partial to agent history for context\n const partialResponse = streamingTextRef.current.trim();\n sdk.agent.interrupt(partialResponse);\n\n // Flush partial streaming text as a message\n if (partialResponse) {\n addMessage(\"assistant\", partialResponse + \"\\n\\n*(interrupted)*\");\n setStreamingText(\"\");\n }\n\n setIsStreaming(false);\n props.onStatus(\"Ready\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n setPendingInterrupt(null);\n\n // Send the new message \u2014 agent.cancel() calls onComplete which resets state,\n // so we use a small delay to let that settle\n setTimeout(() => {\n doSendMessage(text, images);\n }, 100);\n };\n\n // \u2500\u2500 Queue: add to queue, process after current stream finishes \u2500\u2500\n\n const handleQueue = (text: string) => {\n queuedMessagesRef.current.push(text);\n addMessage(\"system\", `\uD83D\uDCEC Queued message (${queuedMessagesRef.current.length} in queue)`);\n setPendingInterrupt(null);\n };\n\n // \u2500\u2500 Process queued messages after streaming completes \u2500\u2500\n\n const processQueue = () => {\n if (queuedMessagesRef.current.length > 0) {\n const next = queuedMessagesRef.current.shift()!;\n setTimeout(() => doSendMessage(next), 100);\n }\n };\n\n // \u2500\u2500 Send Message \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const sendMessage = async (text: string, images?: ImageAttachment[]) => {\n if (text.startsWith(\"/\")) {\n handleSlashCommand(text);\n return;\n }\n\n // Shell commands always run immediately\n const shellCmd = text.startsWith(\"!\")\n ? text.slice(1).trim()\n : detectShellCommand(text);\n\n if (shellCmd) {\n // Intercept \"cd\" \u2014 execSync runs in a child process, so cd has no effect there\n const shellParts = shellCmd.trim().split(/\\s+/);\n if (shellParts[0] === \"cd\") {\n const target = shellParts.slice(1).join(\" \") || process.env.HOME || \"/\";\n const resolved = path.resolve(sdk.workingDir, target);\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n if (sdk.setWorkingDir) sdk.setWorkingDir(resolved);\n addMessage(\"system\", `Working directory changed to: ${resolved}`);\n } else {\n addMessage(\"system\", `cd: no such directory: ${resolved}`);\n }\n return;\n }\n runShellCommand(shellCmd);\n return;\n }\n\n // If currently streaming, show interrupt/queue prompt\n if (isStreaming) {\n setPendingInterrupt({ text, images });\n return;\n }\n\n await doSendMessage(text, images);\n };\n\n // Auto-send initial message from home screen input\n const initialMessageSentRef = useRef(false);\n useEffect(() => {\n if (props.initialMessage && !initialMessageSentRef.current) {\n initialMessageSentRef.current = true;\n sendMessage(props.initialMessage.text, props.initialMessage.images);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n const doSendMessage = async (text: string, images?: ImageAttachment[]) => {\n // Inject plan mode context if active\n let messageText = text;\n if (planPendingRef.current || sdk.permissionManager.getMode() === (\"plan\" as any)) {\n messageText = `[PLAN MODE \u2014 Read-only] You are in plan mode. Do NOT write files, run commands, or modify anything. Only read, search, analyze, and create a plan using the todo tool. When your plan is ready, call plan_exit.\\n\\n${text}`;\n }\n\n // Resolve @mention context providers\n let expandedText = messageText;\n if (hasContextMentions(messageText)) {\n try {\n expandedText = await resolveContextProviders(text, sdk.workingDir);\n } catch {\n // If expansion fails, send original text\n }\n }\n\n addMessage(\"user\", text + (images && images.length > 0 ? ` [${images.length} image${images.length > 1 ? \"s\" : \"\"}]` : \"\"));\n setIsStreaming(true);\n setStreamingText(\"\");\n props.onStatus(\"Processing...\");\n\n let currentToolId: string | undefined;\n let turnInput = 0;\n\n const callbacks: AgentCallbacks = {\n onToken: (token) => {\n setStreamingText((prev) => prev + token);\n },\n\n onToolCall: (name, input) => {\n // Flush streaming text to a message\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n\n const toolInput = (typeof input === \"object\" && input) ? input as Record<string, any> : {};\n const description = toolInput.description || \"\";\n currentToolId = addMessage(\"tool\", description, {\n toolName: name,\n toolStatus: \"running\",\n toolInput,\n });\n setActiveTool(name);\n props.onActiveTool(name);\n },\n\n onToolResult: (_name, result, isError) => {\n if (currentToolId) {\n const summary = result.length > 80 ? result.substring(0, 77) + \"...\" : result;\n updateMessage(currentToolId, {\n content: summary,\n toolStatus: isError ? \"error\" : \"done\",\n isError,\n });\n currentToolId = undefined;\n }\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n },\n\n onCompactStart: (contextPercent) => {\n try {\n addMessage(\"system\", `\u27F3 Compacting context (${contextPercent}% used)...`);\n } catch {}\n },\n\n onCompactEnd: (savedTokens, newPercent) => {\n try {\n addMessage(\"system\", `\u2713 Context compacted \u2014 saved ${savedTokens.toLocaleString()} tokens (now ${newPercent}%)`);\n } catch {}\n },\n\n onComplete: () => {\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n\n setIsStreaming(false);\n props.onStatus(\"Ready\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n props.onTokens(totalInputRef.current, totalOutputRef.current);\n // Process queued messages\n processQueue();\n },\n\n onError: (error) => {\n const current = streamingTextRef.current.trim();\n if (current) {\n addMessage(\"assistant\", current);\n setStreamingText(\"\");\n }\n addMessage(\"system\", `Error: ${error.message}`);\n toast(\"error\", error.message);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n setActiveTool(undefined);\n props.onActiveTool(undefined);\n },\n\n onUsage: (usage) => {\n turnInput += usage.inputTokens;\n totalInputRef.current += usage.inputTokens;\n totalOutputRef.current += usage.outputTokens;\n props.onTokens(totalInputRef.current, totalOutputRef.current);\n // Estimate context usage (rough: typical 200k window)\n const pct = Math.min(100, (turnInput / 200000) * 100);\n props.onContextPercent(pct);\n },\n };\n\n try {\n await sdk.agent.run(expandedText, callbacks, images);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n addMessage(\"system\", `Error: ${msg}`);\n toast(\"error\", msg);\n setIsStreaming(false);\n props.onStatus(\"Error\");\n }\n };\n\n return (\n <box flexDirection=\"column\" flexGrow={1} paddingLeft={2} paddingRight={2} paddingTop={1} paddingBottom={1} gap={1}>\n {/* Scrollable message area \u2014 directly in layout for proper flex height (like OpenCode) */}\n <scrollbox\n stickyScroll={true}\n stickyStart=\"bottom\"\n flexGrow={1}\n scrollY={true}\n >\n <MessageList\n messages={messages}\n streamingText={streamingText}\n isStreaming={isStreaming}\n />\n </scrollbox>\n\n {/* Fixed bottom area \u2014 never pushed off screen */}\n <box flexDirection=\"column\" flexShrink={0}>\n {/* Permission prompt overlay */}\n {pendingPermission && (\n <PermissionPrompt\n toolName={pendingPermission.toolName}\n message={pendingPermission.message}\n onDecision={(decision) => {\n pendingPermission.resolve(decision);\n setPendingPermission(null);\n }}\n />\n )}\n\n {/* Interrupt/Queue prompt */}\n {pendingInterrupt && (\n <InterruptPrompt\n message={pendingInterrupt.text}\n onInterrupt={() => handleInterrupt(pendingInterrupt.text, pendingInterrupt.images)}\n onQueue={() => handleQueue(pendingInterrupt.text)}\n onCancel={() => setPendingInterrupt(null)}\n />\n )}\n\n {/* Loading spinner */}\n {isStreaming && !streamingText && !pendingInterrupt && (\n <LoadingSpinner label={activeTool || \"Thinking...\"} />\n )}\n\n {/* Input area */}\n <InputArea\n onSubmit={sendMessage}\n disabled={false}\n suppressInput={props.dialogOpen}\n placeholder={isStreaming ? \"Type to interrupt or queue...\" : undefined}\n workingDir={sdk.workingDir}\n mode={agentMode}\n onModeChange={handleModeChange}\n modelLabel={sdk.model}\n />\n </box>\n </box>\n );\n}\n", "/**\n * StatusBar \u2014 bottom bar with model info, tokens, context %, keybinds\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface StatusBarProps {\n provider: string;\n model: string;\n mode: string;\n workingDir: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n activeTool?: string;\n isProcessing?: boolean;\n}\n\nexport function StatusBar(props: StatusBarProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const shortDir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length)\n : props.workingDir;\n\n const tokenInfo = props.tokens\n ? ` ${props.tokens.input.toLocaleString()}\u2192${props.tokens.output.toLocaleString()}`\n : \"\";\n\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const contextBar = pct > 0 ? ` ctx:${pct}%` : \"\";\n\n return (\n <box height={1} flexDirection=\"row\" justifyContent=\"space-between\" backgroundColor={t.bgSubtle}>\n <box flexDirection=\"row\">\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {` ${props.provider}`}\n </text>\n <text fg={t.textMuted}>{`/${props.model}`}</text>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.warning}>{props.mode}</text>\n {tokenInfo && (\n <>\n <text fg={t.textDim}>{\" \u2502\"}</text>\n <text fg={t.textMuted}>{tokenInfo}</text>\n </>\n )}\n {contextBar && (\n <>\n <text fg={t.textDim}>{\" \u2502\"}</text>\n <text fg={pct > 75 ? t.warning : t.textMuted}>{contextBar}</text>\n </>\n )}\n {props.activeTool && (\n <>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.toolRunning}>{`\u23F3 ${props.activeTool}`}</text>\n </>\n )}\n {props.isProcessing && !props.activeTool && (\n <>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.primary}>{\"thinking...\"}</text>\n </>\n )}\n </box>\n <box flexDirection=\"row\">\n <text fg={t.textDim}>{shortDir}</text>\n <text fg={t.textDim}>{\" \u2502 \"}</text>\n <text fg={t.textMuted}>{\"^P:Commands ^O:Model ^C:Quit\"}</text>\n </box>\n </box>\n );\n}\n", "/**\n * SessionHeader \u2014 top-line session info bar.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nexport interface SessionHeaderProps {\n title: string;\n provider: string;\n model: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n status: string;\n}\n\nexport function SessionHeader(props: SessionHeaderProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const inTok = props.tokens ? props.tokens.input.toLocaleString() : \"0\";\n const outTok = props.tokens ? props.tokens.output.toLocaleString() : \"0\";\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const pctColor = pct > 75 ? t.error : pct > 50 ? t.warning : t.success;\n const statusColor = props.status === \"Error\" ? t.error\n : props.status === \"Processing...\" ? t.warning : t.success;\n\n const left = ` \u25C6 ${props.title || \"Session\"} \u2502 ${props.provider}/${props.model} \u2502 ${inTok}\u2192${outTok} tokens`;\n\n return (\n <box height={1} flexDirection=\"row\" backgroundColor={t.bgSubtle}>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{left}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={pctColor}>{`${pct}%`}</text>\n <box flexGrow={1} />\n <text fg={statusColor}>{`${props.status} `}</text>\n </box>\n );\n}\n", "/**\n * SessionFooter \u2014 bottom status line with directory and shortcut hints.\n */\n\nimport { useTheme } from \"../context/theme\";\n\nexport interface SessionFooterProps {\n workingDir: string;\n isProcessing: boolean;\n}\n\nexport function SessionFooter(props: SessionFooterProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const shortDir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length)\n : props.workingDir;\n\n const shortcuts = \"^P:Commands ^O:Model ^T:Theme ^S:Sessions ^B:Sidebar\";\n\n return (\n <box height={1} flexDirection=\"row\" backgroundColor={t.bgSubtle}>\n <text fg={t.textDim}>{` ${shortDir}`}</text>\n <box flexGrow={1} />\n <text fg={t.textMuted}>{`${shortcuts} `}</text>\n </box>\n );\n}\n", "/**\n * Sidebar \u2014 collapsible right panel with sections.\n * Uses single text per line to avoid layout concatenation issues.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useTheme } from \"../context/theme\";\n\nconst W = 34; // content width (inside the border)\n\nexport interface SidebarProps {\n provider: string;\n model: string;\n workingDir: string;\n tokens?: { input: number; output: number };\n contextPercent?: number;\n activeTool?: string;\n status: string;\n sessionTitle?: string;\n themeId?: string;\n modifiedFiles?: Array<{ path: string; additions: number; deletions: number }>;\n}\n\nfunction trunc(str: string, max: number): string {\n return str.length > max ? str.slice(0, max - 1) + \"\u2026\" : str;\n}\n\nfunction bar(pct: number, len: number): string {\n const filled = Math.round((pct / 100) * len);\n return \"\u2588\".repeat(filled) + \"\u2591\".repeat(len - filled);\n}\n\nexport function Sidebar(props: SidebarProps) {\n const { theme } = useTheme();\n const t = theme;\n\n const home = process.env.HOME || \"\";\n const dir = home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length) : props.workingDir;\n\n const pct = props.contextPercent ? Math.round(props.contextPercent) : 0;\n const pctColor = pct > 75 ? t.error : pct > 50 ? t.warning : t.success;\n const inTok = props.tokens ? props.tokens.input.toLocaleString() : \"0\";\n const outTok = props.tokens ? props.tokens.output.toLocaleString() : \"0\";\n const statusColor = props.status === \"Error\" ? t.error\n : props.status === \"Processing...\" ? t.warning : t.success;\n\n // Each line is a single string rendered in one <text> to avoid concatenation issues\n const lines: Array<{ text: string; fg: any; bold?: boolean }> = [];\n\n const sep = () => lines.push({ text: \"\u2502\", fg: t.border });\n const header = (title: string) => {\n lines.push({ text: `\u2502 ${title}`, fg: t.primary, bold: true });\n };\n const row = (label: string, value: string, fg?: any) => {\n const padded = label ? `\u2502 ${label.padEnd(10)} ${trunc(value, W - 14)}` : `\u2502 ${trunc(value, W - 4)}`;\n lines.push({ text: padded, fg: fg || t.text });\n };\n const shortcut = (key: string, label: string) => {\n lines.push({ text: `\u2502 ${key.padEnd(10)} ${label}`, fg: t.textDim });\n };\n\n // \u2500\u2500 Session \u2500\u2500\n header(\"Session\");\n row(\"\", props.sessionTitle || \"New Session\");\n row(\"Dir\", trunc(dir, W - 14));\n row(\"Provider\", props.provider);\n row(\"Model\", props.model);\n if (props.themeId) row(\"Theme\", props.themeId);\n sep();\n\n // \u2500\u2500 Context \u2500\u2500\n header(\"Context\");\n row(\"Input\", `${inTok} tokens`);\n row(\"Output\", `${outTok} tokens`);\n lines.push({ text: `\u2502 ${bar(pct, 16)} ${pct}%`, fg: pctColor });\n sep();\n\n // \u2500\u2500 Activity \u2500\u2500\n header(\"Activity\");\n lines.push({ text: `\u2502 Status ${props.status}`, fg: statusColor });\n if (props.activeTool) {\n lines.push({ text: `\u2502 Tool ${trunc(props.activeTool, W - 14)}`, fg: t.toolRunning });\n }\n sep();\n\n // \u2500\u2500 Modified Files \u2500\u2500\n if (props.modifiedFiles && props.modifiedFiles.length > 0) {\n header(`Files (${props.modifiedFiles.length})`);\n for (const f of props.modifiedFiles.slice(0, 6)) {\n const name = f.path.split(\"/\").pop() || f.path;\n const diff = (f.additions > 0 ? ` +${f.additions}` : \"\") + (f.deletions > 0 ? ` -${f.deletions}` : \"\");\n lines.push({ text: `\u2502 ${trunc(name, W - 12)}${diff}`, fg: t.text });\n }\n if (props.modifiedFiles.length > 6) {\n lines.push({ text: `\u2502 \u2026 ${props.modifiedFiles.length - 6} more`, fg: t.textDim });\n }\n sep();\n }\n\n // \u2500\u2500 LSP \u2500\u2500\n header(\"LSP\");\n row(\"\", \"LSPs will activate as files are read\");\n sep();\n\n // \u2500\u2500 Shortcuts \u2500\u2500\n header(\"Shortcuts\");\n shortcut(\"Ctrl+P\", \"Commands\");\n shortcut(\"Ctrl+O\", \"Model\");\n shortcut(\"Ctrl+T\", \"Theme\");\n shortcut(\"Ctrl+N\", \"New session\");\n shortcut(\"Ctrl+S\", \"Sessions\");\n shortcut(\"Ctrl+B\", \"Sidebar\");\n shortcut(\"F1\", \"Help\");\n\n // \u2500\u2500 Getting started card \u2500\u2500\n const cardW = W - 2;\n const cardLines: Array<{ text: string; fg: any; bold?: boolean }> = [];\n cardLines.push({ text: ` \u25C6 Getting started`, fg: t.primary, bold: true });\n cardLines.push({ text: ``, fg: t.textDim });\n cardLines.push({ text: ` Cdoing includes free models`, fg: t.textMuted });\n cardLines.push({ text: ` so you can start immediately.`, fg: t.textMuted });\n cardLines.push({ text: ``, fg: t.textDim });\n cardLines.push({ text: ` Connect from 75+ providers to`, fg: t.textMuted });\n cardLines.push({ text: ` use other models, including`, fg: t.textMuted });\n cardLines.push({ text: ` Claude, GPT, Gemini etc`, fg: t.textMuted });\n cardLines.push({ text: ``, fg: t.textDim });\n cardLines.push({ text: ` Connect provider /setup`, fg: t.text, bold: true });\n\n return (\n <box width={W + 2} flexDirection=\"column\" backgroundColor={t.bgSubtle}>\n <box flexDirection=\"column\" flexGrow={1}>\n {lines.map((line, i) => (\n <box key={i} height={1}>\n <text\n fg={line.fg}\n attributes={line.bold ? TextAttributes.BOLD : undefined}\n >\n {line.text}\n </text>\n </box>\n ))}\n {/* Fill remaining space */}\n <box flexGrow={1}>\n <text fg={t.border}>{\"\u2502\"}</text>\n </box>\n {/* Getting started card at bottom */}\n <box flexDirection=\"column\" paddingX={1}>\n <box height={1}>\n <text fg={t.border}>{\"\u250C\" + \"\u2500\".repeat(cardW) + \"\u2510\"}</text>\n </box>\n {cardLines.map((cl, i) => (\n <box key={`card-${i}`} height={1}>\n <text fg={t.border}>{\"\u2502\"}</text>\n <text fg={cl.fg} attributes={cl.bold ? TextAttributes.BOLD : undefined}>\n {cl.text.padEnd(cardW)}\n </text>\n <text fg={t.border}>{\"\u2502\"}</text>\n </box>\n ))}\n <box height={1}>\n <text fg={t.border}>{\"\u2514\" + \"\u2500\".repeat(cardW) + \"\u2518\"}</text>\n </box>\n </box>\n {/* Working dir + version footer */}\n <box height={1} paddingX={1}>\n <text fg={t.textDim}>\n {trunc((() => {\n const home = process.env.HOME || \"\";\n return home && props.workingDir.startsWith(home)\n ? \"~\" + props.workingDir.slice(home.length) : props.workingDir;\n })(), W - 2)}\n </text>\n </box>\n <box height={1} paddingX={1}>\n <text fg={t.success}>{\"\u25CF \"}</text>\n <text fg={t.text} attributes={TextAttributes.BOLD}>{\"Cdoing\"}</text>\n <text fg={t.textDim}>{\" Agent\"}</text>\n </box>\n </box>\n </box>\n );\n}\n", "/**\n * DialogModel \u2014 model picker dialog (Ctrl+O)\n *\n * Uses OpenTUI <select> for the model list with proper\n * highlight styling and keyboard navigation.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport type { SelectOption } from \"@opentui/core\";\nimport { useState, useMemo } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { getProviders } from \"@cdoing/ai\";\n\nexport interface ModelOption {\n id: string;\n name: string;\n hint?: string;\n}\n\n// Build model map from centralized catalog\nconst MODELS: Record<string, ModelOption[]> = {};\nfor (const p of getProviders() as Array<{ id: string; models: Array<{ id: string; label: string; hint?: string }> }>) {\n MODELS[p.id] = p.models.map((m) => ({ id: m.id, name: m.label, hint: m.hint }));\n}\n\nexport function DialogModel(props: {\n provider: string;\n currentModel: string;\n onSelect: (model: string) => void;\n onClose: () => void;\n}) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n const models = MODELS[props.provider] || [];\n const [isCustom, setIsCustom] = useState(false);\n const [customInput, setCustomInput] = useState(\"\");\n\n // Build SelectOption list: models + \"Custom model...\" at the end\n const selectOptions: SelectOption[] = useMemo(() => {\n const opts: SelectOption[] = models.map((m) => ({\n name: m.name,\n description: [\n m.hint || \"\",\n m.id === props.currentModel ? \"\u25CF current\" : \"\",\n ].filter(Boolean).join(\" \"),\n value: m.id,\n }));\n opts.push({\n name: \"Custom model...\",\n description: \"type any model name\",\n value: \"__custom__\",\n });\n return opts;\n }, [models, props.currentModel]);\n\n const initialIndex = Math.max(0, models.findIndex((m) => m.id === props.currentModel));\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || (key.ctrl && key.name === \"c\")) {\n if (isCustom) { setIsCustom(false); return; }\n props.onClose();\n return;\n }\n if (!isCustom) return; // Let <select> handle navigation\n // Custom model text input mode\n if (key.name === \"return\") {\n const m = customInput.trim();\n if (m) props.onSelect(m);\n } else if (key.name === \"backspace\") {\n setCustomInput((s) => s.slice(0, -1));\n } else if (key.ctrl && key.name === \"u\") {\n setCustomInput(\"\");\n } else if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setCustomInput((s) => s + key.sequence);\n }\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top={Math.max(2, Math.floor((dims.height || 24) * 0.25))}\n left={Math.max(1, Math.floor(((dims.width || 80) - Math.min(60, (dims.width || 80) - 4)) / 2))}\n width={Math.min(60, (dims.width || 80) - 4)}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Select Model\"}\n </text>\n <text fg={t.textDim}>{` Provider: ${props.provider}`}</text>\n <text>{\"\"}</text>\n {isCustom ? (\n <>\n <text fg={t.text}>{\" Enter custom model ID:\"}</text>\n <box flexDirection=\"row\">\n <text fg={t.primary}>{\" > \"}</text>\n <text fg={t.text}>{customInput}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </box>\n <text>{\"\"}</text>\n <text fg={t.textDim}>{\" Enter Confirm Ctrl+U Clear Esc Back\"}</text>\n </>\n ) : (\n <>\n <select\n options={selectOptions}\n focused={!isCustom}\n selectedIndex={initialIndex}\n height={Math.min(selectOptions.length, 10)}\n showDescription={true}\n backgroundColor={customBg || undefined}\n focusedBackgroundColor={customBg || undefined}\n textColor={t.text}\n focusedTextColor={t.text}\n selectedBackgroundColor={t.primary}\n selectedTextColor={t.bg}\n descriptionColor={t.textDim}\n selectedDescriptionColor={t.bg}\n showScrollIndicator={selectOptions.length > 10}\n onSelect={(_index: number, option: SelectOption | null) => {\n if (!option) return;\n if (option.value === \"__custom__\") {\n setIsCustom(true);\n setCustomInput(\"\");\n } else {\n props.onSelect(option.value);\n }\n }}\n />\n <text>{\"\"}</text>\n <text fg={t.textDim}>{\" \u2191\u2193 Navigate Enter Select Esc Close\"}</text>\n </>\n )}\n </box>\n );\n}\n", "/**\n * DialogCommand \u2014 command palette (Ctrl+P)\n *\n * Full command palette with categories, fuzzy search, shortcuts,\n * and keyboard navigation. Inspired by OpenCode's command palette.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport type { SelectOption } from \"@opentui/core\";\nimport { useState, useMemo } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\n// \u2500\u2500 Command Definition \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Command {\n id: string;\n label: string;\n shortcut?: string;\n category: string;\n icon?: string;\n}\n\nconst COMMANDS: Command[] = [\n // Session\n { id: \"session:new\", label: \"New Session\", shortcut: \"Ctrl+N\", category: \"Session\", icon: \"+\" },\n { id: \"session:browse\", label: \"Browse Sessions\", shortcut: \"Ctrl+S\", category: \"Session\", icon: \"\u25E6\" },\n { id: \"session:clear\", label: \"Clear History\", shortcut: \"\", category: \"Session\", icon: \"\u2715\" },\n\n // Model & Provider\n { id: \"model:switch\", label: \"Switch Model\", shortcut: \"Ctrl+O\", category: \"Model\", icon: \"\u25C6\" },\n { id: \"model:provider\", label: \"Switch Provider\", shortcut: \"\", category: \"Model\", icon: \"\u25C6\" },\n\n // Theme & Appearance\n { id: \"theme:picker\", label: \"Browse Themes\", shortcut: \"Ctrl+T\", category: \"Appearance\", icon: \"\u25C8\" },\n { id: \"theme:dark\", label: \"Dark Mode\", shortcut: \"\", category: \"Appearance\", icon: \"\u25CF\" },\n { id: \"theme:light\", label: \"Light Mode\", shortcut: \"\", category: \"Appearance\", icon: \"\u25CB\" },\n { id: \"display:sidebar\", label: \"Toggle Sidebar\", shortcut: \"Ctrl+B\", category: \"Appearance\", icon: \"\u2590\" },\n\n // Tools\n { id: \"tool:shell\", label: \"Run Shell Command\", shortcut: \"\", category: \"Tools\", icon: \"$\" },\n { id: \"tool:search\", label: \"Search Codebase\", shortcut: \"\", category: \"Tools\", icon: \"?\" },\n { id: \"tool:tree\", label: \"File Tree\", shortcut: \"\", category: \"Tools\", icon: \"\u251C\" },\n\n // System\n { id: \"system:status\", label: \"System Status\", shortcut: \"\", category: \"System\", icon: \"i\" },\n { id: \"system:help\", label: \"Help\", shortcut: \"F1\", category: \"System\", icon: \"?\" },\n { id: \"system:doctor\", label: \"Doctor (Diagnostics)\", shortcut: \"\", category: \"System\", icon: \"+\" },\n { id: \"system:setup\", label: \"Setup Wizard (Connect Provider)\", shortcut: \"\", category: \"System\", icon: \"\u2699\" },\n { id: \"system:exit\", label: \"Exit\", shortcut: \"Ctrl+C\", category: \"System\", icon: \"\u23FB\" },\n];\n\n// \u2500\u2500 Fuzzy Match \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction fuzzyMatch(query: string, text: string): boolean {\n if (!query) return true;\n const lower = text.toLowerCase();\n const q = query.toLowerCase();\n let qi = 0;\n for (let i = 0; i < lower.length && qi < q.length; i++) {\n if (lower[i] === q[qi]) qi++;\n }\n return qi === q.length;\n}\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function DialogCommand(props: {\n onSelect: (commandId: string) => void;\n onClose: () => void;\n}) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n const [query, setQuery] = useState(\"\");\n\n const dialogWidth = Math.min(64, (dims.width || 80) - 4);\n const maxVisible = Math.max(8, Math.floor((dims.height || 24) * 0.6));\n\n // Filter commands by fuzzy search across label, category, and id\n const filtered = useMemo(() => {\n return COMMANDS.filter(\n (cmd) =>\n fuzzyMatch(query, cmd.label) ||\n fuzzyMatch(query, cmd.category) ||\n fuzzyMatch(query, cmd.id)\n );\n }, [query]);\n\n // Group by category for display (with separators)\n const selectOptions: SelectOption[] = useMemo(() => {\n const opts: SelectOption[] = [];\n let lastCategory = \"\";\n for (const cmd of filtered) {\n if (cmd.category !== lastCategory) {\n lastCategory = cmd.category;\n }\n const shortcutStr = cmd.shortcut || \"\";\n opts.push({\n name: `${cmd.icon || \" \"} ${cmd.label}`,\n description: [cmd.category, shortcutStr].filter(Boolean).join(\" \"),\n value: cmd.id,\n });\n }\n return opts;\n }, [filtered]);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || (key.ctrl && key.name === \"p\")) {\n props.onClose();\n return;\n }\n\n // Let <select> handle up/down/return\n if (key.name === \"up\" || key.name === \"down\" || key.name === \"return\") return;\n\n // Backspace \u2014 search\n if (key.name === \"backspace\") {\n setQuery((q) => q.slice(0, -1));\n return;\n }\n\n // Ctrl+U \u2014 clear search\n if (key.ctrl && key.name === \"u\") {\n setQuery(\"\");\n return;\n }\n\n // Printable character \u2014 append to query\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setQuery((q) => q + key.sequence);\n }\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={1}\n paddingY={0}\n flexDirection=\"column\"\n position=\"absolute\"\n top={Math.max(1, Math.floor((dims.height || 24) * 0.1))}\n left={Math.max(1, Math.floor(((dims.width || 80) - dialogWidth) / 2))}\n width={dialogWidth}\n >\n {/* Title bar */}\n <box flexDirection=\"row\" flexShrink={0} height={1}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {\" Commands\"}\n </text>\n <text fg={t.textDim}>{\"Ctrl+P \"}</text>\n </box>\n\n {/* Search input */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(dialogWidth - 4)}</text>\n </box>\n <box flexDirection=\"row\" flexShrink={0} height={1}>\n <text fg={t.textMuted}>{\" > \"}</text>\n <text fg={t.text}>{query || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"\u2588\"}</text>\n </box>\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(dialogWidth - 4)}</text>\n </box>\n\n {/* Command list */}\n {selectOptions.length > 0 ? (\n <select\n options={selectOptions}\n focused={true}\n height={Math.min(maxVisible, selectOptions.length)}\n showDescription={true}\n backgroundColor={customBg || undefined}\n focusedBackgroundColor={customBg || undefined}\n textColor={t.text}\n focusedTextColor={t.text}\n selectedBackgroundColor={t.primary}\n selectedTextColor={t.bg}\n descriptionColor={t.textDim}\n selectedDescriptionColor={t.bg}\n showScrollIndicator={selectOptions.length > maxVisible}\n onSelect={(_index: number, option: SelectOption | null) => {\n if (option?.value) props.onSelect(option.value);\n }}\n />\n ) : (\n <box height={1}>\n <text fg={t.textDim}>{\" No matching commands\"}</text>\n </box>\n )}\n\n {/* Footer */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(dialogWidth - 4)}</text>\n </box>\n <box flexDirection=\"row\" height={1} flexShrink={0}>\n <text fg={t.textDim}>{\" \u2191\u2193 navigate \"}</text>\n <text fg={t.textDim}>{\"enter select \"}</text>\n <text fg={t.textDim}>{\"type to filter \"}</text>\n <text fg={t.textDim}>{\"esc close\"}</text>\n </box>\n </box>\n );\n}\n", "/**\n * DialogHelp \u2014 help dialog showing keyboard shortcuts, slash commands, and @mentions\n *\n * Uses native <scrollbox> for smooth scrolling. Close with Esc or q.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\n\n// \u2500\u2500 Content Sections \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface HelpEntry {\n key: string;\n description: string;\n}\n\nconst KEYBOARD_SHORTCUTS: HelpEntry[] = [\n { key: \"Ctrl+P\", description: \"Command palette\" },\n { key: \"Ctrl+O\", description: \"Switch model\" },\n { key: \"Ctrl+N\", description: \"New session\" },\n { key: \"Ctrl+S\", description: \"Browse sessions\" },\n { key: \"F1\", description: \"Show this help\" },\n { key: \"Ctrl+V\", description: \"Paste text or image\" },\n { key: \"Ctrl+U\", description: \"Clear input line\" },\n { key: \"Ctrl+W\", description: \"Delete last word\" },\n { key: \"Tab\", description: \"Switch mode (Build / Plan)\" },\n { key: \"\u2192 (Right)\", description: \"Accept autocomplete\" },\n { key: \"Up / Down\", description: \"Navigate suggestions\" },\n { key: \"Escape\", description: \"Close dialog / dropdown\" },\n { key: \"Ctrl+C\", description: \"Quit\" },\n];\n\nconst SLASH_COMMANDS: HelpEntry[] = [\n { key: \"/help\", description: \"Show help\" },\n { key: \"/clear\", description: \"Clear chat history\" },\n { key: \"/new\", description: \"Start new conversation\" },\n { key: \"/compact\", description: \"Compress context window\" },\n { key: \"/btw <question>\", description: \"Ask without adding to history\" },\n { key: \"/model [name]\", description: \"Show/change model\" },\n { key: \"/provider [name]\", description: \"Show/change provider\" },\n { key: \"/mode\", description: \"Show permission mode\" },\n { key: \"/dir [path]\", description: \"Show/change working directory\" },\n { key: \"/config\", description: \"Show configuration\" },\n { key: \"/config set k v\", description: \"Set a config value\" },\n { key: \"/theme <mode>\", description: \"Switch theme (dark/light/auto)\" },\n { key: \"/effort <level>\", description: \"Set effort level\" },\n { key: \"/plan <on|off>\", description: \"Toggle plan mode\" },\n { key: \"/history\", description: \"List saved conversations\" },\n { key: \"/resume <id>\", description: \"Resume conversation\" },\n { key: \"/view <id>\", description: \"View conversation messages\" },\n { key: \"/fork [id]\", description: \"Fork conversation\" },\n { key: \"/delete <id>\", description: \"Delete conversation\" },\n { key: \"/bg <prompt>\", description: \"Run prompt in background\" },\n { key: \"/jobs [id]\", description: \"List/inspect background jobs\" },\n { key: \"/permissions\", description: \"Show permission rules\" },\n { key: \"/hooks\", description: \"Show configured hooks\" },\n { key: \"/rules\", description: \"Show project rules\" },\n { key: \"/context\", description: \"Show context providers\" },\n { key: \"/mcp\", description: \"MCP server management\" },\n { key: \"/doctor\", description: \"System health check\" },\n { key: \"/usage\", description: \"Show token usage\" },\n { key: \"/auth-status\", description: \"Show authentication status\" },\n { key: \"/setup\", description: \"Run setup wizard\" },\n { key: \"/login\", description: \"Open setup wizard\" },\n { key: \"/logout\", description: \"Clear OAuth tokens\" },\n { key: \"/init\", description: \"Initialize project config\" },\n { key: \"/exit\", description: \"Quit\" },\n];\n\nconst AT_MENTIONS: HelpEntry[] = [\n { key: \"@terminal\", description: \"Recent terminal output\" },\n { key: \"@url\", description: \"Fetch URL content\" },\n { key: \"@tree\", description: \"Directory tree\" },\n { key: \"@codebase\", description: \"Search codebase\" },\n { key: \"@clip\", description: \"Clipboard contents\" },\n { key: \"@file\", description: \"Include file\" },\n];\n\nconst keyColWidth = 20;\n\nfunction Section(props: { title: string; entries: HelpEntry[]; theme: any }) {\n const t = props.theme;\n return (\n <box flexDirection=\"column\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {` ${props.title}`}\n </text>\n <text>{\"\"}</text>\n {props.entries.map((entry) => (\n <box key={entry.key} flexDirection=\"row\">\n <text fg={t.secondary}>{` ${entry.key.padEnd(keyColWidth)}`}</text>\n <text fg={t.textMuted}>{entry.description}</text>\n </box>\n ))}\n <text>{\"\"}</text>\n </box>\n );\n}\n\n// \u2500\u2500 Component \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function DialogHelp(props: {\n onClose: () => void;\n}) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n const dialogWidth = Math.min(70, (dims.width || 80) - 4);\n const dialogHeight = Math.max(10, (dims.height || 24) - 6);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || key.name === \"q\") {\n props.onClose();\n }\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top={Math.max(1, Math.floor((dims.height || 24) * 0.05))}\n left={Math.max(1, Math.floor(((dims.width || 80) - dialogWidth) / 2))}\n width={dialogWidth}\n height={dialogHeight}\n >\n {/* Title bar */}\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {\" Help\"}\n </text>\n <text fg={t.textDim}>{\"esc\"}</text>\n </box>\n <text flexShrink={0}>{\"\"}</text>\n\n {/* Scrollable content */}\n <scrollbox flexGrow={1}>\n <box flexShrink={0}>\n <Section title=\"Keyboard Shortcuts\" entries={KEYBOARD_SHORTCUTS} theme={t} />\n <Section title=\"Slash Commands\" entries={SLASH_COMMANDS} theme={t} />\n <Section title=\"@Mentions\" entries={AT_MENTIONS} theme={t} />\n </box>\n </scrollbox>\n </box>\n );\n}\n", "/**\n * DialogTheme \u2014 theme picker dialog (Ctrl+T)\n *\n * Three sections navigable with Tab:\n * 1. Appearance \u2014 Dark / Light mode toggle\n * 2. Color Themes \u2014 search + browse built-in themes\n * 3. Custom Background \u2014 optional hex override (cleared when a theme is selected)\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport type { SelectOption } from \"@opentui/core\";\nimport { useState, useMemo } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme, THEMES, getThemeIds } from \"../context/theme\";\n\ntype Section = \"mode\" | \"themes\" | \"custombg\";\nconst SECTIONS: Section[] = [\"mode\", \"themes\", \"custombg\"];\n\n/** Preset background colors with names for autocomplete */\nconst BG_PRESETS: Array<{ hex: string; name: string }> = [\n { hex: \"#000000\", name: \"Black\" },\n { hex: \"#0a0a0a\", name: \"AMOLED Black\" },\n { hex: \"#0d1117\", name: \"GitHub Dark\" },\n { hex: \"#1a1b26\", name: \"Tokyo Night\" },\n { hex: \"#1e1e2e\", name: \"Catppuccin\" },\n { hex: \"#191724\", name: \"Ros\u00E9 Pine\" },\n { hex: \"#282828\", name: \"Gruvbox\" },\n { hex: \"#282a36\", name: \"Dracula\" },\n { hex: \"#263238\", name: \"Material\" },\n { hex: \"#262335\", name: \"Synthwave\" },\n { hex: \"#272822\", name: \"Monokai\" },\n { hex: \"#2d353b\", name: \"Everforest\" },\n { hex: \"#2e3440\", name: \"Nord\" },\n { hex: \"#002b36\", name: \"Solarized Dark\" },\n { hex: \"#193549\", name: \"Cobalt2\" },\n { hex: \"#032424\", name: \"Dark Teal\" },\n { hex: \"#1a1a2e\", name: \"Midnight Blue\" },\n { hex: \"#0f0f23\", name: \"Deep Space\" },\n { hex: \"#1b2838\", name: \"Steam\" },\n { hex: \"#2b2b2b\", name: \"VS Code Dark\" },\n { hex: \"#fdf6e3\", name: \"Solarized Light\" },\n { hex: \"#ffffff\", name: \"White\" },\n { hex: \"#f5f5f5\", name: \"Light Gray\" },\n { hex: \"#eff1f5\", name: \"Catppuccin Latte\" },\n];\n\n/** Convert BG_PRESETS to SelectOption format */\nconst BG_SELECT_OPTIONS: SelectOption[] = BG_PRESETS.map((p) => ({\n name: `${p.hex} ${p.name}`,\n description: \"\",\n value: p.hex,\n}));\n\nexport function DialogTheme(props: {\n onClose: () => void;\n}) {\n const { theme, themeId, mode, customBg, setThemeId, setMode, setCustomBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n\n const initialThemeId = themeId;\n const initialMode = mode;\n const initialCustomBg = customBg;\n const themeIds = getThemeIds();\n\n const [section, setSection] = useState<Section>(\"mode\");\n const [bgInput, setBgInput] = useState(customBg || \"\");\n const [query, setQuery] = useState(\"\");\n\n // Mode select options\n const modeOptions: SelectOption[] = useMemo(() => [\n { name: \"Dark Mode\", description: mode === \"dark\" ? \"active\" : \"\", value: \"dark\" },\n { name: \"Light Mode\", description: mode === \"light\" ? \"active\" : \"\", value: \"light\" },\n ], [mode]);\n\n // Filtered BG presets based on input\n const filteredBgOptions: SelectOption[] = useMemo(() => {\n if (!bgInput) return BG_SELECT_OPTIONS;\n const q = bgInput.toLowerCase();\n return BG_SELECT_OPTIONS.filter((o) =>\n o.value.toLowerCase().startsWith(q) ||\n o.name.toLowerCase().includes(q)\n );\n }, [bgInput]);\n\n // Filtered theme options\n const filteredThemeOptions: SelectOption[] = useMemo(() => {\n const ids = query\n ? themeIds.filter((id) => {\n const def = THEMES[id];\n const q = query.toLowerCase();\n return id.toLowerCase().includes(q) || def.name.toLowerCase().includes(q);\n })\n : themeIds;\n return ids.map((id) => {\n const def = THEMES[id];\n return {\n name: def.name,\n description: id === themeId ? \"* current\" : id,\n value: id,\n };\n });\n }, [query, themeIds, themeId]);\n\n const nextSection = () => {\n setSection((s) => {\n const idx = SECTIONS.indexOf(s);\n return SECTIONS[(idx + 1) % SECTIONS.length];\n });\n };\n\n const isValidHex = (s: string): boolean => /^#[0-9a-fA-F]{6}$/.test(s);\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\") {\n setThemeId(initialThemeId);\n setMode(initialMode);\n setCustomBg(initialCustomBg);\n props.onClose();\n return;\n }\n\n if (key.name === \"tab\") {\n nextSection();\n return;\n }\n\n // \u2500\u2500 Custom BG text input \u2500\u2500\n if (section === \"custombg\") {\n // Don't capture up/down/return (let <select> handle those)\n if (key.name === \"up\" || key.name === \"down\" || key.name === \"return\") return;\n if (key.name === \"backspace\") {\n setBgInput((s) => s.slice(0, -1));\n return;\n }\n if (key.ctrl && key.name === \"u\") {\n setBgInput(\"\");\n setCustomBg(null);\n return;\n }\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setBgInput((s) => {\n const next = s + key.sequence;\n if (isValidHex(next)) setCustomBg(next);\n return next;\n });\n return;\n }\n return;\n }\n\n // \u2500\u2500 Themes search input \u2500\u2500\n if (section === \"themes\") {\n // Don't capture up/down/return (let <select> handle those)\n if (key.name === \"up\" || key.name === \"down\" || key.name === \"return\") return;\n if (key.name === \"backspace\") {\n setQuery((q) => q.slice(0, -1));\n return;\n }\n if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {\n setQuery((q) => q + key.sequence);\n return;\n }\n return;\n }\n\n // Mode section: let <select> handle everything\n });\n\n const dialogWidth = Math.min(60, (dims.width || 80) - 4);\n const selectHeight = Math.max(3, Math.floor((dims.height || 24) * 0.2));\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n backgroundColor={t.bg}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top={Math.max(1, Math.floor((dims.height || 24) * 0.1))}\n left={Math.max(1, Math.floor(((dims.width || 80) - dialogWidth) / 2))}\n width={dialogWidth}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\" Themes\"}\n </text>\n <text fg={t.textDim}>\n {` Mode: ${mode} \u2022 ${filteredThemeOptions.length} themes${customBg ? ` \u2022 BG: ${customBg}` : \"\"}`}\n </text>\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 1. Appearance \u2500\u2500 */}\n <text\n fg={section === \"mode\" ? t.primary : t.textDim}\n attributes={section === \"mode\" ? TextAttributes.BOLD : undefined}\n >\n {\" Appearance\"}\n </text>\n <select\n options={modeOptions}\n focused={section === \"mode\"}\n selectedIndex={mode === \"dark\" ? 0 : 1}\n height={2}\n showDescription={false}\n backgroundColor={customBg || undefined}\n focusedBackgroundColor={customBg || undefined}\n textColor={t.textMuted}\n focusedTextColor={t.text}\n selectedBackgroundColor={t.primary}\n selectedTextColor={t.bg}\n onSelect={(_index: number, option: SelectOption | null) => {\n if (option?.value) {\n setMode(option.value as \"dark\" | \"light\");\n nextSection();\n }\n }}\n />\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 2. Color Themes \u2500\u2500 */}\n <text\n fg={section === \"themes\" ? t.primary : t.textDim}\n attributes={section === \"themes\" ? TextAttributes.BOLD : undefined}\n >\n {\" Color Themes\"}\n </text>\n {section === \"themes\" && (\n <box flexDirection=\"row\">\n <text fg={t.textMuted}>{\" Search: \"}</text>\n <text fg={t.text}>{query || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </box>\n )}\n <select\n options={filteredThemeOptions}\n focused={section === \"themes\"}\n height={selectHeight}\n showDescription={true}\n backgroundColor={customBg || undefined}\n focusedBackgroundColor={customBg || undefined}\n textColor={t.text}\n focusedTextColor={t.text}\n selectedBackgroundColor={t.primary}\n selectedTextColor={t.bg}\n descriptionColor={t.textDim}\n selectedDescriptionColor={t.bg}\n showScrollIndicator={filteredThemeOptions.length > selectHeight}\n onChange={(_index: number, option: SelectOption | null) => {\n if (option?.value) {\n setThemeId(option.value);\n // Clear custom bg so the theme's own bg applies\n setCustomBg(null);\n setBgInput(\"\");\n }\n }}\n onSelect={(_index: number, _option: SelectOption | null) => {\n props.onClose();\n }}\n />\n <text>{\"\"}</text>\n\n {/* \u2500\u2500 3. Custom Background (override) \u2500\u2500 */}\n <text\n fg={section === \"custombg\" ? t.primary : t.textDim}\n attributes={section === \"custombg\" ? TextAttributes.BOLD : undefined}\n >\n {\" Custom Background Override\"}\n </text>\n <box flexDirection=\"row\">\n <text fg={t.textMuted}>{\" Hex: \"}</text>\n {section === \"custombg\" ? (\n <>\n <text fg={isValidHex(bgInput) ? t.success : t.text}>{bgInput || \"\"}</text>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"_\"}</text>\n </>\n ) : (\n <text fg={customBg ? t.success : t.textDim}>{customBg || \"(using theme default)\"}</text>\n )}\n </box>\n {section === \"custombg\" && (\n <>\n <text fg={t.textDim}>{\" Type #hex, Ctrl+U clear, \u2191\u2193 presets, Enter apply\"}</text>\n <select\n options={filteredBgOptions}\n focused={section === \"custombg\"}\n height={Math.min(6, filteredBgOptions.length)}\n showDescription={false}\n backgroundColor={customBg || undefined}\n focusedBackgroundColor={customBg || undefined}\n textColor={t.textMuted}\n focusedTextColor={t.text}\n selectedBackgroundColor={t.primary}\n selectedTextColor={t.bg}\n showScrollIndicator={filteredBgOptions.length > 6}\n onChange={(_index: number, option: SelectOption | null) => {\n if (option?.value) {\n setBgInput(option.value);\n setCustomBg(option.value);\n }\n }}\n onSelect={(_index: number, option: SelectOption | null) => {\n if (option?.value) {\n setBgInput(option.value);\n setCustomBg(option.value);\n }\n props.onClose();\n }}\n />\n </>\n )}\n\n <text>{\"\"}</text>\n <text fg={t.textDim}>{\" Tab Section \u2191\u2193 Navigate Enter Select Esc Cancel\"}</text>\n </box>\n );\n}\n", "/**\n * SessionBrowser \u2014 Interactive TUI overlay for browsing saved conversations\n *\n * Features:\n * - Arrow keys to navigate\n * - Enter to resume a conversation\n * - d to delete, f to fork, v to view\n * - Escape to close\n * - Native <scrollbox> for smooth scrolling\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState } from \"react\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport {\n listConversations,\n deleteConversation,\n forkConversation,\n formatRelativeDate,\n type Conversation,\n} from \"../lib/history\";\n\nexport interface SessionBrowserProps {\n onResume: (conv: Conversation) => void;\n onClose: () => void;\n}\n\nexport function SessionBrowser(props: SessionBrowserProps) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const dims = useTerminalDimensions();\n\n const [conversations, setConversations] = useState(() => listConversations());\n const [selected, setSelected] = useState(0);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [viewMode, setViewMode] = useState(false);\n const [viewScroll, setViewScroll] = useState(0);\n\n const maxVisible = Math.max(5, Math.floor((dims.height || 20) - 10));\n\n useKeyboard((key: any) => {\n if (viewMode) {\n // View mode controls\n if (key.name === \"escape\" || key.name === \"q\") {\n setViewMode(false);\n setViewScroll(0);\n } else if (key.name === \"up\" || key.name === \"k\") {\n setViewScroll((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n const conv = conversations[selected];\n if (conv) {\n const msgs = conv.messages.filter((m) => m.role !== \"tool\");\n setViewScroll((s) => Math.min(msgs.length - 1, s + 1));\n }\n } else if (key.name === \"return\") {\n const conv = conversations[selected];\n if (conv) props.onResume(conv);\n }\n return;\n }\n\n if (confirmDelete) {\n if (key.name === \"y\") {\n const conv = conversations[selected];\n if (conv) {\n deleteConversation(conv.id);\n const updated = listConversations();\n setConversations(updated);\n setSelected((s) => Math.min(s, updated.length - 1));\n }\n setConfirmDelete(false);\n } else {\n setConfirmDelete(false);\n }\n return;\n }\n\n if (key.name === \"escape\" || key.name === \"q\") {\n props.onClose();\n } else if (key.name === \"up\" || key.name === \"k\") {\n setSelected((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelected((s) => Math.min(conversations.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const conv = conversations[selected];\n if (conv) props.onResume(conv);\n } else if (key.name === \"d\") {\n if (conversations.length > 0) setConfirmDelete(true);\n } else if (key.name === \"f\") {\n const conv = conversations[selected];\n if (conv) {\n const forked = forkConversation(conv);\n if (forked) {\n setConversations(listConversations());\n }\n }\n } else if (key.name === \"v\") {\n if (conversations.length > 0) {\n setViewMode(true);\n setViewScroll(0);\n }\n }\n });\n\n if (conversations.length === 0) {\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {\"Sessions\"}\n </text>\n <text fg={t.textDim}>{\"esc\"}</text>\n </box>\n <text fg={t.textDim}>{\"\\nNo saved conversations.\\n\"}</text>\n </box>\n );\n }\n\n // View mode \u2014 show messages from selected conversation\n if (viewMode) {\n const conv = conversations[selected];\n const msgs = conv ? conv.messages.filter((m) => m.role !== \"tool\") : [];\n const visibleMsgs = msgs.slice(viewScroll, viewScroll + maxVisible);\n const total = msgs.length;\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {`Viewing: ${conv?.title || \"Untitled\"}`}\n </text>\n <text fg={t.textDim}>{\"esc\"}</text>\n </box>\n <text fg={t.textDim} flexShrink={0}>\n {`${viewScroll + 1}\u2013${Math.min(viewScroll + maxVisible, total)} of ${total} messages`}\n </text>\n <text flexShrink={0}>{\"\"}</text>\n <scrollbox flexGrow={1}>\n <box flexShrink={0}>\n {visibleMsgs.map((m, i) => {\n const prefix = m.role === \"user\" ? \"\u276F\" : \"\u25C6\";\n const color = m.role === \"user\" ? t.success : t.text;\n const content = m.content.length > 120 ? m.content.substring(0, 117) + \"...\" : m.content;\n return (\n <text key={`view-${viewScroll + i}`} fg={color}>\n {` ${prefix} ${content.replace(/\\n/g, \" \")}`}\n </text>\n );\n })}\n </box>\n </scrollbox>\n <text flexShrink={0}>{\"\"}</text>\n <text fg={t.textMuted} flexShrink={0}>{\" \u2191\u2193 Scroll Enter Resume Esc Back\"}</text>\n </box>\n );\n }\n\n // List mode\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {\"Sessions\"}\n </text>\n <text fg={t.textDim}>{\"esc\"}</text>\n </box>\n <text fg={t.textDim} flexShrink={0}>\n {`${conversations.length} conversation${conversations.length !== 1 ? \"s\" : \"\"}`}\n </text>\n <text flexShrink={0}>{\"\"}</text>\n <scrollbox flexGrow={1}>\n <box flexShrink={0}>\n {conversations.map((conv, idx) => {\n const isSelected = idx === selected;\n const date = formatRelativeDate(conv.updatedAt);\n const msgCount = conv.messages.filter((m) => m.role === \"user\").length;\n const title = conv.title.length > 40 ? conv.title.substring(0, 37) + \"...\" : conv.title;\n\n return (\n <box key={conv.id} flexDirection=\"row\">\n <text\n fg={isSelected ? t.primary : t.textMuted}\n attributes={isSelected ? TextAttributes.BOLD : undefined}\n >\n {` ${isSelected ? \"\u276F\" : \" \"} ${title}`}\n </text>\n <text fg={t.textDim}>\n {` ${date} (${msgCount} msgs)`}\n </text>\n </box>\n );\n })}\n </box>\n </scrollbox>\n {confirmDelete && (\n <box flexShrink={0}>\n <text>{\"\"}</text>\n <text fg={t.warning} attributes={TextAttributes.BOLD}>\n {` Delete \"${conversations[selected]?.title}\"? (y/n)`}\n </text>\n </box>\n )}\n <text flexShrink={0}>{\"\"}</text>\n <text fg={t.textMuted} flexShrink={0}>{\" \u2191\u2193 Navigate Enter Resume v View d Delete f Fork Esc Close\"}</text>\n </box>\n );\n}\n", "/**\n * SetupWizard \u2014 Interactive setup overlay for configuring provider, model, API key, or OAuth\n *\n * Steps:\n * 1. Select provider\n * 2. Select auth method (API key or OAuth \u2014 Anthropic only)\n * 3. Select model\n * 4. Enter API key / OAuth code\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { execSync } from \"child_process\";\nimport { TextAttributes } from \"@opentui/core\";\nimport { useState, useRef, useEffect } from \"react\";\nimport { useKeyboard } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { getProviders } from \"@cdoing/ai\";\nimport { getOAuthProvider, supportsOAuth } from \"@cdoing/core\";\n\nexport interface SetupWizardProps {\n onComplete: (config: { provider: string; model: string; apiKey?: string; oauthToken?: string }) => void;\n onClose: () => void;\n}\n\n// \u2500\u2500 Data from centralized catalog \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst _catalog = getProviders();\n\nconst PROVIDERS = _catalog.map((p: { id: string; label: string; hint: string }) => ({\n id: p.id,\n name: p.label,\n hint: p.hint,\n}));\n\nconst AUTH_METHODS = [\n { id: \"apikey\", name: \"API Key\", hint: \"all models available - console.anthropic.com\" },\n { id: \"oauth\", name: \"OAuth\", hint: \"Claude Pro/Max - opens browser\" },\n];\n\n// All models per provider \u2014 from catalog\nconst MODELS: Record<string, { id: string; name: string; hint?: string }[]> = {};\nfor (const p of _catalog) {\n MODELS[p.id] = p.models.map((m: { id: string; label: string; hint?: string }) => ({ id: m.id, name: m.label, hint: m.hint }));\n}\n\n/** Get OAuth models for a provider from core config */\nfunction getOAuthModels(providerId: string) {\n const config = getOAuthProvider(providerId);\n if (!config?.models || config.models.length === 0) {\n return config?.defaultModel\n ? [{ id: config.defaultModel, name: config.defaultModel, hint: \"OAuth\" }]\n : [];\n }\n return config.models.map((m: { id: string; name: string; hint?: string }) => ({ id: m.id, name: m.name, hint: m.hint || \"OAuth\" }));\n}\n\nfunction providerSupportsOAuth(providerId: string): boolean {\n return supportsOAuth(providerId);\n}\n\n// Env vars and key URLs from catalog\nconst ENV_VARS: Record<string, string> = {};\nconst KEY_URLS: Record<string, string> = {};\nfor (const p of _catalog as Array<{ id: string; envVar?: string; keyUrl?: string }>) {\n if (p.envVar) ENV_VARS[p.id] = p.envVar;\n if (p.keyUrl) KEY_URLS[p.id] = p.keyUrl;\n}\n\ntype Step = \"provider\" | \"auth-method\" | \"model\" | \"apikey\" | \"oauth-paste\" | \"oauth-exchanging\";\n\nfunction readClipboard(): string {\n try {\n if (process.platform === \"darwin\") return execSync(\"pbpaste\", { encoding: \"utf-8\" });\n try { return execSync(\"xclip -selection clipboard -o\", { encoding: \"utf-8\" }); }\n catch { return execSync(\"xsel --clipboard --output\", { encoding: \"utf-8\" }); }\n } catch { return \"\"; }\n}\n\nfunction openBrowser(url: string): void {\n try {\n const cmd = process.platform === \"darwin\" ? `open \"${url}\"`\n : process.platform === \"win32\" ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`;\n execSync(cmd, { stdio: \"ignore\", timeout: 3000 });\n } catch { /* browser open is best-effort */ }\n}\n\nexport function SetupWizard(props: SetupWizardProps) {\n const { theme, customBg } = useTheme();\n const t = theme;\n\n const closedRef = useRef(false);\n const [closed, setClosed] = useState(false);\n const [step, setStep] = useState<Step>(\"provider\");\n const [selectedProvider, setSelectedProvider] = useState(0);\n const [selectedAuth, setSelectedAuth] = useState(0);\n const [selectedModel, setSelectedModel] = useState(0);\n const [authMethod, setAuthMethod] = useState<\"apikey\" | \"oauth\">(\"apikey\");\n const [chosenProviderId, setChosenProviderId] = useState(\"anthropic\");\n const [chosenModelId, setChosenModelId] = useState(\"\");\n const [apiKeyInput, setApiKeyInput] = useState(\"\");\n const [showKey, setShowKey] = useState(false);\n const [error, setError] = useState(\"\");\n // Custom model input\n const [customModelInput, setCustomModelInput] = useState(\"\");\n const [isCustomModel, setIsCustomModel] = useState(false);\n\n // OAuth state\n const [oauthUrl, setOauthUrl] = useState(\"\");\n const [oauthVerifier, setOauthVerifier] = useState(\"\");\n const [oauthCodeInput, setOauthCodeInput] = useState(\"\");\n const [showCode, setShowCode] = useState(false);\n const [oauthError, setOauthError] = useState(\"\");\n const exchangingRef = useRef(false);\n\n const provider = PROVIDERS[selectedProvider];\n const models = authMethod === \"oauth\" ? getOAuthModels(chosenProviderId) : (MODELS[chosenProviderId] || []);\n\n // Generate OAuth URL when entering oauth-paste step\n useEffect(() => {\n if (step !== \"oauth-paste\") return;\n try {\n const { generateOAuthUrl } = require(\"@cdoing/core\");\n const { url, codeVerifier } = generateOAuthUrl(chosenProviderId);\n setOauthUrl(url);\n setOauthVerifier(codeVerifier);\n setOauthCodeInput(\"\");\n setOauthError(\"\");\n openBrowser(url);\n } catch {\n setOauthError(\"OAuth not available. Install @cdoing/core with OAuth support.\");\n }\n }, [step, chosenProviderId]);\n\n useKeyboard((key: any) => {\n // If already closed, ignore keys\n if (closedRef.current) return;\n\n // Escape \u2014 close wizard (parent handles navigation to home)\n if (key.name === \"escape\") {\n closedRef.current = true;\n setClosed(true);\n props.onClose();\n return;\n }\n\n // Ctrl+C \u2014 close wizard\n if (key.ctrl && key.name === \"c\") {\n closedRef.current = true;\n setClosed(true);\n props.onClose();\n return;\n }\n\n // \u2500\u2500 Step 1: Provider \u2500\u2500\n if (step === \"provider\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedProvider((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedProvider((s) => Math.min(PROVIDERS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const p = PROVIDERS[selectedProvider];\n setChosenProviderId(p.id);\n setSelectedModel(0);\n if (providerSupportsOAuth(p.id)) {\n setSelectedAuth(0);\n setStep(\"auth-method\");\n } else {\n setAuthMethod(\"apikey\");\n setStep(\"model\");\n }\n }\n return;\n }\n\n // \u2500\u2500 Step 2: Auth method (any OAuth-capable provider) \u2500\u2500\n if (step === \"auth-method\") {\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedAuth((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedAuth((s) => Math.min(AUTH_METHODS.length - 1, s + 1));\n } else if (key.name === \"return\") {\n const auth = AUTH_METHODS[selectedAuth].id as \"apikey\" | \"oauth\";\n setAuthMethod(auth);\n setSelectedModel(0);\n setStep(\"model\");\n }\n return;\n }\n\n // \u2500\u2500 Step 3: Model (presets + custom input) \u2500\u2500\n if (step === \"model\") {\n // Custom model text input mode\n if (isCustomModel) {\n if (key.name === \"return\") {\n const m = customModelInput.trim();\n if (!m) return;\n setChosenModelId(m);\n if (chosenProviderId === \"ollama\") {\n saveAndComplete(chosenProviderId, m, undefined);\n } else if (authMethod === \"oauth\") {\n exchangingRef.current = false;\n setStep(\"oauth-paste\");\n } else {\n setStep(\"apikey\");\n setApiKeyInput(\"\");\n setError(\"\");\n }\n } else if ((key.ctrl || key.meta) && key.name === \"v\") {\n const clip = readClipboard().trim();\n if (clip) setCustomModelInput((s) => s + clip);\n } else if (key.name === \"backspace\") {\n setCustomModelInput((s) => s.slice(0, -1));\n } else if (key.ctrl && key.name === \"u\") {\n setCustomModelInput(\"\");\n } else if (key.sequence && !key.ctrl && !key.meta) {\n setCustomModelInput((s) => s + key.sequence);\n }\n return;\n }\n\n // Preset selection with \"Custom...\" at bottom\n const totalItems = models.length + 1;\n if (key.name === \"up\" || key.name === \"k\") {\n setSelectedModel((s) => Math.max(0, s - 1));\n } else if (key.name === \"down\" || key.name === \"j\") {\n setSelectedModel((s) => Math.min(totalItems - 1, s + 1));\n } else if (key.name === \"return\") {\n if (selectedModel === models.length) {\n // Selected \"Custom model...\"\n setIsCustomModel(true);\n setCustomModelInput(\"\");\n return;\n }\n const m = models[selectedModel];\n setChosenModelId(m.id);\n if (chosenProviderId === \"ollama\") {\n saveAndComplete(chosenProviderId, m.id, undefined);\n } else if (authMethod === \"oauth\") {\n exchangingRef.current = false;\n setStep(\"oauth-paste\");\n } else {\n setStep(\"apikey\");\n setApiKeyInput(\"\");\n setError(\"\");\n }\n }\n return;\n }\n\n // \u2500\u2500 Step 4a: API key \u2500\u2500\n if (step === \"apikey\") {\n if (key.name === \"return\") {\n if (!apiKeyInput.trim()) {\n setError(\"API key cannot be empty\");\n return;\n }\n saveAndComplete(chosenProviderId, chosenModelId, apiKeyInput.trim());\n } else if ((key.ctrl || key.meta) && key.name === \"v\") {\n const clip = readClipboard().trim();\n if (clip) { setApiKeyInput((s) => s + clip); setError(\"\"); }\n } else if (key.ctrl && key.name === \"s\") {\n setShowKey((s) => !s);\n } else if (key.name === \"backspace\") {\n setApiKeyInput((s) => s.slice(0, -1));\n setError(\"\");\n } else if (key.ctrl && key.name === \"u\") {\n setApiKeyInput(\"\");\n setError(\"\");\n } else if (key.sequence && !key.ctrl && !key.meta) {\n setApiKeyInput((s) => s + key.sequence);\n setError(\"\");\n }\n return;\n }\n\n // \u2500\u2500 Step 4b: OAuth code paste \u2500\u2500\n if (step === \"oauth-paste\") {\n if (key.name === \"return\") {\n const code = oauthCodeInput.trim();\n if (!code || exchangingRef.current) return;\n exchangingRef.current = true;\n setStep(\"oauth-exchanging\");\n try {\n const { exchangeOAuthCode } = require(\"@cdoing/core\");\n exchangeOAuthCode(code, oauthVerifier, chosenProviderId)\n .then((tokens: any) => {\n saveAndComplete(chosenProviderId, chosenModelId, undefined);\n props.onComplete({\n provider: chosenProviderId,\n model: chosenModelId,\n oauthToken: tokens.access_token,\n });\n })\n .catch((err: Error) => {\n exchangingRef.current = false;\n setOauthError(err.message);\n setStep(\"oauth-paste\");\n });\n } catch {\n exchangingRef.current = false;\n setOauthError(\"OAuth exchange failed\");\n setStep(\"oauth-paste\");\n }\n return;\n }\n if ((key.ctrl || key.meta) && key.name === \"v\") {\n const clip = readClipboard().trim();\n if (clip) { setOauthCodeInput((s) => s + clip); setOauthError(\"\"); }\n } else if (key.ctrl && key.name === \"s\") {\n setShowCode((s) => !s);\n } else if (key.name === \"backspace\") {\n setOauthCodeInput((s) => s.slice(0, -1));\n setOauthError(\"\");\n } else if (key.ctrl && key.name === \"u\") {\n setOauthCodeInput(\"\");\n setOauthError(\"\");\n } else if (key.sequence && !key.ctrl && !key.meta) {\n setOauthCodeInput((s) => s + key.sequence);\n setOauthError(\"\");\n }\n return;\n }\n });\n\n const saveAndComplete = (prov: string, model: string, apiKey?: string) => {\n const configDir = path.join(os.homedir(), \".cdoing\");\n const configPath = path.join(configDir, \"config.json\");\n\n let config: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n\n config.provider = prov;\n config.model = model;\n if (apiKey) {\n if (!config.apiKeys) config.apiKeys = {};\n config.apiKeys[prov] = apiKey;\n }\n\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n props.onComplete({ provider: prov, model, apiKey });\n };\n\n // Step numbers for display\n const isAnthropic = chosenProviderId === \"anthropic\";\n const total = isAnthropic ? 4 : chosenProviderId === \"ollama\" ? 2 : 3;\n const stepLabel = (s: Step): string => {\n switch (s) {\n case \"provider\": return `1/${total}`;\n case \"auth-method\": return \"2/4\";\n case \"model\": return isAnthropic ? \"3/4\" : chosenProviderId === \"ollama\" ? \"2/2\" : \"2/3\";\n case \"apikey\": return isAnthropic ? \"4/4\" : \"3/3\";\n case \"oauth-paste\": return \"4/4\";\n case \"oauth-exchanging\": return \"4/4\";\n default: return \"\";\n }\n };\n\n // Workaround: OpenTUI doesn't re-render parent on setDialog(\"none\"),\n // so we hide the wizard internally when closed\n if (closed) return <box><text>{\"\"}</text></box>;\n\n return (\n <box\n borderStyle=\"single\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={2}\n paddingY={1}\n flexDirection=\"column\"\n flexGrow={1}\n >\n <text fg={t.primary} attributes={TextAttributes.BOLD}>\n {\"Setup Wizard\"}\n </text>\n <text>{\"\"}</text>\n\n {/* Step 1: Provider */}\n {step === \"provider\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"provider\")}: Select Provider`}\n </text>\n <text>{\"\"}</text>\n {PROVIDERS.map((p: { id: string; name: string; hint: string }, i: number) => (\n <text\n key={p.id}\n fg={selectedProvider === i ? t.primary : t.textMuted}\n attributes={selectedProvider === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedProvider === i ? \">\" : \" \"} ${p.name} ${selectedProvider === i ? p.hint : \"\"}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Cancel\"}</text>\n </box>\n )}\n\n {/* Step 2: Auth method (Anthropic only) */}\n {step === \"auth-method\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"auth-method\")}: How do you want to authenticate?`}\n </text>\n <text>{\"\"}</text>\n {AUTH_METHODS.map((a, i) => (\n <text\n key={a.id}\n fg={selectedAuth === i ? t.primary : t.textMuted}\n attributes={selectedAuth === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedAuth === i ? \">\" : \" \"} ${a.name} ${selectedAuth === i ? a.hint : \"\"}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 3: Model */}\n {step === \"model\" && !isCustomModel && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {authMethod === \"oauth\"\n ? `Step ${stepLabel(\"model\")}: Select Model (OAuth \u2014 ${provider.name})`\n : `Step ${stepLabel(\"model\")}: Select Model (${provider.name})`}\n </text>\n <text>{\"\"}</text>\n {models.map((m: { id: string; name: string; hint?: string }, i: number) => (\n <text\n key={m.id}\n fg={selectedModel === i ? t.primary : t.textMuted}\n attributes={selectedModel === i ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedModel === i ? \">\" : \" \"} ${m.name}${m.hint ? ` ${m.hint}` : \"\"}`}\n </text>\n ))}\n <text\n fg={selectedModel === models.length ? t.primary : t.textMuted}\n attributes={selectedModel === models.length ? TextAttributes.BOLD : undefined}\n >\n {` ${selectedModel === models.length ? \">\" : \" \"} Custom model... type any model name`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Up/Down Navigate Enter Select Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 3b: Custom model input */}\n {step === \"model\" && isCustomModel && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"model\")}: Custom Model (${provider.name})`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.text}>\n {` > ${customModelInput}|`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Type model ID then Enter Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 4a: API key */}\n {step === \"apikey\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"apikey\")}: Enter API Key`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textDim}>\n {` Provider: ${chosenProviderId} Model: ${chosenModelId}`}\n </text>\n {KEY_URLS[chosenProviderId] && (\n <text fg={t.textDim}>\n {` Get a key: ${KEY_URLS[chosenProviderId]}`}\n </text>\n )}\n <text fg={t.textDim}>\n {` Environment variable: ${ENV_VARS[chosenProviderId] || \"N/A\"}`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.text}>\n {` > ${showKey ? apiKeyInput : apiKeyInput.replace(/./g, \"*\")}|`}\n </text>\n {error && (\n <text fg={t.error}>{`\\n ${error}`}</text>\n )}\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Enter Save Ctrl+V Paste Ctrl+S Toggle visibility Ctrl+U Clear Esc Back\"}</text>\n </box>\n )}\n\n {/* Step 4b: OAuth paste */}\n {step === \"oauth-paste\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"oauth-paste\")}: OAuth Login`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.text}>{\" 1. Browser opening to Claude login...\"}</text>\n {oauthUrl ? (\n <text fg={t.textDim}>{` If it didn't open: ${oauthUrl.substring(0, 70)}...`}</text>\n ) : null}\n <text fg={t.text}>{\" 2. Approve -> you'll land on a page with a code in the URL\"}</text>\n <text fg={t.text}>{\" 3. Copy the code= value from the URL and paste below\"}</text>\n {oauthError ? (\n <>\n <text>{\"\"}</text>\n <text fg={t.error}>{` Error: ${oauthError}`}</text>\n </>\n ) : null}\n <text>{\"\"}</text>\n <text fg={t.text}>\n {` Code: ${showCode ? oauthCodeInput : oauthCodeInput.replace(/./g, \"*\")}|`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.textMuted}>{\" Ctrl+V Paste Enter Submit Ctrl+S Toggle visible Esc Cancel\"}</text>\n </box>\n )}\n\n {/* Step 4b: OAuth exchanging */}\n {step === \"oauth-exchanging\" && (\n <box flexDirection=\"column\">\n <text fg={t.text} attributes={TextAttributes.BOLD}>\n {`Step ${stepLabel(\"oauth-exchanging\")}: OAuth Login`}\n </text>\n <text>{\"\"}</text>\n <text fg={t.warning}>{\" Exchanging code for tokens...\"}</text>\n </box>\n )}\n </box>\n );\n}\n", "/**\n * DialogStatus \u2014 system status dialog showing provider, tools, config info.\n * Uses native <scrollbox> for smooth scrolling through sections.\n */\n\nimport { TextAttributes } from \"@opentui/core\";\nimport { useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { useTheme } from \"../context/theme\";\nimport { useSDK } from \"../context/sdk\";\n\nexport function DialogStatus(props: { onClose: () => void }) {\n const { theme, customBg } = useTheme();\n const t = theme;\n const sdk = useSDK();\n const dims = useTerminalDimensions();\n\n const dialogWidth = Math.min(60, (dims.width || 80) - 4);\n const dialogHeight = Math.max(10, (dims.height || 24) - 6);\n\n // Gather status info\n const allTools = sdk.registry.getAll ? sdk.registry.getAll() : [];\n const toolNames = Array.isArray(allTools)\n ? allTools.map((tool: any) =>\n tool.definition?.name || tool.name || \"unknown\"\n )\n : [];\n\n useKeyboard((key: any) => {\n if (key.name === \"escape\" || key.name === \"q\") props.onClose();\n });\n\n return (\n <box\n borderStyle=\"double\"\n borderColor={t.primary}\n backgroundColor={customBg || t.bg}\n paddingX={1}\n paddingY={1}\n flexDirection=\"column\"\n position=\"absolute\"\n top={Math.max(1, Math.floor((dims.height || 24) * 0.1))}\n left={Math.max(1, Math.floor(((dims.width || 80) - dialogWidth) / 2))}\n width={dialogWidth}\n height={dialogHeight}\n >\n {/* Title bar */}\n <box flexDirection=\"row\" flexShrink={0}>\n <text fg={t.primary} attributes={TextAttributes.BOLD} flexGrow={1}>\n {\" System Status\"}\n </text>\n <text fg={t.textDim}>{\"esc\"}</text>\n </box>\n <text flexShrink={0}>{\"\"}</text>\n\n <scrollbox flexGrow={1}>\n <box flexShrink={0}>\n {/* Provider */}\n <text fg={t.secondary} attributes={TextAttributes.BOLD}>{\" Provider\"}</text>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Provider \"}</text><text fg={t.text}>{sdk.provider}</text></box>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Model \"}</text><text fg={t.text}>{sdk.model}</text></box>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Directory \"}</text><text fg={t.text}>{sdk.workingDir}</text></box>\n <text>{\"\"}</text>\n\n {/* System */}\n <text fg={t.secondary} attributes={TextAttributes.BOLD}>{\" System\"}</text>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Node \"}</text><text fg={t.text}>{process.version}</text></box>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Platform \"}</text><text fg={t.text}>{`${process.platform} ${process.arch}`}</text></box>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Terminal \"}</text><text fg={t.text}>{process.env.TERM_PROGRAM || process.env.TERM || \"unknown\"}</text></box>\n <box flexDirection=\"row\"><text fg={t.textMuted}>{\" Shell \"}</text><text fg={t.text}>{process.env.SHELL || \"unknown\"}</text></box>\n <text>{\"\"}</text>\n\n {/* Tools */}\n <text fg={t.secondary} attributes={TextAttributes.BOLD}>{` Tools (${toolNames.length})`}</text>\n {toolNames.map((name: string) => (\n <box key={name} flexDirection=\"row\">\n <text fg={t.textMuted}>{\" \u2022 \"}</text>\n <text fg={t.text}>{name}</text>\n </box>\n ))}\n </box>\n </scrollbox>\n </box>\n );\n}\n", "/**\n * Main TUI Application \u2014 OpenTUI + React\n *\n * Full-featured terminal UI with:\n * - Agent integration (streaming, tool calls, permissions)\n * - Permission prompt wiring (real UI prompts, not auto-allow)\n * - Runtime model/provider switching with agent rebuild\n * - Session browser overlay (Ctrl+S)\n * - Setup wizard overlay (/setup)\n * - Keyboard-driven navigation\n * - Command palette (Ctrl+P)\n * - Theme support (dark/light/auto)\n * - Status bar with token counts and context %\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { createRoot, useKeyboard, useTerminalDimensions } from \"@opentui/react\";\nimport { createCliRenderer, TextAttributes, RGBA } from \"@opentui/core\";\nimport { useState, useRef, useCallback } from \"react\";\nimport {\n ToolRegistry,\n PermissionManager,\n PermissionMode,\n ProcessManager,\n TodoStore,\n MemoryStore,\n registerAllTools,\n resolveOAuthToken,\n supportsOAuth,\n} from \"@cdoing/core\";\nimport { AgentRunner, getDefaultModel, getApiKeyEnvVar } from \"@cdoing/ai\";\nimport type { ModelConfig } from \"@cdoing/ai\";\n\nimport { ThemeProvider, useTheme, detectTerminalTheme, restoreTerminalBackground, getThemeColors, setTerminalBackground } from \"./context/theme\";\nimport { SDKProvider } from \"./context/sdk\";\nimport { ToastProvider } from \"./components/toast\";\nimport { useSettingsStore } from \"./store/settings\";\nimport { Home } from \"./routes/home\";\nimport { SessionView } from \"./routes/session\";\nimport { StatusBar } from \"./components/status-bar\";\nimport { SessionHeader } from \"./components/session-header\";\nimport { SessionFooter } from \"./components/session-footer\";\nimport { Sidebar } from \"./components/sidebar\";\nimport { DialogModel } from \"./components/dialog-model\";\nimport { DialogCommand } from \"./components/dialog-command\";\nimport { DialogHelp } from \"./components/dialog-help\";\nimport { DialogTheme } from \"./components/dialog-theme\";\nimport { SessionBrowser } from \"./components/session-browser\";\nimport { SetupWizard } from \"./components/setup-wizard\";\nimport { DialogStatus } from \"./components/dialog-status\";\nimport { setTerminalTitle, resetTerminalTitle } from \"./lib/terminal-title\";\nimport type { Conversation } from \"./lib/history\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface TUIOptions {\n prompt?: string;\n provider: string;\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n workingDir: string;\n mode: string;\n resume?: string;\n continue?: boolean;\n theme: string;\n}\n\n// \u2500\u2500 App Shell \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype Route = \"home\" | \"session\";\ntype Dialog = \"none\" | \"model\" | \"command\" | \"sessions\" | \"setup\" | \"help\" | \"theme\" | \"status\";\n\nfunction AppShell(props: {\n options: TUIOptions;\n agent: AgentRunner;\n registry: ToolRegistry;\n permissionManager: PermissionManager;\n}) {\n const dims = useTerminalDimensions();\n const { theme, themeId, customBg, setMode, setThemeId } = useTheme();\n const t = theme;\n\n const [route, setRoute] = useState<Route>(props.options.prompt ? \"session\" : \"home\");\n const [dialog, setDialog] = useState<Dialog>(\"none\");\n const [status, setStatus] = useState(\"Ready\");\n const [workingDir, setWorkingDir] = useState(props.options.workingDir);\n const [tokens, setTokens] = useState<{ input: number; output: number } | undefined>();\n const [contextPercent, setContextPercent] = useState(0);\n const [activeTool, setActiveTool] = useState<string | undefined>();\n\n // Persisted settings from Zustand store\n const provider = useSettingsStore((s) => s.provider);\n const model = useSettingsStore((s) => s.model);\n const sidebarMode = useSettingsStore((s) => s.sidebarMode);\n const setProvider = useSettingsStore((s) => s.setProvider);\n const setModel = useSettingsStore((s) => s.setModel);\n const setSidebarMode = useSettingsStore((s) => s.setSidebarMode);\n\n // Auto-hide sidebar when terminal is too narrow (like opencode: > 120 cols)\n const wide = dims.width > 120;\n const showSidebar = sidebarMode === \"show\" || (sidebarMode === \"auto\" && wide);\n\n const closeDialog = useCallback(() => {\n setDialog(\"none\");\n }, []);\n\n // Mutable refs for agent rebuild\n const agentRef = useRef(props.agent);\n const registryRef = useRef(props.registry);\n const pmRef = useRef(props.permissionManager);\n\n // Initial message from home screen input\n const initialMessageRef = useRef<{ text: string; images?: import(\"@cdoing/ai\").ImageAttachment[] } | null>(null);\n\n // \u2500\u2500 Permission prompt bridge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Store a pending permission resolve callback that the UI can call\n const permissionResolveRef = useRef<((decision: \"allow\" | \"always\" | \"deny\") => void) | null>(null);\n const [pendingPermission, setPendingPermission] = useState<{\n toolName: string;\n message: string;\n } | null>(null);\n\n // Wire PermissionManager to show UI prompt\n const requestPermission = useCallback((toolName: string, message: string): Promise<\"allow\" | \"always\" | \"deny\"> => {\n return new Promise((resolve) => {\n permissionResolveRef.current = resolve;\n setPendingPermission({ toolName, message });\n });\n }, []);\n\n // Set up the prompt function on the permission manager\n pmRef.current.setPromptFn(async (toolName: string, message: string) => {\n const decision = await requestPermission(toolName, message);\n return decision === \"always\" ? \"allow\" : decision;\n });\n\n // \u2500\u2500 Agent Rebuild \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const rebuildAgent = useCallback((newProvider: string, newModel: string, apiKey?: string, oauthToken?: string) => {\n // Resolve API key or OAuth token\n // If apiKey is explicitly \"\" (empty string), it means logout \u2014 skip all fallbacks\n let resolvedKey = apiKey;\n let resolvedOAuthToken = oauthToken;\n\n if (!resolvedKey && !resolvedOAuthToken && apiKey !== \"\") {\n // Try OAuth first for providers that support it\n if (supportsOAuth(newProvider)) {\n resolveOAuthToken(newProvider).then((token) => {\n if (token) {\n const modelConfig: Partial<ModelConfig> = {\n provider: newProvider,\n model: newModel,\n oauthToken: token,\n baseURL: props.options.baseUrl || undefined,\n temperature: 0,\n maxTokens: 8096,\n };\n const newAgent = new AgentRunner(modelConfig, registryRef.current, pmRef.current);\n agentRef.current = newAgent;\n setProvider(newProvider);\n setModel(newModel);\n }\n }).catch(() => {});\n // If OAuth token is being resolved async, still try API key fallback synchronously\n }\n\n const envVar = getApiKeyEnvVar(newProvider);\n if (process.env[envVar]) {\n resolvedKey = process.env[envVar];\n } else {\n try {\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n if (fs.existsSync(configPath)) {\n const config = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n resolvedKey = config.apiKeys?.[newProvider];\n }\n } catch {}\n }\n }\n\n const modelConfig: Partial<ModelConfig> = {\n provider: newProvider,\n model: newModel,\n apiKey: resolvedKey || undefined,\n oauthToken: resolvedOAuthToken || undefined,\n baseURL: props.options.baseUrl || undefined,\n temperature: 0,\n maxTokens: 8096,\n };\n\n const newAgent = new AgentRunner(modelConfig, registryRef.current, pmRef.current);\n agentRef.current = newAgent;\n setProvider(newProvider);\n setModel(newModel);\n }, [props.options.baseUrl]);\n\n // \u2500\u2500 Working Directory Change \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const handleSetWorkingDir = useCallback((dir: string) => {\n setWorkingDir(dir);\n }, []);\n\n // \u2500\u2500 Global Keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n useKeyboard((key: any) => {\n // Don't intercept keys when a dialog is open (let the dialog handle them)\n // Exception: Ctrl+C and Escape should always work\n if (dialog !== \"none\") {\n if (key.ctrl && key.name === \"c\") {\n const cleanup = (globalThis as any).__cdoingCleanup;\n if (cleanup) cleanup();\n process.exit(0);\n }\n if (key.name === \"escape\") {\n setDialog(\"none\");\n setRoute(\"home\");\n }\n return;\n }\n\n // Ctrl+C \u2014 graceful quit\n if (key.ctrl && key.name === \"c\") {\n const cleanup = (globalThis as any).__cdoingCleanup;\n if (cleanup) cleanup();\n else process.exit(0);\n }\n // Ctrl+N \u2014 new session\n if (key.ctrl && key.name === \"n\") {\n setRoute(\"session\");\n setStatus(\"Ready\");\n }\n // Ctrl+P \u2014 command palette\n if (key.ctrl && key.name === \"p\") {\n setDialog((d) => (d === \"command\" ? \"none\" : \"command\"));\n }\n // Ctrl+S \u2014 session browser\n if (key.ctrl && key.name === \"s\") {\n setDialog((d) => (d === \"sessions\" ? \"none\" : \"sessions\"));\n }\n // Ctrl+B \u2014 toggle sidebar\n if (key.ctrl && key.name === \"b\") {\n setSidebarMode(sidebarMode === \"hide\" ? \"show\" : sidebarMode === \"show\" ? \"hide\" : showSidebar ? \"hide\" : \"show\");\n }\n // Ctrl+T \u2014 theme picker\n if (key.ctrl && key.name === \"t\") {\n setDialog((d) => (d === \"theme\" ? \"none\" : \"theme\"));\n }\n // Ctrl+O \u2014 model picker (Ctrl+M = Enter in terminals)\n if (key.ctrl && key.name === \"o\") {\n setDialog((d) => (d === \"model\" ? \"none\" : \"model\"));\n }\n // F1 \u2014 help dialog\n if (key.name === \"f1\") {\n setDialog((d) => (d === \"help\" ? \"none\" : \"help\"));\n }\n // Escape \u2014 close any dialog\n if (key.name === \"escape\") {\n setDialog(\"none\");\n }\n }, {});\n\n // \u2500\u2500 Session Resume Handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const handleResumeSession = useCallback((_conv: Conversation) => {\n // TODO: restore conversation messages into agent history\n setRoute(\"session\");\n setDialog(\"none\");\n setStatus(\"Ready\");\n }, []);\n\n return (\n <box width={dims.width} height={dims.height} flexDirection=\"column\" backgroundColor={customBg ? RGBA.fromHex(customBg) : t.bg}>\n {/* Header bar */}\n <box height={1} flexDirection=\"row\" paddingX={1} flexShrink={0} backgroundColor={t.bgSubtle}>\n <text fg={t.primary} attributes={TextAttributes.BOLD}>{\"cdoing\"}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={t.textMuted}>{model}</text>\n <text fg={t.border}>{\" \u2502 \"}</text>\n <text fg={status === \"Error\" ? t.error : status === \"Processing...\" ? t.warning : t.success}>\n {status}\n </text>\n </box>\n\n {/* Session header (only in session route) */}\n {route === \"session\" && (\n <SessionHeader\n title=\"Session\"\n provider={provider}\n model={model}\n tokens={tokens}\n contextPercent={contextPercent}\n status={status}\n />\n )}\n\n {/* Separator */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(Math.max(dims.width, 40))}</text>\n </box>\n\n {/* Main content area with optional sidebar */}\n <box flexDirection=\"row\" flexGrow={1}>\n <SDKProvider\n value={{\n agent: agentRef.current,\n registry: registryRef.current,\n permissionManager: pmRef.current,\n workingDir,\n provider,\n model,\n requestPermission,\n rebuildAgent,\n setWorkingDir: handleSetWorkingDir,\n }}\n >\n <box flexGrow={1} flexDirection=\"column\">\n {dialog === \"sessions\" ? (\n <SessionBrowser\n onResume={handleResumeSession}\n onClose={() => setDialog(\"none\")}\n />\n ) : dialog === \"setup\" ? (\n <SetupWizard\n onComplete={(config) => {\n rebuildAgent(config.provider, config.model, config.apiKey, config.oauthToken);\n setDialog(\"none\");\n }}\n onClose={() => setDialog(\"none\")}\n />\n ) : route === \"home\" ? (\n <Home\n provider={provider}\n model={model}\n workingDir={workingDir}\n themeId={themeId}\n onSubmit={(text, images) => {\n initialMessageRef.current = { text, images };\n setRoute(\"session\");\n }}\n />\n ) : (\n <SessionView\n onStatus={setStatus}\n onTokens={(i, o) => setTokens({ input: i, output: o })}\n onActiveTool={setActiveTool}\n onContextPercent={setContextPercent}\n onOpenDialog={(d) => setDialog(d as Dialog)}\n initialMessage={initialMessageRef.current}\n dialogOpen={dialog !== \"none\"}\n />\n )}\n </box>\n </SDKProvider>\n\n {/* Vertical border between content and sidebar */}\n {showSidebar && (\n <box width={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2502\\n\".repeat(Math.max(dims.height - 4, 1))}</text>\n </box>\n )}\n\n {/* Sidebar (right panel) */}\n {showSidebar && (\n <Sidebar\n provider={provider}\n model={model}\n workingDir={workingDir}\n tokens={tokens}\n contextPercent={contextPercent}\n activeTool={activeTool}\n status={status}\n themeId={themeId}\n />\n )}\n </box>\n\n {/* Separator */}\n <box height={1} flexShrink={0}>\n <text fg={t.border}>{\"\u2500\".repeat(Math.max(dims.width, 40))}</text>\n </box>\n\n {/* Footer: session footer in session route, status bar always */}\n {route === \"session\" ? (\n <SessionFooter\n workingDir={workingDir}\n isProcessing={status === \"Processing...\"}\n />\n ) : (\n <StatusBar\n provider={provider}\n model={model}\n mode={props.options.mode}\n workingDir={workingDir}\n tokens={tokens}\n contextPercent={contextPercent}\n activeTool={activeTool}\n isProcessing={status === \"Processing...\"}\n />\n )}\n\n {/* Model picker dialog (overlay) */}\n {dialog === \"model\" && (\n <DialogModel\n provider={provider}\n currentModel={model}\n onSelect={(m) => {\n rebuildAgent(provider, m);\n setDialog(\"none\");\n }}\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Command palette dialog (overlay) */}\n {dialog === \"command\" && (\n <DialogCommand\n onSelect={(commandId) => {\n setDialog(\"none\");\n switch (commandId) {\n // Session\n case \"session:new\":\n setRoute(\"session\");\n setStatus(\"Ready\");\n break;\n case \"session:browse\":\n setDialog(\"sessions\");\n break;\n case \"session:clear\":\n setRoute(\"session\");\n setStatus(\"Ready\");\n break;\n // Model\n case \"model:switch\":\n case \"model:provider\":\n setDialog(\"model\");\n break;\n // Theme\n case \"theme:dark\":\n setMode(\"dark\");\n break;\n case \"theme:light\":\n setMode(\"light\");\n break;\n case \"theme:picker\":\n setDialog(\"theme\");\n break;\n // Display\n case \"display:sidebar\":\n setSidebarMode(sidebarMode === \"hide\" ? \"show\" : sidebarMode === \"show\" ? \"hide\" : showSidebar ? \"hide\" : \"show\");\n break;\n // Tools (dispatch as slash commands into session)\n case \"tool:shell\":\n case \"tool:search\":\n case \"tool:tree\":\n setRoute(\"session\");\n break;\n // System\n case \"system:status\":\n setDialog(\"status\");\n break;\n case \"system:help\":\n setDialog(\"help\");\n break;\n case \"system:doctor\":\n setStatus(\"Doctor\");\n break;\n case \"system:setup\":\n setDialog(\"setup\");\n break;\n case \"system:exit\": {\n const exit = (globalThis as any).__cdoingCleanup;\n if (exit) exit();\n else process.exit(0);\n break;\n }\n }\n }}\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Help dialog (overlay) */}\n {dialog === \"help\" && (\n <DialogHelp\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Theme picker dialog (overlay) */}\n {dialog === \"theme\" && (\n <DialogTheme\n onClose={() => setDialog(\"none\")}\n />\n )}\n\n {/* Status dialog (overlay) */}\n {dialog === \"status\" && (\n <DialogStatus onClose={() => setDialog(\"none\")} />\n )}\n\n </box>\n );\n}\n\n// \u2500\u2500 Error Boundary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// Global error signal \u2014 set by uncaughtException/unhandledRejection handlers,\n// read by the AppRoot wrapper to swap in the error screen.\nlet __fatalError: Error | null = null;\nlet __fatalErrorSetter: ((err: Error | null) => void) | null = null;\n\nfunction AppRoot(props: {\n children: any;\n}) {\n const [error, setError] = useState<Error | null>(__fatalError);\n __fatalErrorSetter = setError;\n\n if (error) {\n return <ErrorScreen error={error} onReset={() => setError(null)} />;\n }\n return props.children;\n}\n\nfunction ErrorScreen(props: {\n error: Error;\n onReset: () => void;\n}) {\n const dims = useTerminalDimensions();\n const maxW = Math.max(dims.width, 40);\n\n const colors = {\n bg: \"#0a0a0a\",\n text: \"#eeeeee\",\n muted: \"#808080\",\n primary: \"#fab283\",\n error: \"#ff6b6b\",\n };\n\n const issueURL = `https://github.com/AhmadMuj/cdoing-agent/issues/new?title=${encodeURIComponent(`tui: fatal: ${props.error.message}`)}&body=${encodeURIComponent(\"```\\n\" + (props.error.stack || props.error.message).substring(0, 4000) + \"\\n```\")}`;\n\n useKeyboard((key: any) => {\n if (key.ctrl && key.name === \"c\") {\n const cleanup = (globalThis as any).__cdoingCleanup;\n if (cleanup) cleanup();\n else process.exit(1);\n }\n if (key.name === \"r\") {\n props.onReset();\n }\n if (key.name === \"q\" || key.name === \"escape\") {\n const cleanup = (globalThis as any).__cdoingCleanup;\n if (cleanup) cleanup();\n else process.exit(0);\n }\n });\n\n const stackLines = (props.error.stack || \"\").split(\"\\n\").slice(0, Math.max(5, dims.height - 12));\n\n return (\n <box\n width={dims.width}\n height={dims.height}\n flexDirection=\"column\"\n backgroundColor={colors.bg}\n paddingX={2}\n paddingY={1}\n >\n <text fg={colors.error} attributes={TextAttributes.BOLD}>\n {\" A fatal error occurred!\"}\n </text>\n <text>{\"\"}</text>\n <text fg={colors.text} attributes={TextAttributes.BOLD}>\n {` ${props.error.message}`}\n </text>\n <text>{\"\"}</text>\n <text fg={colors.muted}>{\" Stack trace:\"}</text>\n {stackLines.map((line, i) => (\n <text key={i} fg={colors.muted}>\n {` ${line}`}\n </text>\n ))}\n <text>{\"\"}</text>\n <text fg={colors.primary}>{\" Report this issue:\"}</text>\n <text fg={colors.muted}>{` ${issueURL.length > maxW - 4 ? issueURL.substring(0, maxW - 7) + \"...\" : issueURL}`}</text>\n <text>{\"\"}</text>\n <box height={1} flexShrink={0}>\n <text fg={colors.muted}>{\"\u2500\".repeat(maxW)}</text>\n </box>\n <text fg={colors.text}>{\" r Reset TUI \u2022 q/Esc Exit \u2022 Ctrl+C Force quit\"}</text>\n </box>\n );\n}\n\n// \u2500\u2500 Entry Point \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport async function startTUI(options: TUIOptions): Promise<void> {\n // Initialize core services\n const registry = new ToolRegistry();\n const permMode = options.mode === \"auto\" ? PermissionMode.BYPASS\n : options.mode === \"auto-edit\" ? PermissionMode.ACCEPT_EDITS\n : PermissionMode.DEFAULT;\n const pm = new PermissionManager(permMode, options.workingDir);\n\n // Permission prompt will be wired up via React state in AppShell\n // Set a temporary default \u2014 will be overridden once React mounts\n pm.setPromptFn(async (_toolName, _message) => {\n return \"allow\";\n });\n\n const processManager = new ProcessManager();\n const todoStore = new TodoStore();\n const memoryStore = new MemoryStore(options.workingDir);\n await registerAllTools(registry, {\n workingDir: options.workingDir,\n permissionManager: pm,\n processManager,\n todoStore,\n memoryStore,\n planExitCallback: (summary: string) => {\n // Signal that plan is ready \u2014 the session component handles the approval via /plan approve\n console.log(\"\\n \uD83D\uDCCB Plan ready: \" + summary);\n console.log(\" Use /plan approve, /plan reject, or /plan show\\n\");\n },\n });\n\n // Resolve API key: flag \u2192 env var \u2192 stored config \u2192 OAuth token\n let resolvedApiKey = options.apiKey;\n let resolvedOAuthToken: string | undefined;\n let resolvedProvider = options.provider;\n let resolvedModel = options.model;\n let resolvedBaseUrl = options.baseUrl;\n\n if (!resolvedApiKey) {\n // Load stored config\n const configPath = path.join(os.homedir(), \".cdoing\", \"config.json\");\n let storedConfig: Record<string, any> = {};\n try {\n if (fs.existsSync(configPath)) {\n storedConfig = JSON.parse(fs.readFileSync(configPath, \"utf-8\"));\n }\n } catch {}\n\n // Apply stored provider/model/baseUrl if not set via flags\n if (resolvedProvider === \"anthropic\" && storedConfig.provider) {\n resolvedProvider = storedConfig.provider;\n }\n if (!resolvedModel && storedConfig.model) {\n resolvedModel = storedConfig.model;\n }\n if (!resolvedBaseUrl && storedConfig.baseUrl) {\n resolvedBaseUrl = storedConfig.baseUrl;\n }\n\n // Check env var\n const envVar = getApiKeyEnvVar(resolvedProvider);\n if (process.env[envVar]) {\n resolvedApiKey = process.env[envVar];\n }\n // Check stored API keys\n else if (storedConfig.apiKeys?.[resolvedProvider]) {\n resolvedApiKey = storedConfig.apiKeys[resolvedProvider];\n }\n\n // If no API key found, try OAuth token\n if (!resolvedApiKey && supportsOAuth(resolvedProvider)) {\n try {\n const token = await resolveOAuthToken(resolvedProvider);\n if (token) resolvedOAuthToken = token;\n } catch {}\n }\n }\n\n // Hydrate settings store with resolved CLI values (overrides persisted defaults when flags are explicit)\n const settingsStore = useSettingsStore.getState();\n if (resolvedProvider && resolvedProvider !== \"anthropic\") {\n settingsStore.setProvider(resolvedProvider);\n } else if (!settingsStore.provider || settingsStore.provider === \"anthropic\") {\n settingsStore.setProvider(resolvedProvider);\n }\n if (resolvedModel) {\n settingsStore.setModel(resolvedModel);\n } else if (!settingsStore.model) {\n settingsStore.setModel(getDefaultModel(settingsStore.provider) || \"default\");\n }\n\n // Use persisted values as the effective config (store is now hydrated)\n const effectiveProvider = useSettingsStore.getState().provider;\n const effectiveModel = useSettingsStore.getState().model;\n\n // Build model config (use effective values from persisted store)\n const modelConfig: Partial<ModelConfig> = {\n provider: effectiveProvider,\n model: effectiveModel || undefined,\n apiKey: resolvedApiKey || undefined,\n oauthToken: resolvedOAuthToken || undefined,\n baseURL: resolvedBaseUrl || undefined,\n temperature: 0,\n maxTokens: 8096,\n };\n\n // Create agent\n const agent = new AgentRunner(modelConfig, registry, pm);\n\n // Detect terminal background color before rendering (async OSC 11 query)\n let detectedMode: \"dark\" | \"light\" | undefined;\n if (options.theme === \"auto\") {\n detectedMode = await detectTerminalTheme();\n }\n\n // Set terminal background BEFORE clearing so it fills the entire screen\n const resolvedMode: \"dark\" | \"light\" = options.theme === \"light\" ? \"light\"\n : options.theme === \"auto\" ? (detectedMode || \"dark\")\n : \"dark\";\n // Hydrate theme settings from store\n const persistedThemeId = useSettingsStore.getState().themeId;\n const persistedMode = useSettingsStore.getState().mode;\n if (options.theme !== \"light\" && options.theme !== \"dark\") {\n // \"auto\" mode \u2014 use persisted mode if available\n if (persistedMode) settingsStore.setMode(persistedMode);\n } else {\n settingsStore.setMode(options.theme === \"light\" ? \"light\" : \"dark\");\n }\n\n const initialColors = getThemeColors(persistedThemeId || \"default\", resolvedMode);\n setTerminalBackground(initialColors.bg);\n\n // Reset terminal size to a good default (80x24 minimum)\n const cols = Math.max(process.stdout.columns || 80, 80);\n const rows = Math.max(process.stdout.rows || 24, 24);\n process.stdout.write(`\\x1b[8;${rows};${cols}t`);\n\n console.clear();\n\n // Set terminal title on mount\n setTerminalTitle(\"cdoing\");\n\n const renderer = await createCliRenderer({\n useMouse: true,\n exitOnCtrlC: false,\n });\n const root = createRoot(renderer);\n // Install global error handlers to catch uncaught exceptions and show the error screen\n const handleFatalError = (err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n process.stderr.write(`\\n[cdoing] Fatal error: ${error.message}\\n${error.stack || \"\"}\\n`);\n __fatalError = error;\n if (__fatalErrorSetter) __fatalErrorSetter(error);\n };\n process.on(\"uncaughtException\", handleFatalError);\n process.on(\"unhandledRejection\", handleFatalError);\n\n root.render(\n <AppRoot>\n <ThemeProvider mode={options.theme} themeId={persistedThemeId} detectedMode={detectedMode} syncTerminalBg>\n <ToastProvider>\n <AppShell\n options={{ ...options, provider: effectiveProvider, model: effectiveModel || undefined }}\n agent={agent}\n registry={registry}\n permissionManager={pm}\n />\n </ToastProvider>\n </ThemeProvider>\n </AppRoot>\n );\n\n // Graceful cleanup: unmount React, destroy renderer, restore terminal\n let isCleaningUp = false;\n const cleanup = () => {\n if (isCleaningUp) return;\n isCleaningUp = true;\n try { root.unmount(); } catch {}\n try { renderer.destroy(); } catch {}\n resetTerminalTitle();\n restoreTerminalBackground();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Expose cleanup globally so the keyboard handler can use it\n (globalThis as any).__cdoingCleanup = cleanup;\n\n // Keep alive\n await new Promise(() => {});\n}\n", "/**\n * cdoing-tui \u2014 OpenTUI-based terminal interface for cdoing agent\n *\n * This is the advanced TUI (like opencode) using @opentui/react for\n * a rich, interactive terminal experience with:\n * - Split panes (chat + file preview)\n * - Dialog system (model picker, session list, command palette)\n * - Theme support\n * - Keyboard-driven navigation\n *\n * The existing @cdoing/cli uses Ink (React) for a simpler TUI.\n * This package provides the opencode-style experience.\n */\n\nimport { Command } from \"commander\";\nimport { getDefaultModel, getRegisteredProviders } from \"@cdoing/ai\";\n\nconst program = new Command();\n\nprogram\n .name(\"cdoing-tui\")\n .description(\"OpenTUI-based terminal interface for cdoing agent\")\n .version(\"0.1.0\")\n .option(\"-m, --model <model>\", \"Model name\")\n .option(\"-p, --provider <provider>\", \"AI provider\", \"anthropic\")\n .option(\"--api-key <key>\", \"API key\")\n .option(\"--base-url <url>\", \"Base URL for custom providers\")\n .option(\"-d, --dir <directory>\", \"Working directory\", process.cwd())\n .option(\"--mode <mode>\", \"Permission mode: ask, auto-edit, auto\", \"ask\")\n .option(\"-r, --resume <id>\", \"Resume conversation by ID\")\n .option(\"-c, --continue\", \"Continue most recent conversation\")\n .option(\"--theme <theme>\", \"Theme: dark, light, auto\", \"dark\")\n .argument(\"[prompt]\", \"Initial prompt\")\n .action(async (prompt, opts) => {\n const { startTUI } = await import(\"./app\");\n await startTUI({\n prompt,\n provider: opts.provider,\n model: opts.model || getDefaultModel(opts.provider),\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n workingDir: opts.dir,\n mode: opts.mode,\n resume: opts.resume,\n continue: opts.continue,\n theme: opts.theme,\n });\n });\n\nprogram.parse();\n"],
5
- "mappings": "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",
6
- "names": ["createStoreImpl", "createStore", "init_vanilla", "__esmMin", "createState", "state", "listeners", "setState", "partial", "replace", "nextState", "previousState", "listener", "getState", "api", "initialState", "React", "useStore", "api", "selector", "identity", "slice", "createImpl", "create", "init_react", "__esmMin", "init_vanilla", "arg", "createState", "createStore", "useBoundStore", "init_esm", "__esmMin", "init_vanilla", "init_react", "createJSONStorage", "getStorage", "options", "storage", "name", "_a", "parse", "str2", "str", "newValue", "toThenable", "persistImpl", "persist", "init_middleware", "__esmMin", "fn", "input", "result", "onFulfilled", "_onRejected", "e", "_onFulfilled", "onRejected", "config", "baseOptions", "set", "get", "api", "state", "persistedState", "currentState", "hasHydrated", "hydrationVersion", "hydrationListeners", "finishHydrationListeners", "args", "setItem", "savedSetState", "replace", "configResult", "stateFromStorage", "hydrate", "_b", "currentVersion", "cb", "_a2", "postRehydrationCallback", "deserializedStorageValue", "migration", "migrationResult", "migrated", "migratedState", "newOptions", "fs", "path", "os", "SETTINGS_PATH", "fileStorage", "useSettingsStore", "init_settings", "__esmMin", "init_esm", "init_middleware", "name", "data", "value", "dir", "create", "persist", "set", "themeId", "mode", "syncTerminalBg", "sidebarMode", "provider", "model", "createJSONStorage", "state", "RGBA", "rgbToHex", "SyntaxStyle", "createContext", "useContext", "useState", "useEffect", "useRef", "useMemo", "jsx", "t", "hex", "buildTheme", "p", "getThemeIds", "THEMES", "a", "b", "getThemeColors", "themeId", "mode", "def", "luminance", "r", "g", "rs", "gs", "bs", "s", "queryTerminalBackground", "resolve", "timeout", "cleanup", "buf", "onData", "data", "match", "parse", "wasRaw", "detectThemeFromEnv", "bg", "parts", "detectTerminalTheme", "_detectedMode", "rgb", "setTerminalBackground", "color", "restoreTerminalBackground", "generateSyntaxStyle", "theme", "ThemeProvider", "props", "initialMode", "initialThemeId", "setThemeIdState", "currentMode", "setCurrentMode", "setTheme", "syncBg", "setSyncBg", "customBg", "setCustomBgState", "syncBgRef", "customBgRef", "modeRef", "themeIdRef", "applyTerminalBg", "colors", "setThemeId", "id", "useSettingsStore", "setMode", "m", "setCustomBg", "setSyncTerminalBg", "sync", "syntaxStyle", "ThemeContext", "useTheme", "ctx", "init_theme", "__esmMin", "init_settings", "createContext", "useContext", "jsx", "SDKProvider", "props", "SDKContext", "useSDK", "ctx", "init_sdk", "__esmMin", "createContext", "useContext", "useState", "useEffect", "useCallback", "useRef", "jsx", "jsxs", "getToastColor", "type", "theme", "ToastProvider", "props", "useTheme", "toasts", "setToasts", "idRef", "timersRef", "removeToast", "id", "prev", "t", "timer", "toast", "message", "duration", "dur", "DEFAULT_DURATION", "item", "next", "MAX_VISIBLE", "removed", "r", "ToastContext", "color", "icon", "TOAST_ICONS", "useToast", "ctx", "init_toast", "__esmMin", "init_theme", "fs", "path", "getCompletions", "input", "workingDir", "SLASH_COMMANDS", "c", "atIdx", "query", "results", "p", "MENTION_PROVIDERS", "fileQuery", "files", "getProjectFiles", "f", "parts", "tool", "subcommands", "TOOL_SUBCOMMANDS", "sub", "s", "pathResults", "getPathCompletions", "prefix", "getGhostText", "match", "pathCommands", "cmd", "partial", "readPathEntries", "dir", "entries", "base", "e", "a", "b", "lower", "skipDirs", "walk", "rel", "depth", "init_autocomplete", "__esmMin", "TextAttributes", "RGBA", "useState", "useRef", "useMemo", "useKeyboard", "execSync", "Fragment", "jsx", "jsxs", "readClipboard", "readClipboardImage", "base64", "InputArea", "props", "theme", "customBg", "useTheme", "value", "setValue", "pendingImages", "setPendingImages", "selectedIdx", "setSelectedIdx", "dropdownOpen", "setDropdownOpen", "valueRef", "imageCountRef", "suggestions", "completions", "getCompletions", "ghost", "getGhostText", "showDropdown", "key", "i", "s", "text", "v", "img", "prev", "clip", "firstLine", "next", "isSlashCommand", "windowStart", "MAX_VISIBLE", "visibleSuggestions", "hasAbove", "hasBelow", "bgColor", "isSelected", "color", "init_input_area", "__esmMin", "init_theme", "init_autocomplete", "TextAttributes", "useTerminalDimensions", "jsx", "jsxs", "Home", "props", "theme", "useTheme", "t", "dims", "w", "h", "shortDir", "home", "d", "subtitle", "version", "isSmall", "isMedium", "logo", "LOGO_COMPACT", "LOGO_FULL", "infoLines", "maxKeyLen", "k", "actions", "maxActionKey", "a", "line", "i", "key", "val", "action", "InputArea", "init_home", "__esmMin", "init_theme", "init_input_area", "TextAttributes", "Fragment", "jsx", "jsxs", "stripInlineMarkdown", "text", "RenderMarkdown", "props", "t", "syntaxStyle", "useTheme", "lines", "rendered", "i", "line", "codeLines", "codeBlock", "bulletMatch", "indent", "content", "numMatch", "formatTimestamp", "ts", "d", "h", "m", "ampm", "MessageList", "theme", "msg", "ToolCallRow", "trimText", "s", "max", "first", "shortPath", "p", "home", "countLines", "getToolDescription", "name", "input", "getOutputSummary", "output", "isError", "results", "l", "config", "TOOL_CONFIG", "isRunning", "statusIcon", "statusColor", "description", "outputSummary", "isShell", "shellCmd", "filePath", "isSearch", "searchPattern", "hasEditDiff", "oldStr", "newStr", "outputLines", "maxPreviewLines", "previewLines", "hasMoreLines", "init_message_list", "__esmMin", "init_theme", "TextAttributes", "useState", "useKeyboard", "jsx", "jsxs", "PermissionPrompt", "props", "theme", "customBg", "useTheme", "selected", "setSelected", "key", "s", "OPTIONS", "opt", "i", "init_permission_prompt", "__esmMin", "init_theme", "useState", "useEffect", "jsx", "jsxs", "LoadingSpinner", "props", "theme", "useTheme", "t", "frame", "setFrame", "interval", "f", "FRAMES", "init_loading_spinner", "__esmMin", "init_theme", "setTerminalTitle", "title", "resetTerminalTitle", "init_terminal_title", "__esmMin", "fs", "path", "os", "ensureDir", "CONV_DIR", "generateId", "now", "rand", "deriveTitle", "message", "clean", "createConversation", "provider", "model", "addMessage", "conv", "role", "content", "toolName", "saveConversation", "filePath", "loadConversation", "id", "match", "f", "listConversations", "files", "convs", "file", "data", "a", "b", "deleteConversation", "forkConversation", "idOrConv", "original", "forked", "m", "formatRelativeDate", "timestamp", "diff", "seconds", "minutes", "hours", "days", "init_history", "__esmMin", "ContextProviderRegistry", "TerminalContextProvider", "UrlContextProvider", "TreeContextProvider", "CodebaseContextProvider", "ClipboardContextProvider", "FileIncludeContextProvider", "getRegistry", "registry", "terminalProvider", "pushTerminalOutput", "output", "resolveContextProviders", "message", "workingDir", "reg", "expandedMessage", "appendSections", "trigger", "TRIGGERS", "idx", "afterTrigger", "endIdx", "arg", "fullTrigger", "providerName", "provider", "result", "hasContextMentions", "t", "init_context_providers", "__esmMin", "useState", "useRef", "useEffect", "TextAttributes", "useKeyboard", "fs", "path", "os", "execSync", "jsx", "jsxs", "detectShellCommand", "input", "trimmed", "firstWord", "SHELL_COMMANDS", "InterruptPrompt", "props", "theme", "useTheme", "t", "selected", "setSelected", "options", "key", "s", "preview", "opt", "i", "SessionView", "sdk", "useSDK", "setMode", "toast", "useToast", "setTerminalTitle", "messages", "setMessages", "streamingText", "setStreamingText", "streamingTextRef", "isStreaming", "setIsStreaming", "agentMode", "setAgentMode", "handleModeChange", "mode", "activeTool", "setActiveTool", "pendingPermission", "setPendingPermission", "pendingInterrupt", "setPendingInterrupt", "queuedMessagesRef", "totalInputRef", "totalOutputRef", "msgIdCounterRef", "conversationRef", "backgroundJobsRef", "bgIdCounterRef", "planPendingRef", "planSummaryRef", "createConversation", "addMessage", "role", "content", "extra", "msg", "prev", "updateMessage", "id", "updates", "m", "loadStoredConfig", "configPath", "saveConfigKey", "value", "configDir", "config", "loadProjectSettings", "settingsPath", "claudePath", "runBackgroundJob", "prompt", "job", "bgResult", "bgCallbacks", "token", "error", "err", "handleSlashCommand", "cmd", "command", "args", "arg", "getDefaultModel", "defaultModel", "currentMode", "resolved", "setParts", "valParts", "lines", "k", "v", "levels", "rebuildWithHistory", "history", "buildPrompt", "sendMessage", "planPrompt", "settings", "allow", "deny", "hooksPath", "hooks", "keys", "rulesDir", "files", "f", "convs", "listConversations", "c", "date", "formatRelativeDate", "msgCount", "conv", "loadConversation", "viewMsgs", "prefix", "sourceConv", "forked", "forkConversation", "deleteConversation", "jobs", "j", "elapsed", "result", "btwMsg", "btwResult", "btwCallbacks", "fullLogout", "getAllOAuthStatuses", "oauthStatuses", "hasOAuth", "icon", "label", "expires", "prov", "masked", "envVars", "hasEnvKey", "name", "checks", "envKey", "hasAuth", "getOAuthStatus", "hasCdoing", "hasClaude", "runningJobs", "cdoingDir", "runShellCommand", "shellCmd", "output", "errorMsg", "pushTerminalOutput", "handleInterrupt", "text", "images", "partialResponse", "doSendMessage", "handleQueue", "processQueue", "next", "shellParts", "target", "initialMessageSentRef", "messageText", "expandedText", "hasContextMentions", "resolveContextProviders", "currentToolId", "turnInput", "callbacks", "current", "toolInput", "description", "_name", "isError", "summary", "contextPercent", "savedTokens", "newPercent", "usage", "pct", "MessageList", "PermissionPrompt", "decision", "LoadingSpinner", "InputArea", "init_session", "__esmMin", "init_message_list", "init_input_area", "init_permission_prompt", "init_loading_spinner", "init_sdk", "init_theme", "init_toast", "init_terminal_title", "init_history", "init_context_providers", "TextAttributes", "Fragment", "jsx", "jsxs", "StatusBar", "props", "theme", "useTheme", "t", "home", "shortDir", "tokenInfo", "pct", "contextBar", "init_status_bar", "__esmMin", "init_theme", "TextAttributes", "jsx", "jsxs", "SessionHeader", "props", "theme", "useTheme", "t", "inTok", "outTok", "pct", "pctColor", "statusColor", "left", "init_session_header", "__esmMin", "init_theme", "jsx", "jsxs", "SessionFooter", "props", "theme", "useTheme", "t", "home", "shortDir", "init_session_footer", "__esmMin", "init_theme", "TextAttributes", "jsx", "jsxs", "trunc", "str", "max", "bar", "pct", "len", "filled", "Sidebar", "props", "theme", "useTheme", "t", "home", "dir", "pctColor", "inTok", "outTok", "statusColor", "lines", "sep", "header", "title", "row", "label", "value", "fg", "padded", "W", "shortcut", "key", "f", "name", "diff", "cardW", "cardLines", "line", "i", "cl", "init_sidebar", "__esmMin", "init_theme", "TextAttributes", "useState", "useMemo", "useKeyboard", "useTerminalDimensions", "getProviders", "Fragment", "jsx", "jsxs", "DialogModel", "props", "theme", "customBg", "useTheme", "dims", "models", "MODELS", "isCustom", "setIsCustom", "customInput", "setCustomInput", "selectOptions", "opts", "m", "initialIndex", "key", "s", "_index", "option", "init_dialog_model", "__esmMin", "init_theme", "p", "TextAttributes", "useState", "useMemo", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "fuzzyMatch", "query", "text", "lower", "q", "qi", "i", "DialogCommand", "props", "theme", "customBg", "useTheme", "dims", "setQuery", "dialogWidth", "maxVisible", "filtered", "COMMANDS", "cmd", "selectOptions", "opts", "lastCategory", "shortcutStr", "key", "_index", "option", "init_dialog_command", "__esmMin", "init_theme", "TextAttributes", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "Section", "props", "t", "entry", "keyColWidth", "DialogHelp", "theme", "customBg", "useTheme", "dims", "dialogWidth", "dialogHeight", "key", "KEYBOARD_SHORTCUTS", "SLASH_COMMANDS", "AT_MENTIONS", "init_dialog_help", "__esmMin", "init_theme", "TextAttributes", "useState", "useMemo", "useKeyboard", "useTerminalDimensions", "Fragment", "jsx", "jsxs", "DialogTheme", "props", "theme", "themeId", "mode", "customBg", "setThemeId", "setMode", "setCustomBg", "useTheme", "t", "dims", "initialThemeId", "initialMode", "initialCustomBg", "themeIds", "getThemeIds", "section", "setSection", "bgInput", "setBgInput", "query", "setQuery", "modeOptions", "filteredBgOptions", "BG_SELECT_OPTIONS", "q", "o", "filteredThemeOptions", "id", "def", "THEMES", "nextSection", "s", "idx", "SECTIONS", "isValidHex", "key", "next", "dialogWidth", "selectHeight", "_index", "option", "_option", "BG_PRESETS", "init_dialog_theme", "__esmMin", "init_theme", "p", "TextAttributes", "useState", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "SessionBrowser", "props", "theme", "customBg", "useTheme", "dims", "conversations", "setConversations", "listConversations", "selected", "setSelected", "confirmDelete", "setConfirmDelete", "viewMode", "setViewMode", "viewScroll", "setViewScroll", "maxVisible", "key", "s", "conv", "msgs", "m", "deleteConversation", "updated", "forkConversation", "visibleMsgs", "total", "i", "prefix", "color", "content", "idx", "isSelected", "date", "formatRelativeDate", "msgCount", "title", "init_session_browser", "__esmMin", "init_theme", "init_history", "fs", "path", "os", "execSync", "TextAttributes", "useState", "useRef", "useEffect", "useKeyboard", "getProviders", "getOAuthProvider", "supportsOAuth", "Fragment", "jsx", "jsxs", "getOAuthModels", "providerId", "config", "m", "providerSupportsOAuth", "readClipboard", "openBrowser", "url", "cmd", "SetupWizard", "props", "theme", "customBg", "useTheme", "closedRef", "closed", "setClosed", "step", "setStep", "selectedProvider", "setSelectedProvider", "selectedAuth", "setSelectedAuth", "selectedModel", "setSelectedModel", "authMethod", "setAuthMethod", "chosenProviderId", "setChosenProviderId", "chosenModelId", "setChosenModelId", "apiKeyInput", "setApiKeyInput", "showKey", "setShowKey", "error", "setError", "customModelInput", "setCustomModelInput", "isCustomModel", "setIsCustomModel", "oauthUrl", "setOauthUrl", "oauthVerifier", "setOauthVerifier", "oauthCodeInput", "setOauthCodeInput", "showCode", "setShowCode", "oauthError", "setOauthError", "exchangingRef", "provider", "PROVIDERS", "models", "MODELS", "generateOAuthUrl", "codeVerifier", "key", "s", "p", "AUTH_METHODS", "auth", "saveAndComplete", "clip", "totalItems", "code", "exchangeOAuthCode", "tokens", "err", "prov", "model", "apiKey", "configDir", "configPath", "isAnthropic", "total", "stepLabel", "i", "a", "KEY_URLS", "ENV_VARS", "_catalog", "init_setup_wizard", "__esmMin", "init_theme", "TextAttributes", "useKeyboard", "useTerminalDimensions", "jsx", "jsxs", "DialogStatus", "props", "theme", "customBg", "useTheme", "sdk", "useSDK", "dims", "dialogWidth", "dialogHeight", "allTools", "toolNames", "tool", "key", "name", "init_dialog_status", "__esmMin", "init_theme", "init_sdk", "app_exports", "__export", "startTUI", "fs", "path", "os", "createRoot", "useKeyboard", "useTerminalDimensions", "createCliRenderer", "TextAttributes", "RGBA", "useState", "useRef", "useCallback", "ToolRegistry", "PermissionManager", "PermissionMode", "ProcessManager", "TodoStore", "MemoryStore", "registerAllTools", "resolveOAuthToken", "supportsOAuth", "AgentRunner", "getDefaultModel", "getApiKeyEnvVar", "jsx", "jsxs", "AppShell", "props", "dims", "theme", "themeId", "customBg", "setMode", "setThemeId", "useTheme", "t", "route", "setRoute", "dialog", "setDialog", "status", "setStatus", "workingDir", "setWorkingDir", "tokens", "setTokens", "contextPercent", "setContextPercent", "activeTool", "setActiveTool", "provider", "useSettingsStore", "s", "model", "sidebarMode", "setProvider", "setModel", "setSidebarMode", "wide", "showSidebar", "closeDialog", "agentRef", "registryRef", "pmRef", "initialMessageRef", "permissionResolveRef", "pendingPermission", "setPendingPermission", "requestPermission", "toolName", "message", "resolve", "decision", "rebuildAgent", "newProvider", "newModel", "apiKey", "oauthToken", "resolvedKey", "resolvedOAuthToken", "token", "modelConfig", "newAgent", "envVar", "configPath", "handleSetWorkingDir", "dir", "key", "cleanup", "d", "handleResumeSession", "_conv", "SessionHeader", "SDKProvider", "SessionBrowser", "SetupWizard", "config", "Home", "text", "images", "SessionView", "i", "o", "Sidebar", "SessionFooter", "StatusBar", "DialogModel", "m", "DialogCommand", "commandId", "exit", "DialogHelp", "DialogTheme", "DialogStatus", "AppRoot", "error", "setError", "__fatalError", "__fatalErrorSetter", "ErrorScreen", "maxW", "colors", "issueURL", "stackLines", "line", "options", "registry", "permMode", "pm", "_toolName", "_message", "processManager", "todoStore", "memoryStore", "summary", "resolvedApiKey", "resolvedProvider", "resolvedModel", "resolvedBaseUrl", "storedConfig", "settingsStore", "effectiveProvider", "effectiveModel", "agent", "detectedMode", "detectTerminalTheme", "resolvedMode", "persistedThemeId", "persistedMode", "initialColors", "getThemeColors", "setTerminalBackground", "cols", "rows", "setTerminalTitle", "renderer", "root", "handleFatalError", "err", "ThemeProvider", "ToastProvider", "isCleaningUp", "resetTerminalTitle", "restoreTerminalBackground", "init_app", "__esmMin", "init_theme", "init_sdk", "init_toast", "init_settings", "init_home", "init_session", "init_status_bar", "init_session_header", "init_session_footer", "init_sidebar", "init_dialog_model", "init_dialog_command", "init_dialog_help", "init_dialog_theme", "init_session_browser", "init_setup_wizard", "init_dialog_status", "init_terminal_title", "Command", "getDefaultModel", "program", "prompt", "opts", "startTUI"]
7
- }