@keyou007/agent-bot 0.1.4 → 0.1.5
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/CHANGELOG.md +5 -0
- package/README.md +11 -0
- package/README.zh.md +11 -0
- package/dist/cli/Initializer.js +60 -1
- package/dist/cli/Initializer.js.map +1 -1
- package/dist/cli/help.js +7 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/initOptions.js +24 -0
- package/dist/cli/initOptions.js.map +1 -0
- package/dist/cli.js +44 -22
- package/dist/cli.js.map +1 -1
- package/dist/feishu/CardRenderer.js +1 -1
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/startup/StartupNotifier.js +1 -0
- package/dist/startup/StartupNotifier.js.map +1 -1
- package/docs/technical-reference.md +3 -1
- package/docs/technical-reference.zh.md +3 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/skills/agent-bot/SKILL.md +2 -0
- package/src/cli/Initializer.ts +72 -2
- package/src/cli/help.ts +7 -0
- package/src/cli/initOptions.ts +33 -0
- package/src/cli.ts +48 -23
- package/src/feishu/CardRenderer.ts +2 -0
- package/src/index.ts +3 -0
- package/src/startup/StartupNotifier.ts +2 -0
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
2
3
|
import { spawnSync } from "node:child_process";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import qrcode from "qrcode-terminal";
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
type InitializationResult,
|
|
20
21
|
type InitializationStatus,
|
|
21
22
|
} from "./cli/Initializer.js";
|
|
23
|
+
import { parseInitCommandOptions, type InitCommandOptions } from "./cli/initOptions.js";
|
|
22
24
|
import {
|
|
23
25
|
registerFeishuApp,
|
|
24
26
|
type FeishuAppCredentials,
|
|
@@ -47,6 +49,7 @@ import {
|
|
|
47
49
|
prepareCrashReportDirectory,
|
|
48
50
|
resolveSupervisorDiagnosticsPaths,
|
|
49
51
|
} from "./supervision/SupervisorDiagnostics.js";
|
|
52
|
+
import { agentBotHome, defaultSqlitePath } from "./config/paths.js";
|
|
50
53
|
|
|
51
54
|
const args = process.argv.slice(2);
|
|
52
55
|
|
|
@@ -69,7 +72,7 @@ async function main(input: string[]): Promise<void> {
|
|
|
69
72
|
return;
|
|
70
73
|
}
|
|
71
74
|
if (command === "init") {
|
|
72
|
-
await initCommand(rest, parsed.configPath);
|
|
75
|
+
await initCommand(rest, parsed.configPath, Boolean(parsed.profilePath));
|
|
73
76
|
return;
|
|
74
77
|
}
|
|
75
78
|
if (command === "console") {
|
|
@@ -102,44 +105,43 @@ interface InitCommandResult extends InitializationResult {
|
|
|
102
105
|
server: InitializationServerResult;
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
async function initCommand(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const paths = initializeAgentBot({ configPath });
|
|
117
|
-
if (!json) printInitializationPaths(paths);
|
|
118
|
-
const initializationLock = acquireInitializationLock(paths.home.path);
|
|
119
|
-
|
|
108
|
+
async function initCommand(
|
|
109
|
+
input: string[],
|
|
110
|
+
configPath: string | undefined,
|
|
111
|
+
explicitProfile: boolean,
|
|
112
|
+
): Promise<void> {
|
|
113
|
+
const options = parseInitCommandOptions(input, explicitProfile);
|
|
114
|
+
let initializationLock = options.reset
|
|
115
|
+
? acquireInitializationLock(agentBotHome())
|
|
116
|
+
: undefined;
|
|
117
|
+
let paths: InitializationResult;
|
|
120
118
|
let initialized: Omit<InitCommandResult, "server">;
|
|
121
119
|
try {
|
|
120
|
+
if (options.reset) await assertResetProfileServerStopped(configPath);
|
|
121
|
+
paths = initializeAgentBot({ configPath, reset: options.reset });
|
|
122
|
+
if (!options.json) printInitializationPaths(paths);
|
|
123
|
+
initializationLock ??= acquireInitializationLock(paths.home.path);
|
|
122
124
|
cleanupFeishuCredentialTemporaryFiles(paths.env.path);
|
|
123
125
|
const feishu = await initializeFeishu(
|
|
124
126
|
paths,
|
|
125
|
-
|
|
127
|
+
options,
|
|
126
128
|
);
|
|
127
129
|
initialized = { ...paths, feishu };
|
|
128
130
|
} finally {
|
|
129
|
-
initializationLock
|
|
131
|
+
initializationLock?.release();
|
|
130
132
|
}
|
|
131
133
|
|
|
132
|
-
if (!json) printInitializationResult(initialized);
|
|
133
|
-
if (!json && !skipFeishu) process.stdout.write("\nStarting Agent Bot server...\n");
|
|
134
|
-
const server = await startInitializedServer({ skipFeishu, configPath });
|
|
134
|
+
if (!options.json) printInitializationResult(initialized);
|
|
135
|
+
if (!options.json && !options.skipFeishu) process.stdout.write("\nStarting Agent Bot server...\n");
|
|
136
|
+
const server = await startInitializedServer({ skipFeishu: options.skipFeishu, configPath });
|
|
135
137
|
const result: InitCommandResult = { ...initialized, server };
|
|
136
|
-
if (json) printJson(result);
|
|
138
|
+
if (options.json) printJson(result);
|
|
137
139
|
else printInitializationServerResult(server);
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
async function initializeFeishu(
|
|
141
143
|
paths: InitializationResult,
|
|
142
|
-
options:
|
|
144
|
+
options: InitCommandOptions,
|
|
143
145
|
): Promise<InitCommandResult["feishu"]> {
|
|
144
146
|
const existing = readFeishuCredentials(paths.env.path);
|
|
145
147
|
if (options.skipFeishu) {
|
|
@@ -191,6 +193,25 @@ async function initializeFeishu(
|
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
195
|
|
|
196
|
+
async function assertResetProfileServerStopped(configPath?: string): Promise<void> {
|
|
197
|
+
const endpoints = new Set<string>([controlEndpoint(defaultSqlitePath())]);
|
|
198
|
+
const selectedConfigPath = configPath ?? process.env.AGENT_BOT_CONFIG;
|
|
199
|
+
if (selectedConfigPath && fs.existsSync(selectedConfigPath)) {
|
|
200
|
+
try {
|
|
201
|
+
endpoints.add(controlEndpoint(loadConfig(selectedConfigPath).storage.sqlitePath));
|
|
202
|
+
} catch {
|
|
203
|
+
// Reset must remain available when the existing configuration is invalid.
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
for (const endpoint of endpoints) {
|
|
207
|
+
if (await isServerReachable(endpoint)) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
"Cannot reset a running profile. Stop it with agent-bot --profile <directory> server stop, then try again.",
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
194
215
|
function skillsCommand(input: string[]): void {
|
|
195
216
|
const [action = "status", ...rest] = input;
|
|
196
217
|
const sourcePath = fileURLToPath(new URL("../skills/agent-bot/", import.meta.url));
|
|
@@ -462,6 +483,9 @@ function printSkillStatus(status: SkillRegistrationStatus): void {
|
|
|
462
483
|
|
|
463
484
|
function printInitializationPaths(result: InitializationResult): void {
|
|
464
485
|
process.stdout.write("Preparing the Agent Bot user environment...\n");
|
|
486
|
+
if (result.reset) {
|
|
487
|
+
process.stdout.write(`Reset backup: ${result.reset.backupPath}\n`);
|
|
488
|
+
}
|
|
465
489
|
process.stdout.write(`Home directory: ${result.home.path} (${initializationStatusLabel(result.home.status)})\n`);
|
|
466
490
|
process.stdout.write(`Config file: ${result.config.path} (${initializationStatusLabel(result.config.status)})\n`);
|
|
467
491
|
process.stdout.write(`Environment file: ${result.env.path} (${initializationStatusLabel(result.env.status)})\n`);
|
|
@@ -603,6 +627,7 @@ function optionalFeishuFeatureWarnings(missing: FeishuConfigurationChallenge["mi
|
|
|
603
627
|
|
|
604
628
|
function initializationStatusLabel(status: InitializationStatus): string {
|
|
605
629
|
if (status === "created") return "created";
|
|
630
|
+
if (status === "reset") return "reset from template";
|
|
606
631
|
return "already exists; unchanged";
|
|
607
632
|
}
|
|
608
633
|
|
|
@@ -16,6 +16,7 @@ import { localCardImage } from "./LocalCardImage.js";
|
|
|
16
16
|
export interface StartupStatusView {
|
|
17
17
|
startedAt: Date;
|
|
18
18
|
restartReason: string;
|
|
19
|
+
agentBotVersion: string;
|
|
19
20
|
defaultAgentName: string;
|
|
20
21
|
defaultAgentTitle: string;
|
|
21
22
|
cwd: string;
|
|
@@ -340,6 +341,7 @@ export class CardRenderer {
|
|
|
340
341
|
`**默认 Agent**:${view.defaultAgentTitle} (${inlineCode(view.defaultAgentName)})`,
|
|
341
342
|
];
|
|
342
343
|
lines.push(
|
|
344
|
+
`**Agent Bot 版本**:${inlineCode(view.agentBotVersion)}`,
|
|
343
345
|
`**服务状态 / 启动时间**:🟢 在线 / ${formatStartupTime(view.startedAt)}`,
|
|
344
346
|
`**重启原因**:${inlineCode(view.restartReason)}`,
|
|
345
347
|
"> 发送消息即可开始对话;发送 `/new` 创建新任务;发送 `/help` 查看帮助。",
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { CodexProcessManager } from "./codex/CodexProcessManager.js";
|
|
|
7
7
|
import { CodexRuntime } from "./codex/CodexRuntime.js";
|
|
8
8
|
import { LocalControlServer } from "./cli/LocalControlServer.js";
|
|
9
9
|
import { controlEndpoint, type ControlRequest, type ControlResponse } from "./cli/controlProtocol.js";
|
|
10
|
+
import { readPackageVersion } from "./cli/packageVersion.js";
|
|
10
11
|
import { loadConfig } from "./config/loadConfig.js";
|
|
11
12
|
import { ConsoleConnector } from "./console/ConsoleConnector.js";
|
|
12
13
|
import { ConsoleTurnPresenter } from "./console/ConsoleTurnPresenter.js";
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
} from "./supervision/SupervisorDiagnostics.js";
|
|
37
38
|
|
|
38
39
|
const processStartedAt = new Date();
|
|
40
|
+
const agentBotVersion = readPackageVersion();
|
|
39
41
|
const supervised = process.env.AGENT_BOT_SUPERVISED === "1";
|
|
40
42
|
const startupReason = process.env.AGENT_BOT_RESTART_REASON?.trim()
|
|
41
43
|
|| (supervised ? "Supervisor 启动" : "直接启动");
|
|
@@ -79,6 +81,7 @@ if (feishuOutbound) {
|
|
|
79
81
|
const defaultAgent = config.agents[defaultAgentName];
|
|
80
82
|
const metadataHydrator = new SessionMetadataHydrator(store, runtimes);
|
|
81
83
|
startupNotifier = new StartupNotifier(store, feishuOutbound, renderer, logger, {
|
|
84
|
+
agentBotVersion,
|
|
82
85
|
defaultAgentName,
|
|
83
86
|
defaultAgentTitle: defaultAgent?.title ?? defaultAgentName,
|
|
84
87
|
cwd: path.resolve(config.defaults.cwd),
|
|
@@ -5,6 +5,7 @@ import type { FeishuOutbound } from "../feishu/types.js";
|
|
|
5
5
|
import type { SessionRecord, StateStore, UserContextRecord } from "../state/StateStore.js";
|
|
6
6
|
|
|
7
7
|
export interface StartupNotificationOptions {
|
|
8
|
+
agentBotVersion: string;
|
|
8
9
|
defaultAgentName: string;
|
|
9
10
|
defaultAgentTitle: string;
|
|
10
11
|
cwd: string;
|
|
@@ -74,6 +75,7 @@ export class StartupNotifier {
|
|
|
74
75
|
const card = this.renderer.renderStartupStatus({
|
|
75
76
|
startedAt,
|
|
76
77
|
restartReason,
|
|
78
|
+
agentBotVersion: this.options.agentBotVersion,
|
|
77
79
|
defaultAgentName: this.options.defaultAgentName,
|
|
78
80
|
defaultAgentTitle: this.options.defaultAgentTitle,
|
|
79
81
|
cwd,
|