@agent-team-foundation/first-tree-hub 0.3.0 → 0.3.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-B9JsJR3Z.mjs +583 -0
- package/dist/cli/index.mjs +191 -1
- package/dist/core-vR5jYKHZ.mjs +6597 -0
- package/dist/feishu-Y4m2zFc3.mjs +51 -0
- package/dist/index.mjs +4 -2
- package/dist/rolldown-runtime-twds-ZHy.mjs +14 -0
- package/dist/web/assets/{index-B8NgnD3u.js → index-B1dQmYGJ.js} +23 -23
- package/dist/web/index.html +1 -1
- package/package.json +3 -2
- package/dist/core-uG-Hkr9K.mjs +0 -28563
package/dist/cli/index.mjs
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { _ as resetConfig, b as serverConfigSchema, c as DEFAULT_CONFIG_DIR, d as clientConfigSchema, g as readConfigFile, h as loadAgents, l as DEFAULT_DATA_DIR, m as initConfig, o as resolveAgentToken, p as getConfigValue, s as resolveServerUrl, t as bootstrapToken, u as agentConfigSchema, v as resetConfigMeta, x as setConfigValue } from "../bootstrap-B9JsJR3Z.mjs";
|
|
3
|
+
import { A as ClientRuntime, B as registerBuiltinHandlers, C as checkWebSocket, F as SdkError, I as SessionRegistry, L as cleanWorkspaces, M as AgentSlot, N as DEFAULT_WORKSPACE_TTL_MS, P as FirstTreeHubSDK, R as getHandlerFactory, S as checkServerReachable, V as createAdminUser, _ as checkDocker, a as formatCheckReport, b as checkServerConfig, c as onboardContinue, d as runMigrations, f as checkAgentConfigs, g as checkDatabase, h as checkContextTreeRepo, i as promptMissingFields, j as AgentRuntime, k as stopPostgres, l as onboardCreate, m as checkClientConfig, n as isInteractive, o as loadOnboardState, p as checkAgentTokens, r as promptAddAgent, s as onboardCheck, t as startServer, u as saveOnboardState, v as checkGitHubToken, w as printResults, x as checkServerHealth, y as checkNodeVersion, z as loadRuntimeConfig } from "../core-vR5jYKHZ.mjs";
|
|
4
|
+
import { n as bindFeishuUser, t as bindFeishuBot } from "../feishu-Y4m2zFc3.mjs";
|
|
3
5
|
import { createRequire } from "node:module";
|
|
4
6
|
import { Command } from "commander";
|
|
5
7
|
import { existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
6
8
|
import { join } from "node:path";
|
|
9
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
7
10
|
//#region src/commands/admin.ts
|
|
8
11
|
function registerAdminCommands(program) {
|
|
9
12
|
program.command("admin").description("Admin user management").command("create").description("Create an admin user").option("-u, --username <name>", "Admin username", "admin").option("-p, --password <pass>", "Admin password (auto-generated if omitted)").action(async (options) => {
|
|
@@ -84,6 +87,37 @@ function registerAgentCommands(program) {
|
|
|
84
87
|
});
|
|
85
88
|
}
|
|
86
89
|
//#endregion
|
|
90
|
+
//#region src/commands/bind.ts
|
|
91
|
+
function registerBindCommands(program) {
|
|
92
|
+
program.command("bind-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("--server <url>", "Hub server URL").action(async (options) => {
|
|
93
|
+
try {
|
|
94
|
+
if (options.platform !== "feishu") fail("UNSUPPORTED_PLATFORM", `Platform "${options.platform}" is not supported. Use "feishu".`);
|
|
95
|
+
await bindFeishuBot(resolveServerUrl(options.server), resolveAgentToken(), options.appId, options.appSecret);
|
|
96
|
+
process.stderr.write("Feishu bot bound successfully.\n");
|
|
97
|
+
success({
|
|
98
|
+
platform: "feishu",
|
|
99
|
+
bound: true
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
fail("BIND_BOT_ERROR", error instanceof Error ? error.message : String(error));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
program.command("bind-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("--server <url>", "Hub server URL").action(async (humanAgentId, options) => {
|
|
106
|
+
try {
|
|
107
|
+
if (options.platform !== "feishu") fail("UNSUPPORTED_PLATFORM", `Platform "${options.platform}" is not supported. Use "feishu".`);
|
|
108
|
+
await bindFeishuUser(resolveServerUrl(options.server), resolveAgentToken(), humanAgentId, options.feishuId);
|
|
109
|
+
process.stderr.write(`Feishu user ${options.feishuId} bound to ${humanAgentId}.\n`);
|
|
110
|
+
success({
|
|
111
|
+
platform: "feishu",
|
|
112
|
+
humanAgentId,
|
|
113
|
+
feishuUserId: options.feishuId
|
|
114
|
+
});
|
|
115
|
+
} catch (error) {
|
|
116
|
+
fail("BIND_USER_ERROR", error instanceof Error ? error.message : String(error));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
87
121
|
//#region src/cli/util.ts
|
|
88
122
|
function resolveConfig() {
|
|
89
123
|
const token = process.env.FIRST_TREE_HUB_TOKEN;
|
|
@@ -422,6 +456,142 @@ function registerHistoryCommand(program) {
|
|
|
422
456
|
});
|
|
423
457
|
}
|
|
424
458
|
//#endregion
|
|
459
|
+
//#region src/commands/onboard.ts
|
|
460
|
+
async function promptMissing(args) {
|
|
461
|
+
let ghUsername = null;
|
|
462
|
+
try {
|
|
463
|
+
const { getGitHubUsername } = await import("../bootstrap-B9JsJR3Z.mjs").then((n) => n.n);
|
|
464
|
+
ghUsername = getGitHubUsername();
|
|
465
|
+
} catch {}
|
|
466
|
+
if (!args.id) {
|
|
467
|
+
args.id = await input({
|
|
468
|
+
message: "Member ID (directory name):",
|
|
469
|
+
default: ghUsername ?? void 0
|
|
470
|
+
});
|
|
471
|
+
saveOnboardState(args);
|
|
472
|
+
}
|
|
473
|
+
if (!args.type) {
|
|
474
|
+
args.type = await select({
|
|
475
|
+
message: "Agent type:",
|
|
476
|
+
choices: [
|
|
477
|
+
{
|
|
478
|
+
name: "human",
|
|
479
|
+
value: "human"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
name: "personal_assistant",
|
|
483
|
+
value: "personal_assistant"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
name: "autonomous_agent",
|
|
487
|
+
value: "autonomous_agent"
|
|
488
|
+
}
|
|
489
|
+
]
|
|
490
|
+
});
|
|
491
|
+
saveOnboardState(args);
|
|
492
|
+
}
|
|
493
|
+
if (!args.role) {
|
|
494
|
+
args.role = await input({ message: "Role:" });
|
|
495
|
+
saveOnboardState(args);
|
|
496
|
+
}
|
|
497
|
+
if (!args.domains) {
|
|
498
|
+
args.domains = await input({ message: "Domains (comma-separated):" });
|
|
499
|
+
saveOnboardState(args);
|
|
500
|
+
}
|
|
501
|
+
if (!args.displayName) {
|
|
502
|
+
const name = await input({ message: `Display name (Enter to use "${args.id}"):` });
|
|
503
|
+
if (name) {
|
|
504
|
+
args.displayName = name;
|
|
505
|
+
saveOnboardState(args);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (!args.assistant) {
|
|
509
|
+
if (await confirm({
|
|
510
|
+
message: "Create a personal assistant?",
|
|
511
|
+
default: false
|
|
512
|
+
})) {
|
|
513
|
+
args.assistant = await input({
|
|
514
|
+
message: "Assistant ID:",
|
|
515
|
+
default: `${args.id}-assistant`
|
|
516
|
+
});
|
|
517
|
+
saveOnboardState(args);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (!args.server) try {
|
|
521
|
+
const { resolveServerUrl } = await import("../bootstrap-B9JsJR3Z.mjs").then((n) => n.n);
|
|
522
|
+
resolveServerUrl();
|
|
523
|
+
} catch {
|
|
524
|
+
args.server = await input({ message: "Hub server URL:" });
|
|
525
|
+
saveOnboardState(args);
|
|
526
|
+
}
|
|
527
|
+
if (!args.feishuBotAppId) {
|
|
528
|
+
if (await confirm({
|
|
529
|
+
message: "Bind Feishu bot?",
|
|
530
|
+
default: false
|
|
531
|
+
})) {
|
|
532
|
+
args.feishuBotAppId = await input({ message: "Feishu App ID:" });
|
|
533
|
+
args.feishuBotAppSecret = await input({ message: "Feishu App Secret:" });
|
|
534
|
+
saveOnboardState(args);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
function registerOnboardCommand(program) {
|
|
539
|
+
program.command("onboard").description("Onboard a new member to First Tree Hub (end-to-end)").option("--id <id>", "Member ID (directory name)").option("--type <type>", "Agent type: human | personal_assistant | autonomous_agent").option("--display-name <name>", "Display name (defaults to id)").option("--role <role>", "Role description").option("--domains <domains>", "Comma-separated domains").option("--assistant <id>", "Also create a personal_assistant with this ID").option("--delegate-mention <id>", "Set delegate_mention field").option("--server <url>", "Hub server URL").option("--feishu-bot-app-id <id>", "Feishu bot App ID").option("--feishu-bot-app-secret <secret>", "Feishu bot App Secret").option("--check", "Dry-run: show readiness checklist without executing").option("--continue", "Resume after PR merge (Phase 2)").action(async (options) => {
|
|
540
|
+
try {
|
|
541
|
+
const args = {
|
|
542
|
+
...loadOnboardState() ?? {},
|
|
543
|
+
...options.id && { id: options.id },
|
|
544
|
+
...options.type && { type: options.type },
|
|
545
|
+
...options.displayName && { displayName: options.displayName },
|
|
546
|
+
...options.role && { role: options.role },
|
|
547
|
+
...options.domains && { domains: options.domains },
|
|
548
|
+
...options.assistant && { assistant: options.assistant },
|
|
549
|
+
...options.delegateMention && { delegateMention: options.delegateMention },
|
|
550
|
+
...options.server && { server: options.server },
|
|
551
|
+
...options.feishuBotAppId && { feishuBotAppId: options.feishuBotAppId },
|
|
552
|
+
...options.feishuBotAppSecret && { feishuBotAppSecret: options.feishuBotAppSecret },
|
|
553
|
+
check: options.check,
|
|
554
|
+
continue: options.continue
|
|
555
|
+
};
|
|
556
|
+
if (!args.feishuBotAppId && process.env.FEISHU_APP_ID) args.feishuBotAppId = process.env.FEISHU_APP_ID;
|
|
557
|
+
if (!args.feishuBotAppSecret && process.env.FEISHU_APP_SECRET) args.feishuBotAppSecret = process.env.FEISHU_APP_SECRET;
|
|
558
|
+
if (args.continue) {
|
|
559
|
+
await onboardContinue(args);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (args.check) {
|
|
563
|
+
const items = await onboardCheck(args);
|
|
564
|
+
const report = formatCheckReport(items);
|
|
565
|
+
process.stderr.write(`\nOnboard Check: ${args.id ?? "(no id)"}\n\n${report}\n\n`);
|
|
566
|
+
if (items.some((i) => i.status === "missing_required" || i.status === "error")) process.exit(1);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (isInteractive()) await promptMissing(args);
|
|
570
|
+
const items = await onboardCheck(args);
|
|
571
|
+
if (items.some((i) => i.status === "missing_required" || i.status === "error")) {
|
|
572
|
+
const report = formatCheckReport(items);
|
|
573
|
+
process.stderr.write(`\nOnboard Check: ${args.id ?? "(no id)"}\n\n${report}\n\n`);
|
|
574
|
+
fail("MISSING_PARAMS", "Required parameters are missing. See checklist above.");
|
|
575
|
+
}
|
|
576
|
+
const result = await onboardCreate(args);
|
|
577
|
+
process.stderr.write(`\nPR created: ${result.prUrl}\n`);
|
|
578
|
+
process.stderr.write("Review and merge the PR, then run:\n");
|
|
579
|
+
process.stderr.write(" first-tree-hub onboard --continue\n\n");
|
|
580
|
+
success({
|
|
581
|
+
phase: "create",
|
|
582
|
+
prUrl: result.prUrl
|
|
583
|
+
});
|
|
584
|
+
} catch (error) {
|
|
585
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
586
|
+
if (isInteractive()) {
|
|
587
|
+
process.stderr.write(`\n❌ ${msg}\n\n`);
|
|
588
|
+
process.exit(1);
|
|
589
|
+
}
|
|
590
|
+
fail("ONBOARD_ERROR", msg);
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
//#endregion
|
|
425
595
|
//#region src/commands/send.ts
|
|
426
596
|
const MAX_STDIN_BYTES = 10 * 1024 * 1024;
|
|
427
597
|
/** Read all of stdin as a string. Returns null if stdin is a TTY. */
|
|
@@ -582,6 +752,23 @@ function formatUptime(seconds) {
|
|
|
582
752
|
return `${mins}m`;
|
|
583
753
|
}
|
|
584
754
|
//#endregion
|
|
755
|
+
//#region src/commands/token.ts
|
|
756
|
+
function registerTokenCommands(program) {
|
|
757
|
+
program.command("token").description("Agent token management").command("bootstrap <agentId>").description("Bootstrap a token using GitHub identity (requires gh CLI)").option("--save-to <target>", "Save token to: \"agent\" (default) or a file path", "agent").option("--server <url>", "Hub server URL").action(async (agentId, options) => {
|
|
758
|
+
try {
|
|
759
|
+
const result = await bootstrapToken(resolveServerUrl(options.server), agentId, { saveTo: options.saveTo });
|
|
760
|
+
if (options.saveTo === "agent") process.stderr.write(`Token saved to ~/.first-tree-hub/agents/${agentId}/agent.yaml\n`);
|
|
761
|
+
else process.stderr.write(`Token saved to ${options.saveTo}\n`);
|
|
762
|
+
success({
|
|
763
|
+
agentId: result.agentId,
|
|
764
|
+
tokenSaved: true
|
|
765
|
+
});
|
|
766
|
+
} catch (error) {
|
|
767
|
+
fail("BOOTSTRAP_ERROR", error instanceof Error ? error.message : String(error));
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
//#endregion
|
|
585
772
|
//#region src/cli/connect.ts
|
|
586
773
|
function registerConnectCommand(program) {
|
|
587
774
|
program.command("connect").description("Connect a single agent to server and process messages").option("-t, --type <type>", "Handler type", "claude-code").option("--concurrency <n>", "Max parallel message processing", "5").option("--server <url>", "Override FIRST_TREE_HUB_SERVER").action(async (options) => {
|
|
@@ -655,6 +842,9 @@ registerStatusCommand(program);
|
|
|
655
842
|
registerConnectCommand(program);
|
|
656
843
|
registerStartCommand(program);
|
|
657
844
|
registerAgentCommands(program);
|
|
845
|
+
registerOnboardCommand(program);
|
|
846
|
+
registerTokenCommands(program);
|
|
847
|
+
registerBindCommands(program);
|
|
658
848
|
registerSendCommand(program);
|
|
659
849
|
registerChatsCommand(program);
|
|
660
850
|
registerHistoryCommand(program);
|