Initial CST-Agent: portable Linux/Termux/Windows coding agent.
Vendored sashidown, OpenAI-compatible env (OPENAI_*), and bootstrap scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+160
@@ -0,0 +1,160 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(cst-agent C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
option(CST_BUILD_TUI "Build ncurses/PDCurses TUI" ON)
|
||||
option(CST_NATIVE_ARCH "Pass -march=native to sashidown" OFF)
|
||||
option(CST_BUNDLE_BUSYBOX "Install placeholder/scripts for busybox beside binary" ON)
|
||||
|
||||
set(SD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/sashidown")
|
||||
if(CST_NATIVE_ARCH)
|
||||
set(_SD_MAKE_EXTRA CST_NATIVE_ARCH=1)
|
||||
else()
|
||||
set(_SD_MAKE_EXTRA "")
|
||||
endif()
|
||||
|
||||
# Separate archive for MinGW so Linux host builds keep libsashidown.a
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(SASHIDOWN_A "${SD_DIR}/libsashidown-mingw.a")
|
||||
set(_MINGW_AR x86_64-w64-mingw32-ar)
|
||||
add_custom_command(
|
||||
OUTPUT "${SASHIDOWN_A}"
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} -C "${SD_DIR}" clean
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} -C "${SD_DIR}" libsashidown.a
|
||||
CC=${CMAKE_C_COMPILER} AR=${_MINGW_AR} RANLIB=x86_64-w64-mingw32-ranlib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${SD_DIR}/libsashidown.a" "${SASHIDOWN_A}"
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} -C "${SD_DIR}" clean
|
||||
COMMENT "Building libsashidown for MinGW"
|
||||
VERBATIM)
|
||||
else()
|
||||
set(SASHIDOWN_A "${SD_DIR}/libsashidown.a")
|
||||
add_custom_command(
|
||||
OUTPUT "${SASHIDOWN_A}"
|
||||
COMMAND ${CMAKE_MAKE_PROGRAM} -C "${SD_DIR}" libsashidown.a CC=${CMAKE_C_COMPILER} ${_SD_MAKE_EXTRA}
|
||||
COMMENT "Building libsashidown.a"
|
||||
VERBATIM)
|
||||
endif()
|
||||
add_custom_target(sashidown DEPENDS "${SASHIDOWN_A}")
|
||||
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
set(CST_SOURCES
|
||||
src/ctl_parse.c
|
||||
src/os_compat.c
|
||||
src/sandbox.c
|
||||
src/session.c
|
||||
src/tools/tools.c
|
||||
src/llm_openai.c
|
||||
src/agent_loop.c
|
||||
src/agent_store.c
|
||||
src/json_baseline.c
|
||||
src/creds.c
|
||||
src/mm_tool.c
|
||||
src/models.c
|
||||
src/main.c
|
||||
)
|
||||
|
||||
if(CST_BUILD_TUI)
|
||||
list(APPEND CST_SOURCES src/tui.c)
|
||||
else()
|
||||
list(APPEND CST_SOURCES src/tui_stub.c)
|
||||
endif()
|
||||
|
||||
add_executable(cst-agent ${CST_SOURCES})
|
||||
add_dependencies(cst-agent sashidown)
|
||||
|
||||
target_include_directories(cst-agent PRIVATE
|
||||
include
|
||||
"${SD_DIR}/include"
|
||||
)
|
||||
|
||||
target_compile_definitions(cst-agent PRIVATE _GNU_SOURCE)
|
||||
if(NOT WIN32)
|
||||
target_compile_definitions(cst-agent PRIVATE _XOPEN_SOURCE_EXTENDED)
|
||||
endif()
|
||||
|
||||
target_link_libraries(cst-agent PRIVATE
|
||||
"${SASHIDOWN_A}"
|
||||
CURL::libcurl
|
||||
Threads::Threads
|
||||
)
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(cst-agent PRIVATE m)
|
||||
endif()
|
||||
|
||||
if(CST_BUILD_TUI)
|
||||
if(WIN32)
|
||||
# Prefer PDCurses (pdcurses / curses). Users may set PDCurses_ROOT.
|
||||
find_path(PDCURSES_INCLUDE_DIR curses.h
|
||||
HINTS ENV PDCurses_ROOT "${PDCurses_ROOT}"
|
||||
PATH_SUFFIXES include)
|
||||
find_library(PDCURSES_LIBRARY
|
||||
NAMES pdcurses pdcurses.dll curses
|
||||
HINTS ENV PDCurses_ROOT "${PDCurses_ROOT}"
|
||||
PATH_SUFFIXES lib)
|
||||
if(PDCURSES_INCLUDE_DIR AND PDCURSES_LIBRARY)
|
||||
target_include_directories(cst-agent PRIVATE ${PDCURSES_INCLUDE_DIR})
|
||||
target_link_libraries(cst-agent PRIVATE ${PDCURSES_LIBRARY})
|
||||
target_compile_definitions(cst-agent PRIVATE CST_USE_PDCURSES=1)
|
||||
message(STATUS "TUI: PDCurses (${PDCURSES_LIBRARY})")
|
||||
else()
|
||||
message(FATAL_ERROR "CST_BUILD_TUI=ON on Windows requires PDCurses (set PDCurses_ROOT)")
|
||||
endif()
|
||||
else()
|
||||
set(CURSES_NEED_WIDE TRUE)
|
||||
find_package(Curses)
|
||||
if(CURSES_FOUND)
|
||||
target_include_directories(cst-agent PRIVATE ${CURSES_INCLUDE_DIRS})
|
||||
target_link_libraries(cst-agent PRIVATE ${CURSES_LIBRARIES})
|
||||
else()
|
||||
# Fallback common on Linux distros
|
||||
target_link_libraries(cst-agent PRIVATE ncursesw)
|
||||
endif()
|
||||
target_compile_definitions(cst-agent PRIVATE CST_USE_NCURSES=1)
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(cst-agent PRIVATE CST_HEADLESS_ONLY=1)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR WIN32)
|
||||
# curl Schannel + networking
|
||||
target_link_libraries(cst-agent PRIVATE
|
||||
ws2_32 crypt32 secur32 bcrypt advapi32)
|
||||
endif()
|
||||
|
||||
# --- tests ---
|
||||
enable_testing()
|
||||
foreach(t test_ctl_frontier test_json_baseline test_replay_starvation test_mm_tool)
|
||||
if(t STREQUAL test_ctl_frontier)
|
||||
add_executable(${t} tests/test_ctl_frontier.c src/ctl_parse.c)
|
||||
elseif(t STREQUAL test_json_baseline)
|
||||
add_executable(${t} tests/test_json_baseline.c src/json_baseline.c)
|
||||
elseif(t STREQUAL test_replay_starvation)
|
||||
add_executable(${t} tests/test_replay_starvation.c src/ctl_parse.c src/json_baseline.c)
|
||||
else()
|
||||
add_executable(${t} tests/test_mm_tool.c src/mm_tool.c)
|
||||
endif()
|
||||
target_include_directories(${t} PRIVATE include)
|
||||
target_compile_definitions(${t} PRIVATE _GNU_SOURCE)
|
||||
add_test(NAME ${t} COMMAND ${t})
|
||||
endforeach()
|
||||
|
||||
# --- busybox bundle helpers ---
|
||||
if(CST_BUNDLE_BUSYBOX)
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/busybox/README.md"
|
||||
DESTINATION .
|
||||
OPTIONAL)
|
||||
if(WIN32 AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/busybox/busybox.exe")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/busybox/busybox.exe" DESTINATION .)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS cst-agent RUNTIME DESTINATION .)
|
||||
|
||||
message(STATUS "Compiler: ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER}")
|
||||
message(STATUS "CST_BUILD_TUI=${CST_BUILD_TUI}")
|
||||
Reference in New Issue
Block a user