-- renderer.lua — output formatting and ANSI sequences. -- Phase 0: assistant text plain-printed with `CMD: ` lines highlighted; -- exec output framed with the exit code on the closing rule. Syntax -- highlighting hooks land in Phase 6 (was Phase 5 pre-MCP renumber). local M = {} local A = { reset = "\27[0m", bold = "\27[1m", dim = "\27[2m", cyan = "\27[36m", red = "\27[31m", } local function emit(...) io.write(...); io.flush() end -- Print assistant response text. Lines beginning with `CMD: ` (per the §3 -- substrate-locked extraction marker) are emitted bold+cyan so the user -- can spot the suggestion without scanning prose. function M.assistant(text) for line in ((text or "") .. "\n"):gmatch("([^\n]*)\n") do if line:sub(1, 5) == "CMD: " then emit(A.bold, A.cyan, line, A.reset, "\n") else emit(line, "\n") end end end -- Frame captured shell-exec output with a top rule + the body + a closing -- rule that carries the exit code (red on non-zero). function M.exec_output(output, exit_code) output = (output or ""):gsub("\n$", "") emit(A.dim, "─── exec output ───", A.reset, "\n") if output ~= "" then emit(output, "\n") end if exit_code and exit_code ~= 0 then emit(A.dim, "─── exit ", A.reset, A.red, tostring(exit_code), A.reset, A.dim, " ───", A.reset, "\n") else emit(A.dim, "─── exit 0 ───", A.reset, "\n") end end -- Single-line dim status (e.g. §8 eviction notice, model switch confirms). function M.status(line) emit(A.dim, "[aish] ", tostring(line), A.reset, "\n") end return M