@gajae-gateway/cli 0.2.3 → 0.3.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/list.d.ts.map +1 -1
- package/dist/main.d.ts +1 -11
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +196 -68
- package/dist/restart-stack.d.ts.map +1 -1
- package/dist/services.d.ts +20 -0
- package/dist/services.d.ts.map +1 -1
- package/dist/update.d.ts +4 -1
- package/dist/update.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/list.ts +1 -0
- package/src/main.ts +67 -16
- package/src/restart-stack.ts +39 -9
- package/src/services.ts +71 -5
- package/src/update.ts +33 -18
package/dist/list.d.ts.map
CHANGED
|
@@ -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,
|
|
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 [--limit N] [--offset N] [--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. */
|
|
@@ -44,16 +44,6 @@ export interface ParsedServicesArgs {
|
|
|
44
44
|
readonly platform?: ServicePlatform;
|
|
45
45
|
}
|
|
46
46
|
export declare function parseServicesArgs(args: readonly string[]): ParsedServicesArgs;
|
|
47
|
-
/**
|
|
48
|
-
* Operator runtime-cycle view (`gajaeway ops cycle`).
|
|
49
|
-
*
|
|
50
|
-
* Rendering contract:
|
|
51
|
-
* - The aggregate phase line always prints.
|
|
52
|
-
* - Any gate prints under `gates:` and forces exit code 1 — a gated cycle is
|
|
53
|
-
* never reported as healthy, so scripting cannot mistake it for idle.
|
|
54
|
-
* - `--json` emits the typed OpsCycleResult verbatim; the exit-code contract
|
|
55
|
-
* is identical.
|
|
56
|
-
*/
|
|
57
47
|
export declare function renderCycle(cycle: OpsCycleResult): string[];
|
|
58
48
|
/**
|
|
59
49
|
* Exit-code contract for `gajaeway ops cycle`: 0 only when the projection is
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,
|
|
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";
|
|
6
|
-
import { LOOPBACK_ORIGIN, originKey as originKey2, WORK_JOBS_MAX_LIMIT } from "@gajae-gateway/protocol";
|
|
5
|
+
import { isAbsolute, resolve } from "path";
|
|
6
|
+
import { LOOPBACK_ORIGIN, OPS_CYCLE_MAX_LIMIT, 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.
|
|
11
|
+
version: "0.3.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",
|
|
@@ -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 (
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
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
|
|
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 &&
|
|
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
|
|
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
|
|
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
|
|
2730
|
+
const executable = await realpath2(process.execPath).catch(() => {
|
|
2664
2731
|
return;
|
|
2665
2732
|
});
|
|
2666
|
-
if (executable !== undefined &&
|
|
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
|
|
2812
|
+
realpath as realpath3,
|
|
2746
2813
|
rename as rename5,
|
|
2747
|
-
rm as
|
|
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
|
|
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
|
|
2830
|
+
readlink,
|
|
2764
2831
|
rename as rename4,
|
|
2765
|
-
rm as
|
|
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
|
|
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
|
|
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
|
|
2938
|
+
await rm4(temporaryLink, { force: true });
|
|
2872
2939
|
}
|
|
2873
2940
|
return layout.gjcExecutable();
|
|
2874
2941
|
} finally {
|
|
2875
2942
|
if (staging !== undefined)
|
|
2876
|
-
await
|
|
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
|
|
3027
|
+
const real = await realpath3(execPath).catch(() => {
|
|
2962
3028
|
return;
|
|
2963
3029
|
});
|
|
2964
3030
|
if (real === undefined)
|
|
2965
3031
|
return;
|
|
2966
|
-
return
|
|
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,
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
|
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 ${
|
|
3308
|
+
throw new Error(`extracting ${basename3(tarballPath)} failed (tar exit ${exitCode}): ${detail.trim()}`);
|
|
3226
3309
|
}
|
|
3227
|
-
await
|
|
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 [--limit N] [--offset N] [--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((
|
|
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
|
-
|
|
3519
|
+
resolve2(stage);
|
|
3437
3520
|
};
|
|
3438
3521
|
unsubscribe = client.on("monitor.event", (payload) => {
|
|
3439
3522
|
if (typeof payload !== "object" || payload === null)
|
|
@@ -3451,7 +3534,13 @@ function waitForMonitorStage(client, eventId, timeoutSeconds) {
|
|
|
3451
3534
|
timer = setTimeout(finish, timeoutSeconds * 1000);
|
|
3452
3535
|
});
|
|
3453
3536
|
}
|
|
3537
|
+
var OPS_CYCLE_PAGING_UNSUPPORTED = "ops.cycle paging is unsupported by the running gateway; restart the gateway after updating it";
|
|
3538
|
+
function hasCyclePagingMetadata(cycle) {
|
|
3539
|
+
return Number.isSafeInteger(cycle.sessionsTotal) && cycle.sessionsTotal >= 0 && Number.isSafeInteger(cycle.sessionsOffset) && cycle.sessionsOffset >= 0;
|
|
3540
|
+
}
|
|
3454
3541
|
function renderCycle(cycle) {
|
|
3542
|
+
if (!hasCyclePagingMetadata(cycle))
|
|
3543
|
+
throw new Error(OPS_CYCLE_PAGING_UNSUPPORTED);
|
|
3455
3544
|
const lines = [];
|
|
3456
3545
|
lines.push(`phase: ${cycle.phase}`);
|
|
3457
3546
|
if (cycle.gates.length > 0)
|
|
@@ -3484,13 +3573,16 @@ function renderCycle(cycle) {
|
|
|
3484
3573
|
lines.push(`monitors: ${cycle.monitorEvents.length ? cycle.monitorEvents.map((m) => `${m.stage}=${m.count}`).join(" ") : "none"}`);
|
|
3485
3574
|
if (cycle.monitorAuthoringLost.length > 0)
|
|
3486
3575
|
lines.push(`monitor authoring lost: ${cycle.monitorAuthoringLost.map((m) => `${m.eventType}=${m.consecutive} (last ${m.lastFiredAt})`).join(" ")}`);
|
|
3487
|
-
if (cycle.sessions.length
|
|
3488
|
-
lines.push(
|
|
3576
|
+
if (cycle.sessionsTotal > 0 && cycle.sessions.length === 0) {
|
|
3577
|
+
lines.push(`sessions: none at offset ${cycle.sessionsOffset} of ${cycle.sessionsTotal}`);
|
|
3578
|
+
} else if (cycle.sessions.length > 0) {
|
|
3579
|
+
const shownEnd = cycle.sessionsOffset + cycle.sessions.length;
|
|
3580
|
+
lines.push(`sessions: ${cycle.sessionsOffset + 1}-${shownEnd} of ${cycle.sessionsTotal}${shownEnd < cycle.sessionsTotal ? ` (next: --offset ${shownEnd})` : ""}`);
|
|
3489
3581
|
lines.push("INDEX ORIGIN EPOCH SESSION PENDING UNSETTLED OLDEST");
|
|
3490
3582
|
for (const [index, session] of cycle.sessions.entries()) {
|
|
3491
3583
|
const sessionId = session.sessionId === "" ? "(rebinding)" : session.sessionId.slice(0, 11);
|
|
3492
3584
|
const oldest = session.oldestUnsettledAgeMs === null ? "-" : `${Math.round(session.oldestUnsettledAgeMs / 1000)}s`;
|
|
3493
|
-
lines.push(`${String(index).padEnd(6)} ${session.originKey.padEnd(43)} ${String(session.epoch).padEnd(6)} ${sessionId.padEnd(12)} ${String(session.pendingInbound).padEnd(8)} ${String(session.unsettledDeliveries).padEnd(10)} ${oldest}`);
|
|
3585
|
+
lines.push(`${String(cycle.sessionsOffset + index).padEnd(6)} ${session.originKey.padEnd(43)} ${String(session.epoch).padEnd(6)} ${sessionId.padEnd(12)} ${String(session.pendingInbound).padEnd(8)} ${String(session.unsettledDeliveries).padEnd(10)} ${oldest}`);
|
|
3494
3586
|
}
|
|
3495
3587
|
}
|
|
3496
3588
|
return lines;
|
|
@@ -3510,7 +3602,40 @@ function renderSlo(result) {
|
|
|
3510
3602
|
function sloExitCode(result) {
|
|
3511
3603
|
return result.ok ? 0 : 1;
|
|
3512
3604
|
}
|
|
3513
|
-
var OPS_USAGE = "usage: gajaeway ops backup <path>|deliveries [--since ISO] [--state S] [--limit N] [--json]|redeliver <deliveryId>|redeliver --since <iso>|slo [--days N] [--json]|cycle [--json]|integrity|restart-stack [--status]";
|
|
3605
|
+
var OPS_USAGE = "usage: gajaeway ops backup <path>|deliveries [--since ISO] [--state S] [--limit N] [--json]|redeliver <deliveryId>|redeliver --since <iso>|slo [--days N] [--json]|cycle [--limit N] [--offset N] [--json]|integrity|restart-stack [--status]";
|
|
3606
|
+
var OPS_CYCLE_USAGE = "usage: gajaeway ops cycle [--limit N] [--offset N] [--json]";
|
|
3607
|
+
function parseOpsCycleArgs(args) {
|
|
3608
|
+
const params = {};
|
|
3609
|
+
const seen = new Set;
|
|
3610
|
+
let json = false;
|
|
3611
|
+
for (let index = 0;index < args.length; index++) {
|
|
3612
|
+
const flag = args[index];
|
|
3613
|
+
if (flag === "--json") {
|
|
3614
|
+
if (json)
|
|
3615
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3616
|
+
json = true;
|
|
3617
|
+
continue;
|
|
3618
|
+
}
|
|
3619
|
+
if (flag !== "--limit" && flag !== "--offset")
|
|
3620
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3621
|
+
if (seen.has(flag))
|
|
3622
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3623
|
+
seen.add(flag);
|
|
3624
|
+
const value = args[++index];
|
|
3625
|
+
if (!value || value.startsWith("--") || !/^\d+$/.test(value))
|
|
3626
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3627
|
+
const number = Number(value);
|
|
3628
|
+
if (!Number.isSafeInteger(number))
|
|
3629
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3630
|
+
if (flag === "--limit") {
|
|
3631
|
+
if (number < 1 || number > OPS_CYCLE_MAX_LIMIT)
|
|
3632
|
+
throw new Error(OPS_CYCLE_USAGE);
|
|
3633
|
+
params.limit = number;
|
|
3634
|
+
} else
|
|
3635
|
+
params.offset = number;
|
|
3636
|
+
}
|
|
3637
|
+
return { params, json };
|
|
3638
|
+
}
|
|
3514
3639
|
function parseOpsSloArgs(args) {
|
|
3515
3640
|
let days = 7;
|
|
3516
3641
|
let json = false;
|
|
@@ -3594,7 +3719,7 @@ function renderDeliveries(result) {
|
|
|
3594
3719
|
return ["deliveries: none"];
|
|
3595
3720
|
return [
|
|
3596
3721
|
`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)}`)
|
|
3722
|
+
...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
3723
|
];
|
|
3599
3724
|
}
|
|
3600
3725
|
var CHAT_TURN_TIMEOUT_MS = 30 * 60000;
|
|
@@ -3619,16 +3744,16 @@ async function chat(socket) {
|
|
|
3619
3744
|
console.error("(message was not engaged)");
|
|
3620
3745
|
return;
|
|
3621
3746
|
}
|
|
3622
|
-
await new Promise((
|
|
3747
|
+
await new Promise((resolve2) => {
|
|
3623
3748
|
const timer = setTimeout(() => {
|
|
3624
3749
|
turnWaiters.delete(turnId);
|
|
3625
3750
|
console.error(`(turn timed out after ${CHAT_TURN_TIMEOUT_MS / 60000}m)`);
|
|
3626
|
-
|
|
3751
|
+
resolve2();
|
|
3627
3752
|
}, CHAT_TURN_TIMEOUT_MS);
|
|
3628
3753
|
turnWaiters.set(turnId, () => {
|
|
3629
3754
|
clearTimeout(timer);
|
|
3630
3755
|
turnWaiters.delete(turnId);
|
|
3631
|
-
|
|
3756
|
+
resolve2();
|
|
3632
3757
|
});
|
|
3633
3758
|
});
|
|
3634
3759
|
};
|
|
@@ -3668,7 +3793,7 @@ async function pollMemoryOp(client, opRef, maxWaitMs = 300000, pollIntervalMs =
|
|
|
3668
3793
|
if (status.status === "failed") {
|
|
3669
3794
|
return { status: "failed", elapsedMs: status.elapsedMs, error: status.error };
|
|
3670
3795
|
}
|
|
3671
|
-
await new Promise((
|
|
3796
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollIntervalMs));
|
|
3672
3797
|
}
|
|
3673
3798
|
const waitedMs = Date.now() - startTime;
|
|
3674
3799
|
console.error(`memory operation still running (${Math.round(operationElapsedMs / 1000)}s operation elapsed; CLI wait ended after ${Math.round(waitedMs / 1000)}s).
|
|
@@ -3758,6 +3883,7 @@ async function main(args = process.argv.slice(2), options = {}) {
|
|
|
3758
3883
|
${OPS_USAGE}`);
|
|
3759
3884
|
const deliveries = command === "deliveries" ? parseOpsDeliveriesArgs(parsed.rest.slice(1)) : undefined;
|
|
3760
3885
|
const slo = command === "slo" ? parseOpsSloArgs(parsed.rest.slice(1)) : undefined;
|
|
3886
|
+
const cycle = command === "cycle" ? parseOpsCycleArgs(parsed.rest.slice(1)) : undefined;
|
|
3761
3887
|
if (command === "restart-stack") {
|
|
3762
3888
|
const usage2 = "usage: gajaeway ops restart-stack [--status]";
|
|
3763
3889
|
const home = gatewayHome();
|
|
@@ -3813,16 +3939,16 @@ ${OPS_USAGE}`);
|
|
|
3813
3939
|
console.log(JSON.stringify(await client.request("ops.redeliver", redeliverParams)));
|
|
3814
3940
|
else if (command === "integrity")
|
|
3815
3941
|
console.log(JSON.stringify(await client.request("ops.integrity")));
|
|
3816
|
-
else if (
|
|
3817
|
-
const
|
|
3818
|
-
if (
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3942
|
+
else if (cycle) {
|
|
3943
|
+
const result = await client.opsCycle(cycle.params);
|
|
3944
|
+
if (!hasCyclePagingMetadata(result))
|
|
3945
|
+
throw new Error(OPS_CYCLE_PAGING_UNSUPPORTED);
|
|
3946
|
+
if (cycle.json)
|
|
3947
|
+
console.log(JSON.stringify(result));
|
|
3822
3948
|
else
|
|
3823
|
-
for (const line of renderCycle(
|
|
3949
|
+
for (const line of renderCycle(result))
|
|
3824
3950
|
console.log(line);
|
|
3825
|
-
process.exitCode = cycleExitCode(
|
|
3951
|
+
process.exitCode = cycleExitCode(result);
|
|
3826
3952
|
} else if (slo) {
|
|
3827
3953
|
const result = await client.opsSlo(slo.params);
|
|
3828
3954
|
if (slo.json)
|
|
@@ -3949,7 +4075,7 @@ ${OPS_USAGE}`);
|
|
|
3949
4075
|
}
|
|
3950
4076
|
case "work": {
|
|
3951
4077
|
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';
|
|
4078
|
+
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
4079
|
if (command === "status" || command === "steer") {
|
|
3954
4080
|
const name2 = args2[0];
|
|
3955
4081
|
const text2 = args2.slice(1).join(" ").trim();
|
|
@@ -4055,7 +4181,7 @@ ${OPS_USAGE}`);
|
|
|
4055
4181
|
} else if (arg === "--repo") {
|
|
4056
4182
|
if (repo !== undefined)
|
|
4057
4183
|
throw new Error(usage2);
|
|
4058
|
-
repo = value;
|
|
4184
|
+
repo = value.includes("://") || /^[^/@\s]+@[^:/\s]+:/.test(value) ? value : resolve(value);
|
|
4059
4185
|
} else if (arg === "--base") {
|
|
4060
4186
|
if (base !== undefined)
|
|
4061
4187
|
throw new Error(usage2);
|
|
@@ -4076,6 +4202,8 @@ ${OPS_USAGE}`);
|
|
|
4076
4202
|
const text = textParts.join(" ").trim();
|
|
4077
4203
|
if (!name || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(name) || !text)
|
|
4078
4204
|
throw new Error(usage2);
|
|
4205
|
+
if (base !== undefined && repo === undefined)
|
|
4206
|
+
throw new Error(usage2);
|
|
4079
4207
|
const client = await connectGatewaySocket(parsed.socket, {
|
|
4080
4208
|
requestTimeoutMs: command === "run" ? 3600000 : 120000
|
|
4081
4209
|
});
|