centaurus-cli 3.1.1 → 3.1.2
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 +4 -0
- package/dist/index.js.map +1 -1
- package/dist/ui/components/App.js +2 -2
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/AuthWelcomeScreen.js +1 -2
- package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
- package/dist/ui/components/VersionUpdatePrompt.js +31 -2
- package/dist/ui/components/VersionUpdatePrompt.js.map +1 -1
- package/dist/utils/ink-static-render.js +25 -0
- package/dist/utils/ink-static-render.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53,6 +53,7 @@ import { render } from "ink";
|
|
|
53
53
|
import { App } from "./ui/components/App.js";
|
|
54
54
|
import { ErrorBoundary } from "./ui/components/ErrorBoundary.js";
|
|
55
55
|
import { AuthWelcomeScreen } from "./ui/components/AuthWelcomeScreen.js";
|
|
56
|
+
import { WelcomeBanner } from "./ui/components/WelcomeBanner.js";
|
|
56
57
|
import { CentaurusCLI } from "./cli-adapter.js";
|
|
57
58
|
import { apiClient } from "./services/api-client.js";
|
|
58
59
|
import { authenticateWithGoogle } from "./services/auth-handler.js";
|
|
@@ -72,6 +73,9 @@ async function handleAuthentication() {
|
|
|
72
73
|
} catch (error) {
|
|
73
74
|
logWarning("Backend API is not reachable during authentication.");
|
|
74
75
|
}
|
|
76
|
+
const { renderToString } = await import("./utils/ink-static-render.js");
|
|
77
|
+
const bannerOutput = renderToString(React.createElement(WelcomeBanner));
|
|
78
|
+
process.stdout.write(bannerOutput + "\n");
|
|
75
79
|
return new Promise((resolve) => {
|
|
76
80
|
const { waitUntilExit, clear } = render(
|
|
77
81
|
React.createElement(AuthWelcomeScreen, {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Centaurus CLI Entry Point\r\n * \r\n * NOTE: NO .env file loading! All configuration is baked in at build time.\r\n * See config/build-config.ts for the compile-time configuration.\r\n */\r\n\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n// Import logger early for error handlers\r\nimport { logError, logWarning, logInfo } from './utils/logger.js';\r\nimport { quickLog } from './utils/conversation-logger.js';\r\n\r\n// Global handler for EPIPE errors from MCP servers during shutdown\r\n// This prevents crashes when MCP server processes try to write to closed pipes\r\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n // Silently ignore EPIPE errors - these happen during graceful shutdown\r\n logWarning(`stdout EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stdout error', err as Error);\r\n});\r\n\r\nprocess.stderr.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n logWarning(`stderr EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stderr error', err as Error);\r\n});\r\n\r\nprocess.stdin.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE' || err.code === 'EOF') {\r\n logWarning(`stdin error (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n logError('stdin error', err as Error);\r\n});\r\n\r\n// Handle uncaught errors from child processes (MCP servers)\r\nprocess.on('uncaughtException', (err: NodeJS.ErrnoException) => {\r\n // EPIPE, ECONNRESET, and similar errors from MCP/network operations - log and continue\r\n if (err.code === 'EPIPE' || err.code === 'ECONNRESET' || err.code === 'ENOTCONN') {\r\n logWarning(`Uncaught exception (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n\r\n // Yoga WASM memory access errors - these occur during rapid layout recalculations\r\n // in agent control mode and are non-fatal (the app can continue)\r\n if (err.name === 'RuntimeError' && err.message?.includes('memory access out of bounds')) {\r\n // Log to file only, not terminal\r\n quickLog(`[${new Date().toISOString()}] [WASM] Yoga memory error suppressed: ${err.message}\\n`);\r\n return;\r\n }\r\n\r\n // For critical errors, log and exit\r\n logError('Uncaught exception (fatal)', err as Error);\r\n process.exit(1);\r\n});\r\n\r\n// Handle unhandled promise rejections\r\nprocess.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\r\n const error = reason instanceof Error ? reason : new Error(String(reason));\r\n const errnoError = error as NodeJS.ErrnoException;\r\n\r\n // Suppress common non-fatal errors from MCP/network operations\r\n if (errnoError.code === 'EPIPE' || errnoError.code === 'ECONNRESET' ||\r\n errnoError.code === 'ENOTCONN' || errnoError.code === 'ERR_STREAM_DESTROYED') {\r\n logWarning(`Unhandled rejection (suppressed): ${errnoError.code} - ${error.message}`);\r\n return;\r\n }\r\n\r\n logError('Unhandled rejection', error);\r\n});\r\n\r\nimport React from 'react';\r\nimport { render } from 'ink';\r\nimport { App } from './ui/components/App.js';\r\nimport { ErrorBoundary } from './ui/components/ErrorBoundary.js';\r\nimport { AuthWelcomeScreen } from './ui/components/AuthWelcomeScreen.js';\r\nimport { CentaurusCLI } from './cli-adapter.js';\r\nimport { apiClient } from './services/api-client.js';\r\nimport { authenticateWithGoogle } from './services/auth-handler.js';\r\nimport { Text, Box } from 'ink';\r\nimport { Plan, PlanStep } from './tools/plan-mode.js';\r\n\r\nasync function handleAuthentication(): Promise<boolean> {\r\n // Check if already authenticated and verify session is valid\r\n if (apiClient.isAuthenticated()) {\r\n try {\r\n // Verify the session is actually valid by checking with backend\r\n await apiClient.getCurrentUser();\r\n return true; // Session is valid\r\n } catch (error) {\r\n // Session is invalid/expired, clear it and continue to auth flow\r\n logWarning('Session expired. User needs to sign in again.');\r\n }\r\n }\r\n\r\n // Check if backend is reachable\r\n let backendReachable = false;\r\n try {\r\n await apiClient.healthCheck();\r\n backendReachable = true;\r\n } catch (error) {\r\n // Backend is not reachable - we'll still show auth screen but inform user\r\n logWarning('Backend API is not reachable during authentication.');\r\n }\r\n\r\n // Show authentication welcome screen with picker\r\n return new Promise<boolean>((resolve) => {\r\n const { waitUntilExit, clear } = render(\r\n React.createElement(AuthWelcomeScreen, {\r\n onSignIn: async () => {\r\n clear();\r\n\r\n logInfo('Starting authentication process...');\r\n\r\n // Attempt authentication via web app\r\n // The auth handler will open the browser and wait for callback\r\n const result = await authenticateWithGoogle();\r\n\r\n if (result.success) {\r\n logInfo('Authentication successful!');\r\n resolve(true);\r\n } else {\r\n logWarning(`Authentication failed: ${result.error || 'Unknown error'}`);\r\n process.exit(1);\r\n }\r\n },\r\n onExit: () => {\r\n clear();\r\n logInfo('User exited authentication screen.');\r\n process.exit(0);\r\n },\r\n }),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: true,\r\n }\r\n );\r\n });\r\n}\r\n\r\nasync function main() {\r\n // Handle authentication\r\n await handleAuthentication();\r\n\r\n const cli = new CentaurusCLI();\r\n\r\n // Initialize CLI (load config, register tools)\r\n await cli.initialize();\r\n\r\n // Check if configuration migration occurred and show message\r\n const migrationMessage = cli.getMigrationMessage();\r\n if (migrationMessage) {\r\n logInfo(`Configuration migration: ${migrationMessage}`);\r\n\r\n // Wait for user to press Enter, but only if interactive\r\n if (process.stdin.isTTY) {\r\n await new Promise<void>((resolve) => {\r\n const onData = () => {\r\n process.stdin.removeListener('end', onEnd);\r\n resolve();\r\n };\r\n const onEnd = () => {\r\n process.stdin.removeListener('data', onData);\r\n resolve();\r\n };\r\n process.stdin.once('data', onData);\r\n process.stdin.once('end', onEnd);\r\n });\r\n }\r\n }\r\n\r\n // Clear the terminal before starting the UI\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n\r\n // Render Ink app with error boundary\r\n // patchConsole: false prevents console.log from interfering with Ink's rendering\r\n // This is CRITICAL for Static component to work properly\r\n // debug: false reduces flickering by disabling debug output\r\n const { waitUntilExit } = render(\r\n React.createElement(ErrorBoundary, null,\r\n React.createElement(App, {\r\n onMessage: (msg: string) => cli.handleMessage(msg),\r\n onCancelRequest: () => cli.cancelCurrentRequest(),\r\n initialModel: cli.getModel(),\r\n initialPlanMode: cli.getPlanMode(),\r\n onResponseReceived: (callback: (message: string) => void) => {\r\n cli.setOnResponseCallback(callback);\r\n },\r\n onDirectMessage: (callback: (message: string) => void) => {\r\n cli.setOnDirectMessageCallback(callback);\r\n },\r\n onResponseStream: (callback: (chunk: string) => void) => {\r\n cli.setOnResponseStreamCallback(callback);\r\n },\r\n onClearStreamedResponse: (callback: () => void) => {\r\n cli.setOnClearStreamedResponse(callback);\r\n },\r\n onThoughtStream: (callback: (thought: string) => void) => {\r\n cli.setOnThoughtStreamCallback(callback);\r\n },\r\n onThoughtComplete: (callback: (durationSeconds: number) => void) => {\r\n cli.setOnThoughtCompleteCallback(callback);\r\n },\r\n onPickerSetup: (callback: (options: { message: string; choices: Array<{ label: string; value: string }>; type: 'model' }) => void) => {\r\n cli.setOnShowPickerCallback(callback);\r\n },\r\n onPickerSelection: (selection: string, type: 'model') => {\r\n return cli.handlePickerSelection(selection, type);\r\n },\r\n onToolExecutionUpdate: (callback: (update: { toolName: string; status: 'pending' | 'executing' | 'completed' | 'error'; result?: string; error?: string; arguments?: Record<string, any> }) => void) => {\r\n cli.setOnToolExecutionUpdate(callback);\r\n },\r\n onToolApprovalRequest: (callback: (request: { message: string; risky: boolean; preview?: { type: 'code' | 'diff'; content: string; language?: string }; operationType?: 'write_file' | 'edit_file' | 'execute_command'; operationDetails?: Record<string, any> }) => Promise<boolean>) => {\r\n cli.setOnToolApprovalRequest(callback);\r\n },\r\n onToolStreamingOutput: (callback: (update: { toolName: string; chunk: string; type: 'stdout' | 'stderr' }) => void) => {\r\n cli.setOnToolStreamingOutput(callback);\r\n },\r\n onPlanModeChange: (callback: (planMode: boolean) => void) => {\r\n cli.setOnPlanModeChange(callback);\r\n },\r\n onPlanApprovalRequest: (callback: (plan: Plan) => Promise<boolean>) => {\r\n cli.setOnPlanApprovalRequest(callback);\r\n },\r\n onPlanCreated: (callback: (plan: Plan) => void) => {\r\n cli.setOnPlanCreated(callback);\r\n },\r\n onTaskCompleted: (callback: (task: PlanStep, taskNumber: number, totalTasks: number, completionNote?: string, taskDescription?: string) => void) => {\r\n cli.setOnTaskCompleted(callback);\r\n },\r\n onFileChangeSummary: (callback: (data: { filesChanged: number; insertions: number; deletions: number }) => void) => {\r\n cli.setOnFileChangeSummaryCallback(callback);\r\n },\r\n onCommandModeChange: (callback: (commandMode: boolean) => void) => {\r\n cli.setOnCommandModeChange(callback);\r\n },\r\n onToggleCommandMode: () => {\r\n cli.toggleCommandMode();\r\n },\r\n onBackgroundModeChange: (callback: (backgroundMode: boolean) => void) => {\r\n cli.setOnBackgroundModeChange(callback);\r\n },\r\n onToggleBackgroundMode: () => {\r\n cli.toggleBackgroundMode();\r\n },\r\n onBackgroundTaskCountChange: (callback: (count: number) => void) => {\r\n cli.setOnBackgroundTaskCountChange(callback);\r\n },\r\n onSubAgentCountChange: (callback: (count: number) => void) => {\r\n cli.setOnSubAgentCountChange(callback);\r\n },\r\n onSetAutoModeSetup: (callback: (enabled: boolean) => void) => {\r\n cli.setOnSetAutoMode(callback);\r\n },\r\n\r\n onCwdChange: (callback: (cwd: string) => void) => {\r\n cli.setOnCwdChange(callback);\r\n },\r\n onModelChange: (callback: (modelName: string, contextWindow: number) => void) => {\r\n cli.setOnModelChange(callback);\r\n },\r\n onSubshellContextChange: (callback: (context: any) => void) => {\r\n cli.setOnSubshellContextChange(callback);\r\n },\r\n onPasswordRequest: (callback: (message: string) => Promise<string>) => {\r\n cli.setOnPasswordRequest(callback);\r\n },\r\n onShellInput: (input: string) => {\r\n cli.writeToShellStdin(input);\r\n },\r\n onShellSignal: (signal: string) => {\r\n cli.sendSignalToShell(signal as NodeJS.Signals);\r\n },\r\n onKillProcess: () => {\r\n cli.killCurrentProcess();\r\n },\r\n onInteractiveEditorMode: (callback: (active: boolean, command?: string, cwd?: string, remoteContext?: any, parentContext?: any) => void) => {\r\n cli.setOnInteractiveEditorMode(callback);\r\n },\r\n onConnectionStatusUpdate: (callback: (status: { type: 'ssh' | 'wsl' | 'docker'; status: 'connecting' | 'connected' | 'error' | 'disconnected'; connectionString?: string; error?: string }) => void) => {\r\n cli.setOnConnectionStatusUpdate(callback);\r\n },\r\n onTokenCountUpdate: (callback: (tokens: number) => void) => {\r\n cli.setOnTokenCountUpdate(callback);\r\n },\r\n onContextLimitReached: (callback: (reached: boolean) => void) => {\r\n cli.setOnContextLimitReached(callback);\r\n },\r\n onChatPickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatPickerCallback(callback);\r\n },\r\n onChatPickerSelection: (chatId: string) => {\r\n return cli.handleChatPickerSelection(chatId);\r\n },\r\n onChatDeletePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatDeletePickerCallback(callback);\r\n },\r\n onChatDeletePickerSelection: (chatId: string) => {\r\n return cli.handleChatDeleteSelection(chatId);\r\n },\r\n onChatListSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatListCallback(callback);\r\n },\r\n onChatRenamePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatRenamePickerCallback(callback);\r\n },\r\n onChatRename: (chatId: string, newTitle: string) => {\r\n cli.handleChatRename(chatId, newTitle);\r\n },\r\n onRestoreMessagesSetup: (callback: (messages: any[]) => void) => {\r\n cli.setOnRestoreMessagesCallback(callback);\r\n },\r\n onUIMessageHistoryUpdate: (messages: any[]) => {\r\n cli.updateUIMessageHistory(messages);\r\n },\r\n onBackgroundTaskListSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskPickerCallback(callback);\r\n },\r\n onBackgroundTaskSelection: (taskId: string) => {\r\n cli.handleBackgroundTaskSelection(taskId);\r\n },\r\n onBackgroundTaskCancelSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskCancelPickerCallback(callback);\r\n },\r\n onBackgroundTaskCancel: (taskId: string) => {\r\n cli.handleBackgroundTaskCancel(taskId);\r\n },\r\n onBackgroundTaskViewSetup: (callback: (task: any) => void) => {\r\n cli.setOnBackgroundTaskViewCallback(callback);\r\n },\r\n onSessionQuotaUpdate: (callback: (remaining: number, canSend: boolean, timeRemaining: string) => void) => {\r\n cli.setOnSessionQuotaUpdate(callback);\r\n },\r\n // MCP management callbacks\r\n onMCPAddScreenSetup: (callback: () => void) => {\r\n cli.setOnMCPAddScreenSetup(callback);\r\n },\r\n onMCPRemoveScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPRemoveScreenSetup(callback);\r\n },\r\n onMCPEnableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPEnableScreenSetup(callback);\r\n },\r\n onMCPDisableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPDisableScreenSetup(callback);\r\n },\r\n onMCPListScreenSetup: (callback: (servers: Array<{ name: string; enabled: boolean; status: 'connected' | 'disconnected' | 'error' | 'connecting'; tools: Array<{ name: string }> }>) => void) => {\r\n cli.setOnMCPListScreenSetup(callback);\r\n },\r\n onMCPAddServer: (config: any) => {\r\n return cli.mcpAddServer(config);\r\n },\r\n onMCPRemoveServer: (name: string) => {\r\n cli.mcpRemoveServer(name);\r\n },\r\n onMCPEnableServer: (name: string) => {\r\n cli.mcpEnableServer(name);\r\n },\r\n onMCPDisableServer: (name: string) => {\r\n cli.mcpDisableServer(name);\r\n },\r\n onMCPValidateConfig: (jsonString: string) => {\r\n return cli.mcpValidateConfig(jsonString);\r\n },\r\n onPromptAnswered: (callback: (shellId: string) => void) => {\r\n cli.setOnPromptAnswered(callback);\r\n },\r\n getMainConversation: () => {\r\n return cli.getConversationHistory();\r\n },\r\n onWarpifySession: (command: string, type: 'ssh' | 'wsl' | 'docker', connectionString?: string) => {\r\n return cli.warpifySession(command, type, connectionString);\r\n },\r\n onAiAutoSuggestChange: (callback: (enabled: boolean) => void) => {\r\n cli.setOnAiAutoSuggestChange(callback);\r\n },\r\n // Workflow callbacks\r\n\r\n onWorkflowCreatorSetup: (callback: (initialSteps?: Array<{ type: 'command' | 'instruction'; content: string }>) => void) => {\r\n cli.setOnShowWorkflowCreator(callback);\r\n },\r\n onWorkflowSave: (name: string, steps: Array<{ type: 'command' | 'instruction'; content: string }>, description?: string) => {\r\n cli.saveWorkflow(name, steps, description);\r\n },\r\n onRulesEditorSetup: (callback: (request: { mode: 'add' | 'edit'; initialName?: string; initialContent?: string }) => void) => {\r\n cli.setOnShowRulesEditor(callback);\r\n },\r\n onRuleSave: (name: string, content: string, previousName?: string) => {\r\n return cli.saveRule(name, content, previousName);\r\n },\r\n getCheckpoints: () => {\r\n return cli.getCheckpointsForAutocomplete();\r\n },\r\n onRevertToCheckpointSetup: (callback: (checkpointIndex: number, prompt: string) => void) => {\r\n cli.setOnRevertToCheckpoint(callback);\r\n },\r\n onSetInputSetup: (callback: (value: string) => void) => {\r\n cli.setOnSetInput(callback);\r\n },\r\n onInterruptQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnInterruptQueueUpdate(callback);\r\n },\r\n onQueuedMessageDispatched: (callback: (message: string) => void) => {\r\n cli.setOnQueuedMessageDispatched(callback);\r\n },\r\n onCommandQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnCommandQueueUpdate(callback);\r\n },\r\n onQueuedCommandDispatched: (callback: (command: string) => void) => {\r\n cli.setOnQueuedCommandDispatched(callback);\r\n }\r\n })\r\n ),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: false,\r\n debug: false\r\n }\r\n );\r\n\r\n // Wait for user to exit, with a fallback mechanism\r\n // If the React component tree crashes silently or the Ink runtime enters an unexpected state,\r\n // waitUntilExit() may never resolve. This fallback ensures we can still exit via signals.\r\n const exitPromise = waitUntilExit();\r\n\r\n const fallbackPromise = new Promise<void>((resolve) => {\r\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];\r\n\r\n // We don't want to immediately exit on the first SIGINT if Ink is healthy \r\n // and processing it to gracefully unmount. We add a short timeout, \r\n // or just rely on the fact that if this resolves first, we exit.\r\n const signalHandler = (sig: string) => {\r\n logWarning(`Received ${sig} (Fallback handler triggered)`);\r\n // Give Ink a small window to gracefully exit first before we force it\r\n setTimeout(() => {\r\n resolve();\r\n }, 500).unref();\r\n\r\n signals.forEach(s => process.removeListener(s, signalHandler));\r\n };\r\n\r\n signals.forEach(sig => process.once(sig, signalHandler));\r\n });\r\n\r\n try {\r\n await Promise.race([exitPromise, fallbackPromise]);\r\n } catch (err) {\r\n logError('Ink render error', err as Error);\r\n } finally {\r\n // Ensure all background processes and timers are terminated\r\n process.exit(0);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n logError('Fatal error in main()', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Centaurus CLI Entry Point\r\n * \r\n * NOTE: NO .env file loading! All configuration is baked in at build time.\r\n * See config/build-config.ts for the compile-time configuration.\r\n */\r\n\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n// Import logger early for error handlers\r\nimport { logError, logWarning, logInfo } from './utils/logger.js';\r\nimport { quickLog } from './utils/conversation-logger.js';\r\n\r\n// Global handler for EPIPE errors from MCP servers during shutdown\r\n// This prevents crashes when MCP server processes try to write to closed pipes\r\nprocess.stdout.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n // Silently ignore EPIPE errors - these happen during graceful shutdown\r\n logWarning(`stdout EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stdout error', err as Error);\r\n});\r\n\r\nprocess.stderr.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE') {\r\n logWarning(`stderr EPIPE error (suppressed): ${err.message}`);\r\n return;\r\n }\r\n logError('stderr error', err as Error);\r\n});\r\n\r\nprocess.stdin.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EPIPE' || err.code === 'EOF') {\r\n logWarning(`stdin error (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n logError('stdin error', err as Error);\r\n});\r\n\r\n// Handle uncaught errors from child processes (MCP servers)\r\nprocess.on('uncaughtException', (err: NodeJS.ErrnoException) => {\r\n // EPIPE, ECONNRESET, and similar errors from MCP/network operations - log and continue\r\n if (err.code === 'EPIPE' || err.code === 'ECONNRESET' || err.code === 'ENOTCONN') {\r\n logWarning(`Uncaught exception (suppressed): ${err.code} - ${err.message}`);\r\n return;\r\n }\r\n\r\n // Yoga WASM memory access errors - these occur during rapid layout recalculations\r\n // in agent control mode and are non-fatal (the app can continue)\r\n if (err.name === 'RuntimeError' && err.message?.includes('memory access out of bounds')) {\r\n // Log to file only, not terminal\r\n quickLog(`[${new Date().toISOString()}] [WASM] Yoga memory error suppressed: ${err.message}\\n`);\r\n return;\r\n }\r\n\r\n // For critical errors, log and exit\r\n logError('Uncaught exception (fatal)', err as Error);\r\n process.exit(1);\r\n});\r\n\r\n// Handle unhandled promise rejections\r\nprocess.on('unhandledRejection', (reason: any, promise: Promise<any>) => {\r\n const error = reason instanceof Error ? reason : new Error(String(reason));\r\n const errnoError = error as NodeJS.ErrnoException;\r\n\r\n // Suppress common non-fatal errors from MCP/network operations\r\n if (errnoError.code === 'EPIPE' || errnoError.code === 'ECONNRESET' ||\r\n errnoError.code === 'ENOTCONN' || errnoError.code === 'ERR_STREAM_DESTROYED') {\r\n logWarning(`Unhandled rejection (suppressed): ${errnoError.code} - ${error.message}`);\r\n return;\r\n }\r\n\r\n logError('Unhandled rejection', error);\r\n});\r\n\r\nimport React from 'react';\r\nimport { render } from 'ink';\r\nimport { App } from './ui/components/App.js';\r\nimport { ErrorBoundary } from './ui/components/ErrorBoundary.js';\r\nimport { AuthWelcomeScreen } from './ui/components/AuthWelcomeScreen.js';\r\nimport { WelcomeBanner } from './ui/components/WelcomeBanner.js';\r\nimport { CentaurusCLI } from './cli-adapter.js';\r\nimport { apiClient } from './services/api-client.js';\r\nimport { authenticateWithGoogle } from './services/auth-handler.js';\r\nimport { Text, Box } from 'ink';\r\nimport { Plan, PlanStep } from './tools/plan-mode.js';\r\n\r\nasync function handleAuthentication(): Promise<boolean> {\r\n // Check if already authenticated and verify session is valid\r\n if (apiClient.isAuthenticated()) {\r\n try {\r\n // Verify the session is actually valid by checking with backend\r\n await apiClient.getCurrentUser();\r\n return true; // Session is valid\r\n } catch (error) {\r\n // Session is invalid/expired, clear it and continue to auth flow\r\n logWarning('Session expired. User needs to sign in again.');\r\n }\r\n }\r\n\r\n // Check if backend is reachable\r\n let backendReachable = false;\r\n try {\r\n await apiClient.healthCheck();\r\n backendReachable = true;\r\n } catch (error) {\r\n // Backend is not reachable - we'll still show auth screen but inform user\r\n logWarning('Backend API is not reachable during authentication.');\r\n }\r\n\r\n // Show authentication welcome screen with picker\r\n // Pre-render the WelcomeBanner to stdout BEFORE starting the interactive\r\n // Ink instance. This way the banner is static terminal output that won't\r\n // be redrawn when the selector re-renders inside the Ink tree.\r\n const { renderToString } = await import('./utils/ink-static-render.js');\r\n const bannerOutput = renderToString(React.createElement(WelcomeBanner));\r\n process.stdout.write(bannerOutput + '\\n');\r\n\r\n return new Promise<boolean>((resolve) => {\r\n const { waitUntilExit, clear } = render(\r\n React.createElement(AuthWelcomeScreen, {\r\n onSignIn: async () => {\r\n clear();\r\n\r\n logInfo('Starting authentication process...');\r\n\r\n // Attempt authentication via web app\r\n // The auth handler will open the browser and wait for callback\r\n const result = await authenticateWithGoogle();\r\n\r\n if (result.success) {\r\n logInfo('Authentication successful!');\r\n resolve(true);\r\n } else {\r\n logWarning(`Authentication failed: ${result.error || 'Unknown error'}`);\r\n process.exit(1);\r\n }\r\n },\r\n onExit: () => {\r\n clear();\r\n logInfo('User exited authentication screen.');\r\n process.exit(0);\r\n },\r\n }),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: true,\r\n }\r\n );\r\n });\r\n}\r\n\r\nasync function main() {\r\n // Handle authentication\r\n await handleAuthentication();\r\n\r\n const cli = new CentaurusCLI();\r\n\r\n // Initialize CLI (load config, register tools)\r\n await cli.initialize();\r\n\r\n // Check if configuration migration occurred and show message\r\n const migrationMessage = cli.getMigrationMessage();\r\n if (migrationMessage) {\r\n logInfo(`Configuration migration: ${migrationMessage}`);\r\n\r\n // Wait for user to press Enter, but only if interactive\r\n if (process.stdin.isTTY) {\r\n await new Promise<void>((resolve) => {\r\n const onData = () => {\r\n process.stdin.removeListener('end', onEnd);\r\n resolve();\r\n };\r\n const onEnd = () => {\r\n process.stdin.removeListener('data', onData);\r\n resolve();\r\n };\r\n process.stdin.once('data', onData);\r\n process.stdin.once('end', onEnd);\r\n });\r\n }\r\n }\r\n\r\n // Clear the terminal before starting the UI\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n\r\n // Render Ink app with error boundary\r\n // patchConsole: false prevents console.log from interfering with Ink's rendering\r\n // This is CRITICAL for Static component to work properly\r\n // debug: false reduces flickering by disabling debug output\r\n const { waitUntilExit } = render(\r\n React.createElement(ErrorBoundary, null,\r\n React.createElement(App, {\r\n onMessage: (msg: string) => cli.handleMessage(msg),\r\n onCancelRequest: () => cli.cancelCurrentRequest(),\r\n initialModel: cli.getModel(),\r\n initialPlanMode: cli.getPlanMode(),\r\n onResponseReceived: (callback: (message: string) => void) => {\r\n cli.setOnResponseCallback(callback);\r\n },\r\n onDirectMessage: (callback: (message: string) => void) => {\r\n cli.setOnDirectMessageCallback(callback);\r\n },\r\n onResponseStream: (callback: (chunk: string) => void) => {\r\n cli.setOnResponseStreamCallback(callback);\r\n },\r\n onClearStreamedResponse: (callback: () => void) => {\r\n cli.setOnClearStreamedResponse(callback);\r\n },\r\n onThoughtStream: (callback: (thought: string) => void) => {\r\n cli.setOnThoughtStreamCallback(callback);\r\n },\r\n onThoughtComplete: (callback: (durationSeconds: number) => void) => {\r\n cli.setOnThoughtCompleteCallback(callback);\r\n },\r\n onPickerSetup: (callback: (options: { message: string; choices: Array<{ label: string; value: string }>; type: 'model' }) => void) => {\r\n cli.setOnShowPickerCallback(callback);\r\n },\r\n onPickerSelection: (selection: string, type: 'model') => {\r\n return cli.handlePickerSelection(selection, type);\r\n },\r\n onToolExecutionUpdate: (callback: (update: { toolName: string; status: 'pending' | 'executing' | 'completed' | 'error'; result?: string; error?: string; arguments?: Record<string, any> }) => void) => {\r\n cli.setOnToolExecutionUpdate(callback);\r\n },\r\n onToolApprovalRequest: (callback: (request: { message: string; risky: boolean; preview?: { type: 'code' | 'diff'; content: string; language?: string }; operationType?: 'write_file' | 'edit_file' | 'execute_command'; operationDetails?: Record<string, any> }) => Promise<boolean>) => {\r\n cli.setOnToolApprovalRequest(callback);\r\n },\r\n onToolStreamingOutput: (callback: (update: { toolName: string; chunk: string; type: 'stdout' | 'stderr' }) => void) => {\r\n cli.setOnToolStreamingOutput(callback);\r\n },\r\n onPlanModeChange: (callback: (planMode: boolean) => void) => {\r\n cli.setOnPlanModeChange(callback);\r\n },\r\n onPlanApprovalRequest: (callback: (plan: Plan) => Promise<boolean>) => {\r\n cli.setOnPlanApprovalRequest(callback);\r\n },\r\n onPlanCreated: (callback: (plan: Plan) => void) => {\r\n cli.setOnPlanCreated(callback);\r\n },\r\n onTaskCompleted: (callback: (task: PlanStep, taskNumber: number, totalTasks: number, completionNote?: string, taskDescription?: string) => void) => {\r\n cli.setOnTaskCompleted(callback);\r\n },\r\n onFileChangeSummary: (callback: (data: { filesChanged: number; insertions: number; deletions: number }) => void) => {\r\n cli.setOnFileChangeSummaryCallback(callback);\r\n },\r\n onCommandModeChange: (callback: (commandMode: boolean) => void) => {\r\n cli.setOnCommandModeChange(callback);\r\n },\r\n onToggleCommandMode: () => {\r\n cli.toggleCommandMode();\r\n },\r\n onBackgroundModeChange: (callback: (backgroundMode: boolean) => void) => {\r\n cli.setOnBackgroundModeChange(callback);\r\n },\r\n onToggleBackgroundMode: () => {\r\n cli.toggleBackgroundMode();\r\n },\r\n onBackgroundTaskCountChange: (callback: (count: number) => void) => {\r\n cli.setOnBackgroundTaskCountChange(callback);\r\n },\r\n onSubAgentCountChange: (callback: (count: number) => void) => {\r\n cli.setOnSubAgentCountChange(callback);\r\n },\r\n onSetAutoModeSetup: (callback: (enabled: boolean) => void) => {\r\n cli.setOnSetAutoMode(callback);\r\n },\r\n\r\n onCwdChange: (callback: (cwd: string) => void) => {\r\n cli.setOnCwdChange(callback);\r\n },\r\n onModelChange: (callback: (modelName: string, contextWindow: number) => void) => {\r\n cli.setOnModelChange(callback);\r\n },\r\n onSubshellContextChange: (callback: (context: any) => void) => {\r\n cli.setOnSubshellContextChange(callback);\r\n },\r\n onPasswordRequest: (callback: (message: string) => Promise<string>) => {\r\n cli.setOnPasswordRequest(callback);\r\n },\r\n onShellInput: (input: string) => {\r\n cli.writeToShellStdin(input);\r\n },\r\n onShellSignal: (signal: string) => {\r\n cli.sendSignalToShell(signal as NodeJS.Signals);\r\n },\r\n onKillProcess: () => {\r\n cli.killCurrentProcess();\r\n },\r\n onInteractiveEditorMode: (callback: (active: boolean, command?: string, cwd?: string, remoteContext?: any, parentContext?: any) => void) => {\r\n cli.setOnInteractiveEditorMode(callback);\r\n },\r\n onConnectionStatusUpdate: (callback: (status: { type: 'ssh' | 'wsl' | 'docker'; status: 'connecting' | 'connected' | 'error' | 'disconnected'; connectionString?: string; error?: string }) => void) => {\r\n cli.setOnConnectionStatusUpdate(callback);\r\n },\r\n onTokenCountUpdate: (callback: (tokens: number) => void) => {\r\n cli.setOnTokenCountUpdate(callback);\r\n },\r\n onContextLimitReached: (callback: (reached: boolean) => void) => {\r\n cli.setOnContextLimitReached(callback);\r\n },\r\n onChatPickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatPickerCallback(callback);\r\n },\r\n onChatPickerSelection: (chatId: string) => {\r\n return cli.handleChatPickerSelection(chatId);\r\n },\r\n onChatDeletePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatDeletePickerCallback(callback);\r\n },\r\n onChatDeletePickerSelection: (chatId: string) => {\r\n return cli.handleChatDeleteSelection(chatId);\r\n },\r\n onChatListSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatListCallback(callback);\r\n },\r\n onChatRenamePickerSetup: (callback: (chats: Array<{ id: string; title: string; createdAt: string; updatedAt: string; messageCount: number }>, currentChatId: string | null) => void) => {\r\n cli.setOnShowChatRenamePickerCallback(callback);\r\n },\r\n onChatRename: (chatId: string, newTitle: string) => {\r\n cli.handleChatRename(chatId, newTitle);\r\n },\r\n onRestoreMessagesSetup: (callback: (messages: any[]) => void) => {\r\n cli.setOnRestoreMessagesCallback(callback);\r\n },\r\n onUIMessageHistoryUpdate: (messages: any[]) => {\r\n cli.updateUIMessageHistory(messages);\r\n },\r\n onBackgroundTaskListSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskPickerCallback(callback);\r\n },\r\n onBackgroundTaskSelection: (taskId: string) => {\r\n cli.handleBackgroundTaskSelection(taskId);\r\n },\r\n onBackgroundTaskCancelSetup: (callback: (tasks: any[]) => void) => {\r\n cli.setOnShowBackgroundTaskCancelPickerCallback(callback);\r\n },\r\n onBackgroundTaskCancel: (taskId: string) => {\r\n cli.handleBackgroundTaskCancel(taskId);\r\n },\r\n onBackgroundTaskViewSetup: (callback: (task: any) => void) => {\r\n cli.setOnBackgroundTaskViewCallback(callback);\r\n },\r\n onSessionQuotaUpdate: (callback: (remaining: number, canSend: boolean, timeRemaining: string) => void) => {\r\n cli.setOnSessionQuotaUpdate(callback);\r\n },\r\n // MCP management callbacks\r\n onMCPAddScreenSetup: (callback: () => void) => {\r\n cli.setOnMCPAddScreenSetup(callback);\r\n },\r\n onMCPRemoveScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPRemoveScreenSetup(callback);\r\n },\r\n onMCPEnableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPEnableScreenSetup(callback);\r\n },\r\n onMCPDisableScreenSetup: (callback: (servers: Array<{ name: string; command: string; args?: string[]; enabled?: boolean }>) => void) => {\r\n cli.setOnMCPDisableScreenSetup(callback);\r\n },\r\n onMCPListScreenSetup: (callback: (servers: Array<{ name: string; enabled: boolean; status: 'connected' | 'disconnected' | 'error' | 'connecting'; tools: Array<{ name: string }> }>) => void) => {\r\n cli.setOnMCPListScreenSetup(callback);\r\n },\r\n onMCPAddServer: (config: any) => {\r\n return cli.mcpAddServer(config);\r\n },\r\n onMCPRemoveServer: (name: string) => {\r\n cli.mcpRemoveServer(name);\r\n },\r\n onMCPEnableServer: (name: string) => {\r\n cli.mcpEnableServer(name);\r\n },\r\n onMCPDisableServer: (name: string) => {\r\n cli.mcpDisableServer(name);\r\n },\r\n onMCPValidateConfig: (jsonString: string) => {\r\n return cli.mcpValidateConfig(jsonString);\r\n },\r\n onPromptAnswered: (callback: (shellId: string) => void) => {\r\n cli.setOnPromptAnswered(callback);\r\n },\r\n getMainConversation: () => {\r\n return cli.getConversationHistory();\r\n },\r\n onWarpifySession: (command: string, type: 'ssh' | 'wsl' | 'docker', connectionString?: string) => {\r\n return cli.warpifySession(command, type, connectionString);\r\n },\r\n onAiAutoSuggestChange: (callback: (enabled: boolean) => void) => {\r\n cli.setOnAiAutoSuggestChange(callback);\r\n },\r\n // Workflow callbacks\r\n\r\n onWorkflowCreatorSetup: (callback: (initialSteps?: Array<{ type: 'command' | 'instruction'; content: string }>) => void) => {\r\n cli.setOnShowWorkflowCreator(callback);\r\n },\r\n onWorkflowSave: (name: string, steps: Array<{ type: 'command' | 'instruction'; content: string }>, description?: string) => {\r\n cli.saveWorkflow(name, steps, description);\r\n },\r\n onRulesEditorSetup: (callback: (request: { mode: 'add' | 'edit'; initialName?: string; initialContent?: string }) => void) => {\r\n cli.setOnShowRulesEditor(callback);\r\n },\r\n onRuleSave: (name: string, content: string, previousName?: string) => {\r\n return cli.saveRule(name, content, previousName);\r\n },\r\n getCheckpoints: () => {\r\n return cli.getCheckpointsForAutocomplete();\r\n },\r\n onRevertToCheckpointSetup: (callback: (checkpointIndex: number, prompt: string) => void) => {\r\n cli.setOnRevertToCheckpoint(callback);\r\n },\r\n onSetInputSetup: (callback: (value: string) => void) => {\r\n cli.setOnSetInput(callback);\r\n },\r\n onInterruptQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnInterruptQueueUpdate(callback);\r\n },\r\n onQueuedMessageDispatched: (callback: (message: string) => void) => {\r\n cli.setOnQueuedMessageDispatched(callback);\r\n },\r\n onCommandQueueUpdate: (callback: (queue: string[]) => void) => {\r\n cli.setOnCommandQueueUpdate(callback);\r\n },\r\n onQueuedCommandDispatched: (callback: (command: string) => void) => {\r\n cli.setOnQueuedCommandDispatched(callback);\r\n }\r\n })\r\n ),\r\n {\r\n patchConsole: false,\r\n exitOnCtrlC: false,\r\n debug: false\r\n }\r\n );\r\n\r\n // Wait for user to exit, with a fallback mechanism\r\n // If the React component tree crashes silently or the Ink runtime enters an unexpected state,\r\n // waitUntilExit() may never resolve. This fallback ensures we can still exit via signals.\r\n const exitPromise = waitUntilExit();\r\n\r\n const fallbackPromise = new Promise<void>((resolve) => {\r\n const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];\r\n\r\n // We don't want to immediately exit on the first SIGINT if Ink is healthy \r\n // and processing it to gracefully unmount. We add a short timeout, \r\n // or just rely on the fact that if this resolves first, we exit.\r\n const signalHandler = (sig: string) => {\r\n logWarning(`Received ${sig} (Fallback handler triggered)`);\r\n // Give Ink a small window to gracefully exit first before we force it\r\n setTimeout(() => {\r\n resolve();\r\n }, 500).unref();\r\n\r\n signals.forEach(s => process.removeListener(s, signalHandler));\r\n };\r\n\r\n signals.forEach(sig => process.once(sig, signalHandler));\r\n });\r\n\r\n try {\r\n await Promise.race([exitPromise, fallbackPromise]);\r\n } catch (err) {\r\n logError('Ink render error', err as Error);\r\n } finally {\r\n // Ensure all background processes and timers are terminated\r\n process.exit(0);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n logError('Fatal error in main()', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
|
|
@@ -3074,7 +3074,7 @@ const App = ({
|
|
|
3074
3074
|
}
|
|
3075
3075
|
}
|
|
3076
3076
|
}
|
|
3077
|
-
), state.screen === "version-update" && state.versionInfo && /* @__PURE__ */ React.createElement(
|
|
3077
|
+
), state.screen === "version-update" && state.versionInfo && /* @__PURE__ */ React.createElement(
|
|
3078
3078
|
VersionUpdatePrompt,
|
|
3079
3079
|
{
|
|
3080
3080
|
currentVersion: state.versionInfo.currentVersion,
|
|
@@ -3086,7 +3086,7 @@ const App = ({
|
|
|
3086
3086
|
}));
|
|
3087
3087
|
}
|
|
3088
3088
|
}
|
|
3089
|
-
)
|
|
3089
|
+
), state.screen === "background-task-list" && state.backgroundTasks && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#9966ff", paddingX: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#9966ff", bold: true }, "Running Background Tasks"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Select a task to view its output in focus mode"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
|
|
3090
3090
|
SelectInput,
|
|
3091
3091
|
{
|
|
3092
3092
|
items: state.backgroundTasks.map((task) => {
|