fix: parliament UX, prompt alignment, execution nudges (0.9.14)

Inject shared parliament context into the agent environment, switch
prompts away from in-process workers when parliament is active, clear
login tickets on chair sync/new-project, and surface realm/chair/service
in /status. Tighten empty-reply handling and prefer-tool principles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 10:22:31 +08:00
co-authored by Cursor
parent be8d021480
commit 9c6257fc96
9 changed files with 207 additions and 40 deletions
+57 -2
View File
@@ -3,6 +3,7 @@
#endif
#include "cst_parliament.h"
#include "cJSON.h"
#include "cst_agent.h"
#include "cst_util.h"
#include "monocypher.h"
#include "os_compat.h"
@@ -225,9 +226,11 @@ int cst_parliament_new_project(const char *project_id) {
snprintf(m.status, sizeof(m.status), "%s", "open");
m.revision = 1;
/* Keep chair empty until next login claims it. */
cst_parliament_session_clear();
(void)cst_parliament_daemon_stop();
if (cst_parliament_save(&m) != 0)
return -1;
return cst_parliament_context_put("");
return context_write_file("");
}
char *cst_parliament_login(const char *password, const char *instance_id,
@@ -400,11 +403,63 @@ int cst_parliament_apply_sync(unsigned long revision, const char *parliament_id,
snprintf(m.parliament_id, sizeof(m.parliament_id), "%s", parliament_id);
if (project_id)
snprintf(m.project_id, sizeof(m.project_id), "%s", project_id);
if (chair)
if (chair) {
char local_sid[64] = {0};
int had = cst_parliament_session_ok(local_sid, sizeof(local_sid));
if (chair[0] && had && strcmp(local_sid, chair) != 0)
cst_parliament_session_clear();
if (!chair[0])
cst_parliament_session_clear();
snprintf(m.chair_instance, sizeof(m.chair_instance), "%s", chair);
}
m.revision = revision;
snprintf(m.status, sizeof(m.status), "%s", "open");
if (context_write_file(context ? context : "") != 0)
return -1;
return cst_parliament_save(&m);
}
int cst_parliament_is_active(void) {
const char *mode = getenv("CST_COLLABORATION");
if (mode && mode[0])
return strcmp(mode, "parliament") == 0;
cst_settings_t s;
if (cst_settings_load(&s) == 0 && s.collaboration[0])
return strcmp(s.collaboration, "parliament") == 0;
char dir[OS_PATH_MAX];
if (cst_realm_dir(dir, sizeof(dir)) == 0 && cst_realm_is_password_mode(dir))
return 1;
cst_parliament_meta_t m;
if (cst_parliament_load(&m) == 0 && m.status[0] &&
strcmp(m.status, "idle") != 0 && strcmp(m.status, "dissolved") != 0)
return 1;
return 0;
}
char *cst_parliament_status_text(void) {
cst_buf_t b = {0};
char dir[OS_PATH_MAX];
if (cst_realm_dir(dir, sizeof(dir)) != 0) {
cst_buf_puts(&b, "parliament (no realm dir)\n");
return cst_buf_steal(&b);
}
int pw = cst_realm_is_password_mode(dir);
cst_parliament_meta_t m;
memset(&m, 0, sizeof(m));
cst_parliament_load(&m);
char sid[64] = {0};
int sess = cst_parliament_session_ok(sid, sizeof(sid));
int svc = cst_parliament_daemon_running();
cst_buf_printf(&b, "realm %s\n", pw ? "password" : "file-keys/legacy");
cst_buf_printf(&b, "parliament %s project=%s rev=%lu\n",
m.status[0] ? m.status : "idle",
m.project_id[0] ? m.project_id : "-",
m.revision);
cst_buf_printf(&b, "chair %s%s%s\n",
m.chair_instance[0] ? m.chair_instance : "(none)",
m.chair_device[0] ? " @ " : "", m.chair_device);
cst_buf_printf(&b, "login %s%s%s\n", sess ? "ok" : "required",
sess && sid[0] ? " as " : "", sess ? sid : "");
cst_buf_printf(&b, "service %s\n", svc ? "running" : "stopped");
return cst_buf_steal(&b);
}