@agent-team-foundation/first-tree-hub 0.14.0 → 0.14.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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import "../observability-BAScT_5S-BcW9HgkG.mjs";
3
- import { $ as formatStaleReason, A as checkDocker, B as isServiceSupported, C as createApiNameResolver, D as checkBackgroundService, E as checkAgentConfigs, F as checkWebSocket, H as restartClientService, I as printResults, J as stopPostgres, L as reconcileAgentConfigs, M as checkServerConfig, N as checkServerHealth, O as checkClientConfig, P as checkServerReachable, Q as findStaleAliases, R as getClientServiceStatus, S as runHomeMigration, T as runMigrations, U as startClientService, W as stopClientService, X as handleClientOrgMismatch, Y as ClientRuntime, _ as formatCheckReport, a as declineUpdate, at as fail, b as onboardCreate, c as detectInstallMode, ct as ClientUserMismatchError, d as startServer, dt as SessionRegistry, et as removeLocalAgent, f as reconcileLocalRuntimeProviders, ft as cleanWorkspaces, g as promptMissingFields, h as promptAddAgent, ht as configureClientLoggerForService, i as createExecuteUpdate, it as resolveSenderName, j as checkNodeVersion, k as checkDatabase, l as fetchLatestVersion, lt as FirstTreeHubSDK, m as isInteractive, mt as applyClientLoggerConfig, o as promptUpdate, ot as success, p as uploadClientCapabilities, pt as probeCapabilities, r as registerSaaSConnectCommand, rt as resolveReplyToFromEnv, s as PACKAGE_NAME, st as ClientOrgMismatchError, tt as createOwner, u as installGlobalLatest, ut as SdkError, v as loadOnboardState, w as migrateLocalAgentDirs, x as saveOnboardState, y as onboardCheck, z as installClientService } from "../saas-connect-DX3-nDs9.mjs";
3
+ import { $ as formatStaleReason, A as checkDocker, B as isServiceSupported, C as createApiNameResolver, D as checkBackgroundService, E as checkAgentConfigs, F as checkWebSocket, H as restartClientService, I as printResults, J as stopPostgres, L as reconcileAgentConfigs, M as checkServerConfig, N as checkServerHealth, O as checkClientConfig, P as checkServerReachable, Q as findStaleAliases, R as getClientServiceStatus, S as runHomeMigration, T as runMigrations, U as startClientService, W as stopClientService, X as handleClientOrgMismatch, Y as ClientRuntime, _ as formatCheckReport, a as declineUpdate, at as fail, b as onboardCreate, c as detectInstallMode, ct as ClientUserMismatchError, d as startServer, dt as SessionRegistry, et as removeLocalAgent, f as reconcileLocalRuntimeProviders, ft as cleanWorkspaces, g as promptMissingFields, h as promptAddAgent, ht as configureClientLoggerForService, i as createExecuteUpdate, it as resolveSenderName, j as checkNodeVersion, k as checkDatabase, l as fetchLatestVersion, lt as FirstTreeHubSDK, m as isInteractive, mt as applyClientLoggerConfig, o as promptUpdate, ot as success, p as uploadClientCapabilities, pt as probeCapabilities, r as registerSaaSConnectCommand, rt as resolveReplyToFromEnv, s as PACKAGE_NAME, st as ClientOrgMismatchError, tt as createOwner, u as installGlobalLatest, ut as SdkError, v as loadOnboardState, w as migrateLocalAgentDirs, x as saveOnboardState, y as onboardCheck, z as installClientService } from "../saas-connect-BBRxjmBS.mjs";
4
4
  import "../logger-core-BTmvdflj-DjW8FM4T.mjs";
5
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, v as initConfig, w as resolveConfigReadonly, x as readConfigFile, y as loadAgents } from "../bootstrap-C15ZBOCC.mjs";
6
6
  import { a as print, n as CLI_USER_AGENT, o as setJsonMode, r as COMMAND_VERSION, t as cliFetch } from "../cli-fetch--tiwKm5S.mjs";
@@ -8,7 +8,7 @@ import "../dist-1XGLJMOq.mjs";
8
8
  import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-BGx71p5s.mjs";
9
9
  import "../errors-LPcARA4K-Dbrptiyz.mjs";
10
10
  import "../src-DNBS5Yjj.mjs";
11
- import "../client-RM_03B_l-DiEIa9xe.mjs";
11
+ import "../client-CzXmweS9-DhUiuQvL.mjs";
12
12
  import "../invitation-DZO4NX3P-BPxTeHf-.mjs";
13
13
  import { join } from "node:path";
14
14
  import { existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
@@ -3,5 +3,5 @@ import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
3
3
  import "./dist-1XGLJMOq.mjs";
4
4
  import "./errors-LPcARA4K-Dbrptiyz.mjs";
5
5
  import "./src-DNBS5Yjj.mjs";
6
- import { J as listMyPinnedAgents } from "./client-RM_03B_l-DiEIa9xe.mjs";
6
+ import { J as listMyPinnedAgents } from "./client-CzXmweS9-DhUiuQvL.mjs";
7
7
  export { listMyPinnedAgents };
@@ -4,7 +4,7 @@ import { a as ConflictError, i as ClientUserMismatchError, l as organizations, n
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { and, desc, eq, inArray, isNotNull, lt, ne, or, sql } from "drizzle-orm";
6
6
  import { bigserial, boolean, customType, index, integer, jsonb, pgTable, primaryKey, text, timestamp, unique } from "drizzle-orm/pg-core";
7
- //#region ../server/dist/client-RM_03B_l.mjs
7
+ //#region ../server/dist/client-CzXmweS9.mjs
8
8
  /**
9
9
  * Client connections. A client is a single SDK process (AgentRuntime) that may
10
10
  * host multiple agents. From the unified-user-token milestone on, a client is
@@ -1775,18 +1775,31 @@ async function sendMessageInner(db, chatId, senderId, data, options) {
1775
1775
  tx.select({ type: chats.type }).from(chats).where(eq(chats.id, chatId)).limit(1),
1776
1776
  tx.select({
1777
1777
  inboxId: agents.inboxId,
1778
- organizationId: agents.organizationId
1778
+ organizationId: agents.organizationId,
1779
+ type: agents.type
1779
1780
  }).from(agents).where(eq(agents.uuid, senderId)).limit(1)
1780
1781
  ]);
1781
1782
  const chatType = chatRow?.type ?? null;
1782
1783
  if (!senderRow) throw new NotFoundError(`Sender agent "${senderId}" not found`);
1784
+ let effectiveContent = data.content;
1785
+ if (senderRow.type !== "human" && typeof effectiveContent === "string") {
1786
+ const unwrapped = maybeUnwrapDoubleEncoded(effectiveContent);
1787
+ if (unwrapped !== null) {
1788
+ log.warn({
1789
+ metric: "double_encoded_content_unwrapped_total",
1790
+ chatId,
1791
+ senderId
1792
+ }, "agent sent JSON-encoded string content — unwrapping to restore markdown rendering");
1793
+ effectiveContent = unwrapped;
1794
+ }
1795
+ }
1783
1796
  if (data.replyToInbox !== void 0 && data.replyToInbox !== null) {
1784
1797
  if (senderRow.inboxId !== data.replyToInbox) throw new BadRequestError("replyToInbox must reference the sender's own inbox");
1785
1798
  }
1786
1799
  const incomingMeta = data.metadata ?? {};
1787
1800
  const explicitMentionsRaw = incomingMeta.mentions;
1788
1801
  const explicitMentions = Array.isArray(explicitMentionsRaw) ? explicitMentionsRaw.filter((m) => typeof m === "string") : [];
1789
- const contentText = typeof data.content === "string" ? data.content : "";
1802
+ const contentText = typeof effectiveContent === "string" ? effectiveContent : "";
1790
1803
  const resolved = contentText ? extractMentions(contentText, participants) : [];
1791
1804
  const mergedMentions = [...new Set([...explicitMentions, ...resolved])];
1792
1805
  const metadataToStore = mergedMentions.length > 0 ? {
@@ -1797,7 +1810,7 @@ async function sendMessageInner(db, chatId, senderId, data, options) {
1797
1810
  if (options.enforceGroupMention && chatType === "group") {
1798
1811
  if (mergedMentions.filter((id) => id !== senderId).length === 0) throw new BadRequestError("Sending to a group chat requires an explicit @mention. Use `first-tree-hub chat send <name>` to message a single agent, or @<name> in the content to address one or more group members.");
1799
1812
  }
1800
- let outboundContent = data.content;
1813
+ let outboundContent = effectiveContent;
1801
1814
  if (options.normalizeMentionsInContent && typeof outboundContent === "string") {
1802
1815
  const present = new Set(scanMentionTokens(outboundContent));
1803
1816
  const missingNames = [];
@@ -1909,6 +1922,35 @@ async function sendMessageInner(db, chatId, senderId, data, options) {
1909
1922
  recipients: txResult.recipients
1910
1923
  };
1911
1924
  }
1925
+ /**
1926
+ * Detect agent-sent content that was JSON.stringify-ed once before reaching
1927
+ * the CLI / API. The bad shape is an outer `"..."` wrapper + interior `\n` /
1928
+ * `\"` escape sequences, which the UI renders as a quoted literal instead of
1929
+ * markdown (issue #389). Returns the unwrapped inner string on a confident
1930
+ * match, or `null` to leave the content alone.
1931
+ *
1932
+ * Match conditions (all required) — kept strict so legitimate human content
1933
+ * that happens to look like a quoted phrase is never touched. The caller is
1934
+ * additionally responsible for restricting this to non-human senders.
1935
+ *
1936
+ * - first and last char are `"`
1937
+ * - body contains at least one typical JSON escape sequence
1938
+ * (`\n`, `\r`, `\t`, `\"`, or `\\`)
1939
+ * - `JSON.parse` succeeds
1940
+ * - the parse result is a `string` (excludes `{...}`, `[...]`, numbers)
1941
+ */
1942
+ function maybeUnwrapDoubleEncoded(content) {
1943
+ if (content.length < 4) return null;
1944
+ if (content.charCodeAt(0) !== 34) return null;
1945
+ if (content.charCodeAt(content.length - 1) !== 34) return null;
1946
+ if (!/\\[nrt"\\]/.test(content)) return null;
1947
+ try {
1948
+ const parsed = JSON.parse(content);
1949
+ return typeof parsed === "string" ? parsed : null;
1950
+ } catch {
1951
+ return null;
1952
+ }
1953
+ }
1912
1954
  function stripMentionPrefix(content) {
1913
1955
  return content.replace(/^(@\S+\s*)+/, "").trim();
1914
1956
  }
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./observability-BAScT_5S-BcW9HgkG.mjs";
2
- import { A as checkDocker, B as isServiceSupported, E as checkAgentConfigs, F as checkWebSocket, G as uninstallClientService, H as restartClientService, I as printResults, J as stopPostgres, K as ensurePostgres, M as checkServerConfig, N as checkServerHealth, O as checkClientConfig, P as checkServerReachable, R as getClientServiceStatus, S as runHomeMigration, T as runMigrations, U as startClientService, V as resolveCliInvocation, W as stopClientService, X as handleClientOrgMismatch, Y as ClientRuntime, Z as rotateClientIdWithBackup, _ as formatCheckReport, b as onboardCreate, d as startServer, g as promptMissingFields, h as promptAddAgent, j as checkNodeVersion, k as checkDatabase, lt as FirstTreeHubSDK, m as isInteractive, n as deriveHubUrlFromToken, nt as hasUser, q as isDockerAvailable, t as HubUrlDerivationError, tt as createOwner, ut as SdkError, y as onboardCheck, z as installClientService } from "./saas-connect-DX3-nDs9.mjs";
2
+ import { A as checkDocker, B as isServiceSupported, E as checkAgentConfigs, F as checkWebSocket, G as uninstallClientService, H as restartClientService, I as printResults, J as stopPostgres, K as ensurePostgres, M as checkServerConfig, N as checkServerHealth, O as checkClientConfig, P as checkServerReachable, R as getClientServiceStatus, S as runHomeMigration, T as runMigrations, U as startClientService, V as resolveCliInvocation, W as stopClientService, X as handleClientOrgMismatch, Y as ClientRuntime, Z as rotateClientIdWithBackup, _ as formatCheckReport, b as onboardCreate, d as startServer, g as promptMissingFields, h as promptAddAgent, j as checkNodeVersion, k as checkDatabase, lt as FirstTreeHubSDK, m as isInteractive, n as deriveHubUrlFromToken, nt as hasUser, q as isDockerAvailable, t as HubUrlDerivationError, tt as createOwner, ut as SdkError, y as onboardCheck, z as installClientService } from "./saas-connect-BBRxjmBS.mjs";
3
3
  import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
4
4
  import { a as ensureFreshAdminToken, c as resolveServerUrl, i as ensureFreshAccessToken, n as AuthRefreshRateLimitedError, s as resolveAccessToken, t as AuthRefreshFailedError } from "./bootstrap-C15ZBOCC.mjs";
5
5
  import { i as blank, s as status } from "./cli-fetch--tiwKm5S.mjs";
@@ -7,6 +7,6 @@ import "./dist-1XGLJMOq.mjs";
7
7
  import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-BGx71p5s.mjs";
8
8
  import "./errors-LPcARA4K-Dbrptiyz.mjs";
9
9
  import "./src-DNBS5Yjj.mjs";
10
- import "./client-RM_03B_l-DiEIa9xe.mjs";
10
+ import "./client-CzXmweS9-DhUiuQvL.mjs";
11
11
  import "./invitation-DZO4NX3P-BPxTeHf-.mjs";
12
12
  export { AuthRefreshFailedError, AuthRefreshRateLimitedError, 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 };
@@ -5,7 +5,7 @@ import { a as print, i as blank, n as CLI_USER_AGENT, r as COMMAND_VERSION, s as
5
5
  import { $ as listMeChatSourceCountsQuerySchema, A as createMeChatSchema, At as updateOrganizationSchema, B as githubAppInstallationClaimBodySchema, C as clientRegisterSchema, Ct as submitQuestionAnswerSchema, D as createAdapterMappingSchema, Dt as updateChatSchema, E as createAdapterConfigSchema, Et as updateAgentSchema, F as delegateFeishuUserSchema, G as imageInlineContentSchema, H as githubCallbackQuerySchema, I as dryRunAgentRuntimeConfigSchema, J as inboxPollQuerySchema, K as inboxAckFrameSchema, M as createOrgFromMeSchema, O as createAgentSchema, Ot as updateClientCapabilitiesSchema, P as defaultRuntimeConfigPayload, Q as joinByInvitationSchema, R as getMeDocResponseSchema, St as stripCode, T as contextTreeSnapshotSchema, Tt as updateAgentRuntimeConfigSchema, U as githubDevCallbackQuerySchema, V as githubAppInstallationPermissionsSchema$1, W as githubStartQuerySchema, X as isRedactedEnvValue, Y as isOrgSettingNamespace, Z as isReservedAgentName$1, _ as agentBindRequestSchema, _t as sendToAgentSchema, a as AGENT_TYPES, at as paginationQuerySchema, b as agentTypeSchema$1, bt as sessionReconcileRequestSchema, d as MENTION_REGEX, dt as refreshTokenSchema, et as listMeChatsQuerySchema, f as NOTIFICATION_TYPES, ft as runtimeStateMessageSchema, g as addParticipantSchema, gt as sendMessageSchema, h as addMeChatParticipantsSchema, ht as selfServiceFeishuBotSchema, i as AGENT_STATUSES, it as onboardingEventSchema, j as createMemberSchema, jt as wsAuthFrameSchema, k as createChatSchema, kt as updateMemberSchema, l as GITHUB_ENTITY_TYPES, m as WS_AUTH_FRAME_TIMEOUT_MS, n as AGENT_NAME_REGEX$1, nt as messageSourceSchema$1, o as AGENT_VISIBILITY, ot as patchChatEngagementSchema, p as ORG_SETTINGS_NAMESPACES$1, pt as safeRedirectPath, q as inboxDeliverFrameSchema$1, r as AGENT_SELECTOR_HEADER$1, rt as notificationQuerySchema, s as CHAT_ENGAGEMENT_STATUSES, st as patchOnboardingSchema, t as AGENT_BIND_REJECT_REASONS, tt as loginSchema, ut as rebindAgentSchema, v as agentPinnedMessageSchema$1, vt as sessionEventMessageSchema, w as connectTokenExchangeSchema, wt as updateAdapterConfigSchema, x as chatMetadataSchema$1, xt as sessionStateMessageSchema, y as agentRuntimeConfigPayloadSchema$1, yt as sessionEventSchema$1, z as getMeDocSchema } from "./dist-1XGLJMOq.mjs";
6
6
  import { a as ConflictError, c as UnauthorizedError, i as ClientUserMismatchError$1, l as organizations, n as BadRequestError, o as ForbiddenError, r as ClientOrgMismatchError$1, s as NotFoundError, t as AppError, u as users } from "./errors-LPcARA4K-Dbrptiyz.mjs";
7
7
  import { n as init_esm, r as trace, t as esm_exports } from "./esm-iadMkGbV.mjs";
8
- import { $ as notifyRecipients, A as getPresence, B as listAgentsManagedByUser, C as ensureParticipant, D as getChatDetail, E as getCachedAudience, F as joinAsParticipant, G as listClients, H as listChatParticipantsWithNames, I as joinChat, K as listClientsForOrgAdmin, L as leaveAsParticipant, M as heartbeatInstance, N as inboxEntries, O as getClient, P as invalidateChatAudience, Q as messages, R as leaveChat, S as ensureCanJoin, T as getActivityOverview, U as listChats, V as listAgentsWithRuntime, W as listChatsForMember, X as markSupersededByChat, Y as markStaleAgents, Z as members, _ as createChat, _t as unbindAgent, a as agentVisibilityCondition, at as registerClient, b as disconnectClient, c as assertParticipant, ct as resolveChatMembership, d as chatMembership, dt as sendToAgent$1, et as pendingQuestions, f as chats, ft as serverInstances, g as clients, gt as touchAgent, h as cleanupStalePresence, ht as submitAnswer, i as agentPresence, it as registerChatMessageDispatcher, j as heartbeatClient, k as getOnlineCount, l as bindAgent, lt as retireClient, m as cleanupStaleClients, mt as setRuntimeState, n as addParticipant, nt as recomputeWatchersForAgent, o as agents, ot as removeParticipant, p as claimClient, pt as setOffline, q as listMessages, r as agentChatSessions, rt as recomputeWatchersForMember, s as assertClientOwner, st as resetActivity, t as addChatParticipants, tt as recomputeChatWatchers, u as changeChatType, ut as sendMessage, v as createNotifier, vt as updateClientCapabilities, w as findOrCreateDirectChat, x as editMessage, y as deriveAuthState, yt as upsertSessionState, z as listActiveAgentsPinnedToClient } from "./client-RM_03B_l-DiEIa9xe.mjs";
8
+ import { $ as notifyRecipients, A as getPresence, B as listAgentsManagedByUser, C as ensureParticipant, D as getChatDetail, E as getCachedAudience, F as joinAsParticipant, G as listClients, H as listChatParticipantsWithNames, I as joinChat, K as listClientsForOrgAdmin, L as leaveAsParticipant, M as heartbeatInstance, N as inboxEntries, O as getClient, P as invalidateChatAudience, Q as messages, R as leaveChat, S as ensureCanJoin, T as getActivityOverview, U as listChats, V as listAgentsWithRuntime, W as listChatsForMember, X as markSupersededByChat, Y as markStaleAgents, Z as members, _ as createChat, _t as unbindAgent, a as agentVisibilityCondition, at as registerClient, b as disconnectClient, c as assertParticipant, ct as resolveChatMembership, d as chatMembership, dt as sendToAgent$1, et as pendingQuestions, f as chats, ft as serverInstances, g as clients, gt as touchAgent, h as cleanupStalePresence, ht as submitAnswer, i as agentPresence, it as registerChatMessageDispatcher, j as heartbeatClient, k as getOnlineCount, l as bindAgent, lt as retireClient, m as cleanupStaleClients, mt as setRuntimeState, n as addParticipant, nt as recomputeWatchersForAgent, o as agents, ot as removeParticipant, p as claimClient, pt as setOffline, q as listMessages, r as agentChatSessions, rt as recomputeWatchersForMember, s as assertClientOwner, st as resetActivity, t as addChatParticipants, tt as recomputeChatWatchers, u as changeChatType, ut as sendMessage, v as createNotifier, vt as updateClientCapabilities, w as findOrCreateDirectChat, x as editMessage, y as deriveAuthState, yt as upsertSessionState, z as listActiveAgentsPinnedToClient } from "./client-CzXmweS9-DhUiuQvL.mjs";
9
9
  import { a as invitationRedemptions, c as recordRedemption, i as getActiveInvitation, l as rotateInvitation, n as ensureActiveInvitation, o as invitations, r as findActiveByToken, t as buildInviteUrl, u as uuidv7 } from "./invitation-DZO4NX3P-BPxTeHf-.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { ZodError, z } from "zod";
@@ -3436,68 +3436,44 @@ function installFirstTreeIntegration(options) {
3436
3436
  function generateToolsDoc() {
3437
3437
  return `# Agent Hub SDK
3438
3438
 
3439
- ## How You Communicate
3440
-
3441
3439
  You are running inside **Agent Hub**, a messaging platform for agent teams.
3442
3440
 
3443
- - Messages from other team members arrive as your prompt input
3444
- - Each message includes a \`[From: <agent-name>]\` header — that name is also
3445
- what you pass back to \`chat send\` to reply to or address that agent
3446
- - **Your final text response is automatically delivered** to the chat just respond normally
3447
- - For **proactive communication** (sending to other agents, other chats, or structured data),
3448
- use the \`first-tree-hub\` CLI below
3449
- - **Use your judgment about when to respond.** Not every message requires
3450
- a reply — if you have nothing new for the recipient, output nothing and
3451
- the runtime will end the turn silently.
3452
- Your role and responsibilities are injected via the Hub-managed system prompt.
3453
-
3454
- ## Environment Variables
3455
-
3456
- These are injected automatically when the agent process starts:
3457
-
3458
- | Variable | Description |
3459
- |----------|-------------|
3460
- | \`FIRST_TREE_HUB_SERVER_URL\` | Server address for API calls |
3461
- | \`FIRST_TREE_HUB_ACCESS_TOKEN\` | User member access JWT (short-lived) |
3462
- | \`FIRST_TREE_HUB_AGENT_ID\` | YOUR own agent UUID. The CLI reads it to identify you as the sender — never pass it as a \`send\` target. |
3463
- | \`FIRST_TREE_HUB_CHAT_ID\` | The chat this session is currently bound to. The CLI uses it to route messages — you don't need to pass it manually. |
3464
-
3465
- The \`first-tree-hub\` CLI reads these automatically — no extra setup needed.
3441
+ - Messages from other team members arrive as your prompt input. Each message has a
3442
+ \`[From: <agent-name>]\` header — that name is what you pass back to \`chat send\`.
3443
+ - **Your final text response is automatically delivered** to the chat just respond normally.
3444
+ - **Stay silent when you have nothing to add.** Not every message needs a reply.
3445
+ If you have nothing new for the recipient, output nothing and the runtime ends the turn.
3446
+ - For **proactive communication** (other agents, other chats, or different format),
3447
+ use the \`first-tree-hub\` CLI below.
3466
3448
 
3467
3449
  ## Sending Messages
3468
3450
 
3469
- Use the \`first-tree-hub chat send\` CLIit reads the env vars above and
3470
- attaches the \`Authorization\` + \`X-Agent-Id\` headers automatically:
3451
+ The CLI auto-reads its config from env no setup needed.
3471
3452
 
3472
3453
  \`\`\`bash
3473
- # Send to another agent — first positional argument is the recipient's NAME
3474
- # (NOT a uuid; uuids in chat history / participant lists are not accepted).
3475
- # Run \`first-tree-hub agent list\` to see available names.
3476
- #
3477
- # Routing: if the recipient is a participant of your current chat (typically
3478
- # the case in a group chat where someone @-mentioned you to talk to them),
3479
- # the message stays in that chat. Otherwise it falls back to a direct chat
3480
- # between you and the recipient. You don't need to think about which.
3454
+ # Send to an agent by NAME (uuids are NOT accepted run \`first-tree-hub agent list\` for names)
3481
3455
  first-tree-hub chat send <agentName> "your message"
3482
3456
 
3483
- # Send into a specific chat by id — use this only when you explicitly want
3484
- # to address a chat your current session is NOT bound to.
3457
+ # Address a specific chat (only when not your current chat)
3485
3458
  first-tree-hub chat send --chat <chatId> "your message"
3486
3459
 
3487
- # Send markdown (default format is text)
3488
- first-tree-hub chat send <agentName> -f markdown "**bold** message"
3460
+ # Markdown format (default is text)
3461
+ first-tree-hub chat send <agentName> -f markdown "**bold**"
3489
3462
 
3490
- # Reply to a specific message
3491
- first-tree-hub chat send <agentName> --reply-to <messageId> "reply content"
3463
+ # Reply to a message
3464
+ first-tree-hub chat send <agentName> --reply-to <messageId> "reply"
3492
3465
 
3493
- # Pipe long content via stdin (recommended for special characters)
3494
- echo "long message body" | first-tree-hub chat send <agentName>
3466
+ # Pipe long / multiline content via stdin
3467
+ echo "long body" | first-tree-hub chat send <agentName>
3495
3468
  \`\`\`
3496
3469
 
3497
- > Agent uuids appear in \`chat list\`, chat history, and participant lists,
3498
- > but they are NOT accepted by \`chat send\` — always use the name.
3470
+ **Content rules (important):**
3499
3471
 
3500
- For content with quotes, \`$\`, backticks, or newlines, prefer stdin to avoid shell escaping issues.
3472
+ - Pass content as a **raw string** never \`JSON.stringify\` it first. Wrapping in
3473
+ outer quotes + \`\\n\` escapes produces a literal \`"@x ...\\n..."\` that the UI
3474
+ cannot render as markdown.
3475
+ - For multi-line / markdown / special chars (quotes, \`$\`, backticks, newlines),
3476
+ use **stdin** with real newlines, plus \`-f markdown\`.
3501
3477
  `;
3502
3478
  }
3503
3479
  function resolveGitRepoTargetPath(workspace, localPath) {
@@ -10896,7 +10872,7 @@ function createFeedbackHandler(config) {
10896
10872
  return { handle };
10897
10873
  }
10898
10874
  //#endregion
10899
- //#region ../server/dist/app-l2iy80P2.mjs
10875
+ //#region ../server/dist/app-BcZq1C1l.mjs
10900
10876
  var import_fastify_opentelemetry = /* @__PURE__ */ __toESM(require_fastify_opentelemetry(), 1);
10901
10877
  init_esm();
10902
10878
  var __defProp = Object.defineProperty;
@@ -18378,7 +18354,7 @@ async function meRoutes(app) {
18378
18354
  */
18379
18355
  app.get("/me/pinned-agents", async (request) => {
18380
18356
  const { userId } = requireUser(request);
18381
- const { listMyPinnedAgents } = await import("./client-gSnsRu5W-v_mC1sRY.mjs");
18357
+ const { listMyPinnedAgents } = await import("./client-CREn8bJ0-C5fHJir6.mjs");
18382
18358
  return listMyPinnedAgents(app.db, { userId });
18383
18359
  });
18384
18360
  /**
@@ -1,4 +1,4 @@
1
- import{c as r,j as e,U as o,L as s,A as i,F as a,r as l}from"./index-Is-7_y6O.js";/**
1
+ import{c as r,j as e,U as o,L as s,A as i,F as a,r as l}from"./index-QDcpYpEa.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.