Extensions: skills, plugins, MCP, sub-agents; configurable keys

- Skills (SKILL.md discovery, skill tool, /skills /skill)
- plugin.json exec tools with permission prompts, timeouts and workspace trust (/plugins)
- MCP stdio client: JSON-RPC initialize/tools/list/tools/call, mcp__server__tool, /mcp and sidebar status
- task tool with general/explore/plan and .agent/agents/*.md roles, parallel read-only runs, cancel propagation, /agents
- Keymap with Ctrl+X leader, keybinds.json overrides and /keys panel
- Collapsed thinking, throttled streaming Markdown, leaner tool output, parallel read-only tools
- Spawn: close-on-exec pipes and a process-wide fork lock
- Tests for keymap, skills, plugins, MCP, sub-agents, shell compaction; docs/plugins.md
This commit is contained in:
WHC
2026-10-05 14:55:31 +08:00
parent c81df42f0b
commit 7d3ec9fcb9
38 changed files with 8356 additions and 399 deletions
+116
View File
@@ -0,0 +1,116 @@
/* cst_shell_compact: ANSI stripping, \r progress folding, repeated-line
* collapse and head/tail cutting of run_shell output. */
#include "cst_tools.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int nfail;
#define CHECK(cond, msg) \
do { \
if (!(cond)) { \
fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, msg); \
nfail++; \
} \
} while (0)
static char *compact(const char *s) {
size_t n = 0;
return cst_shell_compact(s, strlen(s), &n);
}
int main(void) {
char *o;
o = compact("plain\noutput\n");
CHECK(o && strcmp(o, "plain\noutput\n") == 0, "clean output unchanged");
free(o);
o = compact("no newline");
CHECK(o && strcmp(o, "no newline") == 0, "missing final newline kept");
free(o);
o = compact("");
CHECK(o && strcmp(o, "") == 0, "empty");
free(o);
o = compact("a\n\nb\n");
CHECK(o && strcmp(o, "a\n\nb\n") == 0, "blank lines kept");
free(o);
o = compact("\x1b[1;31merror\x1b[0m: bad\n\x1b]0;title\x07ok\n");
CHECK(o && strcmp(o, "error: bad\nok\n") == 0, "ANSI CSI and OSC removed");
free(o);
o = compact(" 0%\r 50%\r100%\ndone\r\n");
CHECK(o && strcmp(o, "100%\ndone\n") == 0, "\\r progress folded, CRLF ok");
free(o);
o = compact("ab\bc\n");
CHECK(o && strcmp(o, "ac\n") == 0, "backspace applied");
free(o);
o = compact("x\nx\ny\n");
CHECK(o && strcmp(o, "x\nx\ny\n") == 0, "a pair is kept as is");
free(o);
o = compact("start\nwarn\nwarn\nwarn\nwarn\nend\n");
CHECK(o && strcmp(o, "start\nwarn\n… (previous line repeated 3 more "
"times)\nend\n") == 0,
"runs collapsed");
free(o);
{
char *big = malloc(1000 * 16);
size_t used = 0;
for (int i = 1; i <= 1000; i++)
used += (size_t)sprintf(big + used, "line %d\n", i);
o = compact(big);
CHECK(o && strstr(o, "line 1\n") && strstr(o, "line 80\n") &&
!strstr(o, "line 81\n") && strstr(o, "… 800 lines omitted …\n") &&
strstr(o, "line 881\n") && strstr(o, "line 1000\n"),
"head + tail with omitted count");
free(o);
free(big);
}
{
char *wide = malloc(5000 + 2);
memset(wide, 'w', 5000);
wide[5000] = '\n';
wide[5001] = 0;
o = compact(wide);
CHECK(o && strstr(o, " … [+3000 bytes]\n") && strlen(o) < 2100,
"long line cut");
free(o);
free(wide);
}
{
/* 200 lines of 1 KB: over the byte budget, the tail wins */
char *fat = malloc(200 * 1030);
size_t used = 0;
for (int i = 1; i <= 200; i++) {
used += (size_t)sprintf(fat + used, "%04d ", i);
memset(fat + used, 'f', 1000);
used += 1000;
fat[used++] = '\n';
}
fat[used] = 0;
o = compact(fat);
CHECK(o && strlen(o) <= 42 * 1024 && strstr(o, "0200 ") &&
strstr(o, "lines omitted"),
"byte budget keeps the tail");
free(o);
free(fat);
}
if (nfail) {
fprintf(stderr, "test_shell_compact: %d failure(s)\n", nfail);
return 1;
}
printf("test_shell_compact: OK\n");
return 0;
}