@gajae-gateway/cli 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import type { OpsCycleResult, OpsDeliveriesResult, OpsSloResult } from "@gajae-gateway/protocol";
3
+ import { GajaewayClient } from "@gajae-gateway/sdk";
3
4
  import { type LaunchRestartOptions, type RunRestartOptions } from "./restart-stack";
4
5
  import { type InstallServicesOptions, type ServicePlatform } from "./services";
5
6
  import { type RunSetupOptions } from "./setup";
@@ -12,7 +13,7 @@ export declare function socketPath(home?: string | undefined): string;
12
13
  * never after, so the list is checked up front.
13
14
  */
14
15
  export declare const COMMANDS: readonly ["status", "shutdown", "chat", "daemon", "sessions", "ops", "memory", "monitors", "work", "services", "migrate", "update", "setup"];
15
- export declare const CLI_USAGE = "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
16
+ export declare const CLI_USAGE = "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (settle <eventId>|retry <eventId>|test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
16
17
  /** Usage errors exit 2, as `gajaeway-gateway` does; 1 stays a runtime failure. */
17
18
  export declare const USAGE_EXIT_CODE = 2;
18
19
  /** The usage text when `command` cannot be dispatched, undefined when it can. */
@@ -62,5 +63,17 @@ export declare function cycleExitCode(cycle: OpsCycleResult): number;
62
63
  export declare function renderSlo(result: OpsSloResult): string[];
63
64
  export declare function sloExitCode(result: OpsSloResult): number;
64
65
  export declare function renderDeliveries(result: OpsDeliveriesResult): string[];
66
+ /**
67
+ * Poll for memory operation completion. Memory operations (audit, autolink) are
68
+ * long-running and return an opRef immediately; this function polls for the result.
69
+ * If the CLI wait expires before completion, report 'still running' instead of failure.
70
+ */
71
+ export declare function pollMemoryOp(client: Pick<GajaewayClient, "request">, opRef: string, maxWaitMs?: number, // 5 min default CLI timeout
72
+ pollIntervalMs?: number): Promise<{
73
+ status: "completed" | "failed" | "still_running";
74
+ elapsedMs: number;
75
+ result?: unknown;
76
+ error?: string;
77
+ }>;
65
78
  export declare function main(args?: string[], options?: MainOptions): Promise<void>;
66
79
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAKX,cAAc,EAEd,mBAAmB,EAEnB,YAAY,EASZ,MAAM,yBAAyB,CAAC;AAiBjC,OAAO,EAEN,KAAK,oBAAoB,EAEzB,KAAK,iBAAiB,EAItB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,sBAAsB,EAAmB,KAAK,eAAe,EAAgB,MAAM,YAAY,CAAC;AAC9G,OAAO,EAAE,KAAK,eAAe,EAAY,MAAM,SAAS,CAAC;AACzD,OAAO,EAA4C,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AASrF,wBAAgB,UAAU,CAAC,IAAI,qBAA4B,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,8IAcX,CAAC;AAEX,eAAO,MAAM,SAAS,stCAC8rC,CAAC;AAErtC,kFAAkF;AAClF,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQ9F;AAMD,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,iBAAiB,GAAG,WAAW,CAAC,CAAC;IAClF,mEAAmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,gBAAgB,CAAC,CAAC;IACnG,oFAAoF;IACpF,QAAQ,CAAC,YAAY,CAAC,EAAE;QACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;KACtD,CAAC;IACF,kFAAkF;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;CAC7B;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;CACpC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,kBAAkB,CA8B7E;AAqID;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CAgE3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAE3D;AACD,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAkBxD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAExD;AAyED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAStE;AA8DD,wBAAsB,IAAI,CAAC,IAAI,WAAwB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4cjG"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -8,7 +8,7 @@ import { GajaewayClient } from "@gajae-gateway/sdk";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "@gajae-gateway/cli",
11
- version: "0.2.0",
11
+ version: "0.2.1",
12
12
  type: "module",
13
13
  description: "Owner CLI for the gajaeway gateway: status, sessions, chat, monitors, and worker lanes over the gateway socket. Requires the Bun runtime (uses Bun.file/Bun.spawn).",
14
14
  license: "AGPL-3.0-only",
@@ -1879,7 +1879,9 @@ async function runRestartStackWithLease(options) {
1879
1879
  originalPids.set(spec.label, (await probe(spec.label))?.pid);
1880
1880
  }
1881
1881
  const existing = await readRestartReceipt(options.home);
1882
- const receipt = existing?.id === options.id && existing.state === "queued" ? existing : newReceipt(options.id, platform, options.uid, now(), options.trigger ?? "manual");
1882
+ if (existing?.id === options.id && existing.state !== "queued")
1883
+ throw new Error(`restart-stack ${options.id}: receipt is ${existing.state}; refusing to start worker`);
1884
+ const receipt = existing?.id === options.id ? existing : newReceipt(options.id, platform, options.uid, now(), options.trigger ?? "manual");
1883
1885
  receipt.state = "running";
1884
1886
  receipt.supervisorPid = process.pid;
1885
1887
  await writeReceipt(options.home, receipt);
@@ -2034,6 +2036,7 @@ async function runRestartStackWithLease(options) {
2034
2036
  }
2035
2037
  }
2036
2038
  }
2039
+ var SYSTEMD_RUN_TIMEOUT_MS = 30000;
2037
2040
  function cliCommand() {
2038
2041
  return Bun.main.startsWith("/$bunfs/") ? [process.execPath] : [process.execPath, Bun.main];
2039
2042
  }
@@ -2045,31 +2048,67 @@ async function launchRestartStack(options) {
2045
2048
  await writeReceipt(options.home, receipt);
2046
2049
  const worker = [...options.worker ?? [...cliCommand(), "ops", "restart-stack"], "--run", receipt.id];
2047
2050
  const argv = supervisorArgv(platform, worker, options.home, receipt.id, options.binDir);
2051
+ const spawnOptions = {
2052
+ detached: true,
2053
+ stdin: "ignore",
2054
+ stdout: "ignore",
2055
+ stderr: "ignore",
2056
+ env: {
2057
+ ...options.env ?? process.env,
2058
+ GAJAEWAY_HOME: options.home,
2059
+ ...options.binDir === undefined ? {} : { GAJAEWAY_BIN_DIR: options.binDir }
2060
+ }
2061
+ };
2048
2062
  let child;
2049
2063
  try {
2050
- child = Bun.spawn(argv, {
2051
- detached: true,
2052
- stdin: "ignore",
2053
- stdout: "ignore",
2054
- stderr: "ignore",
2055
- env: {
2056
- ...options.env ?? process.env,
2057
- GAJAEWAY_HOME: options.home,
2058
- ...options.binDir === undefined ? {} : { GAJAEWAY_BIN_DIR: options.binDir }
2059
- }
2060
- });
2064
+ child = platform === "linux" ? (options.systemdRun ?? ((command) => Bun.spawn([...command], spawnOptions)))(argv) : Bun.spawn(argv, spawnOptions);
2061
2065
  } catch (error) {
2062
- receipt.state = "failed";
2063
- receipt.finishedAt = new Date().toISOString();
2064
- receipt.detail = `supervisor ${argv[0]} could not be started (${error instanceof Error ? error.message : String(error)}); without a service manager here, restart through the host's own supervisor`;
2065
- for (const step of receipt.steps)
2066
- step.result = "skipped";
2067
- await writeReceipt(options.home, receipt);
2068
- throw new Error(`restart-stack ${receipt.id}: failed: ${receipt.detail}`);
2066
+ const detail = platform === "linux" ? `supervisor systemd-run could not be started (${error instanceof Error ? error.message : String(error)}); without a service manager here, restart through the host's own supervisor` : `supervisor ${argv[0]} could not be started (${error instanceof Error ? error.message : String(error)})`;
2067
+ await failLaunch(options.home, receipt, detail);
2068
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
2069
+ }
2070
+ if (platform === "linux") {
2071
+ const outcome = await waitForLauncher(child, options.systemdRunTimeoutMs ?? SYSTEMD_RUN_TIMEOUT_MS);
2072
+ if (outcome.kind === "timed_out") {
2073
+ const detail = `supervisor systemd-run timed out after ${options.systemdRunTimeoutMs ?? SYSTEMD_RUN_TIMEOUT_MS}ms; handoff outcome is indeterminate`;
2074
+ await failLaunch(options.home, receipt, detail);
2075
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
2076
+ }
2077
+ if (outcome.exitStatus !== 0) {
2078
+ const detail = `supervisor systemd-run exited with status ${outcome.exitStatus}`;
2079
+ await failLaunch(options.home, receipt, detail);
2080
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
2081
+ }
2069
2082
  }
2070
2083
  child.unref();
2071
2084
  return { receipt, supervisorPid: child.pid };
2072
2085
  }
2086
+ async function failLaunch(home, receipt, detail) {
2087
+ receipt.state = "failed";
2088
+ receipt.finishedAt = new Date().toISOString();
2089
+ receipt.detail = detail;
2090
+ for (const step of receipt.steps)
2091
+ step.result = "skipped";
2092
+ await writeReceipt(home, receipt);
2093
+ }
2094
+ async function waitForLauncher(child, timeoutMs) {
2095
+ let timer;
2096
+ const outcome = await Promise.race([
2097
+ child.exited.then((exitStatus) => ({ kind: "exited", exitStatus })),
2098
+ new Promise((resolve) => {
2099
+ timer = setTimeout(() => resolve({ kind: "timed_out" }), timeoutMs);
2100
+ })
2101
+ ]);
2102
+ if (timer !== undefined)
2103
+ clearTimeout(timer);
2104
+ if (outcome.kind === "timed_out") {
2105
+ child.kill("SIGKILL");
2106
+ child.exited.catch(() => {
2107
+ return;
2108
+ });
2109
+ }
2110
+ return outcome;
2111
+ }
2073
2112
  function supervisorArgv(platform, worker, home, id, binDir) {
2074
2113
  if (platform === "darwin")
2075
2114
  return [...worker];
@@ -2078,6 +2117,7 @@ function supervisorArgv(platform, worker, home, id, binDir) {
2078
2117
  "--user",
2079
2118
  "--collect",
2080
2119
  "--quiet",
2120
+ "--service-type=exec",
2081
2121
  `--unit=gajaeway-restart-stack-${id}`,
2082
2122
  `--setenv=GAJAEWAY_HOME=${home}`,
2083
2123
  ...binDir === undefined ? [] : [`--setenv=GAJAEWAY_BIN_DIR=${binDir}`],
@@ -2841,6 +2881,7 @@ async function installPinnedGjc(options) {
2841
2881
  var UPDATE_USAGE = "usage: gajaeway update [--check] [--force] [--bin-dir DIR] [--no-restart]";
2842
2882
  var DEFAULT_RELEASE_REPO = "Yeachan-Heo/gajae-way";
2843
2883
  var RELEASE_REPO_OVERRIDE_ENV = "GAJAEWAY_UPDATE_REPO";
2884
+ var PIN_MANIFEST = "package.json";
2844
2885
  function releaseRepo(env = process.env) {
2845
2886
  const override = env[RELEASE_REPO_OVERRIDE_ENV]?.trim();
2846
2887
  return override ? override : declaredReleaseRepo();
@@ -3051,7 +3092,7 @@ async function runUpdate(options) {
3051
3092
  if (missingCore.length > 0)
3052
3093
  throw new Error(`release tarball is missing core binaries: ${missingCore.join(", ")}`);
3053
3094
  await assertStagedBinariesUsable(staged, toInstall);
3054
- const gjcVersion = await readPinnedGjcVersion(join10(staged.dir, "package.json"));
3095
+ const gjcVersion = await readPinnedGjcVersion(join10(staged.dir, PIN_MANIFEST));
3055
3096
  await installPinnedGjc({
3056
3097
  home: options.home,
3057
3098
  version: gjcVersion,
@@ -3060,16 +3101,17 @@ async function runUpdate(options) {
3060
3101
  const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[-:]/g, "").slice(0, 15);
3061
3102
  const backupDir = join10(binDir, `backup-${current}-${stamp}Z`);
3062
3103
  await mkdir7(backupDir, { recursive: false });
3063
- for (const name of toInstall) {
3104
+ const replaced = [...toInstall, PIN_MANIFEST];
3105
+ for (const name of replaced) {
3064
3106
  const target = join10(binDir, name);
3065
3107
  if (await exists(target))
3066
3108
  await copyFile(target, join10(backupDir, name));
3067
3109
  }
3068
- for (const name of toInstall) {
3110
+ for (const name of replaced) {
3069
3111
  const stagedPath = join10(staged.dir, name);
3070
3112
  const tempPath = join10(binDir, `.update-${name}`);
3071
3113
  await copyFile(stagedPath, tempPath);
3072
- await chmod5(tempPath, 493);
3114
+ await chmod5(tempPath, name === PIN_MANIFEST ? 420 : 493);
3073
3115
  await rename5(tempPath, join10(binDir, name));
3074
3116
  }
3075
3117
  await writeFile6(releaseMarkerPath(binDir), `${latest}
@@ -3211,7 +3253,7 @@ var COMMANDS = [
3211
3253
  "update",
3212
3254
  "setup"
3213
3255
  ];
3214
- var CLI_USAGE = "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
3256
+ var CLI_USAGE = "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (settle <eventId>|retry <eventId>|test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
3215
3257
  var USAGE_EXIT_CODE = 2;
3216
3258
  function usageFor(command) {
3217
3259
  return command !== undefined && COMMANDS.includes(command) ? undefined : CLI_USAGE;
@@ -3320,6 +3362,13 @@ function parseMonitorUpdateArgs(args) {
3320
3362
  var MONITOR_TEST_USAGE = "usage: gajaeway monitors test <id> [--type T] [--payload J] [--wait[=SECONDS]]";
3321
3363
  var MONITOR_WAIT_ERROR = `${MONITOR_TEST_USAGE}
3322
3364
  --wait expects a finite non-negative integer up to 86400`;
3365
+ var MONITOR_OPERATOR_USAGE = "usage: gajaeway monitors settle <eventId>|retry <eventId>";
3366
+ function parseMonitorEventOperatorArgs(args) {
3367
+ const eventId = args[0];
3368
+ if (args.length !== 1 || !eventId?.trim() || eventId.startsWith("--"))
3369
+ throw new Error(MONITOR_OPERATOR_USAGE);
3370
+ return eventId;
3371
+ }
3323
3372
  function parseMonitorTestArgs(args) {
3324
3373
  const [monitorId, ...flags] = args;
3325
3374
  if (!monitorId || monitorId.startsWith("--"))
@@ -3370,7 +3419,7 @@ unknown argument: ${flag}`);
3370
3419
  ...waitSeconds === undefined ? {} : { waitSeconds }
3371
3420
  };
3372
3421
  }
3373
- var TERMINAL_MONITOR_STAGES = new Set(["delivered", "authored_no_delivery", "failed", "failed_no_retry"]);
3422
+ var TERMINAL_MONITOR_STAGES = new Set(["delivered", "authored_no_delivery", "failed", "failed_no_retry", "skipped"]);
3374
3423
  function waitForMonitorStage(client, eventId, timeoutSeconds) {
3375
3424
  return new Promise((resolve) => {
3376
3425
  let stage = "admitted";
@@ -3607,6 +3656,25 @@ async function chat(socket) {
3607
3656
  await client.close();
3608
3657
  }
3609
3658
  }
3659
+ async function pollMemoryOp(client, opRef, maxWaitMs = 300000, pollIntervalMs = 1000) {
3660
+ const startTime = Date.now();
3661
+ let operationElapsedMs = 0;
3662
+ while (Date.now() - startTime < maxWaitMs) {
3663
+ const status = await client.request("memory.status", { opRef });
3664
+ operationElapsedMs = status.elapsedMs;
3665
+ if (status.status === "completed") {
3666
+ return { status: "completed", elapsedMs: status.elapsedMs, result: status.result };
3667
+ }
3668
+ if (status.status === "failed") {
3669
+ return { status: "failed", elapsedMs: status.elapsedMs, error: status.error };
3670
+ }
3671
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
3672
+ }
3673
+ const waitedMs = Date.now() - startTime;
3674
+ console.error(`memory operation still running (${Math.round(operationElapsedMs / 1000)}s operation elapsed; CLI wait ended after ${Math.round(waitedMs / 1000)}s).
3675
+ Check status: gajaeway memory status ${opRef}`);
3676
+ return { status: "still_running", elapsedMs: operationElapsedMs };
3677
+ }
3610
3678
  async function main(args = process.argv.slice(2), options = {}) {
3611
3679
  const parsed = parseArgs(args);
3612
3680
  if (parsed.command === "--version" && parsed.rest.length === 0) {
@@ -3771,20 +3839,52 @@ ${OPS_USAGE}`);
3771
3839
  break;
3772
3840
  }
3773
3841
  case "memory": {
3774
- const usage2 = "usage: gajaeway memory audit|memory autolink|memory search <query>";
3842
+ const usage2 = "usage: gajaeway memory audit|autolink|search <query>|status <opRef>";
3775
3843
  if ((parsed.rest[0] === "audit" || parsed.rest[0] === "autolink") && parsed.rest.length > 1)
3776
3844
  throw new Error(`${usage2} (unknown argument: ${parsed.rest[1]})`);
3845
+ if (parsed.rest[0] === "status" && parsed.rest.length < 2)
3846
+ throw new Error(`${usage2} (status requires opRef)`);
3777
3847
  const client = await connectGatewaySocket(parsed.socket);
3778
3848
  try {
3779
3849
  if (parsed.rest[0] === "audit") {
3780
- const result = await client.request("memory.audit");
3781
- console.log(JSON.stringify(result.issues));
3782
- if (!result.ok)
3850
+ const initResp = await client.request("memory.audit");
3851
+ const poll = await pollMemoryOp(client, initResp.opRef);
3852
+ if (poll.status === "failed") {
3853
+ console.error(`audit failed after ${poll.elapsedMs}ms: ${poll.error}`);
3783
3854
  process.exitCode = 1;
3855
+ } else if (poll.status === "still_running") {
3856
+ process.exitCode = 75;
3857
+ } else {
3858
+ const auditResult = poll.result;
3859
+ console.log(JSON.stringify(auditResult?.issues ?? []));
3860
+ console.error(`audit completed in ${poll.elapsedMs}ms`);
3861
+ if (!auditResult?.ok)
3862
+ process.exitCode = 1;
3863
+ }
3784
3864
  } else if (parsed.rest[0] === "autolink") {
3785
- console.log(JSON.stringify(await client.request("memory.autolink")));
3865
+ const initResp = await client.request("memory.autolink");
3866
+ const poll = await pollMemoryOp(client, initResp.opRef);
3867
+ if (poll.status === "failed") {
3868
+ console.error(`autolink failed after ${poll.elapsedMs}ms: ${poll.error}`);
3869
+ process.exitCode = 1;
3870
+ } else if (poll.status === "still_running") {
3871
+ process.exitCode = 75;
3872
+ } else {
3873
+ console.log(JSON.stringify(poll.result));
3874
+ }
3786
3875
  } else if (parsed.rest[0] === "search" && parsed.rest.slice(1).join(" ")) {
3787
3876
  console.log(JSON.stringify(await client.request("memory.search", { query: parsed.rest.slice(1).join(" ") })));
3877
+ } else if (parsed.rest[0] === "status" && parsed.rest[1]) {
3878
+ const opRef = parsed.rest[1];
3879
+ const result = await client.request("memory.status", { opRef });
3880
+ if (result.status === "failed") {
3881
+ console.error(`operation ${opRef} failed after ${result.elapsedMs}ms: ${result.error}`);
3882
+ process.exitCode = 1;
3883
+ } else if (result.status === "completed") {
3884
+ console.log(JSON.stringify(result));
3885
+ } else {
3886
+ console.log(JSON.stringify({ status: result.status, elapsedMs: result.elapsedMs }));
3887
+ }
3788
3888
  } else
3789
3889
  throw new Error(usage2);
3790
3890
  } finally {
@@ -3797,6 +3897,7 @@ ${OPS_USAGE}`);
3797
3897
  const listOptions = command === "list" ? parseListOptions(args2, MONITOR_COLUMNS) : undefined;
3798
3898
  const update = command === "update" ? parseMonitorUpdateArgs(args2) : undefined;
3799
3899
  const monitorTest = command === "test" ? parseMonitorTestArgs(args2) : undefined;
3900
+ const operatorEventId = command === "settle" || command === "retry" ? parseMonitorEventOperatorArgs(args2) : undefined;
3800
3901
  const client = await connectGatewaySocket(parsed.socket);
3801
3902
  try {
3802
3903
  if (command === "add" && args2[0] === "--json" && args2[1])
@@ -3832,8 +3933,15 @@ ${OPS_USAGE}`);
3832
3933
  const stage = await waitForMonitorStage(client, result.eventId, monitorTest.waitSeconds);
3833
3934
  console.log(JSON.stringify({ eventId: result.eventId, stage }));
3834
3935
  }
3936
+ } else if ((command === "settle" || command === "retry") && operatorEventId !== undefined) {
3937
+ const result = await client.request(`monitor.${command}`, {
3938
+ eventId: operatorEventId
3939
+ });
3940
+ console.log(JSON.stringify(result));
3941
+ if (!result.done)
3942
+ process.exitCode = 1;
3835
3943
  } else
3836
- throw new Error(`usage: gajaeway monitors add --json '<MonitorSpec json>'|update <id> (--json '<partial MonitorSpec JSON>'|--schedule '<cron>' [--enabled true|false]|--enabled true|false [--schedule '<cron>'])|list [--json] [--fields ${columnNames(MONITOR_COLUMNS).join(",")}] [--limit N] [--offset N]|inspect <id>|remove <id>|test <id> [--type T] [--payload J] [--wait[=SECONDS]]`);
3944
+ throw new Error(`usage: gajaeway monitors add --json '<MonitorSpec json>'|update <id> (--json '<partial MonitorSpec JSON>'|--schedule '<cron>' [--enabled true|false]|--enabled true|false [--schedule '<cron>'])|list [--json] [--fields ${columnNames(MONITOR_COLUMNS).join(",")}] [--limit N] [--offset N]|inspect <id>|remove <id>|settle <eventId>|retry <eventId>|test <id> [--type T] [--payload J] [--wait[=SECONDS]]`);
3837
3945
  } finally {
3838
3946
  await client.close();
3839
3947
  }
@@ -3930,11 +4038,13 @@ ${OPS_USAGE}`);
3930
4038
  const name = args2[0];
3931
4039
  let cwd;
3932
4040
  let resume = false;
4041
+ let repo;
4042
+ let base;
3933
4043
  let model;
3934
4044
  const textParts = [];
3935
4045
  for (let i = 1;i < args2.length; i++) {
3936
4046
  const arg = args2[i];
3937
- if (arg === "--cwd" || arg === "--model" || arg === "--preset") {
4047
+ if (arg === "--cwd" || arg === "--repo" || arg === "--base" || arg === "--model" || arg === "--preset") {
3938
4048
  const value = args2[++i];
3939
4049
  if (!value?.trim() || value.startsWith("--"))
3940
4050
  throw new Error(usage2);
@@ -3942,6 +4052,14 @@ ${OPS_USAGE}`);
3942
4052
  if (cwd !== undefined || !isAbsolute(value))
3943
4053
  throw new Error(usage2);
3944
4054
  cwd = value;
4055
+ } else if (arg === "--repo") {
4056
+ if (repo !== undefined)
4057
+ throw new Error(usage2);
4058
+ repo = value;
4059
+ } else if (arg === "--base") {
4060
+ if (base !== undefined)
4061
+ throw new Error(usage2);
4062
+ base = value;
3945
4063
  } else {
3946
4064
  if (model !== undefined)
3947
4065
  throw new Error(`${usage2}
@@ -3967,6 +4085,8 @@ ${OPS_USAGE}`);
3967
4085
  name,
3968
4086
  text,
3969
4087
  ...cwd ? { cwd } : {},
4088
+ ...repo ? { repo } : {},
4089
+ ...base ? { base } : {},
3970
4090
  ...resume ? { resume: true } : {},
3971
4091
  ...model === undefined ? {} : { model },
3972
4092
  ...callerSessionId ? { callerSessionId } : {}
@@ -4045,6 +4165,7 @@ export {
4045
4165
  main,
4046
4166
  parseArgs,
4047
4167
  parseServicesArgs,
4168
+ pollMemoryOp,
4048
4169
  renderCycle,
4049
4170
  renderDeliveries,
4050
4171
  renderSlo,
@@ -93,12 +93,16 @@ export interface LaunchRestartOptions {
93
93
  /** Argv that re-enters the CLI; `--run <id>` is appended. */
94
94
  readonly worker?: readonly string[];
95
95
  readonly env?: NodeJS.ProcessEnv;
96
+ /** Starts systemd-run; injectable for launcher-result handling. */
97
+ readonly systemdRun?: (command: readonly string[]) => Bun.Subprocess;
98
+ /** Maximum time to wait for systemd-run to acknowledge the worker exec. */
99
+ readonly systemdRunTimeoutMs?: number;
96
100
  }
97
101
  /** The argv that runs this CLI again, whether compiled or run from source. */
98
102
  export declare function cliCommand(): string[];
99
103
  /**
100
- * Queues a restart and hands it to a detached supervisor, returning as soon as
101
- * the supervisor is spawned so the caller may be killed by the restart itself.
104
+ * Queues a restart and hands it to a detached supervisor, returning once the
105
+ * platform launcher acknowledges it so the caller may be killed by the restart.
102
106
  */
103
107
  export declare function launchRestartStack(options: LaunchRestartOptions): Promise<{
104
108
  readonly receipt: RestartReceipt;
@@ -1 +1 @@
1
- {"version":3,"file":"restart-stack.d.ts","sourceRoot":"","sources":["../src/restart-stack.ts"],"names":[],"mappings":"AAcA,OAAO,EAMN,KAAK,eAAe,EAKpB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAClF,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACtC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;CAC9B;AAED,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AACzF,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;AAClF,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAErE,2FAA2F;AAC3F,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,2GAA2G;IAC3G,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD,uDAAuD;IACvD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,kGAAkG;IAClG,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC1B;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAS1F;AAsDD,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,SAA0B,GAAG,YAAY,CAa1G;AAqED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAezF;AA6MD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACjC;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAmC/E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACb,MAAM,EAAE,CAaV;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC,CAGvC;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,YAAY,GAAG,aAA6B,GACjD,MAAM,EAAE,CAkBV"}
1
+ {"version":3,"file":"restart-stack.d.ts","sourceRoot":"","sources":["../src/restart-stack.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,eAAe,CAAC;AAExE,OAAO,EACN,KAAK,sBAAsB,EAK3B,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AAEH,eAAO,MAAM,YAAY,8EAA8E,CAAC;AAExG,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAI5D,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAGxE;AASD,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAuBzE;AAED,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9D;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CAElH;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE/F;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,wHAOjB,CAAC;AAEX,eAAO,MAAM,aAAa,2CAA4C,CAAC;AAQvE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAOtF;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,QAAQ,SAAmB,GACzB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK7B;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,CAsB3D;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACvF,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAC9G,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAElF,KAAK,oBAAoB,GAAG,IAAI,CAC/B,sBAAsB,EACtB,iBAAiB,GAAG,SAAS,GAAG,iBAAiB,GAAG,WAAW,CAC/D,CAAC;AAEF,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,cAAc,CAAC;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;IACzC,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,oBAAoB,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC3B;AAyED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmHhF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gajae-gateway/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "description": "Owner CLI for the gajaeway gateway: status, sessions, chat, monitors, and worker lanes over the gateway socket. Requires the Bun runtime (uses Bun.file/Bun.spawn).",
6
6
  "license": "AGPL-3.0-only",
@@ -41,8 +41,8 @@
41
41
  "prepublishOnly": "bun run build"
42
42
  },
43
43
  "dependencies": {
44
- "@gajae-gateway/sdk": "0.2.0",
45
- "@gajae-gateway/protocol": "0.2.0"
44
+ "@gajae-gateway/sdk": "0.2.1",
45
+ "@gajae-gateway/protocol": "0.2.1"
46
46
  },
47
47
  "engines": {
48
48
  "bun": ">=1.4.0"
package/src/main.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import { isAbsolute, join } from "node:path";
3
+ import { isAbsolute } from "node:path";
4
4
 
5
5
  import type {
6
+ MonitorEventOperatorResult,
6
7
  MonitorEventRecord,
7
8
  MonitorRecord,
8
9
  MonitorScheduleProjection,
@@ -84,7 +85,7 @@ export const COMMANDS = [
84
85
  ] as const;
85
86
 
86
87
  export const CLI_USAGE =
87
- "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
88
+ "usage: gajaeway [--version] [--socket PATH] status|shutdown|chat|daemon run|sessions list [--json] [--fields a,b,c] [--limit N] [--offset N]|sessions inspect <originKey-or-index>|memory audit|memory search <query>|monitors ... (settle <eventId>|retry <eventId>|test <id> [--type T] [--payload J] [--wait[=SECONDS]])|work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] [--notify originKey (start only)] <text>|work status <name>|work steer <name> <text>|work retire [--force] <name>|work retire --all-dead|work jobs [--limit N] [--offset N]|ops backup <path>|ops deliveries [--since ISO] [--state S] [--limit N] [--json]|ops redeliver <deliveryId>|ops redeliver --since <iso>|ops cycle [--json]|ops integrity|ops restart-stack [--status]|services install|repair --bin-dir DIR [--launch-agents-dir DIR] [--unit-dir DIR] [--platform darwin|linux]|migrate [--source PATH] [--target PATH] [--dry-run]|update [--check] [--force] [--bin-dir DIR] [--no-restart]|setup [--from-env] [--adapters discord,slack,telegram] [--owner ID] [--discord-app-id ID]|setup --status|setup --broker-agent [--from DIR] (work run waits for a response; caller timeout does not end the attempt); cron timezone is an IANA zone and defaults to the gateway host's local timezone";
88
89
 
89
90
  /** Usage errors exit 2, as `gajaeway-gateway` does; 1 stays a runtime failure. */
90
91
  export const USAGE_EXIT_CODE = 2;
@@ -225,6 +226,13 @@ interface ParsedMonitorTestArgs {
225
226
 
226
227
  const MONITOR_TEST_USAGE = "usage: gajaeway monitors test <id> [--type T] [--payload J] [--wait[=SECONDS]]";
227
228
  const MONITOR_WAIT_ERROR = `${MONITOR_TEST_USAGE}\n--wait expects a finite non-negative integer up to 86400`;
229
+ const MONITOR_OPERATOR_USAGE = "usage: gajaeway monitors settle <eventId>|retry <eventId>";
230
+
231
+ function parseMonitorEventOperatorArgs(args: readonly string[]): string {
232
+ const eventId = args[0];
233
+ if (args.length !== 1 || !eventId?.trim() || eventId.startsWith("--")) throw new Error(MONITOR_OPERATOR_USAGE);
234
+ return eventId;
235
+ }
228
236
 
229
237
  function parseMonitorTestArgs(args: readonly string[]): ParsedMonitorTestArgs {
230
238
  const [monitorId, ...flags] = args;
@@ -265,7 +273,7 @@ function parseMonitorTestArgs(args: readonly string[]): ParsedMonitorTestArgs {
265
273
  };
266
274
  }
267
275
 
268
- const TERMINAL_MONITOR_STAGES = new Set(["delivered", "authored_no_delivery", "failed", "failed_no_retry"]);
276
+ const TERMINAL_MONITOR_STAGES = new Set(["delivered", "authored_no_delivery", "failed", "failed_no_retry", "skipped"]);
269
277
 
270
278
  function waitForMonitorStage(client: GajaewayClient, eventId: string, timeoutSeconds: number): Promise<string> {
271
279
  return new Promise((resolve) => {
@@ -543,6 +551,49 @@ async function chat(socket: string): Promise<void> {
543
551
  }
544
552
  }
545
553
 
554
+ /**
555
+ * Poll for memory operation completion. Memory operations (audit, autolink) are
556
+ * long-running and return an opRef immediately; this function polls for the result.
557
+ * If the CLI wait expires before completion, report 'still running' instead of failure.
558
+ */
559
+ export async function pollMemoryOp(
560
+ client: Pick<GajaewayClient, "request">,
561
+ opRef: string,
562
+ maxWaitMs = 300_000, // 5 min default CLI timeout
563
+ pollIntervalMs = 1_000,
564
+ ): Promise<{ status: "completed" | "failed" | "still_running"; elapsedMs: number; result?: unknown; error?: string }> {
565
+ const startTime = Date.now();
566
+ let operationElapsedMs = 0;
567
+
568
+ while (Date.now() - startTime < maxWaitMs) {
569
+ const status = await client.request<{
570
+ status: "pending" | "completed" | "failed";
571
+ elapsedMs: number;
572
+ result?: unknown;
573
+ error?: string;
574
+ }>("memory.status", { opRef });
575
+ operationElapsedMs = status.elapsedMs;
576
+
577
+ if (status.status === "completed") {
578
+ return { status: "completed", elapsedMs: status.elapsedMs, result: status.result };
579
+ }
580
+
581
+ if (status.status === "failed") {
582
+ return { status: "failed", elapsedMs: status.elapsedMs, error: status.error };
583
+ }
584
+
585
+ // Wait before polling again
586
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
587
+ }
588
+
589
+ // CLI wait expired, but operation may still be running on the server
590
+ const waitedMs = Date.now() - startTime;
591
+ console.error(
592
+ `memory operation still running (${Math.round(operationElapsedMs / 1000)}s operation elapsed; CLI wait ended after ${Math.round(waitedMs / 1000)}s).\nCheck status: gajaeway memory status ${opRef}`,
593
+ );
594
+ return { status: "still_running", elapsedMs: operationElapsedMs };
595
+ }
596
+
546
597
  export async function main(args = process.argv.slice(2), options: MainOptions = {}): Promise<void> {
547
598
  const parsed = parseArgs(args);
548
599
  if (parsed.command === "--version" && parsed.rest.length === 0) {
@@ -721,24 +772,64 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
721
772
  break;
722
773
  }
723
774
  case "memory": {
724
- const usage = "usage: gajaeway memory audit|memory autolink|memory search <query>";
775
+ const usage = "usage: gajaeway memory audit|autolink|search <query>|status <opRef>";
725
776
  // An unrecognised argument is refused before the socket is opened rather
726
777
  // than ignored: a run of `memory audit --fix` that silently degraded to a
727
778
  // plain audit would read as a repair attempt that reproduced the failure.
728
779
  if ((parsed.rest[0] === "audit" || parsed.rest[0] === "autolink") && parsed.rest.length > 1)
729
780
  throw new Error(`${usage} (unknown argument: ${parsed.rest[1]})`);
781
+ if (parsed.rest[0] === "status" && parsed.rest.length < 2) throw new Error(`${usage} (status requires opRef)`);
730
782
  const client = await connectGatewaySocket(parsed.socket);
731
783
  try {
732
784
  if (parsed.rest[0] === "audit") {
733
- const result = await client.request<{ ok: boolean; issues: unknown[] }>("memory.audit");
734
- console.log(JSON.stringify(result.issues));
735
- if (!result.ok) process.exitCode = 1;
785
+ // Request audit operation; get opRef and poll for completion
786
+ const initResp = await client.request<{ opRef: string }>("memory.audit");
787
+ const poll = await pollMemoryOp(client, initResp.opRef);
788
+ if (poll.status === "failed") {
789
+ console.error(`audit failed after ${poll.elapsedMs}ms: ${poll.error}`);
790
+ process.exitCode = 1;
791
+ } else if (poll.status === "still_running") {
792
+ // Operation is still running; exit with distinct code so it's not reported as failure
793
+ process.exitCode = 75;
794
+ } else {
795
+ const auditResult = poll.result as { ok?: boolean; issues?: unknown[] };
796
+ console.log(JSON.stringify(auditResult?.issues ?? []));
797
+ console.error(`audit completed in ${poll.elapsedMs}ms`);
798
+ if (!auditResult?.ok) process.exitCode = 1;
799
+ }
736
800
  } else if (parsed.rest[0] === "autolink") {
737
- console.log(JSON.stringify(await client.request("memory.autolink")));
801
+ // Request autolink operation; get opRef and poll for completion
802
+ const initResp = await client.request<{ opRef: string }>("memory.autolink");
803
+ const poll = await pollMemoryOp(client, initResp.opRef);
804
+ if (poll.status === "failed") {
805
+ console.error(`autolink failed after ${poll.elapsedMs}ms: ${poll.error}`);
806
+ process.exitCode = 1;
807
+ } else if (poll.status === "still_running") {
808
+ // Operation is still running; exit with distinct code so it's not reported as failure
809
+ process.exitCode = 75;
810
+ } else {
811
+ console.log(JSON.stringify(poll.result));
812
+ }
738
813
  } else if (parsed.rest[0] === "search" && parsed.rest.slice(1).join(" ")) {
739
814
  console.log(
740
815
  JSON.stringify(await client.request("memory.search", { query: parsed.rest.slice(1).join(" ") })),
741
816
  );
817
+ } else if (parsed.rest[0] === "status" && parsed.rest[1]) {
818
+ const opRef = parsed.rest[1];
819
+ const result = await client.request<{
820
+ status: "pending" | "completed" | "failed";
821
+ elapsedMs: number;
822
+ result?: unknown;
823
+ error?: string;
824
+ }>("memory.status", { opRef });
825
+ if (result.status === "failed") {
826
+ console.error(`operation ${opRef} failed after ${result.elapsedMs}ms: ${result.error}`);
827
+ process.exitCode = 1;
828
+ } else if (result.status === "completed") {
829
+ console.log(JSON.stringify(result));
830
+ } else {
831
+ console.log(JSON.stringify({ status: result.status, elapsedMs: result.elapsedMs }));
832
+ }
742
833
  } else throw new Error(usage);
743
834
  } finally {
744
835
  await client.close();
@@ -750,6 +841,8 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
750
841
  const listOptions = command === "list" ? parseListOptions(args, MONITOR_COLUMNS) : undefined;
751
842
  const update = command === "update" ? parseMonitorUpdateArgs(args) : undefined;
752
843
  const monitorTest = command === "test" ? parseMonitorTestArgs(args) : undefined;
844
+ const operatorEventId =
845
+ command === "settle" || command === "retry" ? parseMonitorEventOperatorArgs(args) : undefined;
753
846
  const client = await connectGatewaySocket(parsed.socket);
754
847
  try {
755
848
  if (command === "add" && args[0] === "--json" && args[1])
@@ -787,9 +880,15 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
787
880
  const stage = await waitForMonitorStage(client, result.eventId, monitorTest.waitSeconds);
788
881
  console.log(JSON.stringify({ eventId: result.eventId, stage }));
789
882
  }
883
+ } else if ((command === "settle" || command === "retry") && operatorEventId !== undefined) {
884
+ const result = await client.request<MonitorEventOperatorResult>(`monitor.${command}`, {
885
+ eventId: operatorEventId,
886
+ });
887
+ console.log(JSON.stringify(result));
888
+ if (!result.done) process.exitCode = 1;
790
889
  } else
791
890
  throw new Error(
792
- `usage: gajaeway monitors add --json '<MonitorSpec json>'|update <id> (--json '<partial MonitorSpec JSON>'|--schedule '<cron>' [--enabled true|false]|--enabled true|false [--schedule '<cron>'])|list [--json] [--fields ${columnNames(MONITOR_COLUMNS).join(",")}] [--limit N] [--offset N]|inspect <id>|remove <id>|test <id> [--type T] [--payload J] [--wait[=SECONDS]]`,
891
+ `usage: gajaeway monitors add --json '<MonitorSpec json>'|update <id> (--json '<partial MonitorSpec JSON>'|--schedule '<cron>' [--enabled true|false]|--enabled true|false [--schedule '<cron>'])|list [--json] [--fields ${columnNames(MONITOR_COLUMNS).join(",")}] [--limit N] [--offset N]|inspect <id>|remove <id>|settle <eventId>|retry <eventId>|test <id> [--type T] [--payload J] [--wait[=SECONDS]]`,
793
892
  );
794
893
  } finally {
795
894
  await client.close();
@@ -907,16 +1006,24 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
907
1006
  const name = args[0];
908
1007
  let cwd: string | undefined;
909
1008
  let resume = false;
1009
+ let repo: string | undefined;
1010
+ let base: string | undefined;
910
1011
  let model: string | { preset: string } | undefined;
911
1012
  const textParts: string[] = [];
912
1013
  for (let i = 1; i < args.length; i++) {
913
1014
  const arg = args[i];
914
- if (arg === "--cwd" || arg === "--model" || arg === "--preset") {
1015
+ if (arg === "--cwd" || arg === "--repo" || arg === "--base" || arg === "--model" || arg === "--preset") {
915
1016
  const value = args[++i];
916
1017
  if (!value?.trim() || value.startsWith("--")) throw new Error(usage);
917
1018
  if (arg === "--cwd") {
918
1019
  if (cwd !== undefined || !isAbsolute(value)) throw new Error(usage);
919
1020
  cwd = value;
1021
+ } else if (arg === "--repo") {
1022
+ if (repo !== undefined) throw new Error(usage);
1023
+ repo = value;
1024
+ } else if (arg === "--base") {
1025
+ if (base !== undefined) throw new Error(usage);
1026
+ base = value;
920
1027
  } else {
921
1028
  if (model !== undefined) throw new Error(`${usage}\n--model and --preset are mutually exclusive`);
922
1029
  model = arg === "--preset" ? { preset: value } : value;
@@ -938,6 +1045,8 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
938
1045
  name,
939
1046
  text,
940
1047
  ...(cwd ? { cwd } : {}),
1048
+ ...(repo ? { repo } : {}),
1049
+ ...(base ? { base } : {}),
941
1050
  ...(resume ? { resume: true } : {}),
942
1051
  ...(model === undefined ? {} : { model }),
943
1052
  ...(callerSessionId ? { callerSessionId } : {}),
@@ -304,8 +304,10 @@ async function runRestartStackWithLease(options: RunRestartOptions): Promise<Res
304
304
  }
305
305
 
306
306
  const existing = await readRestartReceipt(options.home);
307
+ if (existing?.id === options.id && existing.state !== "queued")
308
+ throw new Error(`restart-stack ${options.id}: receipt is ${existing.state}; refusing to start worker`);
307
309
  const receipt =
308
- existing?.id === options.id && existing.state === "queued"
310
+ existing?.id === options.id
309
311
  ? existing
310
312
  : newReceipt(options.id, platform, options.uid, now(), options.trigger ?? "manual");
311
313
  receipt.state = "running";
@@ -491,16 +493,22 @@ export interface LaunchRestartOptions {
491
493
  /** Argv that re-enters the CLI; `--run <id>` is appended. */
492
494
  readonly worker?: readonly string[];
493
495
  readonly env?: NodeJS.ProcessEnv;
496
+ /** Starts systemd-run; injectable for launcher-result handling. */
497
+ readonly systemdRun?: (command: readonly string[]) => Bun.Subprocess;
498
+ /** Maximum time to wait for systemd-run to acknowledge the worker exec. */
499
+ readonly systemdRunTimeoutMs?: number;
494
500
  }
495
501
 
502
+ const SYSTEMD_RUN_TIMEOUT_MS = 30_000;
503
+
496
504
  /** The argv that runs this CLI again, whether compiled or run from source. */
497
505
  export function cliCommand(): string[] {
498
506
  return Bun.main.startsWith("/$bunfs/") ? [process.execPath] : [process.execPath, Bun.main];
499
507
  }
500
508
 
501
509
  /**
502
- * Queues a restart and hands it to a detached supervisor, returning as soon as
503
- * the supervisor is spawned so the caller may be killed by the restart itself.
510
+ * Queues a restart and hands it to a detached supervisor, returning once the
511
+ * platform launcher acknowledges it so the caller may be killed by the restart.
504
512
  */
505
513
  export async function launchRestartStack(
506
514
  options: LaunchRestartOptions,
@@ -512,35 +520,75 @@ export async function launchRestartStack(
512
520
  await writeReceipt(options.home, receipt);
513
521
  const worker = [...(options.worker ?? [...cliCommand(), "ops", "restart-stack"]), "--run", receipt.id];
514
522
  const argv = supervisorArgv(platform, worker, options.home, receipt.id, options.binDir);
523
+ const spawnOptions = {
524
+ detached: true,
525
+ stdin: "ignore" as const,
526
+ stdout: "ignore" as const,
527
+ stderr: "ignore" as const,
528
+ env: {
529
+ ...(options.env ?? process.env),
530
+ GAJAEWAY_HOME: options.home,
531
+ ...(options.binDir === undefined ? {} : { GAJAEWAY_BIN_DIR: options.binDir }),
532
+ },
533
+ };
515
534
  let child: Bun.Subprocess;
516
535
  try {
517
- child = Bun.spawn(argv, {
518
- detached: true,
519
- stdin: "ignore",
520
- stdout: "ignore",
521
- stderr: "ignore",
522
- env: {
523
- ...(options.env ?? process.env),
524
- GAJAEWAY_HOME: options.home,
525
- ...(options.binDir === undefined ? {} : { GAJAEWAY_BIN_DIR: options.binDir }),
526
- },
527
- });
536
+ child =
537
+ platform === "linux"
538
+ ? (options.systemdRun ?? ((command) => Bun.spawn([...command], spawnOptions)))(argv)
539
+ : Bun.spawn(argv, spawnOptions);
528
540
  } catch (error) {
529
- // Nothing will ever pick this receipt up: leaving it `queued` reads as a
530
- // restart still on its way. A host without a systemd user manager (a
531
- // container) has no `systemd-run`, and its restart belongs to whatever
532
- // supervises that host.
533
- receipt.state = "failed";
534
- receipt.finishedAt = new Date().toISOString();
535
- receipt.detail = `supervisor ${argv[0]} could not be started (${error instanceof Error ? error.message : String(error)}); without a service manager here, restart through the host's own supervisor`;
536
- for (const step of receipt.steps) step.result = "skipped";
537
- await writeReceipt(options.home, receipt);
538
- throw new Error(`restart-stack ${receipt.id}: failed: ${receipt.detail}`);
541
+ const detail =
542
+ platform === "linux"
543
+ ? `supervisor systemd-run could not be started (${error instanceof Error ? error.message : String(error)}); without a service manager here, restart through the host's own supervisor`
544
+ : `supervisor ${argv[0]} could not be started (${error instanceof Error ? error.message : String(error)})`;
545
+ await failLaunch(options.home, receipt, detail);
546
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
547
+ }
548
+ if (platform === "linux") {
549
+ const outcome = await waitForLauncher(child, options.systemdRunTimeoutMs ?? SYSTEMD_RUN_TIMEOUT_MS);
550
+ if (outcome.kind === "timed_out") {
551
+ const detail = `supervisor systemd-run timed out after ${options.systemdRunTimeoutMs ?? SYSTEMD_RUN_TIMEOUT_MS}ms; handoff outcome is indeterminate`;
552
+ await failLaunch(options.home, receipt, detail);
553
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
554
+ }
555
+ if (outcome.exitStatus !== 0) {
556
+ const detail = `supervisor systemd-run exited with status ${outcome.exitStatus}`;
557
+ await failLaunch(options.home, receipt, detail);
558
+ throw new Error(`restart-stack ${receipt.id}: failed: ${detail}`);
559
+ }
539
560
  }
540
561
  child.unref();
541
562
  return { receipt, supervisorPid: child.pid };
542
563
  }
543
564
 
565
+ async function failLaunch(home: string, receipt: RestartReceipt, detail: string): Promise<void> {
566
+ receipt.state = "failed";
567
+ receipt.finishedAt = new Date().toISOString();
568
+ receipt.detail = detail;
569
+ for (const step of receipt.steps) step.result = "skipped";
570
+ await writeReceipt(home, receipt);
571
+ }
572
+
573
+ async function waitForLauncher(
574
+ child: Bun.Subprocess,
575
+ timeoutMs: number,
576
+ ): Promise<{ readonly kind: "exited"; readonly exitStatus: number } | { readonly kind: "timed_out" }> {
577
+ let timer: ReturnType<typeof setTimeout> | undefined;
578
+ const outcome = await Promise.race([
579
+ child.exited.then((exitStatus) => ({ kind: "exited" as const, exitStatus })),
580
+ new Promise<{ readonly kind: "timed_out" }>((resolve) => {
581
+ timer = setTimeout(() => resolve({ kind: "timed_out" }), timeoutMs);
582
+ }),
583
+ ]);
584
+ if (timer !== undefined) clearTimeout(timer);
585
+ if (outcome.kind === "timed_out") {
586
+ child.kill("SIGKILL");
587
+ void child.exited.catch(() => undefined);
588
+ }
589
+ return outcome;
590
+ }
591
+
544
592
  /**
545
593
  * A new session escapes the caller's process group, which is enough under
546
594
  * launchd. Under systemd the caller usually lives in a service cgroup that the
@@ -560,6 +608,7 @@ export function supervisorArgv(
560
608
  "--user",
561
609
  "--collect",
562
610
  "--quiet",
611
+ "--service-type=exec",
563
612
  `--unit=gajaeway-restart-stack-${id}`,
564
613
  `--setenv=GAJAEWAY_HOME=${home}`,
565
614
  ...(binDir === undefined ? [] : [`--setenv=GAJAEWAY_BIN_DIR=${binDir}`]),
package/src/update.ts CHANGED
@@ -39,6 +39,8 @@ export const UPDATE_USAGE = "usage: gajaeway update [--check] [--force] [--bin-d
39
39
 
40
40
  export const DEFAULT_RELEASE_REPO = "Yeachan-Heo/gajae-way";
41
41
  const RELEASE_REPO_OVERRIDE_ENV = "GAJAEWAY_UPDATE_REPO";
42
+ /** The release manifest carrying the gjc pin; installed beside the binaries. */
43
+ const PIN_MANIFEST = "package.json";
42
44
  /** A fork can point updates at its own releases; the declared upstream stays the default. */
43
45
  export function releaseRepo(env: NodeJS.ProcessEnv = process.env): string {
44
46
  const override = env[RELEASE_REPO_OVERRIDE_ENV]?.trim();
@@ -360,7 +362,7 @@ export async function runUpdate(options: RunUpdateOptions): Promise<UpdateResult
360
362
  throw new Error(`release tarball is missing core binaries: ${missingCore.join(", ")}`);
361
363
  await assertStagedBinariesUsable(staged, toInstall);
362
364
 
363
- const gjcVersion = await readPinnedGjcVersion(join(staged.dir, "package.json"));
365
+ const gjcVersion = await readPinnedGjcVersion(join(staged.dir, PIN_MANIFEST));
364
366
  await installPinnedGjc({
365
367
  home: options.home,
366
368
  version: gjcVersion,
@@ -370,15 +372,18 @@ export async function runUpdate(options: RunUpdateOptions): Promise<UpdateResult
370
372
  const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[-:]/g, "").slice(0, 15);
371
373
  const backupDir = join(binDir, `backup-${current}-${stamp}Z`);
372
374
  await mkdir(backupDir, { recursive: false });
373
- for (const name of toInstall) {
375
+ // The compiled gateway and broker host read the gjc pin from the package.json
376
+ // beside them; a stale one makes the new binaries refuse the gjc just installed.
377
+ const replaced = [...toInstall, PIN_MANIFEST];
378
+ for (const name of replaced) {
374
379
  const target = join(binDir, name);
375
380
  if (await exists(target)) await copyFile(target, join(backupDir, name));
376
381
  }
377
- for (const name of toInstall) {
382
+ for (const name of replaced) {
378
383
  const stagedPath = join(staged.dir, name);
379
384
  const tempPath = join(binDir, `.update-${name}`);
380
385
  await copyFile(stagedPath, tempPath);
381
- await chmod(tempPath, 0o755);
386
+ await chmod(tempPath, name === PIN_MANIFEST ? 0o644 : 0o755);
382
387
  await rename(tempPath, join(binDir, name));
383
388
  }
384
389
  await writeFile(releaseMarkerPath(binDir), `${latest}\n`, "utf8");