@keyou007/agent-bot 0.1.14-alpha.1 → 0.1.14-alpha.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/README.md +42 -12
  3. package/README.zh.md +42 -12
  4. package/config.example.yaml +1 -1
  5. package/dist/cli/AutostartManager.js +431 -0
  6. package/dist/cli/AutostartManager.js.map +1 -0
  7. package/dist/cli/FeishuAppConfiguration.js +17 -13
  8. package/dist/cli/FeishuAppConfiguration.js.map +1 -1
  9. package/dist/cli/Initializer.js +35 -0
  10. package/dist/cli/Initializer.js.map +1 -1
  11. package/dist/cli/SelfUpdateRunner.js +552 -0
  12. package/dist/cli/SelfUpdateRunner.js.map +1 -0
  13. package/dist/cli/SelfUpdater.js +431 -0
  14. package/dist/cli/SelfUpdater.js.map +1 -0
  15. package/dist/cli/autostartOutput.js +63 -0
  16. package/dist/cli/autostartOutput.js.map +1 -0
  17. package/dist/cli/controlProtocol.js.map +1 -1
  18. package/dist/cli/help.js +92 -18
  19. package/dist/cli/help.js.map +1 -1
  20. package/dist/cli/taskGroupOptions.js +14 -11
  21. package/dist/cli/taskGroupOptions.js.map +1 -1
  22. package/dist/cli/taskListOutput.js +3 -0
  23. package/dist/cli/taskListOutput.js.map +1 -1
  24. package/dist/cli/taskTarget.js +99 -0
  25. package/dist/cli/taskTarget.js.map +1 -0
  26. package/dist/cli.js +643 -58
  27. package/dist/cli.js.map +1 -1
  28. package/dist/codex/CodexRuntime.js +8 -2
  29. package/dist/codex/CodexRuntime.js.map +1 -1
  30. package/dist/commands/CommandRouter.js +7 -1
  31. package/dist/commands/CommandRouter.js.map +1 -1
  32. package/dist/feishu/CardRenderer.js +172 -23
  33. package/dist/feishu/CardRenderer.js.map +1 -1
  34. package/dist/feishu/FeishuMarkdown.js +25 -1
  35. package/dist/feishu/FeishuMarkdown.js.map +1 -1
  36. package/dist/index.js +134 -2
  37. package/dist/index.js.map +1 -1
  38. package/dist/proxy/ProxySessionController.js +436 -12
  39. package/dist/proxy/ProxySessionController.js.map +1 -1
  40. package/dist/state/StateStore.js +18 -0
  41. package/dist/state/StateStore.js.map +1 -1
  42. package/docs/technical-reference.md +17 -7
  43. package/docs/technical-reference.zh.md +17 -7
  44. package/npm-shrinkwrap.json +2 -2
  45. package/package.json +2 -2
  46. package/skills/agent-bot/SKILL.md +107 -188
  47. package/src/cli/AutostartManager.ts +579 -0
  48. package/src/cli/FeishuAppConfiguration.ts +22 -7
  49. package/src/cli/Initializer.ts +57 -0
  50. package/src/cli/SelfUpdateRunner.ts +817 -0
  51. package/src/cli/SelfUpdater.ts +688 -0
  52. package/src/cli/autostartOutput.ts +75 -0
  53. package/src/cli/controlProtocol.ts +111 -1
  54. package/src/cli/help.ts +92 -18
  55. package/src/cli/taskGroupOptions.ts +27 -17
  56. package/src/cli/taskListOutput.ts +10 -0
  57. package/src/cli/taskTarget.ts +168 -0
  58. package/src/cli.ts +781 -65
  59. package/src/codex/CodexRuntime.ts +8 -2
  60. package/src/commands/CommandRouter.ts +6 -1
  61. package/src/commands/commandTypes.ts +1 -0
  62. package/src/feishu/CardRenderer.ts +199 -23
  63. package/src/feishu/FeishuMarkdown.ts +27 -1
  64. package/src/index.ts +172 -2
  65. package/src/proxy/ProxySessionController.ts +532 -15
  66. package/src/runtime/types.ts +1 -0
  67. package/src/state/StateStore.ts +19 -0
@@ -0,0 +1,75 @@
1
+ import type { AutostartRegistrationStatus } from "./AutostartManager.js";
2
+ import { cliLanguage, cliText, type CliLanguage } from "./i18n.js";
3
+
4
+ export interface AutostartServerStatus {
5
+ running: boolean;
6
+ ready: boolean;
7
+ }
8
+
9
+ export interface CombinedAutostartStatus {
10
+ registration: AutostartRegistrationStatus;
11
+ server: AutostartServerStatus;
12
+ }
13
+
14
+ export function formatAutostartStatus(
15
+ status: CombinedAutostartStatus,
16
+ language: CliLanguage = cliLanguage,
17
+ ): string {
18
+ const registration = status.registration;
19
+ const enabled = registration.supported
20
+ ? registration.enabled
21
+ ? cliText("enabled", "已启用", language)
22
+ : cliText("disabled", "未启用", language)
23
+ : cliText("unsupported", "不支持", language);
24
+ const server = !status.server.running
25
+ ? cliText("not running", "未运行", language)
26
+ : status.server.ready
27
+ ? cliText("running", "运行中", language)
28
+ : cliText("starting", "启动中", language);
29
+ const lines = [
30
+ `${cliText("Agent Bot autostart: ", "Agent Bot 自启动:", language)}${enabled}`,
31
+ `${cliText("Platform: ", "平台:", language)}${platformLabel(registration.platform, language)}`,
32
+ `${cliText("Profile: ", "Profile:", language)}${registration.profilePath}`,
33
+ `${cliText("Config: ", "配置:", language)}${registration.configPath}`,
34
+ ];
35
+ if (registration.name) {
36
+ lines.push(`${cliText("Registration: ", "启动项:", language)}${registration.name}`);
37
+ }
38
+ if (registration.definitionPath) {
39
+ lines.push(`${cliText("Definition: ", "定义文件:", language)}${registration.definitionPath}`);
40
+ }
41
+ if (registration.mechanism) {
42
+ const mechanism = registration.mechanism === "task-scheduler"
43
+ ? "Task Scheduler"
44
+ : registration.mechanism === "startup-folder"
45
+ ? cliText("Startup folder", "启动文件夹", language)
46
+ : registration.mechanism === "launch-agent"
47
+ ? "LaunchAgent"
48
+ : "systemd";
49
+ lines.push(`${cliText("Mechanism: ", "启动机制:", language)}${mechanism}`);
50
+ }
51
+ if (registration.trigger) {
52
+ lines.push(`${cliText("Trigger: ", "触发方式:", language)}${registration.trigger === "boot"
53
+ ? cliText("system boot (systemd linger enabled)", "系统启动(已启用 systemd linger)", language)
54
+ : cliText("user login", "用户登录", language)}`);
55
+ }
56
+ if (registration.loaded !== undefined) {
57
+ lines.push(`${cliText("Loaded by OS: ", "操作系统已加载:", language)}${registration.loaded
58
+ ? cliText("yes", "是", language)
59
+ : cliText("no", "否", language)}`);
60
+ }
61
+ if (registration.platform === "linux") {
62
+ lines.push(`${cliText("Systemd linger: ", "Systemd linger:", language)}${registration.linger
63
+ ? cliText("enabled", "已启用", language)
64
+ : cliText("disabled", "未启用", language)}`);
65
+ }
66
+ lines.push(`${cliText("Agent Bot server: ", "Agent Bot 服务:", language)}${server}`, "");
67
+ return lines.join("\n");
68
+ }
69
+
70
+ function platformLabel(platform: NodeJS.Platform, language: CliLanguage): string {
71
+ if (platform === "win32") return "Windows";
72
+ if (platform === "darwin") return "macOS";
73
+ if (platform === "linux") return "Linux";
74
+ return cliText(`${platform} (unsupported)`, `${platform}(不支持)`, language);
75
+ }
@@ -1,8 +1,16 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import type { TurnViewState } from "../presentation/turnViewTypes.js";
4
- import type { RemoteSessionSummary } from "../runtime/types.js";
4
+ import type {
5
+ ModelOption,
6
+ ModelProviderOption,
7
+ PermissionMode,
8
+ ReasoningEffortOption,
9
+ RemoteSessionSummary,
10
+ RuntimeGoal,
11
+ } from "../runtime/types.js";
5
12
  import type { SessionRecord } from "../state/StateStore.js";
13
+ import type { ShellCommandResult } from "../utils/executeShellCommand.js";
6
14
 
7
15
  export type ControlRequest =
8
16
  | { action: "health" }
@@ -12,11 +20,53 @@ export type ControlRequest =
12
20
  reason: string;
13
21
  notificationSessionId?: string;
14
22
  }
23
+ | {
24
+ action: "server_update";
25
+ planPath: string;
26
+ reason: string;
27
+ notificationSessionId?: string;
28
+ }
15
29
  | { action: "server_stop" }
16
30
  | { action: "task_status"; localSessionId: string }
17
31
  | { action: "task_stop"; localSessionId: string }
32
+ | { action: "task_archive"; localSessionId: string }
18
33
  | { action: "task_title"; localSessionId: string; title: string }
19
34
  | { action: "task_prompt"; localSessionId: string; text: string }
35
+ | {
36
+ action: "task_new";
37
+ localSessionId: string;
38
+ title?: string;
39
+ cwd?: string;
40
+ agentName?: string;
41
+ projectless?: boolean;
42
+ }
43
+ | { action: "task_fork"; localSessionId: string }
44
+ | {
45
+ action: "task_switch";
46
+ localSessionId: string;
47
+ targetLocalSessionId?: string;
48
+ previous?: boolean;
49
+ }
50
+ | { action: "task_queue"; localSessionId: string; text: string }
51
+ | { action: "task_agent"; localSessionId: string; agentName?: string }
52
+ | {
53
+ action: "task_settings";
54
+ localSessionId: string;
55
+ setting?: "provider" | "model" | "thinking" | "permissions";
56
+ value?: string;
57
+ }
58
+ | {
59
+ action: "task_goal";
60
+ localSessionId: string;
61
+ goalAction: "show" | "set" | "edit" | "pause" | "resume" | "clear";
62
+ objective?: string;
63
+ }
64
+ | { action: "task_turns"; localSessionId: string }
65
+ | { action: "task_reset"; localSessionId: string; turnId: string }
66
+ | { action: "task_mute"; localSessionId: string; enabled?: boolean }
67
+ | { action: "task_shell"; localSessionId: string; command: string }
68
+ | { action: "task_directory"; localSessionId: string; directory?: string; page?: number }
69
+ | { action: "task_send_file"; localSessionId: string; filePath: string }
20
70
  | {
21
71
  action: "task_new_group";
22
72
  localSessionId: string;
@@ -50,6 +100,66 @@ export interface TaskGroupControlData {
50
100
  task: SessionRecord;
51
101
  }
52
102
 
103
+ export interface TaskForkControlData {
104
+ sourceLocalSessionId: string;
105
+ sourceTurnId: string;
106
+ task: SessionRecord;
107
+ }
108
+
109
+ export interface TaskAgentControlData {
110
+ current: string;
111
+ agents: Array<{ name: string; title: string }>;
112
+ }
113
+
114
+ export interface TaskSettingsControlData {
115
+ session: SessionRecord;
116
+ providers: ModelProviderOption[];
117
+ models: ModelOption[];
118
+ reasoningOptions: ReasoningEffortOption[];
119
+ permissionModes: PermissionMode[];
120
+ }
121
+
122
+ export interface TaskGoalControlData {
123
+ goal?: RuntimeGoal;
124
+ cleared?: boolean;
125
+ }
126
+
127
+ export interface TaskTurnControlEntry {
128
+ sequence: number;
129
+ turnId: string;
130
+ parentTurnId?: string;
131
+ prompt?: string;
132
+ startedAt?: number;
133
+ completedAt?: number;
134
+ current: boolean;
135
+ }
136
+
137
+ export interface TaskTurnsControlData {
138
+ session: SessionRecord;
139
+ turns: TaskTurnControlEntry[];
140
+ }
141
+
142
+ export interface TaskMuteControlData {
143
+ contextKey: string;
144
+ enabled: boolean;
145
+ }
146
+
147
+ export type TaskDirectoryEntryKind = "directory" | "image" | "binary" | "file" | "drive";
148
+
149
+ export interface TaskDirectoryControlData {
150
+ directory: string;
151
+ parentDirectory?: string;
152
+ page: number;
153
+ totalPages: number;
154
+ totalEntries: number;
155
+ entries: Array<{ name: string; path: string; kind: TaskDirectoryEntryKind }>;
156
+ }
157
+
158
+ export interface TaskShellControlData extends ShellCommandResult {
159
+ cwd: string;
160
+ command: string;
161
+ }
162
+
53
163
  export function controlEndpoint(sqlitePath: string): string {
54
164
  const resolvedPath = path.resolve(sqlitePath);
55
165
  const key = createHash("sha256").update(resolvedPath.toLowerCase()).digest("hex").slice(0, 16);
package/src/cli/help.ts CHANGED
@@ -11,23 +11,45 @@ export function renderCliHelp(version: string, language: CliLanguage = cliLangua
11
11
  常用命令:
12
12
  init 检查并配置 Agent,初始化飞书应用和服务
13
13
  init --reset 重置并重新配置显式指定的 Profile
14
+ update 安全更新 npm 安装的 Agent Bot
14
15
  console 打开本地控制台
15
16
  server start 在后台启动 Agent Bot
16
17
  server status 显示服务、飞书 App ID、Agent 进程和安全重启状态
18
+ server autostart <操作> 管理当前 Profile 的系统自启动
17
19
  server restart [--task <任务>] 安排安全重启并将状态发回指定任务会话
18
20
  server stop 停止 Agent Bot
19
- task list 列出任务
20
- task current [--json] 显示当前调用任务的详情
21
- task status <任务> 显示任务状态
22
- task chat <任务> 显示任务绑定的飞书会话
23
- task prompt <任务> <提示词> 向任务发送提示词
24
- task newgroup <任务> [标题] 创建新群;支持 --agent、--dir、--nodir
25
- task forkgroup <任务> [标题] 从任务 Fork 新群
26
- task stop <任务> 停止任务
27
- task title <任务> <标题> 重命名任务
28
21
  skills status 显示内置 Skill 状态
29
22
  skills install 安装内置 Skill
30
23
 
24
+ 任务命令:
25
+ task list 列出任务;支持 --search,sessions 是别名
26
+ task current [--json] 显示当前调用任务的详情
27
+ task status|chat [任务] 显示任务状态或绑定的飞书会话
28
+ task prompt [任务] <提示词> 向任务发送提示词;send 是别名
29
+ task new [任务] [标题] 在同一会话新建任务;支持 --agent、--dir、--nodir
30
+ task newgroup [任务] [标题] 创建新群;支持 --agent、--dir、--nodir
31
+ task fork [任务] 从任务最近完成的 Turn 创建分支
32
+ task forkgroup [任务] [标题] 从任务 Fork 新群
33
+ task switch [任务] [目标任务] 切换会话任务;--previous 切回上一任务
34
+ task queue [任务] <提示词> 将提示词排队;nosteer 是别名
35
+ task agent [任务] [名称] 查看或设置该会话的新任务默认 Agent
36
+ task provider|model [任务] [值] 查看选项或设置 Provider、模型
37
+ task thinking [任务] [强度] 查看或设置思考强度
38
+ task permissions [任务] [模式] 查看或设置权限模式:auto、confirm
39
+ task goal [任务] [操作或目标] 查看、设置、修改、暂停、恢复或清除 Goal
40
+ task turns [任务] 列出已完成的历史 Turn
41
+ task reset [任务] <Turn ID> 将对话上下文 Reset 到指定 Turn
42
+ task mute [任务] [on|off] 设置群聊仅 @ 响应模式;不传值等同于 on
43
+ task dir [任务] [目录] 浏览任务目录;支持 --page、--json
44
+ task file [任务] <路径> 将文件发送到任务绑定的飞书会话
45
+ task shell [任务] <命令> 在任务目录执行本地命令
46
+ task stop [任务] 停止任务
47
+ task archive [任务] 归档任务
48
+ task title [任务] <标题> 重命名任务
49
+ task restart [任务] [--force] 从任务会话请求安全或立即重启
50
+
51
+ 在 Agent Bot 启动的 Agent 中可省略任务,CLI 会自动使用当前任务;--task <任务> 可显式覆盖。
52
+
31
53
  选项:
32
54
  --profile <目录> 使用独立的 Profile 目录
33
55
  --config <路径> 使用指定的配置文件
@@ -40,17 +62,32 @@ export function renderCliHelp(version: string, language: CliLanguage = cliLangua
40
62
  --skip-feishu 仅初始化 Console 环境
41
63
  --reconfigure-feishu 仅替换现有飞书凭据
42
64
 
65
+ 更新选项:
66
+ --alpha 更新到 Alpha 通道
67
+ --stable 更新到稳定通道
68
+ --version <版本> 更新到指定版本
69
+ --task <任务> 将更新和重启状态发回任务所在会话
70
+ --allow-downgrade 明确允许安装较旧版本
71
+
43
72
  重启选项:
44
73
  --task <任务> 将安全重启状态发回任务所在会话
45
74
  --reason <原因> 设置重启原因
46
75
  --immediate 立即重启,可能中断任务
47
76
 
77
+ 自启动操作:
78
+ server autostart enable 在用户登录时自动启动当前 Profile
79
+ server autostart enable --linger Linux:系统启动时自动启动,无需登录
80
+ server autostart status 显示系统启动项及服务运行状态
81
+ server autostart disable 移除启动项,不停止当前服务
82
+
48
83
  示例:
49
84
  agentbot init
85
+ agentbot update
50
86
  agentbot --profile ~/.agent-bot init --reset
51
87
  agentbot --profile ~/.agent-bot-rescue init
52
88
  agentbot server start
53
89
  agentbot server status
90
+ agentbot server autostart enable
54
91
  agentbot task list
55
92
  agentbot server restart --reason "更新 Agent Bot"
56
93
  `;
@@ -65,23 +102,45 @@ Usage:
65
102
  Common commands:
66
103
  init Check and configure Agents; initialize the Lark app and service
67
104
  init --reset Reset and reconfigure an explicit profile
105
+ update Safely update an npm-installed Agent Bot
68
106
  console Open the local console
69
107
  server start Start Agent Bot in the background
70
108
  server status Show the server, Lark App ID, Agent processes, and safe-restart status
109
+ server autostart <action> Manage OS autostart for the selected Profile
71
110
  server restart [--task <task>] Schedule a safe restart and return status to the task's conversation
72
111
  server stop Stop Agent Bot
73
- task list List tasks
74
- task current [--json] Show details for the task invoking the CLI
75
- task status <task> Show task status
76
- task chat <task> Show the task's Lark chat binding
77
- task prompt <task> <prompt> Send a Prompt to a task
78
- task newgroup <task> [title] Create a group; supports --agent, --dir, --nodir
79
- task forkgroup <task> [title] Fork a task into a new group
80
- task stop <task> Stop a task
81
- task title <task> <title> Rename a task
82
112
  skills status Show the built-in Skill status
83
113
  skills install Install the built-in Skill
84
114
 
115
+ Task commands:
116
+ task list List tasks; supports --search; sessions is an alias
117
+ task current [--json] Show details for the task invoking the CLI
118
+ task status|chat [task] Show task status or its Lark chat binding
119
+ task prompt [task] <prompt> Send a Prompt to a task; send is an alias
120
+ task new [task] [title] Create a task in the same conversation; supports --agent, --dir, --nodir
121
+ task newgroup [task] [title] Create a group; supports --agent, --dir, --nodir
122
+ task fork [task] Fork the task's latest completed Turn
123
+ task forkgroup [task] [title] Fork a task into a new group
124
+ task switch [task] [target] Switch the conversation task; --previous selects the prior task
125
+ task queue [task] <prompt> Queue a Prompt; nosteer is an alias
126
+ task agent [task] [name] Show or set the conversation's default Agent for new tasks
127
+ task provider|model [task] [value] Show choices or set the Provider or model
128
+ task thinking [task] [effort] Show or set reasoning effort
129
+ task permissions [task] [mode] Show or set permission mode: auto or confirm
130
+ task goal [task] [action|goal] Show, set, edit, pause, resume, or clear a Goal
131
+ task turns [task] List completed historical Turns
132
+ task reset [task] <Turn ID> Reset conversation context to a Turn
133
+ task mute [task] [on|off] Set group mention-only mode; omitted means on
134
+ task dir [task] [directory] Browse task files; supports --page and --json
135
+ task file [task] <path> Send a file to the task's Lark conversation
136
+ task shell [task] <command> Run a local command in the task directory
137
+ task stop [task] Stop a task
138
+ task archive [task] Archive a task
139
+ task title [task] <title> Rename a task
140
+ task restart [task] [--force] Request a safe or immediate restart from a task
141
+
142
+ Inside an Agent started by Agent Bot, omit task to use the current task; --task <task> overrides it.
143
+
85
144
  Options:
86
145
  --profile <directory> Use an isolated profile directory
87
146
  --config <path> Use a specific config file
@@ -94,17 +153,32 @@ Init options:
94
153
  --skip-feishu Initialize for Console only
95
154
  --reconfigure-feishu Replace only the existing Lark credentials
96
155
 
156
+ Update options:
157
+ --alpha Update from the Alpha channel
158
+ --stable Update from the stable channel
159
+ --version <version> Update to an exact version
160
+ --task <task> Return update and restart status to the task's conversation
161
+ --allow-downgrade Explicitly allow an older version
162
+
97
163
  Restart options:
98
164
  --task <task> Return safe-restart status to the task's conversation
99
165
  --reason <reason> Set the restart reason
100
166
  --immediate Restart immediately and possibly interrupt tasks
101
167
 
168
+ Autostart actions:
169
+ server autostart enable Start this Profile automatically at user login
170
+ server autostart enable --linger Linux: start at system boot without a login
171
+ server autostart status Show OS registration and live server state
172
+ server autostart disable Remove registration without stopping the current server
173
+
102
174
  Examples:
103
175
  agentbot init
176
+ agentbot update
104
177
  agentbot --profile ~/.agent-bot init --reset
105
178
  agentbot --profile ~/.agent-bot-rescue init
106
179
  agentbot server start
107
180
  agentbot server status
181
+ agentbot server autostart enable
108
182
  agentbot task list
109
183
  agentbot server restart --reason "Update Agent Bot"
110
184
  `;
@@ -9,6 +9,8 @@ export interface TaskNewGroupOptions {
9
9
  json: boolean;
10
10
  }
11
11
 
12
+ export type TaskNewOptions = TaskNewGroupOptions;
13
+
12
14
  export interface TaskForkGroupOptions {
13
15
  reference: string;
14
16
  title?: string;
@@ -19,6 +21,14 @@ export function parseTaskNewGroupOptions(
19
21
  input: string[],
20
22
  language: CliLanguage = cliLanguage,
21
23
  ): TaskNewGroupOptions {
24
+ return parseTaskNewOptions(input, "newgroup", language);
25
+ }
26
+
27
+ export function parseTaskNewOptions(
28
+ input: string[],
29
+ action: "new" | "newgroup" = "new",
30
+ language: CliLanguage = cliLanguage,
31
+ ): TaskNewOptions {
22
32
  const positionals: string[] = [];
23
33
  let cwd: string | undefined;
24
34
  let agentName: string | undefined;
@@ -31,19 +41,19 @@ export function parseTaskNewGroupOptions(
31
41
  continue;
32
42
  }
33
43
  if (argument === "--nodir") {
34
- if (projectless) throw optionError("newgroup", "--nodir", language);
35
- if (cwd !== undefined) throw conflictingProjectOptions(language);
44
+ if (projectless) throw optionError(action, "--nodir", language);
45
+ if (cwd !== undefined) throw conflictingProjectOptions(action, language);
36
46
  projectless = true;
37
47
  continue;
38
48
  }
39
49
  if (argument === "--dir") {
40
- if (projectless) throw conflictingProjectOptions(language);
41
- if (cwd !== undefined) throw optionError("newgroup", "--dir", language);
50
+ if (projectless) throw conflictingProjectOptions(action, language);
51
+ if (cwd !== undefined) throw optionError(action, "--dir", language);
42
52
  const directory = input[index + 1];
43
53
  if (!directory || directory.startsWith("--")) {
44
54
  throw new Error(cliText(
45
- "task newgroup requires a project directory after --dir.",
46
- "task newgroup 需要在 --dir 后指定项目目录。",
55
+ `task ${action} requires a project directory after --dir.`,
56
+ `task ${action} 需要在 --dir 后指定项目目录。`,
47
57
  language,
48
58
  ));
49
59
  }
@@ -52,12 +62,12 @@ export function parseTaskNewGroupOptions(
52
62
  continue;
53
63
  }
54
64
  if (argument === "--agent") {
55
- if (agentName !== undefined) throw optionError("newgroup", "--agent", language);
65
+ if (agentName !== undefined) throw optionError(action, "--agent", language);
56
66
  const name = input[index + 1];
57
67
  if (!name?.trim() || name.startsWith("--")) {
58
68
  throw new Error(cliText(
59
- "task newgroup requires an Agent standard name after --agent.",
60
- "task newgroup 需要在 --agent 后指定 Agent 标准名。",
69
+ `task ${action} requires an Agent standard name after --agent.`,
70
+ `task ${action} 需要在 --agent 后指定 Agent 标准名。`,
61
71
  language,
62
72
  ));
63
73
  }
@@ -65,11 +75,11 @@ export function parseTaskNewGroupOptions(
65
75
  index += 1;
66
76
  continue;
67
77
  }
68
- if (argument.startsWith("--")) throw unsupportedOption("newgroup", argument, language);
78
+ if (argument.startsWith("--")) throw unsupportedOption(action, argument, language);
69
79
  positionals.push(argument);
70
80
  }
71
81
  const [reference, ...titleParts] = positionals;
72
- requireTaskReference("newgroup", reference, language);
82
+ requireTaskReference(action, reference, language);
73
83
  return {
74
84
  reference,
75
85
  title: titleParts.join(" ").trim() || undefined,
@@ -104,7 +114,7 @@ export function parseTaskForkGroupOptions(
104
114
  }
105
115
 
106
116
  function requireTaskReference(
107
- action: "newgroup" | "forkgroup",
117
+ action: "new" | "newgroup" | "forkgroup",
108
118
  reference: string | undefined,
109
119
  language: CliLanguage,
110
120
  ): asserts reference is string {
@@ -117,7 +127,7 @@ function requireTaskReference(
117
127
  }
118
128
 
119
129
  function optionError(
120
- action: "newgroup",
130
+ action: "new" | "newgroup",
121
131
  option: "--agent" | "--dir" | "--nodir",
122
132
  language: CliLanguage,
123
133
  ): Error {
@@ -128,16 +138,16 @@ function optionError(
128
138
  ));
129
139
  }
130
140
 
131
- function conflictingProjectOptions(language: CliLanguage): Error {
141
+ function conflictingProjectOptions(action: "new" | "newgroup", language: CliLanguage): Error {
132
142
  return new Error(cliText(
133
- "task newgroup cannot combine --dir and --nodir.",
134
- "task newgroup 的 --dir 和 --nodir 不能同时使用。",
143
+ `task ${action} cannot combine --dir and --nodir.`,
144
+ `task ${action} 的 --dir 和 --nodir 不能同时使用。`,
135
145
  language,
136
146
  ));
137
147
  }
138
148
 
139
149
  function unsupportedOption(
140
- action: "newgroup" | "forkgroup",
150
+ action: "new" | "newgroup" | "forkgroup",
141
151
  option: string,
142
152
  language: CliLanguage,
143
153
  ): Error {
@@ -37,6 +37,16 @@ export function currentAppServerThreadIds(env: NodeJS.ProcessEnv): string[] {
37
37
  ].filter((value): value is string => Boolean(value)))];
38
38
  }
39
39
 
40
+ export function taskCurrentExternalInvocationMessage(
41
+ language: CliLanguage = cliLanguage,
42
+ ): string {
43
+ return cliText(
44
+ "agentbot task current is designed for an Agent running inside Agent Bot. A regular terminal has no current Agent task. Use agentbot task list to find a task, then run agentbot task status <task>.",
45
+ "agentbot task current 是为 Agent Bot 中运行的 Agent 调用设计的。普通终端没有可自动识别的当前 Agent 任务;请先使用 agentbot task list 查找任务,再运行 agentbot task status <任务>。",
46
+ language,
47
+ );
48
+ }
49
+
40
50
  export function resolveCurrentTask(
41
51
  sessions: SessionRecord[],
42
52
  currentThreadIds: readonly string[],