()
| 293 | } |
| 294 | |
| 295 | protected async runMainLoop(): Promise<void> { |
| 296 | const session = this.session; |
| 297 | const messageBuffer = this.messageBuffer; |
| 298 | const appServerClient = this.appServerClient; |
| 299 | const appServerEventConverter = new AppServerEventConverter(); |
| 300 | |
| 301 | const normalizeCommand = (value: unknown): string | undefined => { |
| 302 | if (typeof value === 'string') { |
| 303 | const trimmed = value.trim(); |
| 304 | return trimmed.length > 0 ? trimmed : undefined; |
| 305 | } |
| 306 | if (Array.isArray(value)) { |
| 307 | const joined = value.filter((part): part is string => typeof part === 'string').join(' '); |
| 308 | return joined.length > 0 ? joined : undefined; |
| 309 | } |
| 310 | return undefined; |
| 311 | }; |
| 312 | |
| 313 | const asRecord = (value: unknown): Record<string, unknown> | null => { |
| 314 | if (!value || typeof value !== 'object') { |
| 315 | return null; |
| 316 | } |
| 317 | return value as Record<string, unknown>; |
| 318 | }; |
| 319 | |
| 320 | const asString = (value: unknown): string | null => { |
| 321 | return typeof value === 'string' && value.length > 0 ? value : null; |
| 322 | }; |
| 323 | |
| 324 | const errorMessage = (error: unknown): string => { |
| 325 | return error instanceof Error ? error.message : String(error); |
| 326 | }; |
| 327 | |
| 328 | const extractSpawnAgentStartErrorFromStderr = (text: string): string | null => { |
| 329 | const cleanText = stripAnsi(text); |
| 330 | return cleanText.includes(CODEX_SPAWN_AGENT_FULL_HISTORY_ARGUMENT_ERROR) |
| 331 | ? CODEX_SPAWN_AGENT_FULL_HISTORY_ARGUMENT_ERROR |
| 332 | : null; |
| 333 | }; |
| 334 | |
| 335 | const isExitPlanModeTool = (toolName: string): boolean => { |
| 336 | return toolName === 'exit_plan_mode' || toolName === 'ExitPlanMode'; |
| 337 | }; |
| 338 | |
| 339 | const shouldRetryWithoutCollaborationMode = (error: unknown): boolean => { |
| 340 | const message = errorMessage(error).toLowerCase(); |
| 341 | const mentionsCollaborationMode = message.includes('collaborationmode') |
| 342 | || message.includes('collaboration_mode') |
| 343 | || message.includes('collaboration mode'); |
| 344 | if (!mentionsCollaborationMode) { |
| 345 | return false; |
| 346 | } |
| 347 | |
| 348 | return message.includes('experimentalapi') |
| 349 | || message.includes('unsupported') |
| 350 | || message.includes('unknown') |
| 351 | || message.includes('unrecognized') |
| 352 | || message.includes('unexpected') |
nothing calls this directly
no test coverage detected