@keyou007/agent-bot 0.1.4 → 0.1.6
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 +9 -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 +45 -23
- package/dist/cli.js.map +1 -1
- package/dist/config/loadConfig.js +15 -0
- package/dist/config/loadConfig.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 +51 -24
- package/src/config/loadConfig.ts +14 -0
- 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,8 +1,9 @@
|
|
|
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";
|
|
5
|
-
import { loadConfig } from "./config/loadConfig.js";
|
|
6
|
+
import { loadConfig, loadConfigWithoutEnvironmentMutation } from "./config/loadConfig.js";
|
|
6
7
|
import { sendControlRequest, isServerReachable } from "./cli/LocalControlClient.js";
|
|
7
8
|
import {
|
|
8
9
|
controlEndpoint,
|
|
@@ -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,27 @@ 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(
|
|
202
|
+
loadConfigWithoutEnvironmentMutation(selectedConfigPath).storage.sqlitePath,
|
|
203
|
+
));
|
|
204
|
+
} catch {
|
|
205
|
+
// Reset must remain available when the existing configuration is invalid.
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
for (const endpoint of endpoints) {
|
|
209
|
+
if (await isServerReachable(endpoint)) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
"Cannot reset a running profile. Stop it with agent-bot --profile <directory> server stop, then try again.",
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
194
217
|
function skillsCommand(input: string[]): void {
|
|
195
218
|
const [action = "status", ...rest] = input;
|
|
196
219
|
const sourcePath = fileURLToPath(new URL("../skills/agent-bot/", import.meta.url));
|
|
@@ -462,6 +485,9 @@ function printSkillStatus(status: SkillRegistrationStatus): void {
|
|
|
462
485
|
|
|
463
486
|
function printInitializationPaths(result: InitializationResult): void {
|
|
464
487
|
process.stdout.write("Preparing the Agent Bot user environment...\n");
|
|
488
|
+
if (result.reset) {
|
|
489
|
+
process.stdout.write(`Reset backup: ${result.reset.backupPath}\n`);
|
|
490
|
+
}
|
|
465
491
|
process.stdout.write(`Home directory: ${result.home.path} (${initializationStatusLabel(result.home.status)})\n`);
|
|
466
492
|
process.stdout.write(`Config file: ${result.config.path} (${initializationStatusLabel(result.config.status)})\n`);
|
|
467
493
|
process.stdout.write(`Environment file: ${result.env.path} (${initializationStatusLabel(result.env.status)})\n`);
|
|
@@ -603,6 +629,7 @@ function optionalFeishuFeatureWarnings(missing: FeishuConfigurationChallenge["mi
|
|
|
603
629
|
|
|
604
630
|
function initializationStatusLabel(status: InitializationStatus): string {
|
|
605
631
|
if (status === "created") return "created";
|
|
632
|
+
if (status === "reset") return "reset from template";
|
|
606
633
|
return "already exists; unchanged";
|
|
607
634
|
}
|
|
608
635
|
|
package/src/config/loadConfig.ts
CHANGED
|
@@ -114,6 +114,20 @@ export function loadConfig(
|
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
export function loadConfigWithoutEnvironmentMutation(configPath?: string): AppConfig {
|
|
118
|
+
const environment = new Map(Object.entries(process.env));
|
|
119
|
+
try {
|
|
120
|
+
return loadConfig(configPath);
|
|
121
|
+
} finally {
|
|
122
|
+
for (const name of Object.keys(process.env)) {
|
|
123
|
+
if (!environment.has(name)) delete process.env[name];
|
|
124
|
+
}
|
|
125
|
+
for (const [name, value] of environment) {
|
|
126
|
+
process.env[name] = value;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
function expandEnv(raw: string): string {
|
|
118
132
|
return raw.replace(ENV_PATTERN, (_match, name: string) => process.env[name] ?? "");
|
|
119
133
|
}
|
|
@@ -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,
|