feat: todo lists, permission modes, project instructions, and agent robustness

- Add todo_write tool with live checklist rendering in the UI
- Add permission modes (default/plan/auto-edit/auto-accept) cycled via Shift+Tab or /perm
- Load CLAUDE.md/AGENTS.md as project instructions into the system prompt
- Forward sub-agent tool calls/results to parent UI panel
- Auto-compact context mid-turn and keep model moving with a synthetic user turn
- Prune older image_url parts to cap vision token cost
- Idle-abort guard for stalled streaming backends
- Improve background bash jobs, kill whole process trees on timeout/exit
- Expand hooks: command/http hooks, blocking, JSON outputSchema
- MCP: JSON schema → Zod conversion, parallel connection, duplicate server detection
- Add tests for loop, confirmFn, projectInstructions, readFile, bash, todoWrite, contextWindowCache
This commit is contained in:
kim
2026-07-13 15:47:48 +09:00
parent f01898a9c3
commit eb03d0bd14
59 changed files with 1757 additions and 208 deletions
+11 -3
View File
@@ -114,7 +114,7 @@ configCmd
configCmd
.command("set <key> <value>")
.description("Persist a config value (backend, model, baseUrl, contextWindow, maxIterations, autoCompactThreshold, requestTimeoutMs)")
.description("Persist a config value (backend, model, baseUrl, contextWindow, maxIterations, autoCompactThreshold, requestTimeoutMs, subagentTimeoutMs)")
.action((key: string, value: string) => {
if (
key !== "backend" &&
@@ -123,10 +123,11 @@ configCmd
key !== "contextWindow" &&
key !== "maxIterations" &&
key !== "autoCompactThreshold" &&
key !== "requestTimeoutMs"
key !== "requestTimeoutMs" &&
key !== "subagentTimeoutMs"
) {
console.error(
`Unknown config key "${key}". Valid keys: backend, model, baseUrl, contextWindow, maxIterations, autoCompactThreshold, requestTimeoutMs`,
`Unknown config key "${key}". Valid keys: backend, model, baseUrl, contextWindow, maxIterations, autoCompactThreshold, requestTimeoutMs, subagentTimeoutMs`,
);
process.exit(1);
}
@@ -152,6 +153,13 @@ configCmd
process.exit(1);
}
stored[key] = n;
} else if (key === "subagentTimeoutMs") {
const n = Number(value);
if (!Number.isFinite(n) || n < 1_000 || n > 3_600_000) {
console.error(`subagentTimeoutMs must be between 1000 and 3600000, got "${value}".`);
process.exit(1);
}
stored[key] = n;
} else {
stored[key] = value;
}