Wave 8: tech-debt audits, core unit tests, CLI pipe input (W11.1-W11.7)
- W11.1 context_plugin audit (architect-huang): 3 findings on ABI exception safety, strdup null checks, dead g_max_tokens variable. Rating: B. - W11.2 config audit (engineer-chen): identified 74-line TOML parser duplication between config_plugin and config_store, dual-store data isolation, dangling c_str() risk. Rating: C. - W11.3 event_bus + service_registry unit tests (qa-liu): 12 cases total, ctest coverage 2 -> 4 targets, 100% pass. - W11.4 CLI stdin pipe mode (engineer-zhao): isatty detection, single-shot inference path with exit codes 0/1/2/3. - W11.6 scripts/refresh_status.py (engineer-li): 431-line generator that scans 16 profile.md + 5 group.md to regenerate STATUS.md. - W11.7 destructive testing (qa-xu): 10 input scenarios PASS, found bin copy mismatch (BUG-1) plus 3 minor UX bugs for follow-up. Verified: cmake build 0 error, ctest 4/4 pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -349,19 +349,22 @@ int main(int argc, char* argv[])
|
||||
SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
#endif
|
||||
|
||||
// ---- C1: batch 模式检测 ----
|
||||
// ---- C1: batch/pipe 模式检测 ----
|
||||
#ifdef _WIN32
|
||||
bool pipe_mode = (_isatty(_fileno(stdin)) == 0);
|
||||
#else
|
||||
bool pipe_mode = (isatty(fileno(stdin)) == 0);
|
||||
#endif
|
||||
bool batch_mode = false;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (std::strcmp(argv[i], "--batch") == 0) {
|
||||
batch_mode = true;
|
||||
break;
|
||||
if (!pipe_mode) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (std::strcmp(argv[i], "--batch") == 0) {
|
||||
batch_mode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (!batch_mode && _isatty(_fileno(stdin)) == 0) batch_mode = true;
|
||||
#else
|
||||
if (!batch_mode && isatty(fileno(stdin)) == 0) batch_mode = true;
|
||||
#endif
|
||||
if (pipe_mode) batch_mode = true;
|
||||
|
||||
// ---- B1: 安装 Ctrl+C 处理 ----
|
||||
#ifdef _WIN32
|
||||
@@ -435,6 +438,40 @@ int main(int argc, char* argv[])
|
||||
std::printf("\n");
|
||||
}
|
||||
|
||||
// ---- B3: 管道输入模式 (非交互) ----
|
||||
if (pipe_mode) {
|
||||
std::string input;
|
||||
char buf[4096];
|
||||
while (std::fgets(buf, sizeof(buf), stdin)) {
|
||||
input += buf;
|
||||
}
|
||||
if (input.empty()) {
|
||||
std::fprintf(stderr, "empty prompt\n");
|
||||
dstalk_shutdown();
|
||||
return 1;
|
||||
}
|
||||
if (!g_ai || !g_session) {
|
||||
std::fprintf(stderr, CLR_RED "[ERROR] AI or session service unavailable\n" CLR_RESET);
|
||||
dstalk_shutdown();
|
||||
return EXIT_SVC_UNAVAIL;
|
||||
}
|
||||
int history_count = 0;
|
||||
const dstalk_message_t* history = g_session->history(&history_count);
|
||||
dstalk_chat_result_t result = g_ai->chat(history, history_count, input.c_str(), nullptr);
|
||||
if (result.ok) {
|
||||
std::printf("%s\n", result.content ? result.content : "");
|
||||
g_ai->free_result(&result);
|
||||
dstalk_shutdown();
|
||||
return EXIT_OK;
|
||||
} else {
|
||||
std::fprintf(stderr, CLR_RED "[ERROR] AI error: %s\n" CLR_RESET,
|
||||
result.error ? result.error : "unknown");
|
||||
g_ai->free_result(&result);
|
||||
dstalk_shutdown();
|
||||
return EXIT_AI_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[8192];
|
||||
while (true) {
|
||||
// B1: 检查退出标志
|
||||
|
||||
Reference in New Issue
Block a user