@agent-team-foundation/first-tree-hub 0.10.9 → 0.10.11
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/{bootstrap-jx5nN1qZ.mjs → bootstrap-BTKiVIYk.mjs} +4 -1
- package/dist/cli/index.mjs +198 -68
- package/dist/{dist-DSr_I5Ia.mjs → dist-DwbhZyGi.mjs} +1 -1
- package/dist/{feishu-eynC54km.mjs → feishu-viiZmwcn.mjs} +1 -1
- package/dist/index.mjs +5 -5
- package/dist/{invitation-CBnQyB7o-DVOpS_Ts.mjs → invitation-CBnQyB7o-DLQyW5ek.mjs} +1 -1
- package/dist/{saas-connect-CKQ15VLz.mjs → saas-connect-D-7x9KRd.mjs} +428 -56
- package/dist/web/assets/{index-B33n1w2k.js → index-CJ9XbSvm.js} +81 -81
- package/dist/web/assets/{index-DIgiOalZ.js → index-iNiy68VO.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
|
@@ -585,11 +585,14 @@ const serverConfigSchema = defineConfig({
|
|
|
585
585
|
})
|
|
586
586
|
}) }),
|
|
587
587
|
cors: optional({ origin: field(z.string(), { env: "FIRST_TREE_HUB_CORS_ORIGIN" }) }),
|
|
588
|
+
trustProxy: field(z.boolean().default(false), { env: "FIRST_TREE_HUB_TRUST_PROXY" }),
|
|
588
589
|
rateLimit: optional({
|
|
589
590
|
max: field(z.number().default(100), { env: "FIRST_TREE_HUB_RATE_LIMIT_MAX" }),
|
|
590
591
|
loginMax: field(z.number().default(5), { env: "FIRST_TREE_HUB_RATE_LIMIT_LOGIN_MAX" }),
|
|
591
|
-
webhookMax: field(z.number().default(60), { env: "FIRST_TREE_HUB_RATE_LIMIT_WEBHOOK_MAX" })
|
|
592
|
+
webhookMax: field(z.number().default(60), { env: "FIRST_TREE_HUB_RATE_LIMIT_WEBHOOK_MAX" }),
|
|
593
|
+
agentMessageMax: field(z.number().default(30), { env: "FIRST_TREE_HUB_RATE_LIMIT_AGENT_MESSAGE_MAX" })
|
|
592
594
|
}),
|
|
595
|
+
ws: optional({ maxPayload: field(z.number().int().min(1024).default(262144), { env: "FIRST_TREE_HUB_WS_MAX_PAYLOAD" }) }),
|
|
593
596
|
inbox: optional({ maxInFlightPerAgent: field(z.number().int().min(1).max(1024).default(32), { env: "FIRST_TREE_HUB_INBOX_MAX_IN_FLIGHT_PER_AGENT" }) }),
|
|
594
597
|
kael: optional({
|
|
595
598
|
endpoint: field(z.string(), { env: "KAEL_ENDPOINT" }),
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "../observability-DPyf745N-BSc8QNcR.mjs";
|
|
3
|
-
import { $ as
|
|
3
|
+
import { $ as findStaleAliases, A as checkDatabase, B as installClientService, C as runHomeMigration, D as checkAgentConfigs, E as runMigrations, F as checkServerReachable, G as stopClientService, I as checkWebSocket, L as printResults, M as checkNodeVersion, N as checkServerConfig, O as checkBackgroundService, P as checkServerHealth, R as reconcileAgentConfigs, S as saveOnboardState, T as migrateLocalAgentDirs, U as restartClientService, V as isServiceSupported, W as startClientService, X as ClientRuntime, Y as stopPostgres, Z as handleClientOrgMismatch, _ as promptMissingFields, _t as probeCapabilities, a as declineUpdate, at as fail, b as onboardCheck, c as detectInstallMode, ct as print, d as startServer, dt as ClientOrgMismatchError, et as formatStaleReason, f as COMMAND_VERSION, ft as ClientUserMismatchError, g as promptAddAgent, gt as cleanWorkspaces, h as isInteractive, ht as SessionRegistry, i as createExecuteUpdate, it as resolveReplyToFromEnv, j as checkDocker, k as checkClientConfig, l as fetchLatestVersion, lt as setJsonMode, m as uploadClientCapabilities, mt as SdkError, nt as createOwner, o as promptUpdate, ot as success, p as reconcileLocalRuntimeProviders, pt as FirstTreeHubSDK, r as registerSaaSConnectCommand, s as PACKAGE_NAME, tt as removeLocalAgent, u as installGlobalLatest, v as formatCheckReport, vt as applyClientLoggerConfig, w as createApiNameResolver, x as onboardCreate, y as loadOnboardState, yt as configureClientLoggerForService, z as getClientServiceStatus } from "../saas-connect-D-7x9KRd.mjs";
|
|
4
4
|
import "../logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
5
|
-
import { C as serverConfigSchema, S as resolveConfigReadonly, _ as loadAgents, b as resetConfig, c as saveCredentials, d as DEFAULT_HOME_DIR, f as agentConfigSchema, g as initConfig, h as getConfigValue, i as loadCredentials, l as DEFAULT_CONFIG_DIR, n as ensureFreshAccessToken, o as resolveServerUrl, p as clientConfigSchema, r as ensureFreshAdminToken, s as saveAgentConfig, u as DEFAULT_DATA_DIR, w as setConfigValue, x as resetConfigMeta, y as readConfigFile } from "../bootstrap-
|
|
6
|
-
import "../dist-
|
|
7
|
-
import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-
|
|
5
|
+
import { C as serverConfigSchema, S as resolveConfigReadonly, _ as loadAgents, b as resetConfig, c as saveCredentials, d as DEFAULT_HOME_DIR, f as agentConfigSchema, g as initConfig, h as getConfigValue, i as loadCredentials, l as DEFAULT_CONFIG_DIR, n as ensureFreshAccessToken, o as resolveServerUrl, p as clientConfigSchema, r as ensureFreshAdminToken, s as saveAgentConfig, u as DEFAULT_DATA_DIR, w as setConfigValue, x as resetConfigMeta, y as readConfigFile } from "../bootstrap-BTKiVIYk.mjs";
|
|
6
|
+
import "../dist-DwbhZyGi.mjs";
|
|
7
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-viiZmwcn.mjs";
|
|
8
8
|
import "../invitation-B1pjAyOz-BaCA9PII.mjs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
|
|
11
|
+
import * as semver from "semver";
|
|
11
12
|
import { Command } from "commander";
|
|
12
13
|
import { confirm, input, password, select } from "@inquirer/prompts";
|
|
13
14
|
//#region src/commands/agent-config.ts
|
|
@@ -1081,8 +1082,37 @@ function registerConnectCommand(parent) {
|
|
|
1081
1082
|
function registerClientCommands(program) {
|
|
1082
1083
|
const client = program.command("client").description("Client runtime — connect agents to the server");
|
|
1083
1084
|
registerConnectCommand(client);
|
|
1084
|
-
client.command("start").description("Start client — connect all configured agents to the server").option("--no-interactive", "Skip interactive prompts (for Docker/CI)").action(async (options) => {
|
|
1085
|
+
client.command("start").description("Start client — connect all configured agents to the server").option("--no-interactive", "Skip interactive prompts (for Docker/CI)").option("--foreground", "Run inline instead of delegating to the background service (for debugging)").action(async (options) => {
|
|
1085
1086
|
try {
|
|
1087
|
+
const isSupervisorChild = options.interactive === false && process.env.FIRST_TREE_HUB_SERVICE_MODE === "1";
|
|
1088
|
+
if (!(options.foreground === true || isSupervisorChild) && isServiceSupported()) {
|
|
1089
|
+
const svc = getClientServiceStatus();
|
|
1090
|
+
if (svc.state === "active") {
|
|
1091
|
+
print.line("\n");
|
|
1092
|
+
print.line(` Service is already running (${svc.platform}${svc.detail ? `, ${svc.detail}` : ""}).\n`);
|
|
1093
|
+
print.line(" Use `first-tree-hub client restart` to restart, or `--foreground` to run inline.\n\n");
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (svc.state === "inactive") {
|
|
1097
|
+
const res = startClientService();
|
|
1098
|
+
if (!res.ok) {
|
|
1099
|
+
print.line(`\n Failed to start service: ${res.reason}\n`);
|
|
1100
|
+
print.line(" Try `--foreground` to run inline instead.\n\n");
|
|
1101
|
+
process.exit(1);
|
|
1102
|
+
}
|
|
1103
|
+
const after = getClientServiceStatus();
|
|
1104
|
+
print.line("\n");
|
|
1105
|
+
print.line(` Started ${after.platform} service${after.detail ? ` (${after.detail})` : ""}.\n`);
|
|
1106
|
+
const journalHint = after.platform === "systemd" ? ` (or \`journalctl --user -u ${after.label.replace(/\.service$/, "")}\`)` : "";
|
|
1107
|
+
print.line(` Logs: ${after.logDir}${journalHint}\n\n`);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
if (svc.state === "unknown") {
|
|
1111
|
+
print.line(`\n Service state could not be determined (${svc.platform}${svc.detail ? `: ${svc.detail}` : ""}).\n`);
|
|
1112
|
+
print.line(" Inspect with `first-tree-hub client doctor`, or pass `--foreground` to bypass.\n\n");
|
|
1113
|
+
process.exit(1);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1086
1116
|
await promptMissingFields({
|
|
1087
1117
|
schema: clientConfigSchema,
|
|
1088
1118
|
role: "client",
|
|
@@ -1212,11 +1242,72 @@ function registerClientCommands(program) {
|
|
|
1212
1242
|
checkBackgroundService()
|
|
1213
1243
|
]);
|
|
1214
1244
|
});
|
|
1215
|
-
client.command("stop").description("Stop the
|
|
1216
|
-
|
|
1217
|
-
|
|
1245
|
+
client.command("stop").description("Stop the background service (preserves auto-start; use `client start` to bring it back)").action(() => {
|
|
1246
|
+
if (!isServiceSupported()) {
|
|
1247
|
+
print.line(`\n Service control not supported on ${process.platform}.\n`);
|
|
1248
|
+
print.line(" If running inline, use Ctrl+C or kill the process.\n\n");
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
const svc = getClientServiceStatus();
|
|
1252
|
+
if (svc.state === "not-installed") {
|
|
1253
|
+
print.line("\n No background service installed — nothing to stop.\n");
|
|
1254
|
+
print.line(" If running inline, use Ctrl+C or kill the process.\n\n");
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
if (svc.state === "inactive") {
|
|
1258
|
+
print.line("\n Service is already stopped.\n\n");
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const res = stopClientService();
|
|
1262
|
+
if (!res.ok) {
|
|
1263
|
+
print.line(`\n Failed to stop service: ${res.reason}\n\n`);
|
|
1264
|
+
process.exit(1);
|
|
1265
|
+
}
|
|
1266
|
+
print.line(`\n Stopped ${svc.platform} service.\n`);
|
|
1267
|
+
print.line(" Auto-start on next login is preserved. Run `first-tree-hub client start` to bring it back.\n\n");
|
|
1268
|
+
});
|
|
1269
|
+
client.command("restart").description("Restart the background service").action(() => {
|
|
1270
|
+
if (!isServiceSupported()) {
|
|
1271
|
+
print.line(`\n Service control not supported on ${process.platform}.\n`);
|
|
1272
|
+
print.line(" Restart your inline `client start` process manually.\n\n");
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
if (getClientServiceStatus().state === "not-installed") {
|
|
1276
|
+
print.line("\n No background service installed.\n");
|
|
1277
|
+
print.line(" Run `first-tree-hub client connect <url>` first.\n\n");
|
|
1278
|
+
process.exit(1);
|
|
1279
|
+
}
|
|
1280
|
+
const res = restartClientService();
|
|
1281
|
+
if (!res.ok) {
|
|
1282
|
+
print.line(`\n Failed to restart service: ${res.reason}\n\n`);
|
|
1283
|
+
process.exit(1);
|
|
1284
|
+
}
|
|
1285
|
+
const after = getClientServiceStatus();
|
|
1286
|
+
print.line(`\n Restarted ${after.platform} service${after.detail ? ` (${after.detail})` : ""}.\n\n`);
|
|
1218
1287
|
});
|
|
1219
|
-
client.command("status").description("Show
|
|
1288
|
+
client.command("status").description("Show CLI, service, hub, and agent status (one-screen overview)").action(() => {
|
|
1289
|
+
print.line("\n");
|
|
1290
|
+
print.line(` CLI: ${COMMAND_VERSION}\n`);
|
|
1291
|
+
if (isServiceSupported()) {
|
|
1292
|
+
const svc = getClientServiceStatus();
|
|
1293
|
+
const tail = svc.platform === "systemd" ? ` (logs: journalctl --user -u ${svc.label.replace(/\.service$/, "")} -f)` : "";
|
|
1294
|
+
if (svc.state === "active") print.line(` Service: ✓ running (${svc.platform}${svc.detail ? `, ${svc.detail}` : ""})${tail}\n`);
|
|
1295
|
+
else if (svc.state === "inactive") print.line(` Service: ✗ stopped (${svc.platform}${svc.detail ? `, ${svc.detail}` : ""})\n`);
|
|
1296
|
+
else if (svc.state === "not-installed") print.line(" Service: not installed — run `first-tree-hub client connect <url>`\n");
|
|
1297
|
+
else print.line(` Service: unknown (${svc.platform}${svc.detail ? `, ${svc.detail}` : ""})\n`);
|
|
1298
|
+
} else print.line(` Service: not supported on ${process.platform} (runs inline)\n`);
|
|
1299
|
+
const clientYaml = join(DEFAULT_CONFIG_DIR, "client.yaml");
|
|
1300
|
+
if (existsSync(clientYaml)) try {
|
|
1301
|
+
const cfg = readConfigFile(clientYaml);
|
|
1302
|
+
const serverUrl = getNested(cfg, "server.url");
|
|
1303
|
+
const clientId = getNested(cfg, "client.id");
|
|
1304
|
+
print.line(` Hub: ${serverUrl ?? "(not configured)"}\n`);
|
|
1305
|
+
print.line(` Client: ${clientId ?? "(not configured)"}\n`);
|
|
1306
|
+
} catch (err) {
|
|
1307
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1308
|
+
print.line(` Hub: (could not read ${clientYaml}: ${msg.slice(0, 60)})\n`);
|
|
1309
|
+
}
|
|
1310
|
+
else print.line(" Hub: (not configured — run `first-tree-hub client connect <url>`)\n");
|
|
1220
1311
|
const agentsDir = join(DEFAULT_CONFIG_DIR, "agents");
|
|
1221
1312
|
try {
|
|
1222
1313
|
const agents = loadAgents({
|
|
@@ -1224,14 +1315,14 @@ function registerClientCommands(program) {
|
|
|
1224
1315
|
agentsDir
|
|
1225
1316
|
});
|
|
1226
1317
|
if (agents.size === 0) {
|
|
1227
|
-
print.line("
|
|
1318
|
+
print.line(" Agents: 0 configured\n\n");
|
|
1228
1319
|
return;
|
|
1229
1320
|
}
|
|
1230
|
-
print.line(
|
|
1231
|
-
for (const [name, config] of agents) print.line(`
|
|
1321
|
+
print.line(` Agents: ${agents.size} configured\n\n`);
|
|
1322
|
+
for (const [name, config] of agents) print.line(` ${name.padEnd(20)} runtime: ${config.runtime.padEnd(14)} agentId: ${config.agentId}\n`);
|
|
1232
1323
|
print.line("\n");
|
|
1233
1324
|
} catch {
|
|
1234
|
-
print.line("
|
|
1325
|
+
print.line(" Agents: (no agents directory)\n\n");
|
|
1235
1326
|
}
|
|
1236
1327
|
});
|
|
1237
1328
|
client.command("hub-list").description("List clients on the Hub server").option("--server <url>", "Hub server URL").action(async (options) => {
|
|
@@ -1374,6 +1465,15 @@ function timeSince(isoDate) {
|
|
|
1374
1465
|
if (hours < 24) return `${hours}h ${minutes % 60}m`;
|
|
1375
1466
|
return `${Math.floor(hours / 24)}d ${hours % 24}h`;
|
|
1376
1467
|
}
|
|
1468
|
+
/** Read a `dot.path.like.this` from a parsed YAML object, returning string | null. */
|
|
1469
|
+
function getNested(obj, path) {
|
|
1470
|
+
let cur = obj;
|
|
1471
|
+
for (const part of path.split(".")) {
|
|
1472
|
+
if (cur === null || cur === void 0 || typeof cur !== "object") return null;
|
|
1473
|
+
cur = cur[part];
|
|
1474
|
+
}
|
|
1475
|
+
return typeof cur === "string" ? cur : null;
|
|
1476
|
+
}
|
|
1377
1477
|
//#endregion
|
|
1378
1478
|
//#region src/commands/config.ts
|
|
1379
1479
|
function resolveConfigPath(flags) {
|
|
@@ -1471,13 +1571,13 @@ function isSecretField(schema, dotPath) {
|
|
|
1471
1571
|
//#region src/commands/onboard.ts
|
|
1472
1572
|
async function promptMissing(args) {
|
|
1473
1573
|
if (!args.server) try {
|
|
1474
|
-
const { resolveServerUrl } = await import("../bootstrap-
|
|
1574
|
+
const { resolveServerUrl } = await import("../bootstrap-BTKiVIYk.mjs").then((n) => n.t);
|
|
1475
1575
|
resolveServerUrl();
|
|
1476
1576
|
} catch {
|
|
1477
1577
|
args.server = await input({ message: "Hub server URL:" });
|
|
1478
1578
|
saveOnboardState(args);
|
|
1479
1579
|
}
|
|
1480
|
-
const { loadCredentials } = await import("../bootstrap-
|
|
1580
|
+
const { loadCredentials } = await import("../bootstrap-BTKiVIYk.mjs").then((n) => n.t);
|
|
1481
1581
|
if (!loadCredentials()) throw new Error("No saved credentials. Run `first-tree-hub client connect <server-url>` before onboarding.");
|
|
1482
1582
|
if (!args.id) {
|
|
1483
1583
|
args.id = await input({ message: "Agent ID:" });
|
|
@@ -1679,62 +1779,92 @@ function registerServerCommands(program) {
|
|
|
1679
1779
|
});
|
|
1680
1780
|
}
|
|
1681
1781
|
//#endregion
|
|
1682
|
-
//#region src/commands/
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1782
|
+
//#region src/commands/update.ts
|
|
1783
|
+
/**
|
|
1784
|
+
* `first-tree-hub update` — user-driven CLI upgrade.
|
|
1785
|
+
*
|
|
1786
|
+
* Lives at the top level (not under `client`) because the tarball bundles
|
|
1787
|
+
* server / client / web / shared into a single artifact: upgrading affects
|
|
1788
|
+
* the whole CLI, not the client subsystem alone.
|
|
1789
|
+
*
|
|
1790
|
+
* Pairs with — but does not replace — the server-driven UpdateManager
|
|
1791
|
+
* (packages/client/src/runtime/update-manager.ts), which fires automatically
|
|
1792
|
+
* when a connected client falls behind the server-bundled version. This
|
|
1793
|
+
* command is the manual equivalent: same install + restart sequence, but
|
|
1794
|
+
* triggered on the operator's terms.
|
|
1795
|
+
*/
|
|
1796
|
+
function registerUpdateCommand(program) {
|
|
1797
|
+
program.command("update").description("Upgrade first-tree-hub to the latest published version and restart the service").option("--check", "Only check whether a newer version is available; do not install").option("--no-restart", "Install the new version but skip restarting the background service").action(async (options) => {
|
|
1798
|
+
const mode = detectInstallMode();
|
|
1799
|
+
if (mode === "source") {
|
|
1800
|
+
print.line("\n Running from a source checkout — `update` is a no-op.\n");
|
|
1801
|
+
print.line(" Use `git pull` instead.\n\n");
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
if (mode === "npx") {
|
|
1805
|
+
print.line("\n Not launched from a global npm install — cannot self-update.\n");
|
|
1806
|
+
print.line(` Install globally first: npm i -g ${PACKAGE_NAME}\n\n`);
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
print.line("\n Checking npm registry...\n");
|
|
1810
|
+
const latest = fetchLatestVersion();
|
|
1811
|
+
if (!latest.ok) {
|
|
1812
|
+
print.line(` Could not fetch latest version: ${latest.reason}\n\n`);
|
|
1813
|
+
process.exit(1);
|
|
1814
|
+
}
|
|
1815
|
+
const current = COMMAND_VERSION;
|
|
1816
|
+
if ((semver.valid(current) ? semver.compare(current, latest.version) : -1) >= 0) {
|
|
1817
|
+
print.line(` Already on ${current} (latest is ${latest.version}).\n\n`);
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
if (options.check) {
|
|
1821
|
+
print.line(` Update available: ${current} → ${latest.version}\n`);
|
|
1822
|
+
print.line(" Run `first-tree-hub update` to install.\n\n");
|
|
1823
|
+
return;
|
|
1824
|
+
}
|
|
1825
|
+
print.line(` Updating ${current} → ${latest.version}...\n`);
|
|
1826
|
+
const installRes = await installGlobalLatest();
|
|
1827
|
+
if (!installRes.ok) {
|
|
1828
|
+
print.line(`\n Install failed: ${installRes.reason}\n\n`);
|
|
1829
|
+
process.exit(1);
|
|
1830
|
+
}
|
|
1831
|
+
const installed = installRes.installedVersion ?? latest.version;
|
|
1832
|
+
print.line(` Installed ${installed}.\n`);
|
|
1833
|
+
if (options.restart === false) {
|
|
1834
|
+
print.line(" Skipping restart (--no-restart). Run `first-tree-hub client restart` when ready.\n\n");
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
if (!isServiceSupported()) {
|
|
1838
|
+
print.line(` No service manager on ${process.platform}; restart your inline `);
|
|
1839
|
+
print.line("`client start` process to pick up the new version.\n\n");
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
const svc = getClientServiceStatus();
|
|
1843
|
+
if (svc.state === "not-installed") {
|
|
1844
|
+
print.line(" No background service installed — nothing to restart.\n");
|
|
1845
|
+
print.line(" Run `first-tree-hub client connect <url>` to set one up.\n\n");
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1689
1848
|
try {
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
} else print.line(` Server: ✗ unhealthy (${res.status})\n`);
|
|
1696
|
-
} catch {
|
|
1697
|
-
print.line(` Server: ✗ not running (${serverUrl})\n`);
|
|
1849
|
+
installClientService();
|
|
1850
|
+
} catch (err) {
|
|
1851
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1852
|
+
print.line(` warning: unit-file refresh failed: ${msg}\n`);
|
|
1853
|
+
print.line(" Continuing with restart against the old unit.\n");
|
|
1698
1854
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
print.line(" Agents: error reading config\n");
|
|
1711
|
-
}
|
|
1712
|
-
else print.line(" Agents: 0 configured\n");
|
|
1713
|
-
const clientConfigPath = join(DEFAULT_CONFIG_DIR, "client.yaml");
|
|
1714
|
-
if (existsSync(clientConfigPath)) {
|
|
1715
|
-
const clientServerUrl = getNestedValue(readConfigFile(clientConfigPath), "server.url");
|
|
1716
|
-
print.line(` Client: configured → ${clientServerUrl}\n`);
|
|
1717
|
-
} else print.line(" Client: not configured\n");
|
|
1718
|
-
print.line("\n");
|
|
1855
|
+
if (svc.state === "inactive") {
|
|
1856
|
+
print.line(" Service is stopped — leaving it stopped. Use `client start` to bring it up.\n\n");
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
const restartRes = restartClientService();
|
|
1860
|
+
if (!restartRes.ok) {
|
|
1861
|
+
print.line(`\n Service restart failed: ${restartRes.reason}\n`);
|
|
1862
|
+
print.line(" Run `first-tree-hub client restart` to retry.\n\n");
|
|
1863
|
+
process.exit(1);
|
|
1864
|
+
}
|
|
1865
|
+
print.line(` Service restarted on ${installed}.\n\n`);
|
|
1719
1866
|
});
|
|
1720
1867
|
}
|
|
1721
|
-
function getNestedValue(obj, dotPath) {
|
|
1722
|
-
const parts = dotPath.split(".");
|
|
1723
|
-
let current = obj;
|
|
1724
|
-
for (const part of parts) {
|
|
1725
|
-
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
1726
|
-
current = current[part];
|
|
1727
|
-
}
|
|
1728
|
-
return current;
|
|
1729
|
-
}
|
|
1730
|
-
function formatUptime(seconds) {
|
|
1731
|
-
const days = Math.floor(seconds / 86400);
|
|
1732
|
-
const hours = Math.floor(seconds % 86400 / 3600);
|
|
1733
|
-
const mins = Math.floor(seconds % 3600 / 60);
|
|
1734
|
-
if (days > 0) return `${days}d ${hours}h`;
|
|
1735
|
-
if (hours > 0) return `${hours}h ${mins}m`;
|
|
1736
|
-
return `${mins}m`;
|
|
1737
|
-
}
|
|
1738
1868
|
//#endregion
|
|
1739
1869
|
//#region src/cli/index.ts
|
|
1740
1870
|
runHomeMigration();
|
|
@@ -1759,7 +1889,7 @@ registerServerCommands(program);
|
|
|
1759
1889
|
registerClientCommands(program);
|
|
1760
1890
|
registerAgentCommands(program);
|
|
1761
1891
|
registerConfigCommands(program);
|
|
1762
|
-
|
|
1892
|
+
registerUpdateCommand(program);
|
|
1763
1893
|
registerOnboardCommand(program);
|
|
1764
1894
|
program.parse();
|
|
1765
1895
|
//#endregion
|
|
@@ -253,7 +253,7 @@ const createAgentSchema = z.object({
|
|
|
253
253
|
type: agentTypeSchema,
|
|
254
254
|
displayName: z.string().min(1).max(200).optional(),
|
|
255
255
|
delegateMention: z.string().max(100).optional(),
|
|
256
|
-
organizationId: z.string().max(100).optional(),
|
|
256
|
+
organizationId: z.string().min(1).max(100).optional(),
|
|
257
257
|
source: agentSourceSchema.optional(),
|
|
258
258
|
visibility: agentVisibilitySchema.optional(),
|
|
259
259
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as __exportAll } from "./esm-CYu4tXXn.mjs";
|
|
2
|
-
import { r as AGENT_SELECTOR_HEADER } from "./dist-
|
|
2
|
+
import { r as AGENT_SELECTOR_HEADER } from "./dist-DwbhZyGi.mjs";
|
|
3
3
|
//#region src/core/feishu.ts
|
|
4
4
|
var feishu_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
bindFeishuBot: () => bindFeishuBot,
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "./observability-DPyf745N-BSc8QNcR.mjs";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as checkDatabase, B as installClientService, C as runHomeMigration, D as checkAgentConfigs, E as runMigrations, F as checkServerReachable, G as stopClientService, H as resolveCliInvocation, I as checkWebSocket, J as isDockerAvailable, K as uninstallClientService, L as printResults, M as checkNodeVersion, N as checkServerConfig, P as checkServerHealth, Q as rotateClientIdWithBackup, U as restartClientService, V as isServiceSupported, W as startClientService, X as ClientRuntime, Y as stopPostgres, Z as handleClientOrgMismatch, _ as promptMissingFields, b as onboardCheck, d as startServer, g as promptAddAgent, h as isInteractive, j as checkDocker, k as checkClientConfig, mt as SdkError, n as deriveHubUrlFromToken, nt as createOwner, pt as FirstTreeHubSDK, q as ensurePostgres, rt as hasUser, st as blank, t as HubUrlDerivationError, ut as status, v as formatCheckReport, x as onboardCreate, z as getClientServiceStatus } from "./saas-connect-D-7x9KRd.mjs";
|
|
3
3
|
import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
4
|
-
import { a as resolveAccessToken, n as ensureFreshAccessToken, o as resolveServerUrl, r as ensureFreshAdminToken } from "./bootstrap-
|
|
5
|
-
import "./dist-
|
|
6
|
-
import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-
|
|
4
|
+
import { a as resolveAccessToken, n as ensureFreshAccessToken, o as resolveServerUrl, r as ensureFreshAdminToken } from "./bootstrap-BTKiVIYk.mjs";
|
|
5
|
+
import "./dist-DwbhZyGi.mjs";
|
|
6
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-viiZmwcn.mjs";
|
|
7
7
|
import "./invitation-B1pjAyOz-BaCA9PII.mjs";
|
|
8
|
-
export { ClientRuntime, FirstTreeHubSDK, HubUrlDerivationError, SdkError, bindFeishuBot, bindFeishuUser, blank, checkAgentConfigs, checkClientConfig, checkDatabase, checkDocker, checkNodeVersion, checkServerConfig, checkServerHealth, checkServerReachable, checkWebSocket, createOwner, deriveHubUrlFromToken, ensureFreshAccessToken, ensureFreshAdminToken, ensurePostgres, formatCheckReport, getClientServiceStatus, handleClientOrgMismatch, hasUser, installClientService, isDockerAvailable, isInteractive, isServiceSupported, onboardCheck, onboardCreate, printResults, promptAddAgent, promptMissingFields, resolveAccessToken, resolveCliInvocation, resolveServerUrl, rotateClientIdWithBackup, runHomeMigration, runMigrations, startServer, status, stopPostgres, uninstallClientService };
|
|
8
|
+
export { ClientRuntime, FirstTreeHubSDK, HubUrlDerivationError, SdkError, bindFeishuBot, bindFeishuUser, blank, checkAgentConfigs, checkClientConfig, checkDatabase, checkDocker, checkNodeVersion, checkServerConfig, checkServerHealth, checkServerReachable, checkWebSocket, createOwner, deriveHubUrlFromToken, ensureFreshAccessToken, ensureFreshAdminToken, ensurePostgres, formatCheckReport, getClientServiceStatus, handleClientOrgMismatch, hasUser, installClientService, isDockerAvailable, isInteractive, isServiceSupported, onboardCheck, onboardCreate, printResults, promptAddAgent, promptMissingFields, resolveAccessToken, resolveCliInvocation, resolveServerUrl, restartClientService, rotateClientIdWithBackup, runHomeMigration, runMigrations, startClientService, startServer, status, stopClientService, stopPostgres, uninstallClientService };
|