@agent-team-foundation/first-tree-hub 0.11.0 → 0.11.2
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-DUeYbwm-.mjs → bootstrap-B-FRMuvL.mjs} +13 -3
- package/dist/chunk-BSw8zbkd.mjs +37 -0
- package/dist/cli/index.mjs +94 -35
- package/dist/client-By1K4VVT-nVOhsXBy.mjs +4 -0
- package/dist/client-CLdRbuml-B416INrm.mjs +524 -0
- package/dist/dist-BLY7Bu-l.mjs +430 -0
- package/dist/{dist-BoHl9HwW.mjs → dist-FuUBFTEB.mjs} +100 -22
- package/dist/drizzle/0031_drop_system_configs.sql +11 -0
- package/dist/drizzle/meta/_journal.json +7 -0
- package/dist/errors-BmyRwN0Y-CIZZ_sDc.mjs +92 -0
- package/dist/{esm-CYu4tXXn.mjs → esm-iadMkGbV.mjs} +2 -37
- package/dist/execAsync-CCyouKZM.mjs +10 -0
- package/dist/{execAsync-XMc-nFn-.mjs → execAsync-pImxPKN5.mjs} +1 -1
- package/dist/{feishu-Dxk6ArOK.mjs → feishu-GvFABWW5.mjs} +2 -2
- package/dist/from-CaD373S1.mjs +3840 -0
- package/dist/{getMachineId-bsd-D0w3uAZa.mjs → getMachineId-bsd-DR4-Dysy.mjs} +3 -2
- package/dist/getMachineId-bsd-DjLgZlll.mjs +27 -0
- package/dist/getMachineId-darwin-B6WCAhc4.mjs +24 -0
- package/dist/{getMachineId-darwin-DOoYFb2_.mjs → getMachineId-darwin-CaD2juTg.mjs} +3 -2
- package/dist/getMachineId-linux-BeWHG1gK.mjs +20 -0
- package/dist/{getMachineId-linux-MlY63Zsw.mjs → getMachineId-linux-Dk3gWdQK.mjs} +2 -1
- package/dist/getMachineId-unsupported-BMJQItvF.mjs +15 -0
- package/dist/{getMachineId-unsupported-BS652RIy.mjs → getMachineId-unsupported-Bgz_Je1J.mjs} +2 -1
- package/dist/getMachineId-win-CdgcrzCW.mjs +26 -0
- package/dist/{getMachineId-win-B6hY8edq.mjs → getMachineId-win-vJ6VfDRI.mjs} +3 -2
- package/dist/index.mjs +9 -6
- package/dist/invitation-DWlyNb8x-BEgoZ9k1.mjs +4 -0
- package/dist/{invitation-B1pjAyOz-BaCA9PII.mjs → invitation-Dnn5gGGX-Ce7zbZpn.mjs} +4 -90
- package/dist/multipart-parser-BIksYTkk.mjs +294 -0
- package/dist/observability-C3nY6Jcz-Bk7FX689.mjs +96006 -0
- package/dist/observability-DttujCqj.mjs +5 -0
- package/dist/{saas-connect-DLSyrQcC.mjs → saas-connect-Df2CVAGp.mjs} +7402 -7052
- package/dist/src-CzQ5KF6D.mjs +1176 -0
- package/dist/src-DNBS5Yjj.mjs +735 -0
- package/dist/web/assets/index-43trJLR8.js +388 -0
- package/dist/web/assets/{index-COflQOwF.js → index-CD7rTdqm.js} +1 -1
- package/dist/web/assets/index-fNb_M0nL.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/invitation-CBnQyB7o-TmnIj3kx.mjs +0 -3
- package/dist/observability-C08jUFsJ.mjs +0 -4
- package/dist/observability-DPyf745N-BSc8QNcR.mjs +0 -33897
- package/dist/web/assets/index-BxGzfDTS.js +0 -383
- package/dist/web/assets/index-DDqPt6PI.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as __exportAll } from "./chunk-BSw8zbkd.mjs";
|
|
2
2
|
import { o as logFormatSchema, s as logLevelSchema } from "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
@@ -569,10 +569,11 @@ const serverConfigSchema = defineConfig({
|
|
|
569
569
|
connectTokenExpiry: field(z.string().default("10m"), { env: "FIRST_TREE_HUB_AUTH_CONNECT_TOKEN_EXPIRY" })
|
|
570
570
|
},
|
|
571
571
|
contextTree: optional({
|
|
572
|
-
repo: field(z.string(), {
|
|
572
|
+
repo: field(z.string().optional(), {
|
|
573
573
|
env: "FIRST_TREE_HUB_CONTEXT_TREE_REPO",
|
|
574
574
|
prompt: { message: "Context Tree repo URL (e.g. https://github.com/org/first-tree):" }
|
|
575
575
|
}),
|
|
576
|
+
localPath: field(z.string().optional(), { env: "FIRST_TREE_HUB_CONTEXT_TREE_PATH" }),
|
|
576
577
|
branch: field(z.string().default("main"))
|
|
577
578
|
}),
|
|
578
579
|
github: {
|
|
@@ -595,6 +596,7 @@ const serverConfigSchema = defineConfig({
|
|
|
595
596
|
max: field(z.number().default(100), { env: "FIRST_TREE_HUB_RATE_LIMIT_MAX" }),
|
|
596
597
|
loginMax: field(z.number().default(5), { env: "FIRST_TREE_HUB_RATE_LIMIT_LOGIN_MAX" }),
|
|
597
598
|
webhookMax: field(z.number().default(60), { env: "FIRST_TREE_HUB_RATE_LIMIT_WEBHOOK_MAX" }),
|
|
599
|
+
contextTreeSnapshotMax: field(z.number().default(6), { env: "FIRST_TREE_HUB_RATE_LIMIT_CONTEXT_TREE_SNAPSHOT_MAX" }),
|
|
598
600
|
agentMessageMax: field(z.number().default(30), { env: "FIRST_TREE_HUB_RATE_LIMIT_AGENT_MESSAGE_MAX" })
|
|
599
601
|
}),
|
|
600
602
|
ws: optional({ maxPayload: field(z.number().int().min(1024).default(262144), { env: "FIRST_TREE_HUB_WS_MAX_PAYLOAD" }) }),
|
|
@@ -642,8 +644,16 @@ const serverConfigSchema = defineConfig({
|
|
|
642
644
|
exporter: field(z.enum(["otlp-http", "otlp-grpc"]).default("otlp-http")),
|
|
643
645
|
serviceName: field(z.string().default("first-tree-hub")),
|
|
644
646
|
environment: field(z.string().default("development"), { env: "FIRST_TREE_HUB_OTEL_ENVIRONMENT" }),
|
|
645
|
-
sampleRate: field(z.number().min(0).max(1).default(1))
|
|
647
|
+
sampleRate: field(z.number().min(0).max(1).default(1)),
|
|
648
|
+
captureClientIp: field(z.boolean().default(false), { env: "FIRST_TREE_HUB_OTEL_CAPTURE_CLIENT_IP" })
|
|
646
649
|
})
|
|
650
|
+
},
|
|
651
|
+
runtime: {
|
|
652
|
+
inboxTimeoutSeconds: field(z.coerce.number().int().positive().default(300), { env: "FIRST_TREE_HUB_INBOX_TIMEOUT_SECONDS" }),
|
|
653
|
+
maxRetryCount: field(z.coerce.number().int().nonnegative().default(3), { env: "FIRST_TREE_HUB_MAX_RETRY_COUNT" }),
|
|
654
|
+
pollingIntervalSeconds: field(z.coerce.number().int().positive().default(5), { env: "FIRST_TREE_HUB_POLLING_INTERVAL_SECONDS" }),
|
|
655
|
+
presenceCleanupSeconds: field(z.coerce.number().int().positive().default(60), { env: "FIRST_TREE_HUB_PRESENCE_CLEANUP_SECONDS" }),
|
|
656
|
+
notificationWebhookUrl: field(z.string().url().optional(), { env: "FIRST_TREE_HUB_NOTIFICATION_WEBHOOK_URL" })
|
|
647
657
|
}
|
|
648
658
|
});
|
|
649
659
|
//#endregion
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
10
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
11
|
+
var __exportAll = (all, no_symbols) => {
|
|
12
|
+
let target = {};
|
|
13
|
+
for (var name in all) __defProp(target, name, {
|
|
14
|
+
get: all[name],
|
|
15
|
+
enumerable: true
|
|
16
|
+
});
|
|
17
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
18
|
+
return target;
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
22
|
+
key = keys[i];
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
24
|
+
get: ((k) => from[k]).bind(null, key),
|
|
25
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return to;
|
|
29
|
+
};
|
|
30
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
31
|
+
value: mod,
|
|
32
|
+
enumerable: true
|
|
33
|
+
}) : target, mod));
|
|
34
|
+
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
36
|
+
//#endregion
|
|
37
|
+
export { __toCommonJS as a, __require as i, __esmMin as n, __toESM as o, __exportAll as r, __commonJSMin as t };
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../observability-
|
|
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-
|
|
2
|
+
import "../observability-C3nY6Jcz-Bk7FX689.mjs";
|
|
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-Df2CVAGp.mjs";
|
|
4
4
|
import "../logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
5
|
-
import { C as resetConfigMeta, E as setConfigValue, S as resetConfig, T as serverConfigSchema, _ as getConfigValue, a as ensureFreshAdminToken, c as resolveServerUrl, d as DEFAULT_CONFIG_DIR, f as DEFAULT_DATA_DIR, h as clientConfigSchema, i as ensureFreshAccessToken, l as saveAgentConfig, m as agentConfigSchema, o as loadCredentials, p as DEFAULT_HOME_DIR, u as saveCredentials, v as initConfig, w as resolveConfigReadonly, x as readConfigFile, y as loadAgents } from "../bootstrap-
|
|
6
|
-
import "../dist-
|
|
7
|
-
import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-
|
|
8
|
-
import "../
|
|
5
|
+
import { C as resetConfigMeta, E as setConfigValue, S as resetConfig, T as serverConfigSchema, _ as getConfigValue, a as ensureFreshAdminToken, c as resolveServerUrl, d as DEFAULT_CONFIG_DIR, f as DEFAULT_DATA_DIR, h as clientConfigSchema, i as ensureFreshAccessToken, l as saveAgentConfig, m as agentConfigSchema, o as loadCredentials, p as DEFAULT_HOME_DIR, u as saveCredentials, v as initConfig, w as resolveConfigReadonly, x as readConfigFile, y as loadAgents } from "../bootstrap-B-FRMuvL.mjs";
|
|
6
|
+
import "../dist-FuUBFTEB.mjs";
|
|
7
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-GvFABWW5.mjs";
|
|
8
|
+
import "../errors-BmyRwN0Y-CIZZ_sDc.mjs";
|
|
9
|
+
import "../client-CLdRbuml-B416INrm.mjs";
|
|
10
|
+
import "../src-DNBS5Yjj.mjs";
|
|
11
|
+
import "../invitation-Dnn5gGGX-Ce7zbZpn.mjs";
|
|
9
12
|
import { join } from "node:path";
|
|
10
13
|
import { existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
|
|
11
14
|
import * as semver from "semver";
|
|
@@ -13,12 +16,12 @@ import { Command } from "commander";
|
|
|
13
16
|
import { confirm, input, password, select } from "@inquirer/prompts";
|
|
14
17
|
//#region src/commands/agent-config.ts
|
|
15
18
|
async function resolveAgentRecord(serverUrl, adminToken, agentName) {
|
|
16
|
-
const res = await fetch(`${serverUrl}/api/v1/
|
|
19
|
+
const res = await fetch(`${serverUrl}/api/v1/me/managed-agents`, {
|
|
17
20
|
headers: { Authorization: `Bearer ${adminToken}` },
|
|
18
21
|
signal: AbortSignal.timeout(1e4)
|
|
19
22
|
});
|
|
20
23
|
if (!res.ok) fail("FETCH_ERROR", `Failed to list agents: ${res.status}`, 1);
|
|
21
|
-
const found = (await res.json()).
|
|
24
|
+
const found = (await res.json()).find((a) => a.name === agentName || a.uuid === agentName);
|
|
22
25
|
if (!found) fail("NOT_FOUND", `Agent "${agentName}" not found`, 1);
|
|
23
26
|
return found;
|
|
24
27
|
}
|
|
@@ -40,13 +43,13 @@ async function adminFetch(url, init) {
|
|
|
40
43
|
return await res.json();
|
|
41
44
|
}
|
|
42
45
|
async function getCurrent(serverUrl, adminToken, agentId) {
|
|
43
|
-
return adminFetch(`${serverUrl}/api/v1/
|
|
46
|
+
return adminFetch(`${serverUrl}/api/v1/agents/${agentId}/config`, {
|
|
44
47
|
method: "GET",
|
|
45
48
|
adminToken
|
|
46
49
|
});
|
|
47
50
|
}
|
|
48
51
|
async function patchConfig(serverUrl, adminToken, agentId, expectedVersion, patch) {
|
|
49
|
-
return adminFetch(`${serverUrl}/api/v1/
|
|
52
|
+
return adminFetch(`${serverUrl}/api/v1/agents/${agentId}/config`, {
|
|
50
53
|
method: "PATCH",
|
|
51
54
|
adminToken,
|
|
52
55
|
body: JSON.stringify({
|
|
@@ -184,7 +187,7 @@ function registerAgentConfigCommands(parent) {
|
|
|
184
187
|
const adminToken = await ensureFreshAdminToken();
|
|
185
188
|
const { uuid } = await resolveAgentRecord(serverUrl, adminToken, agentName);
|
|
186
189
|
const patch = JSON.parse(readFileSync(opts.file, "utf-8"));
|
|
187
|
-
const result = await adminFetch(`${serverUrl}/api/v1/
|
|
190
|
+
const result = await adminFetch(`${serverUrl}/api/v1/agents/${uuid}/config/dry-run`, {
|
|
188
191
|
method: "POST",
|
|
189
192
|
adminToken,
|
|
190
193
|
body: JSON.stringify({ payload: patch })
|
|
@@ -273,12 +276,12 @@ function readStdin() {
|
|
|
273
276
|
});
|
|
274
277
|
}
|
|
275
278
|
async function resolveAgent(serverUrl, adminToken, agentName) {
|
|
276
|
-
const res = await fetch(`${serverUrl}/api/v1/
|
|
279
|
+
const res = await fetch(`${serverUrl}/api/v1/me/managed-agents`, {
|
|
277
280
|
headers: { Authorization: `Bearer ${adminToken}` },
|
|
278
281
|
signal: AbortSignal.timeout(1e4)
|
|
279
282
|
});
|
|
280
283
|
if (!res.ok) fail("FETCH_ERROR", `Failed to list agents: ${res.status}`, 1);
|
|
281
|
-
const found = (await res.json()).
|
|
284
|
+
const found = (await res.json()).find((a) => a.name === agentName || a.uuid === agentName);
|
|
282
285
|
if (!found) fail("NOT_FOUND", `Agent "${agentName}" not found`, 1);
|
|
283
286
|
return found;
|
|
284
287
|
}
|
|
@@ -422,13 +425,30 @@ function registerAgentCommands(program) {
|
|
|
422
425
|
fail("LIST_ERROR", error instanceof Error ? error.message : String(error));
|
|
423
426
|
}
|
|
424
427
|
});
|
|
425
|
-
agent.command("create <name>").description("Create an agent on Hub and bind it locally").requiredOption("--type <type>", "Agent type (human, personal_assistant, autonomous_agent)").requiredOption("--client-id <id>", "Client (machine) that will run this agent — must be owned by you. Run `first-tree-hub client connect` on that machine first.").option("--runtime <runtime>", "Runtime handler (default: claude-code)", "claude-code").option("--display-name <name>", "Display name").option("--server <url>", "Hub server URL").action(async (name, options) => {
|
|
428
|
+
agent.command("create <name>").description("Create an agent on Hub and bind it locally").requiredOption("--type <type>", "Agent type (human, personal_assistant, autonomous_agent)").requiredOption("--client-id <id>", "Client (machine) that will run this agent — must be owned by you. Run `first-tree-hub client connect` on that machine first.").option("--runtime <runtime>", "Runtime handler (default: claude-code)", "claude-code").option("--display-name <name>", "Display name").option("--org <id>", "Target organization id (required when you belong to multiple orgs)").option("--server <url>", "Hub server URL").action(async (name, options) => {
|
|
426
429
|
try {
|
|
427
430
|
const serverUrl = resolveServerUrl(options.server);
|
|
431
|
+
const adminToken = await ensureFreshAccessToken();
|
|
428
432
|
const headers = {
|
|
429
|
-
Authorization: `Bearer ${
|
|
433
|
+
Authorization: `Bearer ${adminToken}`,
|
|
430
434
|
"Content-Type": "application/json"
|
|
431
435
|
};
|
|
436
|
+
const meRes = await fetch(`${serverUrl}/api/v1/me`, {
|
|
437
|
+
headers: { Authorization: `Bearer ${adminToken}` },
|
|
438
|
+
signal: AbortSignal.timeout(1e4)
|
|
439
|
+
});
|
|
440
|
+
if (!meRes.ok) fail("FETCH_ERROR", `Failed to fetch /me: HTTP ${meRes.status}`, 1);
|
|
441
|
+
const me = await meRes.json();
|
|
442
|
+
let orgId;
|
|
443
|
+
if (options.org) {
|
|
444
|
+
if (!me.memberships.some((m) => m.organizationId === options.org)) fail("ORG_NOT_FOUND", `Not an active member of organization "${options.org}"`, 1);
|
|
445
|
+
orgId = options.org;
|
|
446
|
+
} else if (me.memberships.length === 1) orgId = me.memberships[0]?.organizationId ?? "";
|
|
447
|
+
else if (me.memberships.length === 0) fail("NO_ORG", "You don't belong to any organization", 1);
|
|
448
|
+
else {
|
|
449
|
+
fail("AMBIGUOUS_ORG", `You belong to multiple organizations — pass --org <id>:\n${me.memberships.map((m) => ` ${m.organizationId} (${m.organizationName})`).join("\n")}`, 1);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
432
452
|
const createBody = {
|
|
433
453
|
name,
|
|
434
454
|
type: options.type,
|
|
@@ -436,7 +456,7 @@ function registerAgentCommands(program) {
|
|
|
436
456
|
runtimeProvider: options.runtime
|
|
437
457
|
};
|
|
438
458
|
if (options.displayName) createBody.displayName = options.displayName;
|
|
439
|
-
const createRes = await fetch(`${serverUrl}/api/v1/
|
|
459
|
+
const createRes = await fetch(`${serverUrl}/api/v1/orgs/${encodeURIComponent(orgId)}/agents`, {
|
|
440
460
|
method: "POST",
|
|
441
461
|
headers,
|
|
442
462
|
body: JSON.stringify(createBody),
|
|
@@ -463,7 +483,7 @@ function registerAgentCommands(program) {
|
|
|
463
483
|
if (!meRes.ok) fail("ME_ERROR", `Failed to fetch current member (HTTP ${meRes.status})`, 1);
|
|
464
484
|
const me = await meRes.json();
|
|
465
485
|
const target = await resolveAgent(serverUrl, accessToken, agentName);
|
|
466
|
-
const patchRes = await fetch(`${serverUrl}/api/v1/
|
|
486
|
+
const patchRes = await fetch(`${serverUrl}/api/v1/agents/${target.uuid}`, {
|
|
467
487
|
method: "PATCH",
|
|
468
488
|
headers: {
|
|
469
489
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -506,7 +526,7 @@ function registerAgentCommands(program) {
|
|
|
506
526
|
const serverUrl = resolveServerUrl(options.server);
|
|
507
527
|
const accessToken = await ensureFreshAccessToken();
|
|
508
528
|
const target = await resolveAgent(serverUrl, accessToken, agentName);
|
|
509
|
-
const patchRes = await fetch(`${serverUrl}/api/v1/
|
|
529
|
+
const patchRes = await fetch(`${serverUrl}/api/v1/agents/${target.uuid}`, {
|
|
510
530
|
method: "PATCH",
|
|
511
531
|
headers: {
|
|
512
532
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -615,12 +635,41 @@ function registerAgentCommands(program) {
|
|
|
615
635
|
agent.command("status [name]").description("Show agent runtime status from Hub server").option("--server <url>", "Hub server URL").action(async (name, options) => {
|
|
616
636
|
try {
|
|
617
637
|
const serverUrl = resolveServerUrl(options?.server);
|
|
618
|
-
const
|
|
619
|
-
|
|
638
|
+
const accessToken = await ensureFreshAccessToken();
|
|
639
|
+
const meRes = await fetch(`${serverUrl}/api/v1/me`, {
|
|
640
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
620
641
|
signal: AbortSignal.timeout(1e4)
|
|
621
642
|
});
|
|
622
|
-
if (!
|
|
623
|
-
const
|
|
643
|
+
if (!meRes.ok) fail("FETCH_ERROR", `/me HTTP ${meRes.status}`, 1);
|
|
644
|
+
const me = await meRes.json();
|
|
645
|
+
const data = {
|
|
646
|
+
total: 0,
|
|
647
|
+
running: 0,
|
|
648
|
+
byState: {
|
|
649
|
+
idle: 0,
|
|
650
|
+
working: 0,
|
|
651
|
+
blocked: 0,
|
|
652
|
+
error: 0
|
|
653
|
+
},
|
|
654
|
+
clients: 0,
|
|
655
|
+
agents: []
|
|
656
|
+
};
|
|
657
|
+
for (const m of me.memberships) {
|
|
658
|
+
const r = await fetch(`${serverUrl}/api/v1/orgs/${encodeURIComponent(m.organizationId)}/activity`, {
|
|
659
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
660
|
+
signal: AbortSignal.timeout(1e4)
|
|
661
|
+
});
|
|
662
|
+
if (!r.ok) continue;
|
|
663
|
+
const part = await r.json();
|
|
664
|
+
data.total += part.total;
|
|
665
|
+
data.running += part.running;
|
|
666
|
+
data.byState.idle += part.byState.idle;
|
|
667
|
+
data.byState.working += part.byState.working;
|
|
668
|
+
data.byState.blocked += part.byState.blocked;
|
|
669
|
+
data.byState.error += part.byState.error;
|
|
670
|
+
data.clients += part.clients;
|
|
671
|
+
data.agents.push(...part.agents);
|
|
672
|
+
}
|
|
624
673
|
if (name) {
|
|
625
674
|
const ag = data.agents.find((a) => a.agentId === name);
|
|
626
675
|
if (!ag) {
|
|
@@ -656,7 +705,7 @@ function registerAgentCommands(program) {
|
|
|
656
705
|
agent.command("reset <name>").description("Reset agent error state to idle").option("--server <url>", "Hub server URL").action(async (name, options) => {
|
|
657
706
|
try {
|
|
658
707
|
const serverUrl = resolveServerUrl(options.server);
|
|
659
|
-
const response = await fetch(`${serverUrl}/api/v1/
|
|
708
|
+
const response = await fetch(`${serverUrl}/api/v1/agents/${name}/reset-activity`, {
|
|
660
709
|
method: "POST",
|
|
661
710
|
headers: { Authorization: `Bearer ${await ensureFreshAccessToken()}` },
|
|
662
711
|
signal: AbortSignal.timeout(1e4)
|
|
@@ -673,7 +722,7 @@ function registerAgentCommands(program) {
|
|
|
673
722
|
const adminToken = await ensureFreshAccessToken();
|
|
674
723
|
const agentId = (await resolveAgent(serverUrl, adminToken, agentName)).uuid;
|
|
675
724
|
const qs = options.state ? `?state=${options.state}` : "";
|
|
676
|
-
const response = await fetch(`${serverUrl}/api/v1/
|
|
725
|
+
const response = await fetch(`${serverUrl}/api/v1/agents/${agentId}/sessions${qs}`, {
|
|
677
726
|
headers: { Authorization: `Bearer ${adminToken}` },
|
|
678
727
|
signal: AbortSignal.timeout(1e4)
|
|
679
728
|
});
|
|
@@ -702,7 +751,7 @@ function registerAgentCommands(program) {
|
|
|
702
751
|
const serverUrl = resolveServerUrl(options.server);
|
|
703
752
|
const adminToken = await ensureFreshAccessToken();
|
|
704
753
|
const agentId = (await resolveAgent(serverUrl, adminToken, agentName)).uuid;
|
|
705
|
-
const response = await fetch(`${serverUrl}/api/v1/
|
|
754
|
+
const response = await fetch(`${serverUrl}/api/v1/agents/${agentId}/sessions/${chatId}/${cmd}`, {
|
|
706
755
|
method: "POST",
|
|
707
756
|
headers: { Authorization: `Bearer ${adminToken}` },
|
|
708
757
|
signal: AbortSignal.timeout(1e4)
|
|
@@ -725,7 +774,7 @@ function registerAgentCommands(program) {
|
|
|
725
774
|
"Content-Type": "application/json"
|
|
726
775
|
};
|
|
727
776
|
const targetAgent = await resolveAgent(serverUrl, adminToken, agentName);
|
|
728
|
-
const dmRes = await fetch(`${serverUrl}/api/v1/
|
|
777
|
+
const dmRes = await fetch(`${serverUrl}/api/v1/agents/${targetAgent.uuid}/chats`, {
|
|
729
778
|
method: "POST",
|
|
730
779
|
headers,
|
|
731
780
|
signal: AbortSignal.timeout(1e4)
|
|
@@ -747,7 +796,7 @@ function registerAgentCommands(program) {
|
|
|
747
796
|
const pollMessages = async () => {
|
|
748
797
|
try {
|
|
749
798
|
const qs = lastSeenAt ? `?limit=50` : `?limit=10`;
|
|
750
|
-
const msgRes = await fetch(`${serverUrl}/api/v1/
|
|
799
|
+
const msgRes = await fetch(`${serverUrl}/api/v1/chats/${dm.id}/messages${qs}`, {
|
|
751
800
|
headers,
|
|
752
801
|
signal: AbortSignal.timeout(1e4)
|
|
753
802
|
});
|
|
@@ -778,7 +827,7 @@ function registerAgentCommands(program) {
|
|
|
778
827
|
return;
|
|
779
828
|
}
|
|
780
829
|
try {
|
|
781
|
-
const sendRes = await fetch(`${serverUrl}/api/v1/
|
|
830
|
+
const sendRes = await fetch(`${serverUrl}/api/v1/chats/${dm.id}/messages`, {
|
|
782
831
|
method: "POST",
|
|
783
832
|
headers,
|
|
784
833
|
body: JSON.stringify({
|
|
@@ -1347,12 +1396,22 @@ function registerClientCommands(program) {
|
|
|
1347
1396
|
try {
|
|
1348
1397
|
const serverUrl = resolveServerUrl(options.server);
|
|
1349
1398
|
const token = await ensureFreshAccessToken();
|
|
1350
|
-
const
|
|
1399
|
+
const meRes = await fetch(`${serverUrl}/api/v1/me`, {
|
|
1351
1400
|
headers: { Authorization: `Bearer ${token}` },
|
|
1352
1401
|
signal: AbortSignal.timeout(1e4)
|
|
1353
1402
|
});
|
|
1354
|
-
if (!
|
|
1355
|
-
const
|
|
1403
|
+
if (!meRes.ok) fail("FETCH_ERROR", `/me HTTP ${meRes.status}`, 1);
|
|
1404
|
+
const adminOrgs = (await meRes.json()).memberships.filter((m) => m.role === "admin");
|
|
1405
|
+
const clients = [];
|
|
1406
|
+
for (const m of adminOrgs) {
|
|
1407
|
+
const r = await fetch(`${serverUrl}/api/v1/orgs/${encodeURIComponent(m.organizationId)}/clients`, {
|
|
1408
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
1409
|
+
signal: AbortSignal.timeout(1e4)
|
|
1410
|
+
});
|
|
1411
|
+
if (!r.ok) continue;
|
|
1412
|
+
const part = await r.json();
|
|
1413
|
+
clients.push(...part);
|
|
1414
|
+
}
|
|
1356
1415
|
if (clients.length === 0) {
|
|
1357
1416
|
print.line(" No clients.\n");
|
|
1358
1417
|
return;
|
|
@@ -1394,7 +1453,7 @@ function registerClientCommands(program) {
|
|
|
1394
1453
|
}
|
|
1395
1454
|
}
|
|
1396
1455
|
const token = await ensureFreshAccessToken();
|
|
1397
|
-
const response = await fetch(`${serverUrl}/api/v1/
|
|
1456
|
+
const response = await fetch(`${serverUrl}/api/v1/clients/${encodeURIComponent(clientId)}/claim`, {
|
|
1398
1457
|
method: "POST",
|
|
1399
1458
|
headers: {
|
|
1400
1459
|
Authorization: `Bearer ${token}`,
|
|
@@ -1461,7 +1520,7 @@ function registerClientCommands(program) {
|
|
|
1461
1520
|
try {
|
|
1462
1521
|
const serverUrl = resolveServerUrl(options.server);
|
|
1463
1522
|
const token = await ensureFreshAccessToken();
|
|
1464
|
-
const response = await fetch(`${serverUrl}/api/v1/clients/${clientId}/disconnect`, {
|
|
1523
|
+
const response = await fetch(`${serverUrl}/api/v1/clients/${encodeURIComponent(clientId)}/disconnect`, {
|
|
1465
1524
|
method: "POST",
|
|
1466
1525
|
headers: { Authorization: `Bearer ${token}` },
|
|
1467
1526
|
signal: AbortSignal.timeout(1e4)
|
|
@@ -1608,13 +1667,13 @@ function isSecretField(schema, dotPath) {
|
|
|
1608
1667
|
//#region src/commands/onboard.ts
|
|
1609
1668
|
async function promptMissing(args) {
|
|
1610
1669
|
if (!args.server) try {
|
|
1611
|
-
const { resolveServerUrl } = await import("../bootstrap-
|
|
1670
|
+
const { resolveServerUrl } = await import("../bootstrap-B-FRMuvL.mjs").then((n) => n.r);
|
|
1612
1671
|
resolveServerUrl();
|
|
1613
1672
|
} catch {
|
|
1614
1673
|
args.server = await input({ message: "Hub server URL:" });
|
|
1615
1674
|
saveOnboardState(args);
|
|
1616
1675
|
}
|
|
1617
|
-
const { loadCredentials } = await import("../bootstrap-
|
|
1676
|
+
const { loadCredentials } = await import("../bootstrap-B-FRMuvL.mjs").then((n) => n.r);
|
|
1618
1677
|
if (!loadCredentials()) throw new Error("No saved credentials. Run `first-tree-hub client connect <server-url>` before onboarding.");
|
|
1619
1678
|
if (!args.id) {
|
|
1620
1679
|
args.id = await input({ message: "Agent ID:" });
|