// tui_script: scripted headless session over the demo scene, to diff against python. // Script lines (stdin): // feed stdin bytes -> TuiInput -> app.dispatch // flush TuiInput.flush() -> dispatch (lone ESC resolution) // frame print hex of app.frame_bytes() // text print app.render_text() // resize R C like SIGWINCH: new size, invalidate, dirty_layout, Resize event // shell feed text (with \r\n for \n) into the demo shell screen // ask open the demo question dialog (F1 path) // sources install the completion sources used by the prompt dialog #include "TuiComplete.h" #include "TuiDemo.h" #include #include #include #include using namespace detz::tui; static std::string unhex(const std::string& h) { std::string out; for (size_t i = 0; i + 1 < h.size(); i += 2) out.push_back(static_cast(std::stoi(h.substr(i, 2), nullptr, 16))); return out; } static std::string hex(const std::string& s) { static const char* d = "0123456789abcdef"; std::string out; for (unsigned char c : s) { out.push_back(d[c >> 4]); out.push_back(d[c & 15]); } return out; } int main(int argc, char** argv) { int rows = argc > 1 ? std::atoi(argv[1]) : 30; int cols = argc > 2 ? std::atoi(argv[2]) : 100; TuiApp app; app.rows = rows; app.cols = cols; auto built = TuiDemo::build(app, false); app.mount(built.first); auto& refs = *built.second; std::string line; while (std::getline(std::cin, line)) { std::istringstream in(line); std::string cmd; in >> cmd; if (cmd == "feed") { std::string h; in >> h; for (auto& ev : app.input.feed(unhex(h))) app.dispatch(*ev); } else if (cmd == "flush") { for (auto& ev : app.input.flush()) app.dispatch(*ev); } else if (cmd == "frame") { std::printf("%s\n", hex(app.frame_bytes()).c_str()); } else if (cmd == "text") { std::printf("%s\n--\n", app.render_text().c_str()); } else if (cmd == "resize") { int r, c; in >> r >> c; app.rows = r; app.cols = c; app.compositor.invalidate(); app.dirty_layout(); TuiResize ev; ev.panel = app.root.get(); ev.rows = r; ev.cols = c; app.root->emit(ev); } else if (cmd == "shell") { std::string h; in >> h; refs.shell->screen.feed(unhex(h)); } else if (cmd == "ask") { refs.ask(); } else if (cmd == "spawn") { refs.spawn(); } else if (cmd == "sources") { auto& s = TuiComplete::sources(); s.commands = {"help", "profile", "bots", "quit"}; s.help_text = " /help show help Show this help\n /profile NAME switch Switch profile\n /bots list bots\n"; s.provider_labels = {"Muse", "Grok"}; s.default_models = [] { return std::vector{"model-a", "model-b"}; }; s.complete_files = [](const std::string&, const std::string&) { return std::vector{"src/a.txt"}; }; s.dir_key = [] { return std::string("/tmp"); }; TuiComplete::reset_command_help(); } } return 0; }