(sessionId: string, options?: AttachSessionOptions)
| 95 | }; |
| 96 | |
| 97 | export async function attachSession(sessionId: string, options?: AttachSessionOptions): Promise<void> { |
| 98 | const metadata = await readSessionMetadata(sessionId); |
| 99 | if (!metadata) { |
| 100 | console.error(chalk.red(`No session found with ID ${sessionId}`)); |
| 101 | process.exitCode = 1; |
| 102 | return; |
| 103 | } |
| 104 | const initialStatus = metadata.status; |
| 105 | const wantsRender = Boolean(options?.renderMarkdown); |
| 106 | const isVerbose = Boolean(process.env.ORACLE_VERBOSE_RENDER); |
| 107 | if (!options?.suppressMetadata) { |
| 108 | const reattachLine = buildReattachLine(metadata); |
| 109 | if (reattachLine) { |
| 110 | console.log(chalk.blue(reattachLine)); |
| 111 | } |
| 112 | console.log(`Created: ${metadata.createdAt}`); |
| 113 | console.log(`Status: ${metadata.status}`); |
| 114 | console.log(`Model: ${metadata.model}`); |
| 115 | const responseSummary = formatResponseMetadata(metadata.response); |
| 116 | if (responseSummary) { |
| 117 | console.log(dim(`Response: ${responseSummary}`)); |
| 118 | } |
| 119 | const transportSummary = formatTransportMetadata(metadata.transport); |
| 120 | if (transportSummary) { |
| 121 | console.log(dim(`Transport: ${transportSummary}`)); |
| 122 | } |
| 123 | const userErrorSummary = formatUserErrorMetadata(metadata.error); |
| 124 | if (userErrorSummary) { |
| 125 | console.log(dim(`User error: ${userErrorSummary}`)); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | const shouldTrimIntro = initialStatus === 'completed' || initialStatus === 'error'; |
| 130 | if (options?.renderPrompt !== false) { |
| 131 | const prompt = await readStoredPrompt(sessionId); |
| 132 | if (prompt) { |
| 133 | console.log(chalk.bold('Prompt:')); |
| 134 | console.log(renderMarkdownAnsi(prompt)); |
| 135 | console.log(dim('---')); |
| 136 | } |
| 137 | } |
| 138 | if (shouldTrimIntro) { |
| 139 | const fullLog = await readSessionLog(sessionId); |
| 140 | const trimmed = trimBeforeFirstAnswer(fullLog); |
| 141 | const size = Buffer.byteLength(trimmed, 'utf8'); |
| 142 | const canRender = wantsRender && isTty() && size <= MAX_RENDER_BYTES; |
| 143 | if (wantsRender && size > MAX_RENDER_BYTES) { |
| 144 | const msg = `Render skipped (log too large: ${size} bytes > ${MAX_RENDER_BYTES}). Showing raw text.`; |
| 145 | console.log(dim(msg)); |
| 146 | if (isVerbose) { |
| 147 | console.log(dim(`Verbose: renderMarkdown=true tty=${isTty()} size=${size}`)); |
| 148 | } |
| 149 | } else if (wantsRender && !isTty()) { |
| 150 | const msg = 'Render requested but stdout is not a TTY; showing raw text.'; |
| 151 | console.log(dim(msg)); |
| 152 | if (isVerbose) { |
| 153 | console.log(dim(`Verbose: renderMarkdown=true tty=${isTty()} size=${size}`)); |
| 154 | } |
no test coverage detected