@keyou007/agent-bot 0.1.3 → 0.1.4
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 +6 -0
- package/README.md +3 -1
- package/README.zh.md +3 -1
- package/dist/cli/FeishuAppConfiguration.js +10 -10
- package/dist/cli/FeishuAppConfiguration.js.map +1 -1
- package/dist/cli/FeishuAppRegistration.js +9 -9
- package/dist/cli/FeishuAppRegistration.js.map +1 -1
- package/dist/cli/Initializer.js +4 -4
- package/dist/cli/Initializer.js.map +1 -1
- package/dist/cli/LocalControlClient.js +2 -2
- package/dist/cli/LocalControlClient.js.map +1 -1
- package/dist/cli/LocalControlServer.js +1 -1
- package/dist/cli/LocalControlServer.js.map +1 -1
- package/dist/cli/ServerStarter.js +3 -3
- package/dist/cli/ServerStarter.js.map +1 -1
- package/dist/cli/SkillRegistry.js +4 -4
- package/dist/cli/SkillRegistry.js.map +1 -1
- package/dist/cli/help.js +2 -57
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/packageVersion.js +1 -1
- package/dist/cli/packageVersion.js.map +1 -1
- package/dist/cli/profile.js +3 -3
- package/dist/cli/profile.js.map +1 -1
- package/dist/cli/serverStatus.js +37 -0
- package/dist/cli/serverStatus.js.map +1 -0
- package/dist/cli/taskChatRoute.js +2 -2
- package/dist/cli/taskChatRoute.js.map +1 -1
- package/dist/cli.js +112 -116
- package/dist/cli.js.map +1 -1
- package/dist/feishu/transport.js +1 -1
- package/dist/feishu/transport.js.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/proxy/ProxySessionController.js +10 -10
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/docs/technical-reference.md +2 -0
- package/docs/technical-reference.zh.md +2 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/skills/agent-bot/SKILL.md +1 -1
- package/src/cli/FeishuAppConfiguration.ts +10 -10
- package/src/cli/FeishuAppRegistration.ts +9 -9
- package/src/cli/Initializer.ts +4 -4
- package/src/cli/LocalControlClient.ts +2 -2
- package/src/cli/LocalControlServer.ts +1 -1
- package/src/cli/ServerStarter.ts +3 -3
- package/src/cli/SkillRegistry.ts +4 -4
- package/src/cli/help.ts +2 -66
- package/src/cli/packageVersion.ts +1 -1
- package/src/cli/profile.ts +3 -3
- package/src/cli/serverStatus.ts +39 -0
- package/src/cli/taskChatRoute.ts +2 -2
- package/src/cli.ts +113 -119
- package/src/feishu/transport.ts +1 -1
- package/src/index.ts +5 -4
- package/src/proxy/ProxySessionController.ts +10 -10
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keyou007/agent-bot",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@keyou007/agent-bot",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.4",
|
|
10
10
|
"license": "GPL-3.0-only",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@agentclientprotocol/sdk": "1.2.1",
|
package/package.json
CHANGED
|
@@ -74,7 +74,7 @@ agent-bot server status
|
|
|
74
74
|
agent-bot task list
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
`agent-bot
|
|
77
|
+
All Agent Bot CLI interface text is English regardless of system locale. `agent-bot server status` also reports the running profile's Lark App ID; with `--json`, read it from `feishuAppId`.
|
|
78
78
|
|
|
79
79
|
Add `--json` to status and list commands when machine-readable output helps. If `agent-bot` is unavailable, report that the CLI is not installed or linked instead of guessing process state.
|
|
80
80
|
|
|
@@ -178,8 +178,8 @@ export async function ensureFeishuAppConfiguration(
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
const detail = lastError instanceof Error ? `
|
|
182
|
-
throw new Error(
|
|
181
|
+
const detail = lastError instanceof Error ? ` Last check failed: ${lastError.message}` : "";
|
|
182
|
+
throw new Error(`Timed out waiting for the core Lark scopes and message event. Run agent-bot init again.${detail}`);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
async function requestMissingFeishuConfiguration(
|
|
@@ -248,14 +248,14 @@ async function readFeishuAppConfiguration(
|
|
|
248
248
|
`${FEISHU_OPEN_BASE_URL}${APPLICATION_PATH_PREFIX}/${appId}?lang=zh_cn`,
|
|
249
249
|
{ headers },
|
|
250
250
|
signal,
|
|
251
|
-
"
|
|
251
|
+
"Read Lark app configuration",
|
|
252
252
|
),
|
|
253
253
|
fetchJson(
|
|
254
254
|
fetchImpl,
|
|
255
255
|
`${FEISHU_OPEN_BASE_URL}${APPLICATION_PATH_PREFIX}/${appId}/app_versions?lang=zh_cn&page_size=2`,
|
|
256
256
|
{ headers },
|
|
257
257
|
signal,
|
|
258
|
-
"
|
|
258
|
+
"Read Lark app versions",
|
|
259
259
|
),
|
|
260
260
|
]);
|
|
261
261
|
|
|
@@ -303,10 +303,10 @@ async function getTenantAccessToken(
|
|
|
303
303
|
}),
|
|
304
304
|
},
|
|
305
305
|
signal,
|
|
306
|
-
"
|
|
306
|
+
"Get the Lark tenant_access_token",
|
|
307
307
|
);
|
|
308
308
|
const token = readString(payload, "tenant_access_token");
|
|
309
|
-
if (!token) throw new Error("
|
|
309
|
+
if (!token) throw new Error("The Lark tenant_access_token response is missing the access token.");
|
|
310
310
|
return token;
|
|
311
311
|
}
|
|
312
312
|
|
|
@@ -327,12 +327,12 @@ async function fetchJson(
|
|
|
327
327
|
const response = await fetchImpl(url, { ...init, signal: controller.signal });
|
|
328
328
|
const payload = (await response.json().catch(() => undefined)) as unknown;
|
|
329
329
|
if (!isJsonObject(payload)) {
|
|
330
|
-
throw new Error(`${operation}
|
|
330
|
+
throw new Error(`${operation} returned an invalid response (HTTP ${response.status}).`);
|
|
331
331
|
}
|
|
332
332
|
const code = readNumber(payload, "code");
|
|
333
333
|
if (!response.ok || code !== 0) {
|
|
334
334
|
throw new FeishuConfigurationApiError(
|
|
335
|
-
`${operation}
|
|
335
|
+
`${operation} failed: ${readString(payload, "msg") || response.statusText || `HTTP ${response.status}`}`,
|
|
336
336
|
code,
|
|
337
337
|
response.status,
|
|
338
338
|
);
|
|
@@ -340,7 +340,7 @@ async function fetchJson(
|
|
|
340
340
|
return payload;
|
|
341
341
|
} catch (error) {
|
|
342
342
|
if (parentSignal?.aborted) throw abortError(parentSignal);
|
|
343
|
-
if (controller.signal.aborted) throw new Error(`${operation}
|
|
343
|
+
if (controller.signal.aborted) throw new Error(`${operation} timed out.`);
|
|
344
344
|
throw error;
|
|
345
345
|
} finally {
|
|
346
346
|
clearTimeout(timeout);
|
|
@@ -442,7 +442,7 @@ function positiveInteger(value: number | undefined): number | undefined {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
function abortError(signal: AbortSignal): Error {
|
|
445
|
-
return signal.reason instanceof Error ? signal.reason : new Error("
|
|
445
|
+
return signal.reason instanceof Error ? signal.reason : new Error("Lark app configuration was cancelled.");
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
function delay(milliseconds: number): Promise<void> {
|
|
@@ -41,12 +41,12 @@ export async function registerFeishuApp(options: FeishuAppRegistrationOptions =
|
|
|
41
41
|
},
|
|
42
42
|
options.signal,
|
|
43
43
|
);
|
|
44
|
-
throwRegistrationError(begin, "
|
|
44
|
+
throwRegistrationError(begin, "Could not start Lark app creation");
|
|
45
45
|
|
|
46
46
|
const deviceCode = readString(begin, "device_code");
|
|
47
47
|
const userCode = readString(begin, "user_code");
|
|
48
48
|
if (!deviceCode || !userCode) {
|
|
49
|
-
throw new Error("
|
|
49
|
+
throw new Error("The Lark app creation response is missing device_code or user_code.");
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const expiresIn =
|
|
@@ -113,16 +113,16 @@ export async function registerFeishuApp(options: FeishuAppRegistrationOptions =
|
|
|
113
113
|
intervalSeconds = Math.min(intervalSeconds + 5, MAX_POLL_INTERVAL_SECONDS);
|
|
114
114
|
continue;
|
|
115
115
|
case "access_denied":
|
|
116
|
-
throw new Error("
|
|
116
|
+
throw new Error("Lark app creation was cancelled.");
|
|
117
117
|
case "expired_token":
|
|
118
118
|
case "invalid_grant":
|
|
119
|
-
throw new Error("
|
|
119
|
+
throw new Error("The Lark app creation link expired. Run agent-bot init again.");
|
|
120
120
|
default:
|
|
121
|
-
throwRegistrationError(payload, "
|
|
121
|
+
throwRegistrationError(payload, "Lark app creation failed");
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
throw new Error("
|
|
125
|
+
throw new Error("Timed out waiting for Lark app creation. Run agent-bot init again.");
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
function buildVerificationUrl(userCode: string): string {
|
|
@@ -152,7 +152,7 @@ async function postRegistration(
|
|
|
152
152
|
});
|
|
153
153
|
const payload = (await response.json().catch(() => undefined)) as unknown;
|
|
154
154
|
if (!isRecord(payload)) {
|
|
155
|
-
throw new Error(
|
|
155
|
+
throw new Error(`The Lark app registration endpoint returned an invalid response (HTTP ${response.status}).`);
|
|
156
156
|
}
|
|
157
157
|
return payload;
|
|
158
158
|
} finally {
|
|
@@ -165,7 +165,7 @@ function throwRegistrationError(payload: RegistrationPayload, prefix: string): v
|
|
|
165
165
|
const code = readString(payload, "error");
|
|
166
166
|
if (!code) return;
|
|
167
167
|
const description = readString(payload, "error_description") || code;
|
|
168
|
-
throw new Error(`${prefix}
|
|
168
|
+
throw new Error(`${prefix}: ${description}`);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
function readString(value: RegistrationPayload, key: string): string {
|
|
@@ -189,7 +189,7 @@ function isRecord(value: unknown): value is RegistrationPayload {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
function abortError(signal: AbortSignal): Error {
|
|
192
|
-
return signal.reason instanceof Error ? signal.reason : new Error("
|
|
192
|
+
return signal.reason instanceof Error ? signal.reason : new Error("Lark app creation was cancelled.");
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
function delay(milliseconds: number): Promise<void> {
|
package/src/cli/Initializer.ts
CHANGED
|
@@ -122,7 +122,7 @@ export function writeFeishuCredentials(envPath: string, credentials: FeishuCrede
|
|
|
122
122
|
|| persisted.appSecret !== credentials.appSecret
|
|
123
123
|
|| persisted.userOpenId !== credentials.userOpenId
|
|
124
124
|
) {
|
|
125
|
-
throw new Error("
|
|
125
|
+
throw new Error("Lark credential verification failed after writing the environment file.");
|
|
126
126
|
}
|
|
127
127
|
} finally {
|
|
128
128
|
if (temporaryFile !== undefined) fs.closeSync(temporaryFile);
|
|
@@ -169,13 +169,13 @@ export function acquireInitializationLock(lockDirectory: string): Initialization
|
|
|
169
169
|
if (created) fs.rmSync(lockPath, { force: true });
|
|
170
170
|
if (!isFileExistsError(error)) throw error;
|
|
171
171
|
if (!isStaleInitializationLock(lockPath)) {
|
|
172
|
-
throw new Error(
|
|
172
|
+
throw new Error(`Another agent-bot init process is running (lock file: ${lockPath}).`);
|
|
173
173
|
}
|
|
174
174
|
fs.rmSync(lockPath, { force: true });
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
throw new Error(
|
|
178
|
+
throw new Error(`Could not acquire the initialization lock: ${lockPath}`);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
export function cleanupFeishuCredentialTemporaryFiles(envPath: string): number {
|
|
@@ -234,7 +234,7 @@ function upsertDotEnvValue(contents: string, key: string, value: string): string
|
|
|
234
234
|
|
|
235
235
|
function assertDotEnvValue(key: string, value: string): void {
|
|
236
236
|
if (!value.trim() || /[\r\n]/.test(value)) {
|
|
237
|
-
throw new Error(`${key}
|
|
237
|
+
throw new Error(`${key} is not a valid single-line environment variable value.`);
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
|
|
@@ -17,7 +17,7 @@ export async function sendControlRequest(
|
|
|
17
17
|
socket.destroy();
|
|
18
18
|
operation();
|
|
19
19
|
};
|
|
20
|
-
const timer = setTimeout(() => finish(() => reject(new Error("
|
|
20
|
+
const timer = setTimeout(() => finish(() => reject(new Error("Timed out connecting to the Agent Bot control endpoint."))), timeoutMs);
|
|
21
21
|
socket.setEncoding("utf8");
|
|
22
22
|
socket.once("connect", () => socket.write(`${JSON.stringify(request)}\n`));
|
|
23
23
|
socket.on("data", (chunk: string) => {
|
|
@@ -33,7 +33,7 @@ export async function sendControlRequest(
|
|
|
33
33
|
});
|
|
34
34
|
socket.once("error", (error) => finish(() => reject(error)));
|
|
35
35
|
socket.once("end", () => {
|
|
36
|
-
if (!settled) finish(() => reject(new Error("Agent Bot
|
|
36
|
+
if (!settled) finish(() => reject(new Error("The Agent Bot control endpoint returned no response.")));
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
}
|
|
@@ -61,7 +61,7 @@ export class LocalControlServer {
|
|
|
61
61
|
function parseRequest(line: string): ControlRequest {
|
|
62
62
|
const value = JSON.parse(line) as unknown;
|
|
63
63
|
if (!value || typeof value !== "object" || !("action" in value) || typeof value.action !== "string") {
|
|
64
|
-
throw new Error("
|
|
64
|
+
throw new Error("Invalid local control request.");
|
|
65
65
|
}
|
|
66
66
|
return value as ControlRequest;
|
|
67
67
|
}
|
package/src/cli/ServerStarter.ts
CHANGED
|
@@ -56,7 +56,7 @@ export async function startServer(
|
|
|
56
56
|
if (await dependencies.isReachable(endpoint)) {
|
|
57
57
|
const running = await dependencies.waitUntilRunning(endpoint, SERVER_START_TIMEOUT_MS);
|
|
58
58
|
if (!running) {
|
|
59
|
-
throw new Error("
|
|
59
|
+
throw new Error("The Agent Bot server started but could not connect to Lark. Check the logs.");
|
|
60
60
|
}
|
|
61
61
|
return { status: "started" };
|
|
62
62
|
}
|
|
@@ -64,7 +64,7 @@ export async function startServer(
|
|
|
64
64
|
dependencies.spawnSupervisor(config);
|
|
65
65
|
const running = await dependencies.waitUntilRunning(endpoint, SERVER_START_TIMEOUT_MS);
|
|
66
66
|
if (!running) {
|
|
67
|
-
throw new Error("
|
|
67
|
+
throw new Error("The Supervisor started, but the server did not connect to Lark within 45 seconds. Check the logs.");
|
|
68
68
|
}
|
|
69
69
|
return { status: "started" };
|
|
70
70
|
}
|
|
@@ -85,7 +85,7 @@ const defaultDependencies: ServerStarterDependencies = {
|
|
|
85
85
|
detached: true,
|
|
86
86
|
windowsHide: true,
|
|
87
87
|
stdio: "ignore",
|
|
88
|
-
env: { ...process.env, AGENT_BOT_RESTART_REASON: "通过
|
|
88
|
+
env: { ...process.env, AGENT_BOT_RESTART_REASON: "通过 Agent Bot CLI 启动" },
|
|
89
89
|
});
|
|
90
90
|
child.unref();
|
|
91
91
|
},
|
package/src/cli/SkillRegistry.ts
CHANGED
|
@@ -65,7 +65,7 @@ export class SkillRegistry {
|
|
|
65
65
|
this.assertValidSource();
|
|
66
66
|
const existing = fs.existsSync(this.targetPath);
|
|
67
67
|
if (existing && this.readMarker()?.managedBy !== "agent-bot") {
|
|
68
|
-
throw new Error(
|
|
68
|
+
throw new Error(`The target directory exists and is not managed by Agent Bot: ${this.targetPath}`);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const before = existing ? this.status() : undefined;
|
|
@@ -93,7 +93,7 @@ export class SkillRegistry {
|
|
|
93
93
|
uninstall(): boolean {
|
|
94
94
|
if (!fs.existsSync(this.targetPath)) return false;
|
|
95
95
|
if (this.readMarker()?.managedBy !== "agent-bot") {
|
|
96
|
-
throw new Error(
|
|
96
|
+
throw new Error(`Refusing to remove a directory that is not managed by Agent Bot: ${this.targetPath}`);
|
|
97
97
|
}
|
|
98
98
|
this.removeManagedTarget();
|
|
99
99
|
return true;
|
|
@@ -101,13 +101,13 @@ export class SkillRegistry {
|
|
|
101
101
|
|
|
102
102
|
private assertValidSource(): void {
|
|
103
103
|
if (!fs.existsSync(path.join(this.sourcePath, "SKILL.md"))) {
|
|
104
|
-
throw new Error(
|
|
104
|
+
throw new Error(`The built-in Agent Bot Skill was not found: ${this.sourcePath}`);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
private assertSafeTarget(): void {
|
|
109
109
|
if (path.dirname(this.targetPath) !== this.skillsRoot || path.basename(this.targetPath) !== SKILL_NAME) {
|
|
110
|
-
throw new Error(
|
|
110
|
+
throw new Error(`Unsafe Skill target path: ${this.targetPath}`);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
package/src/cli/help.ts
CHANGED
|
@@ -1,63 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
export function resolveCliLanguage(
|
|
4
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
5
|
-
systemLocale = Intl.DateTimeFormat().resolvedOptions().locale,
|
|
6
|
-
): CliLanguage {
|
|
7
|
-
const configuredLocale = [
|
|
8
|
-
env.LC_ALL,
|
|
9
|
-
env.LC_MESSAGES,
|
|
10
|
-
env.LANGUAGE,
|
|
11
|
-
env.LANG,
|
|
12
|
-
].find((value) => value?.trim());
|
|
13
|
-
return isChineseLocale(configuredLocale ?? systemLocale) ? "zh" : "en";
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function renderCliHelp(version: string, language = resolveCliLanguage()): string {
|
|
17
|
-
return language === "zh" ? renderChineseHelp(version) : renderEnglishHelp(version);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function renderChineseHelp(version: string): string {
|
|
21
|
-
return `Agent Bot ${version}
|
|
22
|
-
通过飞书/Lark 使用本机 Codex 与 ACP Agent。
|
|
23
|
-
|
|
24
|
-
用法:
|
|
25
|
-
agent-bot [选项] <命令>
|
|
26
|
-
|
|
27
|
-
常用命令:
|
|
28
|
-
init 初始化配置和飞书应用,并启动服务
|
|
29
|
-
console 打开本地 Console
|
|
30
|
-
server start 在后台启动 Agent Bot
|
|
31
|
-
server status 查看服务和安全重启状态
|
|
32
|
-
server restart 安排安全重启
|
|
33
|
-
server stop 停止 Agent Bot
|
|
34
|
-
task list 列出任务
|
|
35
|
-
task status <task> 查看任务状态
|
|
36
|
-
task chat <task> 查看任务绑定的飞书会话
|
|
37
|
-
task prompt <task> <prompt> 向指定任务发送 Prompt
|
|
38
|
-
task stop <task> 停止指定任务
|
|
39
|
-
task title <task> <title> 修改任务标题
|
|
40
|
-
skills status 查看内置 Skill 状态
|
|
41
|
-
skills install 安装内置 Skill
|
|
42
|
-
|
|
43
|
-
选项:
|
|
44
|
-
--profile <directory> 使用指定目录中的独立 Profile
|
|
45
|
-
--config <path> 使用指定配置文件
|
|
46
|
-
--json 在支持的命令中输出 JSON
|
|
47
|
-
-h, --help 显示帮助
|
|
48
|
-
-v, --version 显示版本
|
|
49
|
-
|
|
50
|
-
示例:
|
|
51
|
-
agent-bot init
|
|
52
|
-
agent-bot --profile ~/.agent-bot-rescue init
|
|
53
|
-
agent-bot server start
|
|
54
|
-
agent-bot server status
|
|
55
|
-
agent-bot task list
|
|
56
|
-
agent-bot server restart --reason "升级 Agent Bot"
|
|
57
|
-
`;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function renderEnglishHelp(version: string): string {
|
|
1
|
+
export function renderCliHelp(version: string): string {
|
|
61
2
|
return `Agent Bot ${version}
|
|
62
3
|
Use local Codex and ACP agents from Lark/Feishu.
|
|
63
4
|
|
|
@@ -68,7 +9,7 @@ Common commands:
|
|
|
68
9
|
init Initialize the Lark app and start the service
|
|
69
10
|
console Open the local console
|
|
70
11
|
server start Start Agent Bot in the background
|
|
71
|
-
server status Show server and safe-restart status
|
|
12
|
+
server status Show the server, Lark App ID, and safe-restart status
|
|
72
13
|
server restart Schedule a safe restart
|
|
73
14
|
server stop Stop Agent Bot
|
|
74
15
|
task list List tasks
|
|
@@ -96,8 +37,3 @@ Examples:
|
|
|
96
37
|
agent-bot server restart --reason "Update Agent Bot"
|
|
97
38
|
`;
|
|
98
39
|
}
|
|
99
|
-
|
|
100
|
-
function isChineseLocale(value: string): boolean {
|
|
101
|
-
const locale = value.trim().split(":")[0]?.split(/[.@]/)[0]?.replaceAll("_", "-").toLowerCase();
|
|
102
|
-
return locale === "zh" || Boolean(locale?.startsWith("zh-"));
|
|
103
|
-
}
|
|
@@ -8,7 +8,7 @@ export function readPackageVersion(
|
|
|
8
8
|
fs.readFileSync(fileURLToPath(packageJsonUrl), "utf8"),
|
|
9
9
|
) as { version?: unknown };
|
|
10
10
|
if (typeof metadata.version !== "string" || !metadata.version.trim()) {
|
|
11
|
-
throw new Error("package.json
|
|
11
|
+
throw new Error("package.json does not contain a valid version.");
|
|
12
12
|
}
|
|
13
13
|
return metadata.version;
|
|
14
14
|
}
|
package/src/cli/profile.ts
CHANGED
|
@@ -22,7 +22,7 @@ export function parseGlobalOptions(input: string[]): ParsedGlobalOptions {
|
|
|
22
22
|
const configPath = removeOption(args, "--config");
|
|
23
23
|
const profilePath = removeOption(args, "--profile");
|
|
24
24
|
if (configPath && profilePath) {
|
|
25
|
-
throw new Error("--profile
|
|
25
|
+
throw new Error("--profile and --config cannot be used together. A profile always uses config.yaml in its directory.");
|
|
26
26
|
}
|
|
27
27
|
return {
|
|
28
28
|
args,
|
|
@@ -49,11 +49,11 @@ export function applyExplicitProfile(
|
|
|
49
49
|
|
|
50
50
|
function removeOption(args: string[], option: string): string | undefined {
|
|
51
51
|
const indexes = args.flatMap((value, index) => value === option ? [index] : []);
|
|
52
|
-
if (indexes.length > 1) throw new Error(`${option}
|
|
52
|
+
if (indexes.length > 1) throw new Error(`${option} can only be specified once.`);
|
|
53
53
|
const index = indexes[0];
|
|
54
54
|
if (index === undefined) return undefined;
|
|
55
55
|
const value = args[index + 1];
|
|
56
|
-
if (!value || value.startsWith("--")) throw new Error(`${option}
|
|
56
|
+
if (!value || value.startsWith("--")) throw new Error(`${option} requires a directory or file path.`);
|
|
57
57
|
args.splice(index, 2);
|
|
58
58
|
return value;
|
|
59
59
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function withConfiguredFeishuAppId(
|
|
2
|
+
data: unknown,
|
|
3
|
+
configuredFeishuAppId?: string,
|
|
4
|
+
): Record<string, unknown> {
|
|
5
|
+
const value = data && typeof data === "object"
|
|
6
|
+
? data as Record<string, unknown>
|
|
7
|
+
: {};
|
|
8
|
+
if (Object.hasOwn(value, "feishuAppId")) return value;
|
|
9
|
+
return {
|
|
10
|
+
...value,
|
|
11
|
+
feishuAppId: configuredFeishuAppId ?? null,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function formatServerStatus(data: unknown): string {
|
|
16
|
+
const value = data && typeof data === "object" ? data as Record<string, unknown> : {};
|
|
17
|
+
const activity = value.activity && typeof value.activity === "object"
|
|
18
|
+
? value.activity as Record<string, unknown>
|
|
19
|
+
: {};
|
|
20
|
+
const state = value.running === false
|
|
21
|
+
? "not running"
|
|
22
|
+
: value.ready === false
|
|
23
|
+
? "starting (connecting to Lark)"
|
|
24
|
+
: "running";
|
|
25
|
+
const safeRestart = value.safeRestartScheduled
|
|
26
|
+
? `pending (${String(value.safeRestartReason ?? "no reason provided")})`
|
|
27
|
+
: "not scheduled";
|
|
28
|
+
return [
|
|
29
|
+
`Agent Bot server: ${state}`,
|
|
30
|
+
`Lark App ID: ${value.feishuAppId ?? "not configured"}`,
|
|
31
|
+
`PID: ${value.pid ?? "-"}`,
|
|
32
|
+
`Started at: ${value.startedAt ?? "-"}`,
|
|
33
|
+
`Supervisor: ${value.supervised ? "enabled" : "disabled"}`,
|
|
34
|
+
`Running tasks: ${activity.runningSessions ?? 0}`,
|
|
35
|
+
`Pending final deliveries: ${activity.pendingFinalDeliveries ?? 0}`,
|
|
36
|
+
`Safe restart: ${safeRestart}`,
|
|
37
|
+
"",
|
|
38
|
+
].join("\n");
|
|
39
|
+
}
|
package/src/cli/taskChatRoute.ts
CHANGED
|
@@ -15,10 +15,10 @@ export function taskChatRoute(session: SessionRecord): TaskChatRoute {
|
|
|
15
15
|
const contextKey = session.contextKey;
|
|
16
16
|
const baseContextKey = baseChatContextKey(contextKey);
|
|
17
17
|
if (!baseContextKey.startsWith(CHAT_CONTEXT_PREFIX)) {
|
|
18
|
-
throw new Error(
|
|
18
|
+
throw new Error(`The task is not bound to a Lark chat: ${session.remoteSessionId ?? session.acpSessionId ?? session.localSessionId}`);
|
|
19
19
|
}
|
|
20
20
|
const chatId = baseContextKey.slice(CHAT_CONTEXT_PREFIX.length);
|
|
21
|
-
if (!chatId) throw new Error(
|
|
21
|
+
if (!chatId) throw new Error(`The task has an invalid Lark chat ID: ${contextKey}`);
|
|
22
22
|
const threadId = isThreadContextKey(contextKey)
|
|
23
23
|
? contextKey.slice(contextKey.indexOf(THREAD_CONTEXT_MARKER) + THREAD_CONTEXT_MARKER.length)
|
|
24
24
|
: undefined;
|