feat: password Realm, single-chair login, shared parliament context (0.9.12)

Derive Realm keys from a user password (Argon2id, no private key on disk).
Login claims the sole chair with handover; peers share parliament context;
--new-project clears it. CLI peer/discover helpers and Docker alpine recipe
included; headless empty-answer retries raised for unattended runs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-28 23:06:51 +08:00
co-authored by Cursor
parent 08ca613a0e
commit de9ee28773
18 changed files with 1101 additions and 8 deletions
+15
View File
@@ -775,6 +775,14 @@ static int task_run(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c,
(void)ud;
if (!ctx->agent)
return out_text(r, 1, "error: task needs a running agent");
{
cst_settings_t s; cst_settings_load(&s);
const char *mode = getenv("CST_COLLABORATION");
if ((!mode || !mode[0]) && s.collaboration[0]) mode = s.collaboration;
if (mode && !strcmp(mode, "parliament"))
return out_text(r, 1, "error: collaboration=parliament replaces in-process "
"workers; use Realm peer seats");
}
const cst_agent_config_t *pcfg = cst_agent_config(ctx->agent);
if (pcfg->depth > 0)
return out_text(r, 1, "error: a sub-agent cannot start sub-agents; do "
@@ -1179,6 +1187,13 @@ static int async_worker_tool(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c
if (!ctx->agent) return out_text(out, 1, "error: no agent");
const cst_agent_config_t *cfg = cst_agent_config(ctx->agent);
if (cfg->depth || !cfg->runtime) return out_text(out, 1, "error: only the main agent can schedule workers");
{
cst_settings_t s; cst_settings_load(&s);
const char *mode = getenv("CST_COLLABORATION");
if ((!mode || !mode[0]) && s.collaboration[0]) mode = s.collaboration;
if (mode && !strcmp(mode, "parliament"))
return out_text(out, 1, "error: collaboration=parliament replaces in-process workers; use Realm peer seats");
}
if (strcmp(c->name, "worker_start")) {
const char *wt = arg(c, "worktree"); int code;
if (wt && cst_runtime_resource_busy(cfg->runtime, wt)) return out_text(out, 1, "error: worker is still using this worktree; wait before review/integration");