@agent-team-foundation/first-tree-hub 0.9.11 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import "../observability-DV_fQKqV-oxfXX6Z2.mjs";
3
- import { B as resolveReplyToFromEnv, C as checkServerHealth, D as getClientServiceStatus, E as printResults, F as ClientRuntime, G as ClientOrgMismatchError, H as print, I as handleClientOrgMismatch, J as SessionRegistry, K as FirstTreeHubSDK, O as installClientService, P as stopPostgres, R as createOwner, S as checkServerConfig, T as checkWebSocket, U as setJsonMode, X as applyClientLoggerConfig, Y as cleanWorkspaces, Z as configureClientLoggerForService, _ as checkBackgroundService, a as COMMAND_VERSION, b as checkDocker, c as promptMissingFields, d as onboardCheck, f as onboardCreate, g as checkAgentConfigs, h as runMigrations, i as startServer, k as isServiceSupported, l as formatCheckReport, m as runHomeMigration, n as declineUpdate, o as isInteractive, p as saveOnboardState, q as SdkError, r as promptUpdate, s as promptAddAgent, t as createExecuteUpdate, u as loadOnboardState, v as checkClientConfig, w as checkServerReachable, x as checkNodeVersion, y as checkDatabase } from "../core-CuSIXoof.mjs";
3
+ import { $ as configureClientLoggerForService, A as installClientService, B as createOwner, C as checkNodeVersion, D as checkWebSocket, E as checkServerReachable, G as setJsonMode, H as resolveReplyToFromEnv, I as stopPostgres, J as FirstTreeHubSDK, L as ClientRuntime, O as printResults, Q as applyClientLoggerConfig, R as handleClientOrgMismatch, S as checkDocker, T as checkServerHealth, W as print, X as SessionRegistry, Y as SdkError, Z as cleanWorkspaces, _ as runMigrations, a as COMMAND_VERSION, b as checkClientConfig, c as promptMissingFields, d as onboardCheck, f as onboardCreate, g as migrateLocalAgentDirs, h as createApiNameResolver, i as startServer, j as isServiceSupported, k as getClientServiceStatus, l as formatCheckReport, m as runHomeMigration, n as declineUpdate, o as isInteractive, p as saveOnboardState, q as ClientOrgMismatchError, r as promptUpdate, s as promptAddAgent, t as createExecuteUpdate, u as loadOnboardState, v as checkAgentConfigs, w as checkServerConfig, x as checkDatabase, y as checkBackgroundService } from "../core-BgiFGT7Y.mjs";
4
4
  import "../logger-core-BTmvdflj-DjW8FM4T.mjs";
5
5
  import { C as serverConfigSchema, _ 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-CtVqQA8a.mjs";
6
- import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-B2sjp6Z6.mjs";
6
+ import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-DEmwoNn_.mjs";
7
7
  import { join } from "node:path";
8
8
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync } from "node:fs";
9
9
  import { Command } from "commander";
@@ -295,16 +295,10 @@ async function resolveAgent(serverUrl, adminToken, agentName) {
295
295
  function registerAgentCommands(program) {
296
296
  const agent = program.command("agent").description("Agent management — config, bindings, messaging");
297
297
  registerAgentConfigCommands(agent);
298
- agent.command("add [name]").description("Register a local alias for an existing Hub agent (stores agentId)").option("--agent-id <id>", "Agent UUID on the Hub").action(async (name, options) => {
298
+ agent.command("add").description("Register an existing Hub agent on this client (uses the agent name from the Hub)").option("--agent-id <id>", "Agent UUID on the Hub").action(async (options) => {
299
299
  try {
300
- let agentName = name;
301
- let agentId = options?.agentId;
302
- if (!agentName || !agentId) {
303
- const result = await promptAddAgent();
304
- agentName = agentName ?? result.name;
305
- agentId = agentId ?? result.agentId;
306
- }
307
- if (!agentName || !agentId) fail("MISSING_AGENT_ARGS", "Both agent name and agent-id are required.", 2);
300
+ const { name: agentName, agentId } = await promptAddAgent({ agentId: options?.agentId });
301
+ if (!agentName || !agentId) fail("MISSING_AGENT_ARGS", "Agent UUID (and a hub name for that UUID) are required.", 2);
308
302
  const agentDir = join(DEFAULT_CONFIG_DIR, "agents", agentName);
309
303
  mkdirSync(agentDir, {
310
304
  recursive: true,
@@ -323,7 +317,7 @@ function registerAgentCommands(program) {
323
317
  process.exit(1);
324
318
  }
325
319
  });
326
- agent.command("remove <name>").description("Remove a local agent alias and its runtime data").action((name) => {
320
+ agent.command("remove <name>").description("Remove an agent from this client and delete its local runtime data (config dir, workspace, session state)").action((name) => {
327
321
  const agentDir = join(DEFAULT_CONFIG_DIR, "agents", name);
328
322
  if (!existsSync(agentDir)) {
329
323
  print.line(` Agent "${name}" not found.\n`);
@@ -458,7 +452,7 @@ function registerAgentCommands(program) {
458
452
  fail("BIND_CLIENT_ERROR", error instanceof Error ? error.message : String(error));
459
453
  }
460
454
  });
461
- bind.command("bot").description("Bind a Feishu bot to this agent (self-service)").requiredOption("--platform <platform>", "Platform: feishu").requiredOption("--app-id <id>", "Feishu bot App ID").requiredOption("--app-secret <secret>", "Feishu bot App Secret").option("--agent <name>", "Local agent alias (default: first configured)").option("--server <url>", "Hub server URL").action(async (options) => {
455
+ bind.command("bot").description("Bind a Feishu bot to this agent (self-service)").requiredOption("--platform <platform>", "Platform: feishu").requiredOption("--app-id <id>", "Feishu bot App ID").requiredOption("--app-secret <secret>", "Feishu bot App Secret").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").option("--server <url>", "Hub server URL").action(async (options) => {
462
456
  try {
463
457
  if (options.platform !== "feishu") fail("UNSUPPORTED_PLATFORM", `Platform "${options.platform}" is not supported. Use "feishu".`);
464
458
  const serverUrl = resolveServerUrl(options.server);
@@ -473,7 +467,7 @@ function registerAgentCommands(program) {
473
467
  fail("BIND_BOT_ERROR", error instanceof Error ? error.message : String(error));
474
468
  }
475
469
  });
476
- bind.command("user <humanAgentId>").description("Bind a Feishu user to a human agent (via delegate_mention)").requiredOption("--platform <platform>", "Platform: feishu").requiredOption("--feishu-id <id>", "Feishu user ID (ou_xxx)").option("--agent <name>", "Local agent alias (default: first configured)").option("--server <url>", "Hub server URL").action(async (humanAgentId, options) => {
470
+ bind.command("user <humanAgentId>").description("Bind a Feishu user to a human agent (via delegate_mention)").requiredOption("--platform <platform>", "Platform: feishu").requiredOption("--feishu-id <id>", "Feishu user ID (ou_xxx)").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").option("--server <url>", "Hub server URL").action(async (humanAgentId, options) => {
477
471
  try {
478
472
  if (options.platform !== "feishu") fail("UNSUPPORTED_PLATFORM", `Platform "${options.platform}" is not supported. Use "feishu".`);
479
473
  const serverUrl = resolveServerUrl(options.server);
@@ -489,7 +483,7 @@ function registerAgentCommands(program) {
489
483
  fail("BIND_USER_ERROR", error instanceof Error ? error.message : String(error));
490
484
  }
491
485
  });
492
- agent.command("send <target> [message]").description("Send a message to an agent or chat").option("-f, --format <format>", "Message format (text|markdown|card)", "text").option("--chat", "Treat target as chat ID instead of agent ID").option("-m, --metadata <json>", "JSON metadata to attach").option("--reply-to <messageId>", "Message ID to reply to").option("--reply-to-inbox <inboxId>", "Cross-chat reply target inbox").option("--reply-to-chat <chatId>", "Cross-chat reply target chat").option("--agent <name>", "Local agent alias (default: first configured)").action(async (target, message, options) => {
486
+ agent.command("send <target> [message]").description("Send a message to an agent or chat").option("-f, --format <format>", "Message format (text|markdown|card)", "text").option("--chat", "Treat target as chat ID instead of agent ID").option("-m, --metadata <json>", "JSON metadata to attach").option("--reply-to <messageId>", "Message ID to reply to").option("--reply-to-inbox <inboxId>", "Cross-chat reply target inbox").option("--reply-to-chat <chatId>", "Cross-chat reply target chat").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").action(async (target, message, options) => {
493
487
  try {
494
488
  const content = message ?? await readStdin();
495
489
  if (!content) fail("NO_MESSAGE", "No message provided. Pass as argument or pipe via stdin.", 2);
@@ -523,7 +517,7 @@ function registerAgentCommands(program) {
523
517
  handleSdkError(error);
524
518
  }
525
519
  });
526
- agent.command("chats").description("List chats this agent participates in").option("-l, --limit <number>", "Maximum chats to return (1-100)", "20").option("--cursor <cursor>", "Pagination cursor from previous response").option("--agent <name>", "Local agent alias (default: first configured)").action(async (options) => {
520
+ agent.command("chats").description("List chats this agent participates in").option("-l, --limit <number>", "Maximum chats to return (1-100)", "20").option("--cursor <cursor>", "Pagination cursor from previous response").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").action(async (options) => {
527
521
  try {
528
522
  const limit = parseLimit(options.limit, 100);
529
523
  success(await createSdk(options.agent).listChats({
@@ -534,7 +528,7 @@ function registerAgentCommands(program) {
534
528
  handleSdkError(error);
535
529
  }
536
530
  });
537
- agent.command("history <chatId>").description("View message history in a chat").option("-l, --limit <number>", "Maximum messages to return (1-100)", "20").option("--cursor <cursor>", "Pagination cursor from previous response").option("--agent <name>", "Local agent alias (default: first configured)").action(async (chatId, options) => {
531
+ agent.command("history <chatId>").description("View message history in a chat").option("-l, --limit <number>", "Maximum messages to return (1-100)", "20").option("--cursor <cursor>", "Pagination cursor from previous response").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").action(async (chatId, options) => {
538
532
  try {
539
533
  const limit = parseLimit(options.limit, 100);
540
534
  success(await createSdk(options.agent).listMessages(chatId, {
@@ -738,14 +732,14 @@ function registerAgentCommands(program) {
738
732
  fail("CHAT_ERROR", error instanceof Error ? error.message : String(error));
739
733
  }
740
734
  });
741
- agent.command("register").description("Register this agent and return identity info").option("--agent <name>", "Local agent alias (default: first configured)").action(async (options) => {
735
+ agent.command("register").description("Register this agent and return identity info").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").action(async (options) => {
742
736
  try {
743
737
  success(await createSdk(options.agent).register());
744
738
  } catch (error) {
745
739
  handleSdkError(error);
746
740
  }
747
741
  });
748
- agent.command("pull").description("Pull pending messages from inbox").option("-l, --limit <number>", "Maximum entries to return", "10").option("-a, --ack", "Automatically ACK entries after pulling").option("--agent <name>", "Local agent alias (default: first configured)").action(async (options) => {
742
+ agent.command("pull").description("Pull pending messages from inbox").option("-l, --limit <number>", "Maximum entries to return", "10").option("-a, --ack", "Automatically ACK entries after pulling").option("--agent <name>", "Agent name on the Hub (default: first configured on this client)").action(async (options) => {
749
743
  try {
750
744
  const sdk = createSdk(options.agent);
751
745
  const limit = parseLimit(options.limit, 50);
@@ -922,6 +916,17 @@ function registerConnectCommand(parent) {
922
916
  if (options.service === false) print.line(" (--no-service) running inline — Ctrl+C to stop\n");
923
917
  else print.line(` Background service not supported on ${process.platform}; running inline.\n`);
924
918
  const agentsDir = join(DEFAULT_CONFIG_DIR, "agents");
919
+ try {
920
+ await migrateLocalAgentDirs({
921
+ agentsDir,
922
+ workspacesDir: join(DEFAULT_DATA_DIR, "workspaces"),
923
+ sessionsDir: join(DEFAULT_DATA_DIR, "sessions"),
924
+ resolver: createApiNameResolver(config.server.url, () => ensureFreshAccessToken())
925
+ });
926
+ } catch (err) {
927
+ const msg = err instanceof Error ? err.message : String(err);
928
+ print.status("⚠️", `agent-dir migration skipped: ${msg}`);
929
+ }
925
930
  const agents = loadAgents({
926
931
  schema: agentConfigSchema,
927
932
  agentsDir
@@ -984,6 +989,17 @@ function registerClientCommands(program) {
984
989
  applyClientLoggerConfig({ level: config.logLevel });
985
990
  if (process.env.FIRST_TREE_HUB_SERVICE_MODE === "1") configureClientLoggerForService(join(DEFAULT_HOME_DIR, "logs"));
986
991
  const agentsDir = join(DEFAULT_CONFIG_DIR, "agents");
992
+ try {
993
+ await migrateLocalAgentDirs({
994
+ agentsDir,
995
+ workspacesDir: join(DEFAULT_DATA_DIR, "workspaces"),
996
+ sessionsDir: join(DEFAULT_DATA_DIR, "sessions"),
997
+ resolver: createApiNameResolver(config.server.url, () => ensureFreshAccessToken())
998
+ });
999
+ } catch (err) {
1000
+ const msg = err instanceof Error ? err.message : String(err);
1001
+ print.status("⚠️", `agent-dir migration skipped: ${msg}`);
1002
+ }
987
1003
  const agents = loadAgents({
988
1004
  schema: agentConfigSchema,
989
1005
  agentsDir