@agent-team-foundation/first-tree-hub 0.12.10 → 0.14.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.
- package/dist/{bootstrap-CW73oEYn.mjs → bootstrap-C15ZBOCC.mjs} +7 -6
- package/dist/cli/index.mjs +268 -480
- package/dist/{client-BViGcaUC-CZb2Svgh.mjs → client-RM_03B_l-DiEIa9xe.mjs} +53 -6
- package/dist/{client-DNiLcPEq-db3YS57z.mjs → client-gSnsRu5W-v_mC1sRY.mjs} +3 -3
- package/dist/{dist-B1GHzMLc.mjs → dist-1XGLJMOq.mjs} +163 -11
- package/dist/drizzle/0043_onboarding_completed_at.sql +32 -0
- package/dist/drizzle/0044_agent_avatar_color.sql +11 -0
- package/dist/drizzle/0045_agent_avatar_image.sql +17 -0
- package/dist/drizzle/meta/_journal.json +21 -0
- package/dist/{errors-CF5evtJt-B0NTIVPt.mjs → errors-LPcARA4K-Dbrptiyz.mjs} +2 -1
- package/dist/{feishu-30vUx69l.mjs → feishu-BGx71p5s.mjs} +1 -1
- package/dist/index.mjs +7 -7
- package/dist/invitation-CNv7gfFF-DOFZ75wb.mjs +4 -0
- package/dist/{invitation-Bg0TRiyx-BsZH4GCS.mjs → invitation-DZO4NX3P-BPxTeHf-.mjs} +2 -2
- package/dist/{saas-connect-Fgnnnola.mjs → saas-connect-DX3-nDs9.mjs} +830 -108
- package/dist/web/assets/index-BOK7e_td.css +1 -0
- package/dist/web/assets/{index-B7FIVwrn.js → index-BppGbmdT.js} +1 -1
- package/dist/web/assets/index-Is-7_y6O.js +416 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/invitation-C299fxkP-CZgGbsN_.mjs +0 -4
- package/dist/web/assets/index-DJbUySaH.css +0 -1
- package/dist/web/assets/index-DiDfVdIH.js +0 -421
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { O as withSpan, f as messageAttrs, s as createLogger } from "./observability-BAScT_5S-BcW9HgkG.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as ConflictError, i as ClientUserMismatchError, l as organizations, n as BadRequestError, o as ForbiddenError, s as NotFoundError, u as users } from "./errors-
|
|
2
|
+
import { L as extractMentions, N as defaultParticipantMode, S as clientCapabilitiesSchema, b as agentTypeSchema, ct as questionAnswerMessageContentSchema, i as AGENT_STATUSES, lt as questionMessageContentSchema, mt as scanMentionTokens, o as AGENT_VISIBILITY, s as CHAT_ENGAGEMENT_STATUSES } from "./dist-1XGLJMOq.mjs";
|
|
3
|
+
import { a as ConflictError, i as ClientUserMismatchError, l as organizations, n as BadRequestError, o as ForbiddenError, s as NotFoundError, u as users } from "./errors-LPcARA4K-Dbrptiyz.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { and, desc, eq, inArray, isNotNull, lt, ne, or, sql } from "drizzle-orm";
|
|
6
|
-
import { bigserial, boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp, unique } from "drizzle-orm/pg-core";
|
|
7
|
-
//#region ../server/dist/client-
|
|
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
|
|
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
|
|
@@ -33,6 +33,13 @@ const clients = pgTable("clients", {
|
|
|
33
33
|
lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).notNull().defaultNow(),
|
|
34
34
|
metadata: jsonb("metadata").$type()
|
|
35
35
|
}, (table) => [index("idx_clients_user").on(table.userId), index("idx_clients_org").on(table.organizationId)]);
|
|
36
|
+
/**
|
|
37
|
+
* `bytea` column type — Drizzle ships pg primitives but not bytea out of the
|
|
38
|
+
* box. Reads come back as Node `Buffer` (postgres-js); writes accept any
|
|
39
|
+
* `Uint8Array`. Used for the small inline avatar image blob; no streaming
|
|
40
|
+
* needed at this size (≤ ~50 KB after client-side resize).
|
|
41
|
+
*/
|
|
42
|
+
const bytea = customType({ dataType: () => "bytea" });
|
|
36
43
|
/** Agent registration. Each agent owns a unique inboxId for message delivery. */
|
|
37
44
|
const agents = pgTable("agents", {
|
|
38
45
|
uuid: text("uuid").primaryKey(),
|
|
@@ -49,6 +56,10 @@ const agents = pgTable("agents", {
|
|
|
49
56
|
managerId: text("manager_id").notNull(),
|
|
50
57
|
clientId: text("client_id").references(() => clients.id, { onDelete: "restrict" }),
|
|
51
58
|
runtimeProvider: text("runtime_provider").notNull().default("claude-code"),
|
|
59
|
+
avatarColorToken: text("avatar_color_token"),
|
|
60
|
+
avatarImageData: bytea("avatar_image_data"),
|
|
61
|
+
avatarImageMime: text("avatar_image_mime"),
|
|
62
|
+
avatarImageUpdatedAt: timestamp("avatar_image_updated_at", { withTimezone: true }),
|
|
52
63
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
53
64
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
54
65
|
}, (table) => [
|
|
@@ -1306,6 +1317,7 @@ const pendingQuestions = pgTable("pending_questions", {
|
|
|
1306
1317
|
const INBOX_CHANNEL = "inbox_notifications";
|
|
1307
1318
|
const CONFIG_CHANNEL = "config_changes";
|
|
1308
1319
|
const SESSION_STATE_CHANNEL = "session_state_changes";
|
|
1320
|
+
const SESSION_EVENT_CHANNEL = "session_event_changes";
|
|
1309
1321
|
const RUNTIME_STATE_CHANNEL = "runtime_state_changes";
|
|
1310
1322
|
/**
|
|
1311
1323
|
* Chat-first workspace cross-process kick. Carries `<chatId>:<messageId>`.
|
|
@@ -1326,12 +1338,14 @@ function createNotifier(listenClient) {
|
|
|
1326
1338
|
const subscriptions = /* @__PURE__ */ new Map();
|
|
1327
1339
|
const configChangeHandlers = [];
|
|
1328
1340
|
const sessionStateChangeHandlers = [];
|
|
1341
|
+
const sessionEventHandlers = [];
|
|
1329
1342
|
const runtimeStateChangeHandlers = [];
|
|
1330
1343
|
const chatMessageHandlers = [];
|
|
1331
1344
|
const adminBroadcastHandlers = [];
|
|
1332
1345
|
let unlistenInboxFn = null;
|
|
1333
1346
|
let unlistenConfigFn = null;
|
|
1334
1347
|
let unlistenSessionStateFn = null;
|
|
1348
|
+
let unlistenSessionEventFn = null;
|
|
1335
1349
|
let unlistenRuntimeStateFn = null;
|
|
1336
1350
|
let unlistenChatMessageFn = null;
|
|
1337
1351
|
let unlistenAdminBroadcastFn = null;
|
|
@@ -1384,6 +1398,11 @@ function createNotifier(listenClient) {
|
|
|
1384
1398
|
await listenClient`SELECT pg_notify(${SESSION_STATE_CHANNEL}, ${`${agentId}:${chatId}:${state}:${organizationId}`})`;
|
|
1385
1399
|
} catch {}
|
|
1386
1400
|
},
|
|
1401
|
+
async notifySessionEvent(agentId, chatId, kind, organizationId) {
|
|
1402
|
+
try {
|
|
1403
|
+
await listenClient`SELECT pg_notify(${SESSION_EVENT_CHANNEL}, ${`${agentId}:${chatId}:${kind}:${organizationId}`})`;
|
|
1404
|
+
} catch {}
|
|
1405
|
+
},
|
|
1387
1406
|
async notifyRuntimeStateChange(agentId, state, organizationId) {
|
|
1388
1407
|
try {
|
|
1389
1408
|
await listenClient`SELECT pg_notify(${RUNTIME_STATE_CHANNEL}, ${`${agentId}:${state}:${organizationId}`})`;
|
|
@@ -1432,6 +1451,9 @@ function createNotifier(listenClient) {
|
|
|
1432
1451
|
onSessionStateChange(handler) {
|
|
1433
1452
|
sessionStateChangeHandlers.push(handler);
|
|
1434
1453
|
},
|
|
1454
|
+
onSessionEvent(handler) {
|
|
1455
|
+
sessionEventHandlers.push(handler);
|
|
1456
|
+
},
|
|
1435
1457
|
onRuntimeStateChange(handler) {
|
|
1436
1458
|
runtimeStateChangeHandlers.push(handler);
|
|
1437
1459
|
},
|
|
@@ -1467,6 +1489,27 @@ function createNotifier(listenClient) {
|
|
|
1467
1489
|
}
|
|
1468
1490
|
}
|
|
1469
1491
|
})).unlisten;
|
|
1492
|
+
unlistenSessionEventFn = (await listenClient.listen(SESSION_EVENT_CHANNEL, (payload) => {
|
|
1493
|
+
if (payload) {
|
|
1494
|
+
const firstSep = payload.indexOf(":");
|
|
1495
|
+
const secondSep = payload.indexOf(":", firstSep + 1);
|
|
1496
|
+
const thirdSep = payload.indexOf(":", secondSep + 1);
|
|
1497
|
+
if (firstSep > 0 && secondSep > firstSep && thirdSep > secondSep) {
|
|
1498
|
+
const agentId = payload.slice(0, firstSep);
|
|
1499
|
+
const chatId = payload.slice(firstSep + 1, secondSep);
|
|
1500
|
+
const kind = payload.slice(secondSep + 1, thirdSep);
|
|
1501
|
+
const organizationId = payload.slice(thirdSep + 1);
|
|
1502
|
+
for (const handler of sessionEventHandlers) try {
|
|
1503
|
+
handler({
|
|
1504
|
+
agentId,
|
|
1505
|
+
chatId,
|
|
1506
|
+
kind,
|
|
1507
|
+
organizationId
|
|
1508
|
+
});
|
|
1509
|
+
} catch {}
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
})).unlisten;
|
|
1470
1513
|
unlistenRuntimeStateFn = (await listenClient.listen(RUNTIME_STATE_CHANNEL, (payload) => {
|
|
1471
1514
|
if (payload) {
|
|
1472
1515
|
const firstSep = payload.indexOf(":");
|
|
@@ -1524,6 +1567,10 @@ function createNotifier(listenClient) {
|
|
|
1524
1567
|
await unlistenSessionStateFn();
|
|
1525
1568
|
unlistenSessionStateFn = null;
|
|
1526
1569
|
}
|
|
1570
|
+
if (unlistenSessionEventFn) {
|
|
1571
|
+
await unlistenSessionEventFn();
|
|
1572
|
+
unlistenSessionEventFn = null;
|
|
1573
|
+
}
|
|
1527
1574
|
if (unlistenRuntimeStateFn) {
|
|
1528
1575
|
await unlistenRuntimeStateFn();
|
|
1529
1576
|
unlistenRuntimeStateFn = null;
|
|
@@ -1748,7 +1795,7 @@ async function sendMessageInner(db, chatId, senderId, data, options) {
|
|
|
1748
1795
|
} : incomingMeta;
|
|
1749
1796
|
const dmAutoProjection = chatType === "direct" ? [...new Set([...mergedMentions, ...participants.filter((p) => p.agentId !== senderId).map((p) => p.agentId)])] : mergedMentions;
|
|
1750
1797
|
if (options.enforceGroupMention && chatType === "group") {
|
|
1751
|
-
if (mergedMentions.filter((id) => id !== senderId).length === 0) throw new BadRequestError("Sending to a group chat requires an explicit @mention. Use `
|
|
1798
|
+
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.");
|
|
1752
1799
|
}
|
|
1753
1800
|
let outboundContent = data.content;
|
|
1754
1801
|
if (options.normalizeMentionsInContent && typeof outboundContent === "string") {
|
|
@@ -1933,7 +1980,7 @@ async function sendToAgent(db, senderUuid, targetName, data) {
|
|
|
1933
1980
|
}).from(agents).where(eq(agents.uuid, senderUuid)).limit(1);
|
|
1934
1981
|
if (!sender) throw new NotFoundError(`Agent "${senderUuid}" not found`);
|
|
1935
1982
|
const [target] = await db.select({ uuid: agents.uuid }).from(agents).where(and(eq(agents.organizationId, sender.organizationId), eq(agents.name, targetName), ne(agents.status, "deleted"))).limit(1);
|
|
1936
|
-
if (!target) throw new NotFoundError(`Agent "${targetName}" not found${/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(targetName) ? " — `
|
|
1983
|
+
if (!target) throw new NotFoundError(`Agent "${targetName}" not found${/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(targetName) ? " — `first-tree-hub chat send` expects an agent NAME, not a uuid. Run `first-tree-hub agent list` to see available names." : ""}`);
|
|
1937
1984
|
const incomingMeta = data.metadata ?? {};
|
|
1938
1985
|
const existingMentionsRaw = incomingMeta.mentions;
|
|
1939
1986
|
const existingMentions = Array.isArray(existingMentionsRaw) ? existingMentionsRaw.filter((m) => typeof m === "string") : [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./observability-BAScT_5S-BcW9HgkG.mjs";
|
|
2
2
|
import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
3
|
-
import "./dist-
|
|
4
|
-
import "./errors-
|
|
3
|
+
import "./dist-1XGLJMOq.mjs";
|
|
4
|
+
import "./errors-LPcARA4K-Dbrptiyz.mjs";
|
|
5
5
|
import "./src-DNBS5Yjj.mjs";
|
|
6
|
-
import { J as listMyPinnedAgents } from "./client-
|
|
6
|
+
import { J as listMyPinnedAgents } from "./client-RM_03B_l-DiEIa9xe.mjs";
|
|
7
7
|
export { listMyPinnedAgents };
|
|
@@ -185,6 +185,7 @@ z.object({
|
|
|
185
185
|
const PROMPT_APPEND_MAX_LENGTH = 32e3;
|
|
186
186
|
const MCP_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
|
|
187
187
|
const ENV_KEY_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
188
|
+
const WINDOWS_DRIVE_PATH_PATTERN = /^[A-Za-z]:/;
|
|
188
189
|
const promptConfigSchema = z.object({ append: z.string().max(PROMPT_APPEND_MAX_LENGTH).default("") });
|
|
189
190
|
const mcpStdioServerSchema = z.object({
|
|
190
191
|
name: z.string().regex(MCP_NAME_PATTERN, "MCP name must match /^[a-z0-9][a-z0-9_-]{0,63}$/i"),
|
|
@@ -214,10 +215,38 @@ const envEntrySchema = z.object({
|
|
|
214
215
|
value: z.string(),
|
|
215
216
|
sensitive: z.boolean().default(false)
|
|
216
217
|
});
|
|
218
|
+
function hasControlCharacters(value) {
|
|
219
|
+
for (let idx = 0; idx < value.length; idx++) {
|
|
220
|
+
const code = value.charCodeAt(idx);
|
|
221
|
+
if (code <= 31 || code === 127) return true;
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
function getRepoLocalPathSafetyError(localPath) {
|
|
226
|
+
if (localPath.length === 0) return "Git repo local path must not be empty";
|
|
227
|
+
if (localPath.trim() !== localPath) return "Git repo local path must not have leading or trailing whitespace";
|
|
228
|
+
if (hasControlCharacters(localPath)) return "Git repo local path must not contain control characters";
|
|
229
|
+
if (localPath.includes("\\")) return "Git repo local path must use forward slashes";
|
|
230
|
+
if (localPath.startsWith("/") || WINDOWS_DRIVE_PATH_PATTERN.test(localPath)) return "Git repo local path must be relative";
|
|
231
|
+
const segments = localPath.split("/");
|
|
232
|
+
for (const segment of segments) {
|
|
233
|
+
if (!segment) return "Git repo local path must not contain empty path segments";
|
|
234
|
+
if (segment === "." || segment === "..") return "Git repo local path must not contain dot segments";
|
|
235
|
+
if (segment.trim() !== segment) return "Git repo local path segments must not have leading or trailing whitespace";
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
217
239
|
const gitRepoSchema = z.object({
|
|
218
240
|
url: z.string().min(1),
|
|
219
241
|
ref: z.string().min(1).optional(),
|
|
220
|
-
localPath: z.string().min(1).
|
|
242
|
+
localPath: z.string().min(1).superRefine((localPath, ctx) => {
|
|
243
|
+
const safetyError = getRepoLocalPathSafetyError(localPath);
|
|
244
|
+
if (!safetyError) return;
|
|
245
|
+
ctx.addIssue({
|
|
246
|
+
code: z.ZodIssueCode.custom,
|
|
247
|
+
message: safetyError
|
|
248
|
+
});
|
|
249
|
+
}).optional()
|
|
221
250
|
});
|
|
222
251
|
/**
|
|
223
252
|
* Untagged base shape — 5 user-tunable fields, no `kind` discriminator.
|
|
@@ -491,6 +520,16 @@ const AGENT_VISIBILITY = {
|
|
|
491
520
|
ORGANIZATION: "organization"
|
|
492
521
|
};
|
|
493
522
|
const agentVisibilitySchema = z.enum(["private", "organization"]);
|
|
523
|
+
const avatarColorTokenSchema = z.enum([
|
|
524
|
+
"hue-0",
|
|
525
|
+
"hue-1",
|
|
526
|
+
"hue-2",
|
|
527
|
+
"hue-3",
|
|
528
|
+
"hue-4",
|
|
529
|
+
"hue-5",
|
|
530
|
+
"hue-6",
|
|
531
|
+
"hue-7"
|
|
532
|
+
]);
|
|
494
533
|
const AGENT_STATUSES = {
|
|
495
534
|
ACTIVE: "active",
|
|
496
535
|
SUSPENDED: "suspended",
|
|
@@ -542,7 +581,8 @@ const updateAgentSchema = z.object({
|
|
|
542
581
|
visibility: agentVisibilitySchema.optional(),
|
|
543
582
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
544
583
|
managerId: z.string().nullable().optional(),
|
|
545
|
-
clientId: z.string().min(1).max(100).nullable().optional()
|
|
584
|
+
clientId: z.string().min(1).max(100).nullable().optional(),
|
|
585
|
+
avatarColorToken: avatarColorTokenSchema.nullable().optional()
|
|
546
586
|
});
|
|
547
587
|
/**
|
|
548
588
|
* Service-level rebind input. Admin / owner re-binds an agent to a new
|
|
@@ -571,6 +611,8 @@ z.object({
|
|
|
571
611
|
managerId: z.string().nullable(),
|
|
572
612
|
clientId: z.string().nullable(),
|
|
573
613
|
runtimeProvider: runtimeProviderSchema,
|
|
614
|
+
avatarColorToken: z.string().nullable(),
|
|
615
|
+
avatarImageUrl: z.string().nullable(),
|
|
574
616
|
presenceStatus: presenceStatusSchema.optional(),
|
|
575
617
|
createdAt: z.string(),
|
|
576
618
|
updatedAt: z.string()
|
|
@@ -608,12 +650,30 @@ z.object({
|
|
|
608
650
|
expiresIn: z.number(),
|
|
609
651
|
command: z.string()
|
|
610
652
|
});
|
|
611
|
-
|
|
653
|
+
/**
|
|
654
|
+
* `chats.metadata` is `jsonb` at the DB layer. Without a typed contract every
|
|
655
|
+
* writer was free to invent their own keys, so a GitHub webhook writing
|
|
656
|
+
* `{ source: "github", entityKey: "..." }` and a Feishu adapter writing
|
|
657
|
+
* `{ source: "feishu", externalChannelId: "..." }` could collide on shared
|
|
658
|
+
* keys (`source`, `title`). The discriminated union below pins both writers
|
|
659
|
+
* to a single shape and lets TypeScript narrow on `metadata.source`.
|
|
660
|
+
*
|
|
661
|
+
* Add new variants here; do not extend with free-form `Record<string, unknown>`.
|
|
662
|
+
*/
|
|
663
|
+
/**
|
|
664
|
+
* Source of truth for which github entities get their own tag in the
|
|
665
|
+
* conversation list. Adding a new entry here extends `ChatSource`
|
|
666
|
+
* (`github_${entityType}`) and the SQL CASE/IN-list in
|
|
667
|
+
* `server/services/me-chat.ts` without touching them — both derive from
|
|
668
|
+
* this constant.
|
|
669
|
+
*/
|
|
670
|
+
const GITHUB_ENTITY_TYPES = [
|
|
612
671
|
"issue",
|
|
613
672
|
"pull_request",
|
|
614
673
|
"discussion",
|
|
615
674
|
"commit"
|
|
616
|
-
]
|
|
675
|
+
];
|
|
676
|
+
const githubEntityTypeSchema = z.enum(GITHUB_ENTITY_TYPES);
|
|
617
677
|
const githubChatMetadataSchema = z.object({
|
|
618
678
|
source: z.literal("github"),
|
|
619
679
|
entityType: githubEntityTypeSchema,
|
|
@@ -632,6 +692,14 @@ const chatMetadataSchema = z.discriminatedUnion("source", [githubChatMetadataSch
|
|
|
632
692
|
* sneak through `{ source: "github" }` without the required fields.
|
|
633
693
|
*/
|
|
634
694
|
const optionalChatMetadataSchema = z.union([z.object({}).strict(), chatMetadataSchema]);
|
|
695
|
+
const chatSourceSchema = z.enum([
|
|
696
|
+
"manual",
|
|
697
|
+
"github_issue",
|
|
698
|
+
"github_pull_request",
|
|
699
|
+
"github_discussion",
|
|
700
|
+
"github_commit",
|
|
701
|
+
"feishu"
|
|
702
|
+
]);
|
|
635
703
|
const chatTypeSchema = z.enum(["direct", "group"]);
|
|
636
704
|
/**
|
|
637
705
|
* Per-(chat, user) engagement state. Stored on `chat_user_state` so each
|
|
@@ -868,6 +936,11 @@ const contextTreeSummarySchema = z.object({
|
|
|
868
936
|
removedCount: z.number().int().nonnegative(),
|
|
869
937
|
changedNodeCount: z.number().int().nonnegative()
|
|
870
938
|
});
|
|
939
|
+
const contextTreeUsageSummarySchema = z.object({
|
|
940
|
+
windowDays: z.number().int().positive(),
|
|
941
|
+
agentCount: z.number().int().nonnegative(),
|
|
942
|
+
usageCount: z.number().int().nonnegative()
|
|
943
|
+
});
|
|
871
944
|
const contextTreeSnapshotSchema = z.object({
|
|
872
945
|
repo: z.string().nullable(),
|
|
873
946
|
branch: z.string().nullable(),
|
|
@@ -876,6 +949,7 @@ const contextTreeSnapshotSchema = z.object({
|
|
|
876
949
|
snapshotStatus: contextTreeSnapshotStatusSchema,
|
|
877
950
|
contextStatus: contextTreeStatusSchema,
|
|
878
951
|
summary: contextTreeSummarySchema,
|
|
952
|
+
usage: contextTreeUsageSummarySchema,
|
|
879
953
|
updates: z.array(contextTreeUpdateSchema),
|
|
880
954
|
nodes: z.array(contextTreeNodeSchema),
|
|
881
955
|
edges: z.array(contextTreeEdgeSchema),
|
|
@@ -1161,13 +1235,38 @@ const listMeChatsQuerySchema = z.object({
|
|
|
1161
1235
|
cursor: z.string().optional(),
|
|
1162
1236
|
limit: z.coerce.number().int().min(1).max(200).default(50),
|
|
1163
1237
|
filter: meChatFilterSchema.default("all"),
|
|
1164
|
-
engagement: chatEngagementViewSchema.default("active")
|
|
1238
|
+
engagement: chatEngagementViewSchema.default("active"),
|
|
1239
|
+
source: chatSourceSchema.optional()
|
|
1165
1240
|
});
|
|
1166
1241
|
const meChatParticipantSchema = z.object({
|
|
1167
1242
|
agentId: z.string(),
|
|
1168
1243
|
displayName: z.string(),
|
|
1169
|
-
type: z.string()
|
|
1244
|
+
type: z.string(),
|
|
1245
|
+
avatarColorToken: z.string().nullable(),
|
|
1246
|
+
avatarImageUrl: z.string().nullable()
|
|
1170
1247
|
});
|
|
1248
|
+
/**
|
|
1249
|
+
* Live activity hint surfaced in the conversation row's time slot. Derived
|
|
1250
|
+
* server-side from the latest `session_events` row for the chat. See
|
|
1251
|
+
* `MeChatRow.liveActivity` for the lifecycle rules.
|
|
1252
|
+
*
|
|
1253
|
+
* `kind` is intentionally narrower than the full `sessionEventKind` enum:
|
|
1254
|
+
* `turn_end` / `error` produce `liveActivity: null` rather than a live
|
|
1255
|
+
* indicator.
|
|
1256
|
+
*/
|
|
1257
|
+
const liveActivityKindSchema = z.enum([
|
|
1258
|
+
"tool_call",
|
|
1259
|
+
"thinking",
|
|
1260
|
+
"assistant_text"
|
|
1261
|
+
]);
|
|
1262
|
+
const liveActivitySchema = z.object({
|
|
1263
|
+
agentId: z.string(),
|
|
1264
|
+
kind: liveActivityKindSchema,
|
|
1265
|
+
label: z.string(),
|
|
1266
|
+
startedAt: z.string()
|
|
1267
|
+
});
|
|
1268
|
+
/** Stale threshold (ms) past which a `session_events` row stops driving liveActivity. */
|
|
1269
|
+
const LIVE_ACTIVITY_STALE_MS = 6e4;
|
|
1171
1270
|
const meChatRowSchema = z.object({
|
|
1172
1271
|
chatId: z.string(),
|
|
1173
1272
|
type: z.string(),
|
|
@@ -1181,7 +1280,8 @@ const meChatRowSchema = z.object({
|
|
|
1181
1280
|
unreadMentionCount: z.number().int(),
|
|
1182
1281
|
canReply: z.boolean(),
|
|
1183
1282
|
engagementStatus: chatEngagementStatusSchema,
|
|
1184
|
-
|
|
1283
|
+
engagedAgentIds: z.array(z.string()),
|
|
1284
|
+
liveActivity: liveActivitySchema.nullable()
|
|
1185
1285
|
});
|
|
1186
1286
|
z.object({
|
|
1187
1287
|
rows: z.array(meChatRowSchema),
|
|
@@ -1205,6 +1305,47 @@ z.object({
|
|
|
1205
1305
|
type: z.literal("chat:message"),
|
|
1206
1306
|
chatId: z.string()
|
|
1207
1307
|
});
|
|
1308
|
+
/**
|
|
1309
|
+
* Per-source aggregate for the conversation-list tag bar.
|
|
1310
|
+
*
|
|
1311
|
+
* - `chatCount` — number of chats the caller is in for this source. Used
|
|
1312
|
+
* to hide tags whose count is 0 ("don't render a PR tag if there are no
|
|
1313
|
+
* PRs").
|
|
1314
|
+
* - `unreadChatCount` — number of chats whose `unread_mention_count > 0`.
|
|
1315
|
+
* This is "chats with unread mentions", NOT "total mention count", so
|
|
1316
|
+
* the badge on each tag matches the semantics of the existing `unread`
|
|
1317
|
+
* filter pill (`totalUnread` in `pages/workspace/conversations`) — a
|
|
1318
|
+
* `2` on the PR tag means "2 PR chats have unread mentions", which is
|
|
1319
|
+
* what a user expects to click into.
|
|
1320
|
+
*
|
|
1321
|
+
* The map ALWAYS contains the `manual` key (the default tab is always
|
|
1322
|
+
* available, even at zero counts); other keys are present only when the
|
|
1323
|
+
* caller has at least one chat for that source.
|
|
1324
|
+
*/
|
|
1325
|
+
const chatSourceCountSchema = z.object({
|
|
1326
|
+
chatCount: z.number().int().nonnegative(),
|
|
1327
|
+
unreadChatCount: z.number().int().nonnegative()
|
|
1328
|
+
});
|
|
1329
|
+
const listMeChatSourceCountsQuerySchema = z.object({ engagement: chatEngagementViewSchema.default("active") });
|
|
1330
|
+
z.object({ counts: z.partialRecord(chatSourceSchema, chatSourceCountSchema) });
|
|
1331
|
+
const workspaceDocRefSchema = z.object({
|
|
1332
|
+
type: z.literal("workspace"),
|
|
1333
|
+
chatId: z.string().trim().min(1),
|
|
1334
|
+
agentId: z.string().trim().min(1),
|
|
1335
|
+
basePath: z.string().trim().optional(),
|
|
1336
|
+
path: z.string().trim().min(1)
|
|
1337
|
+
});
|
|
1338
|
+
z.object({ basePath: z.string().trim().min(1) });
|
|
1339
|
+
const getMeDocSchema = z.object({
|
|
1340
|
+
agentId: z.string().trim().min(1),
|
|
1341
|
+
basePath: z.string().trim().optional(),
|
|
1342
|
+
path: z.string().trim().min(1)
|
|
1343
|
+
});
|
|
1344
|
+
const getMeDocResponseSchema = z.object({
|
|
1345
|
+
ref: workspaceDocRefSchema,
|
|
1346
|
+
path: z.string(),
|
|
1347
|
+
content: z.string()
|
|
1348
|
+
});
|
|
1208
1349
|
z.enum([
|
|
1209
1350
|
"connect",
|
|
1210
1351
|
"create_agent",
|
|
@@ -1263,7 +1404,8 @@ z.object({
|
|
|
1263
1404
|
organizationId: z.string(),
|
|
1264
1405
|
organizationName: z.string(),
|
|
1265
1406
|
role: z.enum(["admin", "member"]),
|
|
1266
|
-
agentId: z.string()
|
|
1407
|
+
agentId: z.string(),
|
|
1408
|
+
orgHasOtherMembers: z.boolean()
|
|
1267
1409
|
});
|
|
1268
1410
|
const memberRoleSchema = z.enum(["admin", "member"]);
|
|
1269
1411
|
const memberSchema = z.object({
|
|
@@ -1674,7 +1816,8 @@ const sessionEventKind = z.enum([
|
|
|
1674
1816
|
"error",
|
|
1675
1817
|
"assistant_text",
|
|
1676
1818
|
"thinking",
|
|
1677
|
-
"turn_end"
|
|
1819
|
+
"turn_end",
|
|
1820
|
+
"context_tree_usage"
|
|
1678
1821
|
]);
|
|
1679
1822
|
const toolCallEventPayload = z.object({
|
|
1680
1823
|
toolUseId: z.string(),
|
|
@@ -1716,6 +1859,10 @@ const thinkingEventPayload = z.object({});
|
|
|
1716
1859
|
* completed turns to show only the final result message.
|
|
1717
1860
|
*/
|
|
1718
1861
|
const turnEndEventPayload = z.object({ status: z.enum(["success", "error"]) });
|
|
1862
|
+
const contextTreeUsageEventPayload = z.object({
|
|
1863
|
+
purpose: z.literal("design_decision"),
|
|
1864
|
+
treeRepoUrl: z.string().nullable()
|
|
1865
|
+
});
|
|
1719
1866
|
const sessionEventSchema = z.discriminatedUnion("kind", [
|
|
1720
1867
|
z.object({
|
|
1721
1868
|
kind: z.literal("tool_call"),
|
|
@@ -1736,6 +1883,10 @@ const sessionEventSchema = z.discriminatedUnion("kind", [
|
|
|
1736
1883
|
z.object({
|
|
1737
1884
|
kind: z.literal("turn_end"),
|
|
1738
1885
|
payload: turnEndEventPayload
|
|
1886
|
+
}),
|
|
1887
|
+
z.object({
|
|
1888
|
+
kind: z.literal("context_tree_usage"),
|
|
1889
|
+
payload: contextTreeUsageEventPayload
|
|
1739
1890
|
})
|
|
1740
1891
|
]);
|
|
1741
1892
|
z.object({
|
|
@@ -1749,7 +1900,8 @@ z.object({
|
|
|
1749
1900
|
errorEventPayload,
|
|
1750
1901
|
assistantTextEventPayload,
|
|
1751
1902
|
thinkingEventPayload,
|
|
1752
|
-
turnEndEventPayload
|
|
1903
|
+
turnEndEventPayload,
|
|
1904
|
+
contextTreeUsageEventPayload
|
|
1753
1905
|
]),
|
|
1754
1906
|
createdAt: z.string()
|
|
1755
1907
|
});
|
|
@@ -1826,4 +1978,4 @@ z.object({
|
|
|
1826
1978
|
capabilities: serverCapabilitiesSchema.optional()
|
|
1827
1979
|
}).passthrough();
|
|
1828
1980
|
//#endregion
|
|
1829
|
-
export {
|
|
1981
|
+
export { listMeChatSourceCountsQuerySchema as $, createMeChatSchema as A, updateOrganizationSchema as At, githubAppInstallationClaimBodySchema as B, clientRegisterSchema as C, submitQuestionAnswerSchema as Ct, createAdapterMappingSchema as D, updateChatSchema as Dt, createAdapterConfigSchema as E, updateAgentSchema as Et, delegateFeishuUserSchema as F, imageInlineContentSchema as G, githubCallbackQuerySchema as H, dryRunAgentRuntimeConfigSchema as I, inboxPollQuerySchema as J, inboxAckFrameSchema as K, extractMentions as L, createOrgFromMeSchema as M, defaultParticipantMode as N, createAgentSchema as O, updateClientCapabilitiesSchema as Ot, defaultRuntimeConfigPayload as P, joinByInvitationSchema as Q, getMeDocResponseSchema as R, clientCapabilitiesSchema as S, stripCode as St, contextTreeSnapshotSchema as T, updateAgentRuntimeConfigSchema as Tt, githubDevCallbackQuerySchema as U, githubAppInstallationPermissionsSchema as V, githubStartQuerySchema as W, isRedactedEnvValue as X, isOrgSettingNamespace as Y, isReservedAgentName as Z, agentBindRequestSchema as _, sendToAgentSchema as _t, AGENT_TYPES as a, paginationQuerySchema as at, agentTypeSchema as b, sessionReconcileRequestSchema as bt, DEFAULT_RUNTIME_PROVIDER as c, questionAnswerMessageContentSchema as ct, MENTION_REGEX as d, refreshTokenSchema as dt, listMeChatsQuerySchema as et, NOTIFICATION_TYPES as f, runtimeStateMessageSchema as ft, addParticipantSchema as g, sendMessageSchema as gt, addMeChatParticipantsSchema as h, selfServiceFeishuBotSchema as ht, AGENT_STATUSES as i, onboardingEventSchema as it, createMemberSchema as j, wsAuthFrameSchema as jt, createChatSchema as k, updateMemberSchema as kt, GITHUB_ENTITY_TYPES as l, questionMessageContentSchema as lt, WS_AUTH_FRAME_TIMEOUT_MS as m, scanMentionTokens as mt, AGENT_NAME_REGEX as n, messageSourceSchema as nt, AGENT_VISIBILITY as o, patchChatEngagementSchema as ot, ORG_SETTINGS_NAMESPACES as p, safeRedirectPath as pt, inboxDeliverFrameSchema as q, AGENT_SELECTOR_HEADER as r, notificationQuerySchema as rt, CHAT_ENGAGEMENT_STATUSES as s, patchOnboardingSchema as st, AGENT_BIND_REJECT_REASONS as t, loginSchema as tt, LIVE_ACTIVITY_STALE_MS as u, rebindAgentSchema as ut, agentPinnedMessageSchema as v, sessionEventMessageSchema as vt, connectTokenExchangeSchema as w, updateAdapterConfigSchema as wt, chatMetadataSchema as x, sessionStateMessageSchema as xt, agentRuntimeConfigPayloadSchema as y, sessionEventSchema as yt, getMeDocSchema as z };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Onboarding terminal-state stamp. Distinct from `onboarding_dismissed_at`:
|
|
2
|
+
--
|
|
3
|
+
-- * `onboarding_dismissed_at` means "the user clicked ✕ on the stepper" —
|
|
4
|
+
-- a UI hide, not a setup-complete signal. The user can resume the
|
|
5
|
+
-- wizard from Settings → Onboarding to land back on whichever step is
|
|
6
|
+
-- still incomplete.
|
|
7
|
+
--
|
|
8
|
+
-- * `onboarding_completed_at` means "the user actually walked Step 3 to
|
|
9
|
+
-- success" (admin Continue, invitee Confirm/Continue). Once set, the
|
|
10
|
+
-- Settings → Onboarding entry point and Resume button disappear
|
|
11
|
+
-- permanently. Subsequent tree / source-repo edits go through Settings
|
|
12
|
+
-- → Team and /agents/:uuid.
|
|
13
|
+
--
|
|
14
|
+
-- The two stamps are intentionally orthogonal: `inferOnboardingStep()`
|
|
15
|
+
-- keeps its existing "infer from current resources" semantics and never
|
|
16
|
+
-- consults this column. This field is UI-gate only.
|
|
17
|
+
--
|
|
18
|
+
-- Backfill: every already-dismissed user is treated as completed. The pre-
|
|
19
|
+
-- column population (mid-2025) had no terminal-state concept, so the only
|
|
20
|
+
-- signal we have is "they hid the stepper" — and the alternative (showing
|
|
21
|
+
-- the Onboarding sidebar entry to every legacy user forever) is worse than
|
|
22
|
+
-- the off-by-one risk that a few users dismissed-without-finishing and
|
|
23
|
+
-- will lose their Resume affordance.
|
|
24
|
+
|
|
25
|
+
ALTER TABLE "users"
|
|
26
|
+
ADD COLUMN IF NOT EXISTS "onboarding_completed_at" timestamp with time zone;
|
|
27
|
+
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
UPDATE "users"
|
|
30
|
+
SET "onboarding_completed_at" = "onboarding_dismissed_at"
|
|
31
|
+
WHERE "onboarding_dismissed_at" IS NOT NULL
|
|
32
|
+
AND "onboarding_completed_at" IS NULL;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Add avatar_color_token to agents.
|
|
2
|
+
--
|
|
3
|
+
-- Manager-selected avatar fill color override for the web client. One of
|
|
4
|
+
-- "hue-0".."hue-7", matching the `--avatar-hue-*` CSS tokens in
|
|
5
|
+
-- `packages/web/src/index.css`. NULL means "auto" — the renderer falls
|
|
6
|
+
-- back to the deterministic djb2 hash of `uuid` (the previous default).
|
|
7
|
+
--
|
|
8
|
+
-- Nullable, no default, no backfill: existing rows continue to render the
|
|
9
|
+
-- hashed color until their manager picks something explicit. This is a
|
|
10
|
+
-- pure additive change; no NOT NULL constraint, no enum, no FK.
|
|
11
|
+
ALTER TABLE "agents" ADD COLUMN "avatar_color_token" text;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Add inline avatar image storage to agents.
|
|
2
|
+
--
|
|
3
|
+
-- The PRD chose PG bytea over object storage for the first cut: clients
|
|
4
|
+
-- always pre-resize to 256×256 WEBP (typically < 50 KB), and a few KB ×
|
|
5
|
+
-- N agents per org sits well within row-size budgets. Switching to S3/R2
|
|
6
|
+
-- later is a follow-up migration; the column shape stays the same except
|
|
7
|
+
-- avatar_image_data flips to NULL and avatar_image_url moves to a real
|
|
8
|
+
-- external URL.
|
|
9
|
+
--
|
|
10
|
+
-- All three columns are nullable and move together — either all three
|
|
11
|
+
-- carry an image (data + mime + updated_at) or all are NULL. The service
|
|
12
|
+
-- layer enforces that invariant on writes; SQL keeps it loose so a partial
|
|
13
|
+
-- backfill / restore doesn't break inserts.
|
|
14
|
+
ALTER TABLE "agents"
|
|
15
|
+
ADD COLUMN "avatar_image_data" bytea,
|
|
16
|
+
ADD COLUMN "avatar_image_mime" text,
|
|
17
|
+
ADD COLUMN "avatar_image_updated_at" timestamp with time zone;
|
|
@@ -302,6 +302,27 @@
|
|
|
302
302
|
"when": 1779408000000,
|
|
303
303
|
"tag": "0042_notifications_drop_legacy_types",
|
|
304
304
|
"breakpoints": true
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"idx": 43,
|
|
308
|
+
"version": "7",
|
|
309
|
+
"when": 1779494400000,
|
|
310
|
+
"tag": "0043_onboarding_completed_at",
|
|
311
|
+
"breakpoints": true
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"idx": 44,
|
|
315
|
+
"version": "7",
|
|
316
|
+
"when": 1779580800000,
|
|
317
|
+
"tag": "0044_agent_avatar_color",
|
|
318
|
+
"breakpoints": true
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"idx": 45,
|
|
322
|
+
"version": "7",
|
|
323
|
+
"when": 1779667200000,
|
|
324
|
+
"tag": "0045_agent_avatar_image",
|
|
325
|
+
"breakpoints": true
|
|
305
326
|
}
|
|
306
327
|
]
|
|
307
328
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { integer, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
2
|
-
//#region ../server/dist/errors-
|
|
2
|
+
//#region ../server/dist/errors-LPcARA4K.mjs
|
|
3
3
|
/** Organization entity. Agents and chats belong to exactly one organization. */
|
|
4
4
|
const organizations = pgTable("organizations", {
|
|
5
5
|
id: text("id").primaryKey(),
|
|
@@ -20,6 +20,7 @@ const users = pgTable("users", {
|
|
|
20
20
|
avatarUrl: text("avatar_url"),
|
|
21
21
|
status: text("status").notNull().default("active"),
|
|
22
22
|
onboardingDismissedAt: timestamp("onboarding_dismissed_at", { withTimezone: true }),
|
|
23
|
+
onboardingCompletedAt: timestamp("onboarding_completed_at", { withTimezone: true }),
|
|
23
24
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
24
25
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
25
26
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as __exportAll } from "./chunk-BSw8zbkd.mjs";
|
|
2
2
|
import { t as cliFetch } from "./cli-fetch--tiwKm5S.mjs";
|
|
3
|
-
import { r as AGENT_SELECTOR_HEADER } from "./dist-
|
|
3
|
+
import { r as AGENT_SELECTOR_HEADER } from "./dist-1XGLJMOq.mjs";
|
|
4
4
|
//#region src/core/feishu.ts
|
|
5
5
|
var feishu_exports = /* @__PURE__ */ __exportAll({
|
|
6
6
|
bindFeishuBot: () => bindFeishuBot,
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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-
|
|
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";
|
|
3
3
|
import "./logger-core-BTmvdflj-DjW8FM4T.mjs";
|
|
4
|
-
import { a as ensureFreshAdminToken, c as resolveServerUrl, i as ensureFreshAccessToken, n as AuthRefreshRateLimitedError, s as resolveAccessToken, t as AuthRefreshFailedError } from "./bootstrap-
|
|
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";
|
|
6
|
-
import "./dist-
|
|
7
|
-
import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-
|
|
8
|
-
import "./errors-
|
|
6
|
+
import "./dist-1XGLJMOq.mjs";
|
|
7
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "./feishu-BGx71p5s.mjs";
|
|
8
|
+
import "./errors-LPcARA4K-Dbrptiyz.mjs";
|
|
9
9
|
import "./src-DNBS5Yjj.mjs";
|
|
10
|
-
import "./client-
|
|
11
|
-
import "./invitation-
|
|
10
|
+
import "./client-RM_03B_l-DiEIa9xe.mjs";
|
|
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 };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { l as organizations, s as NotFoundError, u as users } from "./errors-
|
|
1
|
+
import { l as organizations, s as NotFoundError, u as users } from "./errors-LPcARA4K-Dbrptiyz.mjs";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
3
|
import { and, desc, eq, gt, isNull, or } from "drizzle-orm";
|
|
4
4
|
import { index, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
5
|
-
//#region ../server/dist/invitation-
|
|
5
|
+
//#region ../server/dist/invitation-DZO4NX3P.mjs
|
|
6
6
|
/** Generate a UUID v7 (time-ordered). No external dependency. */
|
|
7
7
|
function uuidv7() {
|
|
8
8
|
const now = BigInt(Date.now());
|