Complete build wiring and CLI file commands
Align documented commands with the CLI, enable optional GUI/test targets, and remove committed API secrets so the project is safer to build and run. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -9,3 +9,9 @@ add_executable(dstalk-cli
|
||||
target_link_libraries(dstalk-cli
|
||||
PRIVATE dstalk
|
||||
)
|
||||
|
||||
add_custom_command(TARGET dstalk-cli POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:dstalk>
|
||||
$<TARGET_FILE_DIR:dstalk-cli>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -36,17 +40,66 @@ static void print_banner()
|
||||
static void print_help()
|
||||
{
|
||||
std::printf("\n%s命令列表:%s\n", CLR_BOLD, CLR_RESET);
|
||||
std::printf(" %s/help%s 显示此帮助\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/quit%s 退出程序\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/clear%s 清空当前会话上下文\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/model <name>%s 切换模型\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file read <path>%s 读取文件内容\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file write <p> <c>%s写入文件\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/save <path>%s 保存会话\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/load <path>%s 恢复会话\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/help%s 显示此帮助\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/quit%s 退出程序\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/clear%s 清空当前会话上下文\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/model <name>%s 切换模型\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file list [path]%s 列出目录内容\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file show <path>%s 查看文件内容\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file read <path>%s 读取文件内容\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/file write <p> <c>%s 写入文件\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/save <path>%s 保存会话\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf(" %s/load <path>%s 恢复会话\n", CLR_YELLOW, CLR_RESET);
|
||||
std::printf("\n直接输入问题即可与 AI 对话。\n\n");
|
||||
}
|
||||
|
||||
static void print_file(const char* path)
|
||||
{
|
||||
while (*path == ' ') path++;
|
||||
char* content = nullptr;
|
||||
if (dstalk_file_read(path, &content) == 0 && content) {
|
||||
std::printf("%s--- %s ---%s\n", CLR_DIM, path, CLR_RESET);
|
||||
std::printf("%s\n", content);
|
||||
std::printf(CLR_DIM "--- EOF ---\n" CLR_RESET);
|
||||
dstalk_free_string(content);
|
||||
} else {
|
||||
std::printf(CLR_RED "[ERROR] 无法读取: %s\n" CLR_RESET, path);
|
||||
}
|
||||
}
|
||||
|
||||
static void list_files(const char* path)
|
||||
{
|
||||
while (*path == ' ') path++;
|
||||
std::filesystem::path dir = *path ? std::filesystem::path(path) : std::filesystem::current_path();
|
||||
|
||||
std::error_code ec;
|
||||
if (!std::filesystem::exists(dir, ec) || !std::filesystem::is_directory(dir, ec)) {
|
||||
std::printf(CLR_RED "[ERROR] 不是有效目录: %s\n" CLR_RESET, dir.string().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::directory_entry> entries;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir, ec)) {
|
||||
if (ec) break;
|
||||
entries.push_back(entry);
|
||||
}
|
||||
if (ec) {
|
||||
std::printf(CLR_RED "[ERROR] 无法列出目录: %s\n" CLR_RESET, dir.string().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::sort(entries.begin(), entries.end(), [](const auto& a, const auto& b) {
|
||||
return a.path().filename().string() < b.path().filename().string();
|
||||
});
|
||||
|
||||
std::printf("%s--- %s ---%s\n", CLR_DIM, dir.string().c_str(), CLR_RESET);
|
||||
for (const auto& entry : entries) {
|
||||
std::error_code status_ec;
|
||||
const bool is_dir = entry.is_directory(status_ec);
|
||||
std::printf(" %s%s%s\n", is_dir ? CLR_CYAN : "", entry.path().filename().string().c_str(), is_dir ? "/" CLR_RESET : "");
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_command(const char* line)
|
||||
{
|
||||
if (!line || line[0] != '/') return;
|
||||
@@ -80,19 +133,22 @@ static void handle_command(const char* line)
|
||||
return;
|
||||
}
|
||||
|
||||
// /file list [path]
|
||||
if (std::strcmp(line, "/file list") == 0 || std::strncmp(line, "/file list ", 11) == 0) {
|
||||
const char* path = line + 10;
|
||||
list_files(path);
|
||||
return;
|
||||
}
|
||||
|
||||
// /file show <path>
|
||||
if (std::strncmp(line, "/file show ", 11) == 0) {
|
||||
print_file(line + 11);
|
||||
return;
|
||||
}
|
||||
|
||||
// /file read <path>
|
||||
if (std::strncmp(line, "/file read ", 11) == 0) {
|
||||
const char* path = line + 11;
|
||||
while (*path == ' ') path++;
|
||||
char* content = nullptr;
|
||||
if (dstalk_file_read(path, &content) == 0 && content) {
|
||||
std::printf("%s--- %s ---%s\n", CLR_DIM, path, CLR_RESET);
|
||||
std::printf("%s\n", content);
|
||||
std::printf(CLR_DIM "--- EOF ---\n" CLR_RESET);
|
||||
dstalk_free_string(content);
|
||||
} else {
|
||||
std::printf(CLR_RED "[ERROR] 无法读取: %s\n" CLR_RESET, path);
|
||||
}
|
||||
print_file(line + 11);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user