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
+13 -5
View File
@@ -3251,11 +3251,19 @@ static int run_turn_once(cst_agent_t *a, const char *user_text,
}
turn_free(&t);
if (empty_retries < 2 && step + 1 < a->cfg.max_steps) {
empty_retries++;
nudge = NUDGE_EMPTY;
hook_status(&t, "empty response — retrying...");
continue;
/* Headless / unattended turns allow more empty-answer retries so a
* flaky gateway does not end the turn blank. CST_EMPTY_RETRIES overrides. */
{
int empty_cap = a->cfg.headless ? 4 : 2;
const char *env_er = getenv("CST_EMPTY_RETRIES");
if (env_er && atoi(env_er) > 0)
empty_cap = atoi(env_er);
if (empty_retries < empty_cap && step + 1 < a->cfg.max_steps) {
empty_retries++;
nudge = NUDGE_EMPTY;
hook_status(&t, "empty response — retrying...");
continue;
}
}
/* Last resort: surface the latest tool output so the turn isn't blank. */
if (tools_ran) {