fix: interactive Realm password, recoverable worker budget (0.9.15)
Prompt for Realm password when CST_REALM_PASSWORD is unset; map worker request-gate exhaustion to a clear budget error with partial progress; hard-skip identical tool failures after 3 tries. Add docs/parliament.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+51
-19
@@ -2,6 +2,7 @@
|
||||
#define _DEFAULT_SOURCE
|
||||
#endif
|
||||
#include "cst_parliament_cli.h"
|
||||
#include "cst_agent.h"
|
||||
#include "cst_discover.h"
|
||||
#include "cst_net.h"
|
||||
#include "cst_parliament.h"
|
||||
@@ -29,6 +30,21 @@ static void sleep_ms(int ms) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prefer CST_REALM_PASSWORD; otherwise prompt on a TTY. */
|
||||
static int resolve_password(char *buf, size_t n, const char **out) {
|
||||
const char *env = getenv("CST_REALM_PASSWORD");
|
||||
if (env && env[0]) {
|
||||
*out = env;
|
||||
return 0;
|
||||
}
|
||||
if (cst_prompt_secret("Realm password (input hidden): ", buf, n) != 0) {
|
||||
fprintf(stderr, "password required (set CST_REALM_PASSWORD or type it)\n");
|
||||
return -1;
|
||||
}
|
||||
*out = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cst_parliament_cli_realm_new(void) {
|
||||
char dir[OS_PATH_MAX], fp[33];
|
||||
if (cst_realm_dir(dir, sizeof(dir)) != 0) {
|
||||
@@ -46,24 +62,26 @@ int cst_parliament_cli_realm_new(void) {
|
||||
}
|
||||
|
||||
int cst_parliament_cli_realm_password_init(const char *password) {
|
||||
if (!password || !password[0]) {
|
||||
fprintf(stderr, "password required (or CST_REALM_PASSWORD)\n");
|
||||
char pwbuf[256];
|
||||
const char *pw = password;
|
||||
if ((!pw || !pw[0]) && resolve_password(pwbuf, sizeof(pwbuf), &pw) != 0)
|
||||
return 1;
|
||||
}
|
||||
char dir[OS_PATH_MAX], fp[33];
|
||||
if (cst_realm_dir(dir, sizeof(dir)) != 0) {
|
||||
fprintf(stderr, "cannot resolve realm directory\n");
|
||||
return 1;
|
||||
}
|
||||
if (cst_realm_init_password(dir, password) != 0) {
|
||||
if (cst_realm_init_password(dir, pw) != 0) {
|
||||
fprintf(stderr, "password realm init failed\n");
|
||||
return 1;
|
||||
}
|
||||
cst_realm_keys_t k;
|
||||
if (cst_realm_unlock_password(dir, password, &k) != 0)
|
||||
if (cst_realm_unlock_password(dir, pw, &k) != 0)
|
||||
return 1;
|
||||
cst_realm_fingerprint(k.pk, fp);
|
||||
printf("realm_password_mode dir=%s fingerprint=%s\n", dir, fp);
|
||||
if (pw == pwbuf)
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -76,52 +94,66 @@ int cst_parliament_cli_login(const char *password, const char *instance_id,
|
||||
int cst_parliament_cli_login_and_serve(const char *password,
|
||||
const char *instance_id,
|
||||
const char *device_label, int peer_port) {
|
||||
char err[256];
|
||||
char *hand = cst_parliament_login(password, instance_id, device_label, err,
|
||||
char err[256], pwbuf[256];
|
||||
const char *pw = password;
|
||||
if ((!pw || !pw[0]) && resolve_password(pwbuf, sizeof(pwbuf), &pw) != 0)
|
||||
return 1;
|
||||
char *hand = cst_parliament_login(pw, instance_id, device_label, err,
|
||||
sizeof(err));
|
||||
if (!hand) {
|
||||
fprintf(stderr, "%s\n", err[0] ? err : "login failed");
|
||||
if (pw == pwbuf)
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return 1;
|
||||
}
|
||||
fputs(hand, stdout);
|
||||
free(hand);
|
||||
if (cst_parliament_daemon_start(password, instance_id,
|
||||
if (cst_parliament_daemon_start(pw, instance_id,
|
||||
peer_port > 0 ? peer_port : 9100, err,
|
||||
sizeof(err)) != 0) {
|
||||
fprintf(stderr, "warning: service: %s (chair login still valid)\n",
|
||||
err[0] ? err : "start failed");
|
||||
printf("service=failed\n");
|
||||
if (pw == pwbuf)
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return 0;
|
||||
}
|
||||
if (cst_parliament_daemon_running())
|
||||
printf("service=running\n");
|
||||
if (pw == pwbuf)
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cst_parliament_cli_service(const char *password, const char *instance_id,
|
||||
int peer_port, int foreground) {
|
||||
char err[256];
|
||||
char err[256], pwbuf[256];
|
||||
const char *pw = password;
|
||||
if (!instance_id || !instance_id[0]) {
|
||||
fprintf(stderr, "instance id required\n");
|
||||
return 1;
|
||||
}
|
||||
if ((!pw || !pw[0]) && resolve_password(pwbuf, sizeof(pwbuf), &pw) != 0)
|
||||
return 1;
|
||||
int rc = 0;
|
||||
if (foreground) {
|
||||
if (cst_parliament_daemon_run(password, instance_id,
|
||||
if (cst_parliament_daemon_run(pw, instance_id,
|
||||
peer_port > 0 ? peer_port : 9100, err,
|
||||
sizeof(err)) != 0) {
|
||||
fprintf(stderr, "%s\n", err[0] ? err : "service failed");
|
||||
return 1;
|
||||
rc = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (cst_parliament_daemon_start(password, instance_id,
|
||||
peer_port > 0 ? peer_port : 9100, err,
|
||||
sizeof(err)) != 0) {
|
||||
} else if (cst_parliament_daemon_start(pw, instance_id,
|
||||
peer_port > 0 ? peer_port : 9100, err,
|
||||
sizeof(err)) != 0) {
|
||||
fprintf(stderr, "%s\n", err[0] ? err : "service start failed");
|
||||
return 1;
|
||||
rc = 1;
|
||||
} else {
|
||||
printf("service=running\n");
|
||||
}
|
||||
printf("service=running\n");
|
||||
return 0;
|
||||
if (pw == pwbuf)
|
||||
memset(pwbuf, 0, sizeof(pwbuf));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cst_parliament_cli_service_stop(void) {
|
||||
|
||||
Reference in New Issue
Block a user