Files
Hermit/include/cst_tools.h
T
WHC ef63f6d612
ci / linux (clang) (push) Canceled after 0s
ci / linux (gcc) (push) Canceled after 0s
ci / sanitizers (push) Canceled after 0s
ci / musl (push) Canceled after 0s
ci / macos (push) Canceled after 0s
OpenCode-style TUI, model probing, sandboxed auto approval
- TUI: centered home screen with logo, boxed input with mode line, sidebar
  (>=120 cols), Ctrl+P palette, Tab Build/Plan, Shift+Tab approval cycle,
  mouse (cards, cursor, pickers, wheel), /sidebar /mouse /approval
- /models probing: key check on entry (401 re-asks), API models in /model
- Shell sandbox in C: Linux Landlock (writes limited to workspace/tmp,
  ABI>=4 blocks TCP), macOS sandbox_init, rules fallback elsewhere
- Approval modes ask/auto/yolo (default auto); read-only command whitelist;
  ask to rerun outside the sandbox when a command looks blocked
- Upgradable bootstrap scripts (git pull --ff-only, rebuild, reinstall) and
  cst-agent-update; cst-agent --version
- tests: test_sandbox, test_models
2026-10-05 12:34:46 +08:00

109 lines
4.0 KiB
C

#ifndef CST_TOOLS_H
#define CST_TOOLS_H
#include "cst_agent.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CST_TOOL_MAX_PARAMS 6
#define CST_TOOL_MAX_TARGETS 16
/* Up to max workspace-relative regular files (ignores .git, node_modules,
* root .gitignore ...). Caller frees each entry and the array. */
int cst_workspace_files(const char *ws, char ***out, int max);
/* What a call can touch; drives confirmation, undo and duplicate-read logic. */
typedef enum {
CST_TP_READ = 0, /* reads the workspace */
CST_TP_WRITE, /* changes files (snapshotted for /undo) */
CST_TP_SHELL, /* arbitrary commands */
CST_TP_NET, /* network access */
CST_TP_ASK, /* talks to the user */
CST_TP_META /* agent bookkeeping (todo list) */
} cst_tool_perm_t;
typedef struct {
const char *name;
const char *type; /* "string" | "integer" | "boolean" */
int required;
const char *desc;
} cst_tool_param_t;
typedef struct cst_tool_ctx {
const char *workspace_root;
/* ask_user: fills ans; returns 0, or -1 when nobody can answer. */
int (*ask)(const char *question, const char *options, char *ans,
size_t ans_sz, void *ud);
void *ask_ud;
/* todo_write: the list was replaced (text form, one item per line). */
void (*set_todo)(const char *text, void *ud);
void *todo_ud;
int sandbox; /* run_shell: confine to the workspace (cst_sandbox.h) */
} cst_tool_ctx_t;
typedef int (*cst_tool_run_fn)(const cst_tool_ctx_t *ctx,
const ctl_tool_call_t *call,
cst_tool_result_t *r);
/* Write tools: compute the diff a call would produce without touching disk.
* Returns 0 and a malloc'd text, or -1 with an error text in *out. */
typedef int (*cst_tool_preview_fn)(const cst_tool_ctx_t *ctx,
const ctl_tool_call_t *call, char **out);
typedef struct {
const char *name;
const char *desc;
/* `--tools minimal` schema text (the original wording; required params
* only), so paper runs keep sending byte-identical requests. */
const char *min_desc;
cst_tool_param_t params[CST_TOOL_MAX_PARAMS];
cst_tool_perm_t perm;
int minimal; /* member of `--tools minimal` (the original four) */
cst_tool_run_fn run;
cst_tool_preview_fn preview;
} cst_tool_def_t;
typedef enum { CST_TOOLS_DEFAULT = 0, CST_TOOLS_MINIMAL } cst_tool_profile_t;
int cst_tool_profile_parse(const char *s, int *out);
const char *cst_tool_profile_name(int p);
int cst_tool_count(void);
const cst_tool_def_t *cst_tool_at(int i);
const cst_tool_def_t *cst_tool_find(const char *name);
int cst_tool_index(const char *name);
/* Enabled for this config (profile + /tools switches). cfg may be NULL. */
int cst_tool_active(const cst_agent_config_t *cfg, const cst_tool_def_t *t);
/* OpenAI tools[] for the active set (cJSON*, caller frees). */
void *cst_tools_schema_cfg(const cst_agent_config_t *cfg);
/* "Tools:\n- name(a, b?): ...\n" for the active set (malloc'd). */
char *cst_tools_prompt(const cst_agent_config_t *cfg);
/* Comma-separated active tool names (malloc'd). */
char *cst_tools_names(const cst_agent_config_t *cfg);
/* Missing required args / bad integers. 0 = ok. */
int cst_tool_validate(const cst_tool_def_t *t, const ctl_tool_call_t *call,
char *err, size_t err_sz);
int cst_tool_run(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *call,
cst_tool_result_t *r);
int cst_tool_preview(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *call,
char **out);
/* Workspace-relative files a write call may change (for /undo snapshots).
* Returns the count written into paths. */
int cst_tool_targets(const ctl_tool_call_t *call, char paths[][1024], int max);
/* Unified diff (3 lines of context, GNU `diff -u` layout) with
* `--- a/<label>` / `+++ b/<label>` headers. Returns malloc'd text; "" when
* identical. */
char *cst_diff_unified(const char *label, const char *a, size_t alen,
const char *b, size_t blen);
#ifdef __cplusplus
}
#endif
#endif