@gajae-gateway/cli 0.2.2 → 0.3.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAmBpD,MAAM,WAAW,MAAM,CAAC,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CACnD;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAEtE;AASD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAyBvG;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAGvG;AAED,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAItG;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKjD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAC5B,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,EAC7B,OAAO,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/C,MAAM,EAAE,CAcV;AAED,wBAAgB,WAAW,CAAC,CAAC,EAC5B,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,EAC7B,OAAO,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/C,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAIhC;AAgBD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,CAAC,cAAc,CAAC,EAoB5D,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3G;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,CAAC,cAAc,CAAC,EAa5D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC3B,OAAO,EAAE,SAAS,MAAM,CAAC,CAAC,CAAC,EAAE,EAC7B,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE;IACT,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC;CAC5C,GACC,MAAM,EAAE,CASV"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare function socketPath(home?: string | undefined): string;
13
13
  * never after, so the list is checked up front.
14
14
  */
15
15
  export declare const COMMANDS: readonly ["status", "shutdown", "chat", "daemon", "sessions", "ops", "memory", "monitors", "work", "services", "migrate", "update", "setup"];
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
+ 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] [--repo PATH|URL [--base REF]] [--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";
17
17
  /** Usage errors exit 2, as `gajaeway-gateway` does; 1 stays a runtime failure. */
18
18
  export declare const USAGE_EXIT_CODE = 2;
19
19
  /** The usage text when `command` cannot be dispatched, undefined when it can. */
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAMX,cAAc,EAEd,mBAAmB,EAEnB,YAAY,EASZ,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAcpD,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,uvCAC+tC,CAAC;AAEtvC,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;AA4ID;;;;;;;;;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;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,EACvC,KAAK,EAAE,MAAM,EACb,SAAS,SAAU,EAAE,4BAA4B;AACjD,cAAc,SAAQ,GACpB,OAAO,CAAC;IAAE,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,eAAe,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA+BpH;AAED,wBAAsB,IAAI,CAAC,IAAI,WAAwB,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsgBjG"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -2,13 +2,13 @@
2
2
  // @bun
3
3
 
4
4
  // src/main.ts
5
- import { isAbsolute } from "path";
5
+ import { isAbsolute, resolve } from "path";
6
6
  import { LOOPBACK_ORIGIN, originKey as originKey2, WORK_JOBS_MAX_LIMIT } from "@gajae-gateway/protocol";
7
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.2",
11
+ version: "0.3.0",
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",
@@ -172,6 +172,7 @@ var MONITOR_COLUMNS = [
172
172
  },
173
173
  { name: "events", value: (row) => [...row.monitor.eventTypes] },
174
174
  { name: "target", value: (row) => row.monitor.channelTarget ? originKey(row.monitor.channelTarget.origin) : null },
175
+ { name: "reportTo", value: (row) => row.monitor.reportTo ? originKey(row.monitor.reportTo) : null },
175
176
  { name: "enabled", value: (row) => row.monitor.enabled }
176
177
  ];
177
178
  var SESSION_COLUMNS = [
@@ -1418,12 +1419,12 @@ function parseMigrateArgs(args) {
1418
1419
 
1419
1420
  // src/restart-stack.ts
1420
1421
  import { randomUUID as randomUUID2 } from "crypto";
1421
- import { access, mkdir as mkdir4, readFile as readFile5, rename as rename2, stat, writeFile as writeFile3 } from "fs/promises";
1422
+ import { access, mkdir as mkdir4, readFile as readFile5, realpath, rename as rename2, stat, writeFile as writeFile3 } from "fs/promises";
1422
1423
  import { homedir as homedir3 } from "os";
1423
- import { dirname, join as join7 } from "path";
1424
+ import { basename, dirname, join as join7 } from "path";
1424
1425
 
1425
1426
  // src/services.ts
1426
- import { chmod as chmod2, mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
1427
+ import { chmod as chmod2, mkdir as mkdir3, readFile as readFile4, rm as rm2, writeFile as writeFile2 } from "fs/promises";
1427
1428
  import { homedir as homedir2 } from "os";
1428
1429
  import { join as join6 } from "path";
1429
1430
  import { parseRuntimeConfig, RuntimeConfigError } from "@gajae-gateway/protocol";
@@ -1473,6 +1474,11 @@ var SERVICE_SPECS = [
1473
1474
  function serviceSpecs() {
1474
1475
  return SERVICE_SPECS;
1475
1476
  }
1477
+ function adapterConfigPath(home, specId) {
1478
+ if (!specId.startsWith("adapter-"))
1479
+ return;
1480
+ return join6(home, `adapter-${specId.slice("adapter-".length)}.json`);
1481
+ }
1476
1482
  function homeForEnvironment(env) {
1477
1483
  return env.GAJAEWAY_HOME || join6(env.HOME || homedir2(), ".gajaeway");
1478
1484
  }
@@ -1608,6 +1614,43 @@ function launchAgentPlistPath(spec, launchAgentsDir) {
1608
1614
  function systemdUnitPath(spec, unitDir) {
1609
1615
  return join6(unitDir, systemdUnitName(spec));
1610
1616
  }
1617
+ async function removeStaleServices(options) {
1618
+ const env = options.env ?? process.env;
1619
+ const userHome = env.HOME || homedir2();
1620
+ const definitionDir = options.platform === "darwin" ? options.launchAgentsDir ?? join6(userHome, "Library", "LaunchAgents") : options.unitDir ?? systemdUnitDir(env, userHome);
1621
+ const expandedDefinitionDir = expandHome2(definitionDir, userHome);
1622
+ const staleDefinitions = [];
1623
+ for (const spec of SERVICE_SPECS) {
1624
+ if (await Bun.file(join6(options.binDir, spec.binary)).exists())
1625
+ continue;
1626
+ const path = options.platform === "darwin" ? launchAgentPlistPath(spec, expandedDefinitionDir) : systemdUnitPath(spec, expandedDefinitionDir);
1627
+ if (await Bun.file(path).exists())
1628
+ staleDefinitions.push({ label: spec.label, path, unitName: systemdUnitName(spec) });
1629
+ }
1630
+ const execute = async (command, allowFailure = false) => {
1631
+ const exitCode = await options.run(command, allowFailure ? { allowFailure: true } : undefined);
1632
+ if (exitCode !== 0 && !allowFailure)
1633
+ throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
1634
+ return exitCode;
1635
+ };
1636
+ if (options.platform === "linux") {
1637
+ if (staleDefinitions.length === 0)
1638
+ return;
1639
+ await execute(["systemctl", "--user", "disable", "--now", ...staleDefinitions.map(({ unitName }) => unitName)]);
1640
+ for (const { path } of staleDefinitions)
1641
+ await rm2(path, { force: true });
1642
+ if (options.reloadSystemd ?? true)
1643
+ await execute(["systemctl", "--user", "daemon-reload"]);
1644
+ return;
1645
+ }
1646
+ const target = `gui/${options.uid ?? process.getuid?.() ?? 0}`;
1647
+ for (const { label, path } of staleDefinitions) {
1648
+ const serviceTarget = `${target}/${label}`;
1649
+ if (await execute(["launchctl", "print", serviceTarget], true) === 0)
1650
+ await execute(["launchctl", "bootout", serviceTarget]);
1651
+ await rm2(path, { force: true });
1652
+ }
1653
+ }
1611
1654
  function restartStackCommands(platform, uid) {
1612
1655
  if (platform === "linux")
1613
1656
  return [
@@ -1682,11 +1725,11 @@ async function installServices(options) {
1682
1725
  await mkdir3(targetDir, { recursive: true, mode: 448 });
1683
1726
  const specs = [];
1684
1727
  for (const spec of SERVICE_SPECS) {
1685
- if (options.configuredAdaptersOnly && spec.id.startsWith("adapter-")) {
1686
- const adapter = spec.id.slice("adapter-".length);
1687
- if (!await Bun.file(join6(home, `adapter-${adapter}.json`)).exists())
1688
- continue;
1689
- }
1728
+ if (!await Bun.file(join6(binDir, spec.binary)).exists())
1729
+ continue;
1730
+ const adapterConfig = adapterConfigPath(home, spec.id);
1731
+ if (options.configuredAdaptersOnly && adapterConfig !== undefined && !await Bun.file(adapterConfig).exists())
1732
+ continue;
1690
1733
  specs.push(spec);
1691
1734
  }
1692
1735
  const definitions = specs.map((spec) => platform === "darwin" ? {
@@ -1872,7 +1915,23 @@ async function runRestartStackWithLease(options) {
1872
1915
  const sleep = options.sleep ?? ((ms) => Bun.sleep(ms));
1873
1916
  const timeoutMs = options.verifyTimeoutMs ?? VERIFY_TIMEOUT_MS;
1874
1917
  const pollMs = options.pollMs ?? POLL_MS;
1875
- const binDir = options.binDir ?? process.env.GAJAEWAY_BIN_DIR ?? dirname(process.execPath);
1918
+ const env = options.env ?? process.env;
1919
+ const deployedExecutable = await realpath(process.execPath).catch(() => {
1920
+ return;
1921
+ });
1922
+ const installedBinDir = options.binDir ?? env.GAJAEWAY_BIN_DIR ?? (deployedExecutable !== undefined && basename(deployedExecutable).startsWith("gajaeway") ? dirname(deployedExecutable) : undefined);
1923
+ const binDir = installedBinDir ?? dirname(process.execPath);
1924
+ if (installedBinDir !== undefined) {
1925
+ await removeStaleServices({
1926
+ binDir: installedBinDir,
1927
+ platform,
1928
+ uid: options.uid,
1929
+ env,
1930
+ ...options.launchAgentsDir === undefined ? {} : { launchAgentsDir: options.launchAgentsDir },
1931
+ ...options.unitDir === undefined ? {} : { unitDir: options.unitDir },
1932
+ run: runner
1933
+ });
1934
+ }
1876
1935
  const originalPids = new Map;
1877
1936
  for (const spec of restartOrder()) {
1878
1937
  if (SERVICE_LEASES[spec.id] === undefined && await isInstalled(spec.label))
@@ -1905,6 +1964,14 @@ async function runRestartStackWithLease(options) {
1905
1964
  await writeReceipt(options.home, receipt);
1906
1965
  continue;
1907
1966
  }
1967
+ const adapterSpec = serviceSpecs().find((candidate) => candidate.label === step.label);
1968
+ const adapterConfig = adapterSpec === undefined ? undefined : adapterConfigPath(options.home, adapterSpec.id);
1969
+ if (adapterConfig !== undefined && !await Bun.file(adapterConfig).exists()) {
1970
+ step.result = "skipped";
1971
+ step.detail = "adapter is not configured";
1972
+ await writeReceipt(options.home, receipt);
1973
+ continue;
1974
+ }
1908
1975
  if (step.label === "dev.gajaeway.broker" && receipt.trigger === "update") {
1909
1976
  const stopCommand = serviceStopCommand(platform, options.uid);
1910
1977
  const stopStatus = await runner(stopCommand);
@@ -1952,7 +2019,7 @@ async function runRestartStackWithLease(options) {
1952
2019
  issuedAt = now();
1953
2020
  let command = step.command;
1954
2021
  let status = await runner(command);
1955
- if (status !== 0 && receipt.trigger === "update" && platform === "darwin" && await probe(step.label) === undefined) {
2022
+ if (status !== 0 && platform === "darwin" && await probe(step.label) === undefined) {
1956
2023
  command = serviceBootstrapCommand(options, platform, step.label);
1957
2024
  step.command = command;
1958
2025
  issuedAt = now();
@@ -2152,8 +2219,8 @@ function renderRestartReceipt(receipt, state = receipt.state) {
2152
2219
 
2153
2220
  // src/setup.ts
2154
2221
  import { randomUUID as randomUUID3 } from "crypto";
2155
- import { chmod as chmod3, mkdir as mkdir5, readFile as readFile6, realpath, rename as rename3, rm as rm2, writeFile as writeFile4 } from "fs/promises";
2156
- import { basename, dirname as dirname2, join as join8 } from "path";
2222
+ import { chmod as chmod3, mkdir as mkdir5, readFile as readFile6, realpath as realpath2, rename as rename3, rm as rm3, writeFile as writeFile4 } from "fs/promises";
2223
+ import { basename as basename2, dirname as dirname2, join as join8 } from "path";
2157
2224
 
2158
2225
  // src/discord-setup.ts
2159
2226
  var DEVELOPER_PORTAL_URL = "https://discord.com/developers/applications";
@@ -2463,7 +2530,7 @@ async function writePrivateFile(path, contents) {
2463
2530
  await chmod3(temporary, 384);
2464
2531
  await rename3(temporary, path);
2465
2532
  } finally {
2466
- await rm2(temporary, { force: true });
2533
+ await rm3(temporary, { force: true });
2467
2534
  }
2468
2535
  }
2469
2536
  async function readJsonObject(path) {
@@ -2660,10 +2727,10 @@ async function setupBinDir(options) {
2660
2727
  const env = options.env ?? process.env;
2661
2728
  if (env.GAJAEWAY_BIN_DIR)
2662
2729
  return env.GAJAEWAY_BIN_DIR;
2663
- const executable = await realpath(process.execPath).catch(() => {
2730
+ const executable = await realpath2(process.execPath).catch(() => {
2664
2731
  return;
2665
2732
  });
2666
- if (executable !== undefined && basename(executable).startsWith("gajaeway"))
2733
+ if (executable !== undefined && basename2(executable).startsWith("gajaeway"))
2667
2734
  return dirname2(executable);
2668
2735
  throw new SetupError("setup --broker-agent requires the installed gajaeway binary or an explicit bin directory");
2669
2736
  }
@@ -2742,14 +2809,14 @@ import {
2742
2809
  mkdtemp as mkdtemp2,
2743
2810
  readdir as readdir3,
2744
2811
  readFile as readFile7,
2745
- realpath as realpath2,
2812
+ realpath as realpath3,
2746
2813
  rename as rename5,
2747
- rm as rm4,
2814
+ rm as rm5,
2748
2815
  stat as stat2,
2749
2816
  writeFile as writeFile6
2750
2817
  } from "fs/promises";
2751
2818
  import { tmpdir } from "os";
2752
- import { basename as basename2, dirname as dirname3, join as join10 } from "path";
2819
+ import { basename as basename3, dirname as dirname3, join as join10 } from "path";
2753
2820
 
2754
2821
  // src/gjc-install.ts
2755
2822
  import { randomUUID as randomUUID4 } from "crypto";
@@ -2760,9 +2827,9 @@ import {
2760
2827
  mkdir as mkdir6,
2761
2828
  mkdtemp,
2762
2829
  readdir as readdir2,
2763
- readlink as readlink2,
2830
+ readlink,
2764
2831
  rename as rename4,
2765
- rm as rm3,
2832
+ rm as rm4,
2766
2833
  symlink,
2767
2834
  writeFile as writeFile5
2768
2835
  } from "fs/promises";
@@ -2798,7 +2865,7 @@ ${result.stderr}`);
2798
2865
  }
2799
2866
  async function currentVersion(prefix, current) {
2800
2867
  try {
2801
- const target = await readlink2(current);
2868
+ const target = await readlink(current);
2802
2869
  if (target.includes("/") || !VERSION_PATTERN.test(target))
2803
2870
  return;
2804
2871
  const targetPath = join9(prefix, target);
@@ -2820,7 +2887,7 @@ async function pruneVersions(prefix, keep) {
2820
2887
  }
2821
2888
  for (const version of versions)
2822
2889
  if (!retained.has(version))
2823
- await rm3(join9(prefix, version), { recursive: true, force: true });
2890
+ await rm4(join9(prefix, version), { recursive: true, force: true });
2824
2891
  }
2825
2892
  async function installPinnedGjc(options) {
2826
2893
  const { home, version } = options;
@@ -2868,12 +2935,12 @@ async function installPinnedGjc(options) {
2868
2935
  await symlink(version, temporaryLink, "dir");
2869
2936
  await rename4(temporaryLink, layout.gjcCurrent);
2870
2937
  } finally {
2871
- await rm3(temporaryLink, { force: true });
2938
+ await rm4(temporaryLink, { force: true });
2872
2939
  }
2873
2940
  return layout.gjcExecutable();
2874
2941
  } finally {
2875
2942
  if (staging !== undefined)
2876
- await rm3(staging, { recursive: true, force: true });
2943
+ await rm4(staging, { recursive: true, force: true });
2877
2944
  }
2878
2945
  }
2879
2946
 
@@ -2881,7 +2948,6 @@ async function installPinnedGjc(options) {
2881
2948
  var UPDATE_USAGE = "usage: gajaeway update [--check] [--force] [--bin-dir DIR] [--no-restart]";
2882
2949
  var DEFAULT_RELEASE_REPO = "Yeachan-Heo/gajae-way";
2883
2950
  var RELEASE_REPO_OVERRIDE_ENV = "GAJAEWAY_UPDATE_REPO";
2884
- var PIN_MANIFEST = "package.json";
2885
2951
  function releaseRepo(env = process.env) {
2886
2952
  const override = env[RELEASE_REPO_OVERRIDE_ENV]?.trim();
2887
2953
  return override ? override : declaredReleaseRepo();
@@ -2958,12 +3024,12 @@ async function readInstalledRelease(binDir) {
2958
3024
  async function resolveBinDir(flag, execPath = process.execPath) {
2959
3025
  if (flag !== undefined)
2960
3026
  return flag;
2961
- const real = await realpath2(execPath).catch(() => {
3027
+ const real = await realpath3(execPath).catch(() => {
2962
3028
  return;
2963
3029
  });
2964
3030
  if (real === undefined)
2965
3031
  return;
2966
- return basename2(real).startsWith("gajaeway") ? dirname3(real) : undefined;
3032
+ return basename3(real).startsWith("gajaeway") ? dirname3(real) : undefined;
2967
3033
  }
2968
3034
  function renderUpdate(result) {
2969
3035
  const lines = [];
@@ -3004,10 +3070,10 @@ async function readPinnedGjcVersion(path) {
3004
3070
  throw new Error(`release package metadata at ${path} has no gjc.version`);
3005
3071
  return version;
3006
3072
  }
3007
- async function defaultUpdateCommandRunner(command) {
3073
+ async function defaultUpdateCommandRunner(command, options) {
3008
3074
  const child = Bun.spawn([...command], { stdin: "ignore", stdout: "ignore", stderr: "pipe" });
3009
3075
  const [stderr, exitCode] = await Promise.all([new Response(child.stderr).text(), child.exited]);
3010
- if (exitCode !== 0) {
3076
+ if (exitCode !== 0 && !options?.allowFailure) {
3011
3077
  const detail = stderr.trim();
3012
3078
  throw new Error(`${command.join(" ")} exited with status ${exitCode}${detail.length === 0 ? "" : `: ${detail}`}`);
3013
3079
  }
@@ -3017,6 +3083,22 @@ async function installUpdatedServices(options) {
3017
3083
  const { home, binDir, platform, noRestart, deps } = options;
3018
3084
  const brokerProvisioned = await exists(homeLayout(home).brokerProvisionManifest);
3019
3085
  const env = { ...deps.env ?? process.env, GAJAEWAY_HOME: home };
3086
+ const run = deps.serviceRunner ?? defaultUpdateCommandRunner;
3087
+ const execute = async (command) => {
3088
+ const exitCode = await run(command);
3089
+ if (exitCode !== 0)
3090
+ throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
3091
+ };
3092
+ if (!noRestart) {
3093
+ await removeStaleServices({
3094
+ binDir,
3095
+ platform,
3096
+ env,
3097
+ reloadSystemd: false,
3098
+ ...deps.serviceOptions,
3099
+ run
3100
+ });
3101
+ }
3020
3102
  await installServices({
3021
3103
  binDir,
3022
3104
  platform,
@@ -3026,16 +3108,12 @@ async function installUpdatedServices(options) {
3026
3108
  ...deps.serviceOptions
3027
3109
  });
3028
3110
  if (platform === "linux") {
3029
- const run = deps.serviceRunner ?? defaultUpdateCommandRunner;
3030
- const execute = async (command) => {
3031
- const exitCode = await run(command);
3032
- if (exitCode !== 0)
3033
- throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
3034
- };
3035
3111
  await execute(["systemctl", "--user", "daemon-reload"]);
3036
3112
  if (!noRestart) {
3037
3113
  const enableUnits = [];
3038
3114
  for (const spec of serviceSpecs()) {
3115
+ if (!await exists(join10(binDir, spec.binary)))
3116
+ continue;
3039
3117
  if (spec.id === "broker" && !brokerProvisioned)
3040
3118
  continue;
3041
3119
  if (spec.id.startsWith("adapter-") && !await Bun.file(join10(home, `adapter-${spec.id.slice(8)}.json`)).exists())
@@ -3092,7 +3170,7 @@ async function runUpdate(options) {
3092
3170
  if (missingCore.length > 0)
3093
3171
  throw new Error(`release tarball is missing core binaries: ${missingCore.join(", ")}`);
3094
3172
  await assertStagedBinariesUsable(staged, toInstall);
3095
- const gjcVersion = await readPinnedGjcVersion(join10(staged.dir, PIN_MANIFEST));
3173
+ const gjcVersion = await readPinnedGjcVersion(join10(staged.dir, "package.json"));
3096
3174
  await installPinnedGjc({
3097
3175
  home: options.home,
3098
3176
  version: gjcVersion,
@@ -3101,19 +3179,24 @@ async function runUpdate(options) {
3101
3179
  const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[-:]/g, "").slice(0, 15);
3102
3180
  const backupDir = join10(binDir, `backup-${current}-${stamp}Z`);
3103
3181
  await mkdir7(backupDir, { recursive: false });
3104
- const replaced = [...toInstall, PIN_MANIFEST];
3105
- for (const name of replaced) {
3182
+ for (const name of toInstall) {
3106
3183
  const target = join10(binDir, name);
3107
3184
  if (await exists(target))
3108
3185
  await copyFile(target, join10(backupDir, name));
3109
3186
  }
3110
- for (const name of replaced) {
3187
+ const packagePath = join10(binDir, "package.json");
3188
+ if (await exists(packagePath))
3189
+ await copyFile(packagePath, join10(backupDir, "package.json"));
3190
+ for (const name of toInstall) {
3111
3191
  const stagedPath = join10(staged.dir, name);
3112
3192
  const tempPath = join10(binDir, `.update-${name}`);
3113
3193
  await copyFile(stagedPath, tempPath);
3114
- await chmod5(tempPath, name === PIN_MANIFEST ? 420 : 493);
3194
+ await chmod5(tempPath, 493);
3115
3195
  await rename5(tempPath, join10(binDir, name));
3116
3196
  }
3197
+ const packageTempPath = join10(binDir, ".update-package.json");
3198
+ await copyFile(join10(staged.dir, "package.json"), packageTempPath);
3199
+ await rename5(packageTempPath, packagePath);
3117
3200
  await writeFile6(releaseMarkerPath(binDir), `${latest}
3118
3201
  `, "utf8");
3119
3202
  const brokerNotEnabled = await installUpdatedServices({
@@ -3126,7 +3209,7 @@ async function runUpdate(options) {
3126
3209
  return { toInstall, backupDir, brokerNotEnabled };
3127
3210
  } finally {
3128
3211
  if (staged !== undefined)
3129
- await rm4(staged.dir, { recursive: true, force: true });
3212
+ await rm5(staged.dir, { recursive: true, force: true });
3130
3213
  await lease.release();
3131
3214
  }
3132
3215
  })();
@@ -3222,9 +3305,9 @@ async function defaultExtractTarball(tarball, intoDir) {
3222
3305
  const exitCode = await process2.exited;
3223
3306
  if (exitCode !== 0) {
3224
3307
  const detail = await new Response(process2.stderr).text();
3225
- throw new Error(`extracting ${basename2(tarballPath)} failed (tar exit ${exitCode}): ${detail.trim()}`);
3308
+ throw new Error(`extracting ${basename3(tarballPath)} failed (tar exit ${exitCode}): ${detail.trim()}`);
3226
3309
  }
3227
- await rm4(tarballPath, { force: true });
3310
+ await rm5(tarballPath, { force: true });
3228
3311
  }
3229
3312
  async function defaultQueueRestart(home, binDir, trigger) {
3230
3313
  const { receipt, supervisorPid } = await launchRestartStack({ home, binDir, trigger });
@@ -3253,7 +3336,7 @@ var COMMANDS = [
3253
3336
  "update",
3254
3337
  "setup"
3255
3338
  ];
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";
3339
+ 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] [--repo PATH|URL [--base REF]] [--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";
3257
3340
  var USAGE_EXIT_CODE = 2;
3258
3341
  function usageFor(command) {
3259
3342
  return command !== undefined && COMMANDS.includes(command) ? undefined : CLI_USAGE;
@@ -3421,7 +3504,7 @@ unknown argument: ${flag}`);
3421
3504
  }
3422
3505
  var TERMINAL_MONITOR_STAGES = new Set(["delivered", "authored_no_delivery", "failed", "failed_no_retry", "skipped"]);
3423
3506
  function waitForMonitorStage(client, eventId, timeoutSeconds) {
3424
- return new Promise((resolve) => {
3507
+ return new Promise((resolve2) => {
3425
3508
  let stage = "admitted";
3426
3509
  let settled = false;
3427
3510
  let timer;
@@ -3433,7 +3516,7 @@ function waitForMonitorStage(client, eventId, timeoutSeconds) {
3433
3516
  if (timer !== undefined)
3434
3517
  clearTimeout(timer);
3435
3518
  unsubscribe?.();
3436
- resolve(stage);
3519
+ resolve2(stage);
3437
3520
  };
3438
3521
  unsubscribe = client.on("monitor.event", (payload) => {
3439
3522
  if (typeof payload !== "object" || payload === null)
@@ -3594,7 +3677,7 @@ function renderDeliveries(result) {
3594
3677
  return ["deliveries: none"];
3595
3678
  return [
3596
3679
  `deliveries: ${result.rows.length}`,
3597
- ...result.rows.map((row) => `${row.createdAt} ${row.state} delivery=${row.deliveryId} turn=${row.turnId} origin=${row.originKey} conversation=${row.conversationId} text=${JSON.stringify(row.textPrefix)}`)
3680
+ ...result.rows.map((row) => `${row.createdAt} ${row.state} delivery=${row.deliveryId} turn=${row.turnId} origin=${row.originKey} conversation=${row.conversationId} lastError=${row.lastError ?? "-"} text=${JSON.stringify(row.textPrefix)}`)
3598
3681
  ];
3599
3682
  }
3600
3683
  var CHAT_TURN_TIMEOUT_MS = 30 * 60000;
@@ -3619,16 +3702,16 @@ async function chat(socket) {
3619
3702
  console.error("(message was not engaged)");
3620
3703
  return;
3621
3704
  }
3622
- await new Promise((resolve) => {
3705
+ await new Promise((resolve2) => {
3623
3706
  const timer = setTimeout(() => {
3624
3707
  turnWaiters.delete(turnId);
3625
3708
  console.error(`(turn timed out after ${CHAT_TURN_TIMEOUT_MS / 60000}m)`);
3626
- resolve();
3709
+ resolve2();
3627
3710
  }, CHAT_TURN_TIMEOUT_MS);
3628
3711
  turnWaiters.set(turnId, () => {
3629
3712
  clearTimeout(timer);
3630
3713
  turnWaiters.delete(turnId);
3631
- resolve();
3714
+ resolve2();
3632
3715
  });
3633
3716
  });
3634
3717
  };
@@ -3668,7 +3751,7 @@ async function pollMemoryOp(client, opRef, maxWaitMs = 300000, pollIntervalMs =
3668
3751
  if (status.status === "failed") {
3669
3752
  return { status: "failed", elapsedMs: status.elapsedMs, error: status.error };
3670
3753
  }
3671
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
3754
+ await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
3672
3755
  }
3673
3756
  const waitedMs = Date.now() - startTime;
3674
3757
  console.error(`memory operation still running (${Math.round(operationElapsedMs / 1000)}s operation elapsed; CLI wait ended after ${Math.round(waitedMs / 1000)}s).
@@ -3949,7 +4032,7 @@ ${OPS_USAGE}`);
3949
4032
  }
3950
4033
  case "work": {
3951
4034
  const [command, ...args2] = parsed.rest;
3952
- const usage2 = 'usage: gajaeway work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] "<task text>"|status <name>|steer <name> <text>|retire <name>|jobs';
4035
+ const usage2 = 'usage: gajaeway work run|start <name> [--cwd DIR] [--repo PATH|URL [--base REF]] [--resume] [--model ID|--preset NAME] "<task text>"|status <name>|steer <name> <text>|retire <name>|jobs';
3953
4036
  if (command === "status" || command === "steer") {
3954
4037
  const name2 = args2[0];
3955
4038
  const text2 = args2.slice(1).join(" ").trim();
@@ -4055,7 +4138,7 @@ ${OPS_USAGE}`);
4055
4138
  } else if (arg === "--repo") {
4056
4139
  if (repo !== undefined)
4057
4140
  throw new Error(usage2);
4058
- repo = value;
4141
+ repo = value.includes("://") || /^[^/@\s]+@[^:/\s]+:/.test(value) ? value : resolve(value);
4059
4142
  } else if (arg === "--base") {
4060
4143
  if (base !== undefined)
4061
4144
  throw new Error(usage2);
@@ -4076,6 +4159,8 @@ ${OPS_USAGE}`);
4076
4159
  const text = textParts.join(" ").trim();
4077
4160
  if (!name || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name) || !text)
4078
4161
  throw new Error(usage2);
4162
+ if (base !== undefined && repo === undefined)
4163
+ throw new Error(usage2);
4079
4164
  const client = await connectGatewaySocket(parsed.socket, {
4080
4165
  requestTimeoutMs: command === "run" ? 3600000 : 120000
4081
4166
  });
@@ -1 +1 @@
1
- {"version":3,"file":"restart-stack.d.ts","sourceRoot":"","sources":["../src/restart-stack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restart-stack.d.ts","sourceRoot":"","sources":["../src/restart-stack.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,10 @@ export interface ResolvePathOptions {
15
15
  }
16
16
  /** Service managers this CLI can write definitions for. */
17
17
  export type ServicePlatform = "darwin" | "linux";
18
+ export interface ServiceCommandOptions {
19
+ readonly allowFailure?: boolean;
20
+ }
21
+ export type ServiceCommandRunner = (command: readonly string[], options?: ServiceCommandOptions) => number | PromiseLike<number>;
18
22
  export interface InstallServicesOptions {
19
23
  readonly binDir: string;
20
24
  readonly launchAgentsDir?: string;
@@ -49,6 +53,12 @@ interface ServiceSpec {
49
53
  export declare const BROKER_UNIT = "gajaeway-broker.service";
50
54
  export declare const GATEWAY_UNIT = "gajaeway-gateway.service";
51
55
  export declare function serviceSpecs(): readonly ServiceSpec[];
56
+ /**
57
+ * The `adapter-<platform>.json` an adapter reads at startup, or undefined for services
58
+ * that are not adapters. A unit whose file is absent can never come up — the adapter
59
+ * exits on the credential read — so supervisors skip it instead of looping on it.
60
+ */
61
+ export declare function adapterConfigPath(home: string, specId: string): string | undefined;
52
62
  export declare function mergePathEntries(binDir: string, userHome: string, loginPath: string): string[];
53
63
  export declare function defaultLoginPathRunner(command: readonly string[]): Promise<string>;
54
64
  export declare function discoverLoginPath(env?: NodeJS.ProcessEnv, runner?: LoginPathRunner): Promise<string>;
@@ -62,6 +72,16 @@ export declare function systemdUnitDir(env: NodeJS.ProcessEnv, userHome: string)
62
72
  export declare function launchAgentPlistPath(spec: ServiceSpec, launchAgentsDir: string): string;
63
73
  /** Gets the path where a service's systemd unit file is stored on linux. */
64
74
  export declare function systemdUnitPath(spec: ServiceSpec, unitDir: string): string;
75
+ export interface RemoveStaleServicesOptions extends Pick<InstallServicesOptions, "launchAgentsDir" | "unitDir"> {
76
+ readonly binDir: string;
77
+ readonly platform: ServicePlatform;
78
+ readonly uid?: number;
79
+ readonly env?: NodeJS.ProcessEnv;
80
+ readonly reloadSystemd?: boolean;
81
+ readonly run: ServiceCommandRunner;
82
+ }
83
+ /** Stops and removes service definitions whose executable is no longer installed. */
84
+ export declare function removeStaleServices(options: RemoveStaleServicesOptions): Promise<void>;
65
85
  /**
66
86
  * The ordered commands that realign the whole stack.
67
87
  *
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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"}
package/dist/update.d.ts CHANGED
@@ -73,7 +73,10 @@ export type ReleaseFetcher = (repo: string) => Promise<ReleaseInfo>;
73
73
  export type AssetDownloader = (asset: ReleaseAsset) => Promise<Uint8Array>;
74
74
  export type TarballExtractor = (tarball: Uint8Array, intoDir: string) => Promise<void>;
75
75
  export type RestartQueuer = (home: string, binDir: string, trigger: "update") => Promise<RestartQueueReceipt>;
76
- export type UpdateCommandRunner = (command: readonly string[]) => Promise<number>;
76
+ export interface UpdateCommandOptions {
77
+ readonly allowFailure?: boolean;
78
+ }
79
+ export type UpdateCommandRunner = (command: readonly string[], options?: UpdateCommandOptions) => Promise<number>;
77
80
  type UpdateServiceOptions = Pick<InstallServicesOptions, "launchAgentsDir" | "unitDir" | "loginPathRunner" | "writeFile">;
78
81
  export interface UpdateDeps {
79
82
  readonly fetchLatestRelease?: ReleaseFetcher;
@@ -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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gajae-gateway/cli",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
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.2",
45
- "@gajae-gateway/protocol": "0.2.2"
44
+ "@gajae-gateway/sdk": "0.3.0",
45
+ "@gajae-gateway/protocol": "0.3.0"
46
46
  },
47
47
  "engines": {
48
48
  "bun": ">=1.4.0"
package/src/list.ts CHANGED
@@ -159,6 +159,7 @@ export const MONITOR_COLUMNS: readonly Column<MonitorListRow>[] = [
159
159
  },
160
160
  { name: "events", value: (row) => [...row.monitor.eventTypes] },
161
161
  { name: "target", value: (row) => (row.monitor.channelTarget ? originKey(row.monitor.channelTarget.origin) : null) },
162
+ { name: "reportTo", value: (row) => (row.monitor.reportTo ? originKey(row.monitor.reportTo) : null) },
162
163
  { name: "enabled", value: (row) => row.monitor.enabled },
163
164
  ];
164
165
 
package/src/main.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import { isAbsolute } from "node:path";
3
+ import { isAbsolute, join, resolve } from "node:path";
4
4
 
5
5
  import type {
6
6
  MonitorEventOperatorResult,
@@ -85,7 +85,7 @@ export const COMMANDS = [
85
85
  ] as const;
86
86
 
87
87
  export const CLI_USAGE =
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
+ "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] [--repo PATH|URL [--base REF]] [--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";
89
89
 
90
90
  /** Usage errors exit 2, as `gajaeway-gateway` does; 1 stays a runtime failure. */
91
91
  export const USAGE_EXIT_CODE = 2;
@@ -486,7 +486,7 @@ export function renderDeliveries(result: OpsDeliveriesResult): string[] {
486
486
  `deliveries: ${result.rows.length}`,
487
487
  ...result.rows.map(
488
488
  (row) =>
489
- `${row.createdAt} ${row.state} delivery=${row.deliveryId} turn=${row.turnId} origin=${row.originKey} conversation=${row.conversationId} text=${JSON.stringify(row.textPrefix)}`,
489
+ `${row.createdAt} ${row.state} delivery=${row.deliveryId} turn=${row.turnId} origin=${row.originKey} conversation=${row.conversationId} lastError=${row.lastError ?? "-"} text=${JSON.stringify(row.textPrefix)}`,
490
490
  ),
491
491
  ];
492
492
  }
@@ -898,7 +898,7 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
898
898
  case "work": {
899
899
  const [command, ...args] = parsed.rest;
900
900
  const usage =
901
- 'usage: gajaeway work run|start <name> [--cwd DIR] [--resume] [--model ID|--preset NAME] "<task text>"|status <name>|steer <name> <text>|retire <name>|jobs';
901
+ 'usage: gajaeway work run|start <name> [--cwd DIR] [--repo PATH|URL [--base REF]] [--resume] [--model ID|--preset NAME] "<task text>"|status <name>|steer <name> <text>|retire <name>|jobs';
902
902
  if (command === "status" || command === "steer") {
903
903
  const name = args[0];
904
904
  const text = args.slice(1).join(" ").trim();
@@ -1020,7 +1020,7 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
1020
1020
  cwd = value;
1021
1021
  } else if (arg === "--repo") {
1022
1022
  if (repo !== undefined) throw new Error(usage);
1023
- repo = value;
1023
+ repo = value.includes("://") || /^[^/@\s]+@[^:/\s]+:/.test(value) ? value : resolve(value);
1024
1024
  } else if (arg === "--base") {
1025
1025
  if (base !== undefined) throw new Error(usage);
1026
1026
  base = value;
@@ -1034,6 +1034,7 @@ export async function main(args = process.argv.slice(2), options: MainOptions =
1034
1034
  }
1035
1035
  const text = textParts.join(" ").trim();
1036
1036
  if (!name || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name) || !text) throw new Error(usage);
1037
+ if (base !== undefined && repo === undefined) throw new Error(usage);
1037
1038
  // This is a caller response-wait budget, never an attempt deadline.
1038
1039
  // Timeout/disconnect leaves the attempt observable via work.status.
1039
1040
  const client = await connectGatewaySocket(parsed.socket, {
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { access, mkdir, readFile, readlink, rename, stat, writeFile } from "node:fs/promises";
2
+ import { access, mkdir, readFile, realpath, rename, stat, writeFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
- import { dirname, join } from "node:path";
4
+ import { basename, dirname, join } from "node:path";
5
5
  import {
6
6
  acquireLease,
7
7
  homeLayout,
@@ -13,9 +13,11 @@ import {
13
13
  } from "@gajae-gateway/home";
14
14
 
15
15
  import {
16
+ adapterConfigPath,
16
17
  BROKER_UNIT,
17
18
  currentPlatform,
18
19
  launchAgentPlistPath,
20
+ removeStaleServices,
19
21
  restartOrder,
20
22
  restartStackCommands,
21
23
  type ServicePlatform,
@@ -295,7 +297,26 @@ async function runRestartStackWithLease(options: RunRestartOptions): Promise<Res
295
297
  const sleep = options.sleep ?? ((ms: number) => Bun.sleep(ms));
296
298
  const timeoutMs = options.verifyTimeoutMs ?? VERIFY_TIMEOUT_MS;
297
299
  const pollMs = options.pollMs ?? POLL_MS;
298
- const binDir = options.binDir ?? process.env.GAJAEWAY_BIN_DIR ?? dirname(process.execPath);
300
+ const env = options.env ?? process.env;
301
+ const deployedExecutable = await realpath(process.execPath).catch(() => undefined);
302
+ const installedBinDir =
303
+ options.binDir ??
304
+ env.GAJAEWAY_BIN_DIR ??
305
+ (deployedExecutable !== undefined && basename(deployedExecutable).startsWith("gajaeway")
306
+ ? dirname(deployedExecutable)
307
+ : undefined);
308
+ const binDir = installedBinDir ?? dirname(process.execPath);
309
+ if (installedBinDir !== undefined) {
310
+ await removeStaleServices({
311
+ binDir: installedBinDir,
312
+ platform,
313
+ uid: options.uid,
314
+ env,
315
+ ...(options.launchAgentsDir === undefined ? {} : { launchAgentsDir: options.launchAgentsDir }),
316
+ ...(options.unitDir === undefined ? {} : { unitDir: options.unitDir }),
317
+ run: runner,
318
+ });
319
+ }
299
320
 
300
321
  const originalPids = new Map<string, number | undefined>();
301
322
  for (const spec of restartOrder()) {
@@ -337,6 +358,20 @@ async function runRestartStackWithLease(options: RunRestartOptions): Promise<Res
337
358
  await writeReceipt(options.home, receipt);
338
359
  continue;
339
360
  }
361
+ // An installed unit can still be unable to start: an adapter whose
362
+ // `adapter-<platform>.json` is absent exits on the credential read, and
363
+ // launchd KeepAlive turns that into a crash loop. Skip it the same way an
364
+ // uninstalled service is skipped — the rule `gajaeway update` already
365
+ // applies when it renders adapter units — so one unconfigured adapter
366
+ // cannot abort the rest of the sequence.
367
+ const adapterSpec = serviceSpecs().find((candidate) => candidate.label === step.label);
368
+ const adapterConfig = adapterSpec === undefined ? undefined : adapterConfigPath(options.home, adapterSpec.id);
369
+ if (adapterConfig !== undefined && !(await Bun.file(adapterConfig).exists())) {
370
+ step.result = "skipped";
371
+ step.detail = "adapter is not configured";
372
+ await writeReceipt(options.home, receipt);
373
+ continue;
374
+ }
340
375
 
341
376
  if (step.label === "dev.gajaeway.broker" && receipt.trigger === "update") {
342
377
  const stopCommand = serviceStopCommand(platform, options.uid);
@@ -389,12 +424,7 @@ async function runRestartStackWithLease(options: RunRestartOptions): Promise<Res
389
424
  issuedAt = now();
390
425
  let command = step.command;
391
426
  let status = await runner(command);
392
- if (
393
- status !== 0 &&
394
- receipt.trigger === "update" &&
395
- platform === "darwin" &&
396
- (await probe(step.label)) === undefined
397
- ) {
427
+ if (status !== 0 && platform === "darwin" && (await probe(step.label)) === undefined) {
398
428
  command = serviceBootstrapCommand(options, platform, step.label);
399
429
  step.command = command;
400
430
  issuedAt = now();
package/src/services.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
1
+ import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { homeLayout } from "@gajae-gateway/home";
@@ -26,6 +26,13 @@ export interface ResolvePathOptions {
26
26
 
27
27
  /** Service managers this CLI can write definitions for. */
28
28
  export type ServicePlatform = "darwin" | "linux";
29
+ export interface ServiceCommandOptions {
30
+ readonly allowFailure?: boolean;
31
+ }
32
+ export type ServiceCommandRunner = (
33
+ command: readonly string[],
34
+ options?: ServiceCommandOptions,
35
+ ) => number | PromiseLike<number>;
29
36
 
30
37
  export interface InstallServicesOptions {
31
38
  readonly binDir: string;
@@ -106,6 +113,16 @@ export function serviceSpecs(): readonly ServiceSpec[] {
106
113
  return SERVICE_SPECS;
107
114
  }
108
115
 
116
+ /**
117
+ * The `adapter-<platform>.json` an adapter reads at startup, or undefined for services
118
+ * that are not adapters. A unit whose file is absent can never come up — the adapter
119
+ * exits on the credential read — so supervisors skip it instead of looping on it.
120
+ */
121
+ export function adapterConfigPath(home: string, specId: string): string | undefined {
122
+ if (!specId.startsWith("adapter-")) return undefined;
123
+ return join(home, `adapter-${specId.slice("adapter-".length)}.json`);
124
+ }
125
+
109
126
  function homeForEnvironment(env: NodeJS.ProcessEnv): string {
110
127
  return env.GAJAEWAY_HOME || join(env.HOME || homedir(), ".gajaeway");
111
128
  }
@@ -288,6 +305,55 @@ export function systemdUnitPath(spec: ServiceSpec, unitDir: string): string {
288
305
  return join(unitDir, systemdUnitName(spec));
289
306
  }
290
307
 
308
+ export interface RemoveStaleServicesOptions extends Pick<InstallServicesOptions, "launchAgentsDir" | "unitDir"> {
309
+ readonly binDir: string;
310
+ readonly platform: ServicePlatform;
311
+ readonly uid?: number;
312
+ readonly env?: NodeJS.ProcessEnv;
313
+ readonly reloadSystemd?: boolean;
314
+ readonly run: ServiceCommandRunner;
315
+ }
316
+
317
+ /** Stops and removes service definitions whose executable is no longer installed. */
318
+ export async function removeStaleServices(options: RemoveStaleServicesOptions): Promise<void> {
319
+ const env = options.env ?? process.env;
320
+ const userHome = env.HOME || homedir();
321
+ const definitionDir =
322
+ options.platform === "darwin"
323
+ ? (options.launchAgentsDir ?? join(userHome, "Library", "LaunchAgents"))
324
+ : (options.unitDir ?? systemdUnitDir(env, userHome));
325
+ const expandedDefinitionDir = expandHome(definitionDir, userHome);
326
+ const staleDefinitions: Array<{ readonly label: string; readonly path: string; readonly unitName: string }> = [];
327
+ for (const spec of SERVICE_SPECS) {
328
+ if (await Bun.file(join(options.binDir, spec.binary)).exists()) continue;
329
+ const path =
330
+ options.platform === "darwin"
331
+ ? launchAgentPlistPath(spec, expandedDefinitionDir)
332
+ : systemdUnitPath(spec, expandedDefinitionDir);
333
+ if (await Bun.file(path).exists())
334
+ staleDefinitions.push({ label: spec.label, path, unitName: systemdUnitName(spec) });
335
+ }
336
+ const execute = async (command: readonly string[], allowFailure = false): Promise<number> => {
337
+ const exitCode = await options.run(command, allowFailure ? { allowFailure: true } : undefined);
338
+ if (exitCode !== 0 && !allowFailure) throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
339
+ return exitCode;
340
+ };
341
+ if (options.platform === "linux") {
342
+ if (staleDefinitions.length === 0) return;
343
+ await execute(["systemctl", "--user", "disable", "--now", ...staleDefinitions.map(({ unitName }) => unitName)]);
344
+ for (const { path } of staleDefinitions) await rm(path, { force: true });
345
+ if (options.reloadSystemd ?? true) await execute(["systemctl", "--user", "daemon-reload"]);
346
+ return;
347
+ }
348
+ const target = `gui/${options.uid ?? process.getuid?.() ?? 0}`;
349
+ for (const { label, path } of staleDefinitions) {
350
+ const serviceTarget = `${target}/${label}`;
351
+ if ((await execute(["launchctl", "print", serviceTarget], true)) === 0)
352
+ await execute(["launchctl", "bootout", serviceTarget]);
353
+ await rm(path, { force: true });
354
+ }
355
+ }
356
+
291
357
  /**
292
358
  * The ordered commands that realign the whole stack.
293
359
  *
@@ -375,10 +441,10 @@ export async function installServices(options: InstallServicesOptions): Promise<
375
441
  await mkdir(targetDir, { recursive: true, mode: 0o700 });
376
442
  const specs: ServiceSpec[] = [];
377
443
  for (const spec of SERVICE_SPECS) {
378
- if (options.configuredAdaptersOnly && spec.id.startsWith("adapter-")) {
379
- const adapter = spec.id.slice("adapter-".length);
380
- if (!(await Bun.file(join(home, `adapter-${adapter}.json`)).exists())) continue;
381
- }
444
+ if (!(await Bun.file(join(binDir, spec.binary)).exists())) continue;
445
+ const adapterConfig = adapterConfigPath(home, spec.id);
446
+ if (options.configuredAdaptersOnly && adapterConfig !== undefined && !(await Bun.file(adapterConfig).exists()))
447
+ continue;
382
448
  specs.push(spec);
383
449
  }
384
450
  const definitions = specs.map((spec) =>
package/src/update.ts CHANGED
@@ -20,6 +20,7 @@ import { launchRestartStack } from "./restart-stack";
20
20
  import {
21
21
  type InstallServicesOptions,
22
22
  installServices,
23
+ removeStaleServices,
23
24
  type ServicePlatform,
24
25
  serviceSpecs,
25
26
  systemdUnitName,
@@ -39,8 +40,6 @@ export const UPDATE_USAGE = "usage: gajaeway update [--check] [--force] [--bin-d
39
40
 
40
41
  export const DEFAULT_RELEASE_REPO = "Yeachan-Heo/gajae-way";
41
42
  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";
44
43
  /** A fork can point updates at its own releases; the declared upstream stays the default. */
45
44
  export function releaseRepo(env: NodeJS.ProcessEnv = process.env): string {
46
45
  const override = env[RELEASE_REPO_OVERRIDE_ENV]?.trim();
@@ -214,7 +213,10 @@ export type ReleaseFetcher = (repo: string) => Promise<ReleaseInfo>;
214
213
  export type AssetDownloader = (asset: ReleaseAsset) => Promise<Uint8Array>;
215
214
  export type TarballExtractor = (tarball: Uint8Array, intoDir: string) => Promise<void>;
216
215
  export type RestartQueuer = (home: string, binDir: string, trigger: "update") => Promise<RestartQueueReceipt>;
217
- export type UpdateCommandRunner = (command: readonly string[]) => Promise<number>;
216
+ export interface UpdateCommandOptions {
217
+ readonly allowFailure?: boolean;
218
+ }
219
+ export type UpdateCommandRunner = (command: readonly string[], options?: UpdateCommandOptions) => Promise<number>;
218
220
 
219
221
  type UpdateServiceOptions = Pick<
220
222
  InstallServicesOptions,
@@ -262,10 +264,10 @@ async function readPinnedGjcVersion(path: string): Promise<string> {
262
264
  return version;
263
265
  }
264
266
 
265
- async function defaultUpdateCommandRunner(command: readonly string[]): Promise<number> {
267
+ async function defaultUpdateCommandRunner(command: readonly string[], options?: UpdateCommandOptions): Promise<number> {
266
268
  const child = Bun.spawn([...command], { stdin: "ignore", stdout: "ignore", stderr: "pipe" });
267
269
  const [stderr, exitCode] = await Promise.all([new Response(child.stderr).text(), child.exited]);
268
- if (exitCode !== 0) {
270
+ if (exitCode !== 0 && !options?.allowFailure) {
269
271
  const detail = stderr.trim();
270
272
  throw new Error(`${command.join(" ")} exited with status ${exitCode}${detail.length === 0 ? "" : `: ${detail}`}`);
271
273
  }
@@ -281,7 +283,22 @@ async function installUpdatedServices(options: {
281
283
  }): Promise<boolean> {
282
284
  const { home, binDir, platform, noRestart, deps } = options;
283
285
  const brokerProvisioned = await exists(homeLayout(home).brokerProvisionManifest);
284
- const env = { ...(deps.env ?? process.env), GAJAEWAY_HOME: home };
286
+ const env: NodeJS.ProcessEnv = { ...(deps.env ?? process.env), GAJAEWAY_HOME: home };
287
+ const run = deps.serviceRunner ?? defaultUpdateCommandRunner;
288
+ const execute = async (command: readonly string[]): Promise<void> => {
289
+ const exitCode = await run(command);
290
+ if (exitCode !== 0) throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
291
+ };
292
+ if (!noRestart) {
293
+ await removeStaleServices({
294
+ binDir,
295
+ platform,
296
+ env,
297
+ reloadSystemd: false,
298
+ ...deps.serviceOptions,
299
+ run,
300
+ });
301
+ }
285
302
  await installServices({
286
303
  binDir,
287
304
  platform,
@@ -291,15 +308,11 @@ async function installUpdatedServices(options: {
291
308
  ...deps.serviceOptions,
292
309
  });
293
310
  if (platform === "linux") {
294
- const run = deps.serviceRunner ?? defaultUpdateCommandRunner;
295
- const execute = async (command: readonly string[]): Promise<void> => {
296
- const exitCode = await run(command);
297
- if (exitCode !== 0) throw new Error(`${command.join(" ")} exited with status ${exitCode}`);
298
- };
299
311
  await execute(["systemctl", "--user", "daemon-reload"]);
300
312
  if (!noRestart) {
301
313
  const enableUnits: string[] = [];
302
314
  for (const spec of serviceSpecs()) {
315
+ if (!(await exists(join(binDir, spec.binary)))) continue;
303
316
  if (spec.id === "broker" && !brokerProvisioned) continue;
304
317
  if (
305
318
  spec.id.startsWith("adapter-") &&
@@ -362,7 +375,7 @@ export async function runUpdate(options: RunUpdateOptions): Promise<UpdateResult
362
375
  throw new Error(`release tarball is missing core binaries: ${missingCore.join(", ")}`);
363
376
  await assertStagedBinariesUsable(staged, toInstall);
364
377
 
365
- const gjcVersion = await readPinnedGjcVersion(join(staged.dir, PIN_MANIFEST));
378
+ const gjcVersion = await readPinnedGjcVersion(join(staged.dir, "package.json"));
366
379
  await installPinnedGjc({
367
380
  home: options.home,
368
381
  version: gjcVersion,
@@ -372,20 +385,22 @@ export async function runUpdate(options: RunUpdateOptions): Promise<UpdateResult
372
385
  const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[-:]/g, "").slice(0, 15);
373
386
  const backupDir = join(binDir, `backup-${current}-${stamp}Z`);
374
387
  await mkdir(backupDir, { recursive: false });
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) {
388
+ for (const name of toInstall) {
379
389
  const target = join(binDir, name);
380
390
  if (await exists(target)) await copyFile(target, join(backupDir, name));
381
391
  }
382
- for (const name of replaced) {
392
+ const packagePath = join(binDir, "package.json");
393
+ if (await exists(packagePath)) await copyFile(packagePath, join(backupDir, "package.json"));
394
+ for (const name of toInstall) {
383
395
  const stagedPath = join(staged.dir, name);
384
396
  const tempPath = join(binDir, `.update-${name}`);
385
397
  await copyFile(stagedPath, tempPath);
386
- await chmod(tempPath, name === PIN_MANIFEST ? 0o644 : 0o755);
398
+ await chmod(tempPath, 0o755);
387
399
  await rename(tempPath, join(binDir, name));
388
400
  }
401
+ const packageTempPath = join(binDir, ".update-package.json");
402
+ await copyFile(join(staged.dir, "package.json"), packageTempPath);
403
+ await rename(packageTempPath, packagePath);
389
404
  await writeFile(releaseMarkerPath(binDir), `${latest}\n`, "utf8");
390
405
  const brokerNotEnabled = await installUpdatedServices({
391
406
  home: options.home,