feat: /realm in TUI, daemon instance takeover (0.9.16)

Pidfile records instance+port; login restarts the service when the seat
changes. TUI /realm status|login|stop; prompts discourage filler chatter.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 11:00:34 +08:00
co-authored by Cursor
parent e610d70c30
commit a3e115539e
8 changed files with 202 additions and 24 deletions
+80
View File
@@ -12,6 +12,7 @@
#include "cst_models.h"
#include "cst_parliament.h"
#include "cst_plugins.h"
#include "cst_realm.h"
#include "cst_provider_switch.h"
#include "cst_skills.h"
#include "cst_subagent.h"
@@ -4624,6 +4625,83 @@ static void cmd_max_steps(tui_t *t, char *arg, int *quit) {
push_system_line(t, "(max steps per turn: %d)", cfg->max_steps);
}
static void cmd_realm(tui_t *t, char *arg, int *quit) {
(void)quit;
const char *sub = arg && arg[0] ? arg : "status";
if (!strcmp(sub, "status") || !strcmp(sub, "show")) {
char *pst = cst_parliament_status_text();
if (pst && pst[0]) {
push_system_line(t, "Realm / Parliament:");
char *p = pst;
while (*p) {
char *nl = strchr(p, '\n');
if (nl)
*nl = 0;
if (p[0])
push_system_line(t, " %s", p);
if (!nl)
break;
p = nl + 1;
}
} else {
push_system_line(t, "(no realm status)");
}
free(pst);
return;
}
if (!strcmp(sub, "stop")) {
if (cst_parliament_daemon_stop() != 0)
push_system_line(t, "Error: could not stop parliament service");
else
push_system_line(t, "(parliament service stopped)");
return;
}
if (!strncmp(sub, "login", 5)) {
char dir[OS_PATH_MAX];
if (cst_realm_dir(dir, sizeof(dir)) != 0 ||
!cst_realm_is_password_mode(dir)) {
push_system_line(t, "No password Realm yet. Outside TUI run:");
push_system_line(t, " cst-agent --realm-password-init");
return;
}
char pw[256];
if (secret_input_run(t, "Realm password",
"Unlocks this device as chair; starts the service",
pw, sizeof(pw)) != 0) {
push_system_line(t, "(login cancelled)");
return;
}
const char *iid = getenv("CST_INSTANCE_ID");
if (!iid || !iid[0])
iid = "chair-local";
char err[256];
char *hand = cst_parliament_login(pw, iid, NULL, err, sizeof(err));
if (!hand) {
memset(pw, 0, sizeof(pw));
push_system_line(t, "Login failed: %s", err[0] ? err : "unknown");
return;
}
/* Show a short summary, not the full handover blob. */
push_system_line(t, "(logged in as chair %s)", iid);
if (strstr(hand, "handover_from=") &&
!strstr(hand, "handover_from=\n") &&
!strstr(hand, "handover_from=\r"))
push_system_line(t, "(took chair from previous device)");
free(hand);
{
char serr[256];
if (cst_parliament_daemon_start(pw, iid, 9100, serr, sizeof(serr)) != 0)
push_system_line(t, "warning: service: %s",
serr[0] ? serr : "start failed");
else if (cst_parliament_daemon_running())
push_system_line(t, "(parliament service running)");
}
memset(pw, 0, sizeof(pw));
return;
}
push_system_line(t, "Usage: /realm [status|login|stop]");
}
static void cmd_status(tui_t *t, char *arg, int *quit) {
(void)arg;
(void)quit;
@@ -5605,6 +5683,8 @@ static const slash_cmd_t SLASH[] = {
cmd_mouse},
{"max-steps", "", "[N]", "tool steps allowed per turn", 1, cmd_max_steps},
{"status", "", "", "session, model, context and settings", 1, cmd_status},
{"realm", "parliament login", "[status|login|stop]",
"Realm / parliament chair status, login, or stop service", 1, cmd_realm},
{"cost", "usage", "", "tokens, cache hit rate and estimated cost", 1,
cmd_cost},
{"todo", "tasks", "", "show the agent's task list", 1, cmd_todo},