@keyou007/agent-bot 0.1.15-alpha.4 → 0.1.15-alpha.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +7 -2
  3. package/README.zh.md +7 -2
  4. package/config.example.yaml +6 -0
  5. package/dist/commands/CommandRouter.js +7 -0
  6. package/dist/commands/CommandRouter.js.map +1 -1
  7. package/dist/config/loadConfig.js +4 -0
  8. package/dist/config/loadConfig.js.map +1 -1
  9. package/dist/config/schema.js +31 -0
  10. package/dist/config/schema.js.map +1 -1
  11. package/dist/feishu/CardRenderer.js +76 -9
  12. package/dist/feishu/CardRenderer.js.map +1 -1
  13. package/dist/feishu/FinalResponseBranding.js +1 -1
  14. package/dist/feishu/FinalResponseBranding.js.map +1 -1
  15. package/dist/feishu/GroupNameFormatter.js +193 -0
  16. package/dist/feishu/GroupNameFormatter.js.map +1 -0
  17. package/dist/proxy/ProxySessionController.js +197 -148
  18. package/dist/proxy/ProxySessionController.js.map +1 -1
  19. package/dist/shell/ShellCommandJobManager.js +264 -0
  20. package/dist/shell/ShellCommandJobManager.js.map +1 -0
  21. package/dist/shell/shellCommandRunner.js +157 -0
  22. package/dist/shell/shellCommandRunner.js.map +1 -0
  23. package/dist/utils/executeShellCommand.js +1 -1
  24. package/dist/utils/executeShellCommand.js.map +1 -1
  25. package/docs/technical-reference.md +19 -0
  26. package/docs/technical-reference.zh.md +19 -0
  27. package/npm-shrinkwrap.json +2 -2
  28. package/package.json +1 -1
  29. package/src/commands/CommandRouter.ts +6 -0
  30. package/src/commands/commandTypes.ts +1 -0
  31. package/src/config/loadConfig.ts +4 -0
  32. package/src/config/schema.ts +33 -0
  33. package/src/feishu/CardRenderer.ts +91 -17
  34. package/src/feishu/FinalResponseBranding.ts +2 -1
  35. package/src/feishu/GroupNameFormatter.ts +222 -0
  36. package/src/proxy/ProxySessionController.ts +238 -160
  37. package/src/shell/ShellCommandJobManager.ts +341 -0
  38. package/src/shell/shellCommandRunner.ts +163 -0
  39. package/src/utils/executeShellCommand.ts +1 -1
@@ -0,0 +1,264 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { spawn } from "node:child_process";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ const JOB_SPEC_FILE = "job.json";
7
+ const JOB_STATUS_FILE = "status.json";
8
+ const JOB_PRESENTATION_FILE = "presentation.json";
9
+ const CANCEL_REQUEST_FILE = "cancel.requested";
10
+ const OUTPUT_FILE = "output.log";
11
+ const LEGACY_STDOUT_FILE = "stdout.log";
12
+ const LEGACY_STDERR_FILE = "stderr.log";
13
+ const MAX_CAPTURED_OUTPUT_BYTES = 64 * 1024;
14
+ export class ShellCommandJobManager {
15
+ jobsRoot;
16
+ runnerEntry;
17
+ spawnRunner;
18
+ constructor(jobsRoot, options = {}) {
19
+ this.jobsRoot = jobsRoot;
20
+ this.runnerEntry = options.runnerEntry ?? resolveRunnerEntry();
21
+ this.spawnRunner = options.spawnRunner ?? launchDetachedRunner;
22
+ }
23
+ async createJob(input) {
24
+ const id = randomUUID();
25
+ const createdAt = Date.now();
26
+ const jobDirectory = this.jobDirectory(id);
27
+ const spec = { version: 1, id, createdAt, ...input };
28
+ const state = {
29
+ status: "starting",
30
+ startedAt: createdAt,
31
+ updatedAt: createdAt,
32
+ };
33
+ await fs.mkdir(jobDirectory, { recursive: true });
34
+ await Promise.all([
35
+ writeJsonAtomic(path.join(jobDirectory, JOB_SPEC_FILE), spec),
36
+ writeJsonAtomic(path.join(jobDirectory, JOB_STATUS_FILE), state),
37
+ fs.writeFile(path.join(jobDirectory, OUTPUT_FILE), "", { flag: "wx" }),
38
+ ]);
39
+ return { ...spec, ...state, output: "", outputTruncated: false };
40
+ }
41
+ async bindCard(jobId, cardMessageId) {
42
+ const jobDirectory = this.jobDirectory(jobId);
43
+ const spec = await readJson(path.join(jobDirectory, JOB_SPEC_FILE));
44
+ await writeJsonAtomic(path.join(jobDirectory, JOB_SPEC_FILE), { ...spec, cardMessageId });
45
+ return this.readJob(jobId);
46
+ }
47
+ async startJob(jobId) {
48
+ const jobDirectory = this.jobDirectory(jobId);
49
+ await this.spawnRunner(this.runnerEntry, jobDirectory);
50
+ }
51
+ async failJob(jobId, error) {
52
+ const jobDirectory = this.jobDirectory(jobId);
53
+ const state = await readJson(path.join(jobDirectory, JOB_STATUS_FILE));
54
+ const now = Date.now();
55
+ await writeJsonAtomic(path.join(jobDirectory, JOB_STATUS_FILE), {
56
+ ...state,
57
+ status: "failed",
58
+ updatedAt: now,
59
+ completedAt: now,
60
+ exitCode: null,
61
+ error,
62
+ });
63
+ }
64
+ async readJob(jobId) {
65
+ const jobDirectory = this.jobDirectory(jobId);
66
+ const [spec, savedState, cancellationRequested, output] = await Promise.all([
67
+ readJson(path.join(jobDirectory, JOB_SPEC_FILE)),
68
+ readJson(path.join(jobDirectory, JOB_STATUS_FILE)),
69
+ fileExists(path.join(jobDirectory, CANCEL_REQUEST_FILE)),
70
+ readJobOutput(jobDirectory),
71
+ ]);
72
+ const state = await reconcileExitedRunner(jobDirectory, savedState);
73
+ const status = cancellationRequested && (state.status === "starting" || state.status === "running")
74
+ ? "cancelling"
75
+ : state.status;
76
+ return { ...spec, ...state, ...output, status };
77
+ }
78
+ async listRecoverableJobs() {
79
+ const entries = await fs.readdir(this.jobsRoot, { withFileTypes: true }).catch((error) => {
80
+ if (error.code === "ENOENT")
81
+ return [];
82
+ throw error;
83
+ });
84
+ const jobs = [];
85
+ for (const entry of entries) {
86
+ if (!entry.isDirectory())
87
+ continue;
88
+ try {
89
+ const job = await this.readJob(entry.name);
90
+ const presented = await fileExists(path.join(this.jobDirectory(job.id), JOB_PRESENTATION_FILE));
91
+ if (!presented || isActiveShellCommandJob(job.status))
92
+ jobs.push(job);
93
+ }
94
+ catch {
95
+ // A partially written or unrelated directory is not a recoverable command job.
96
+ }
97
+ }
98
+ return jobs.sort((left, right) => left.createdAt - right.createdAt);
99
+ }
100
+ async requestCancellation(jobId) {
101
+ const job = await this.readJob(jobId);
102
+ if (!isActiveShellCommandJob(job.status))
103
+ return false;
104
+ await fs.writeFile(path.join(this.jobDirectory(jobId), CANCEL_REQUEST_FILE), `${Date.now()}\n`);
105
+ return true;
106
+ }
107
+ async markPresented(jobId) {
108
+ await writeJsonAtomic(path.join(this.jobDirectory(jobId), JOB_PRESENTATION_FILE), { presentedAt: Date.now() });
109
+ }
110
+ jobDirectory(jobId) {
111
+ if (!/^[0-9a-f-]{36}$/iu.test(jobId))
112
+ throw new Error("Invalid shell command job ID.");
113
+ return path.join(this.jobsRoot, jobId);
114
+ }
115
+ }
116
+ export function isActiveShellCommandJob(status) {
117
+ return status === "starting" || status === "running" || status === "cancelling";
118
+ }
119
+ function resolveRunnerEntry() {
120
+ const builtEntry = fileURLToPath(new URL("./shellCommandRunner.js", import.meta.url));
121
+ const sourceEntry = fileURLToPath(new URL("./shellCommandRunner.ts", import.meta.url));
122
+ return fileURLToPath(import.meta.url).endsWith(".ts") ? sourceEntry : builtEntry;
123
+ }
124
+ async function launchDetachedRunner(entry, jobDirectory) {
125
+ const runnerArgs = entry.endsWith(".ts")
126
+ ? [...process.execArgv, entry, jobDirectory]
127
+ : [entry, jobDirectory];
128
+ const child = spawn(process.execPath, runnerArgs, {
129
+ cwd: jobDirectory,
130
+ detached: true,
131
+ env: process.env,
132
+ stdio: "ignore",
133
+ windowsHide: true,
134
+ });
135
+ await waitForSpawn(child);
136
+ child.once("exit", (exitCode, signal) => {
137
+ void recordUnexpectedRunnerExit(jobDirectory, exitCode, signal);
138
+ });
139
+ child.unref();
140
+ }
141
+ async function recordUnexpectedRunnerExit(jobDirectory, exitCode, signal) {
142
+ try {
143
+ const statusPath = path.join(jobDirectory, JOB_STATUS_FILE);
144
+ const state = await readJson(statusPath);
145
+ if (state.status !== "starting" && state.status !== "running")
146
+ return;
147
+ const now = Date.now();
148
+ await writeJsonAtomic(statusPath, {
149
+ ...state,
150
+ status: "failed",
151
+ updatedAt: now,
152
+ completedAt: now,
153
+ exitCode,
154
+ error: `The background shell command runner exited unexpectedly${signal ? ` with ${signal}` : ""}.`,
155
+ });
156
+ }
157
+ catch {
158
+ // Startup recovery will retry a job whose runner exited before writing status.
159
+ }
160
+ }
161
+ function waitForSpawn(child) {
162
+ return new Promise((resolve, reject) => {
163
+ child.once("spawn", resolve);
164
+ child.once("error", reject);
165
+ });
166
+ }
167
+ async function readJobOutput(jobDirectory) {
168
+ const outputPath = path.join(jobDirectory, OUTPUT_FILE);
169
+ if (await fileExists(outputPath)) {
170
+ const output = await readBoundedFile(outputPath, MAX_CAPTURED_OUTPUT_BYTES);
171
+ return { output: output.value, outputTruncated: output.truncated };
172
+ }
173
+ const stdoutPath = path.join(jobDirectory, LEGACY_STDOUT_FILE);
174
+ const stderrPath = path.join(jobDirectory, LEGACY_STDERR_FILE);
175
+ const [stdoutSize, stderrSize] = await Promise.all([fileSize(stdoutPath), fileSize(stderrPath)]);
176
+ const totalSize = stdoutSize + stderrSize;
177
+ const stdoutLimit = totalSize <= MAX_CAPTURED_OUTPUT_BYTES
178
+ ? stdoutSize
179
+ : stderrSize === 0
180
+ ? MAX_CAPTURED_OUTPUT_BYTES
181
+ : Math.max(1_024, Math.floor(MAX_CAPTURED_OUTPUT_BYTES * (stdoutSize / totalSize)));
182
+ const stderrLimit = totalSize <= MAX_CAPTURED_OUTPUT_BYTES
183
+ ? stderrSize
184
+ : Math.max(1_024, MAX_CAPTURED_OUTPUT_BYTES - stdoutLimit);
185
+ const [stdout, stderr] = await Promise.all([
186
+ readBoundedFile(stdoutPath, stdoutLimit),
187
+ readBoundedFile(stderrPath, stderrLimit),
188
+ ]);
189
+ return {
190
+ output: `${stdout.value}${stderr.value}`,
191
+ outputTruncated: stdout.truncated || stderr.truncated,
192
+ };
193
+ }
194
+ async function reconcileExitedRunner(jobDirectory, state) {
195
+ if (state.status !== "running" || state.runnerPid === undefined || processIsAlive(state.runnerPid))
196
+ return state;
197
+ await new Promise((resolve) => setTimeout(resolve, 100));
198
+ const latest = await readJson(path.join(jobDirectory, JOB_STATUS_FILE));
199
+ if (latest.status !== "running" || latest.runnerPid !== state.runnerPid || processIsAlive(latest.runnerPid)) {
200
+ return latest;
201
+ }
202
+ const now = Date.now();
203
+ const failed = {
204
+ ...latest,
205
+ status: "failed",
206
+ updatedAt: now,
207
+ completedAt: now,
208
+ exitCode: null,
209
+ error: "The background shell command runner exited unexpectedly.",
210
+ };
211
+ await writeJsonAtomic(path.join(jobDirectory, JOB_STATUS_FILE), failed);
212
+ return failed;
213
+ }
214
+ function processIsAlive(pid) {
215
+ try {
216
+ process.kill(pid, 0);
217
+ return true;
218
+ }
219
+ catch (error) {
220
+ return typeof error === "object" && error !== null && "code" in error && error.code === "EPERM";
221
+ }
222
+ }
223
+ async function readBoundedFile(filePath, maxBytes) {
224
+ const size = await fileSize(filePath);
225
+ if (size === 0 || maxBytes <= 0)
226
+ return { value: "", truncated: size > 0 };
227
+ if (size <= maxBytes)
228
+ return { value: await fs.readFile(filePath, "utf8"), truncated: false };
229
+ const marker = Buffer.from("\n... output truncated ...\n", "utf8");
230
+ const headBytes = Math.max(0, Math.ceil(maxBytes / 3) - marker.length);
231
+ const tailBytes = Math.max(0, maxBytes - headBytes - marker.length);
232
+ const handle = await fs.open(filePath, "r");
233
+ try {
234
+ const head = Buffer.alloc(headBytes);
235
+ const tail = Buffer.alloc(tailBytes);
236
+ if (headBytes > 0)
237
+ await handle.read(head, 0, headBytes, 0);
238
+ if (tailBytes > 0)
239
+ await handle.read(tail, 0, tailBytes, size - tailBytes);
240
+ return { value: Buffer.concat([head, marker, tail]).toString("utf8"), truncated: true };
241
+ }
242
+ finally {
243
+ await handle.close();
244
+ }
245
+ }
246
+ async function fileSize(filePath) {
247
+ return fs.stat(filePath).then((stat) => stat.size).catch((error) => {
248
+ if (error.code === "ENOENT")
249
+ return 0;
250
+ throw error;
251
+ });
252
+ }
253
+ async function fileExists(filePath) {
254
+ return fs.access(filePath).then(() => true).catch(() => false);
255
+ }
256
+ async function readJson(filePath) {
257
+ return JSON.parse(await fs.readFile(filePath, "utf8"));
258
+ }
259
+ async function writeJsonAtomic(filePath, value) {
260
+ const temporary = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
261
+ await fs.writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`);
262
+ await fs.rename(temporary, filePath);
263
+ }
264
+ //# sourceMappingURL=ShellCommandJobManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShellCommandJobManager.js","sourceRoot":"","sources":["../../src/shell/ShellCommandJobManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ import { spawn } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { prepareShellCommand } from "../utils/executeShellCommand.js";
5
+ const MAX_LOG_BYTES = 8 * 1024 * 1024;
6
+ const RETAINED_LOG_HEAD_BYTES = 2 * 1024 * 1024;
7
+ const RETAINED_LOG_TAIL_BYTES = 4 * 1024 * 1024;
8
+ const LOG_TRUNCATION_MARKER = Buffer.from("\n... earlier output compacted ...\n", "utf8");
9
+ const CANCEL_POLL_INTERVAL_MS = 500;
10
+ const FORCE_KILL_DELAY_MS = 3_000;
11
+ class RotatingLogWriter {
12
+ filePath;
13
+ descriptor;
14
+ size;
15
+ constructor(filePath) {
16
+ this.filePath = filePath;
17
+ this.descriptor = fs.openSync(filePath, "a");
18
+ this.size = fs.fstatSync(this.descriptor).size;
19
+ }
20
+ append(chunk) {
21
+ if (chunk.length === 0)
22
+ return;
23
+ fs.writeSync(this.descriptor, chunk);
24
+ this.size += chunk.length;
25
+ if (this.size > MAX_LOG_BYTES)
26
+ this.compact();
27
+ }
28
+ close() {
29
+ fs.closeSync(this.descriptor);
30
+ }
31
+ compact() {
32
+ fs.closeSync(this.descriptor);
33
+ const current = fs.readFileSync(this.filePath);
34
+ const head = current.subarray(0, Math.min(RETAINED_LOG_HEAD_BYTES, current.length));
35
+ const tailStart = Math.max(head.length, current.length - RETAINED_LOG_TAIL_BYTES);
36
+ const tail = current.subarray(tailStart);
37
+ fs.writeFileSync(this.filePath, Buffer.concat([head, LOG_TRUNCATION_MARKER, tail]));
38
+ this.descriptor = fs.openSync(this.filePath, "a");
39
+ this.size = fs.fstatSync(this.descriptor).size;
40
+ }
41
+ }
42
+ const jobDirectory = path.resolve(process.argv[2] ?? "");
43
+ if (!process.argv[2])
44
+ throw new Error("A shell command job directory is required.");
45
+ const spec = readJson(path.join(jobDirectory, "job.json"));
46
+ const statusPath = path.join(jobDirectory, "status.json");
47
+ const cancelPath = path.join(jobDirectory, "cancel.requested");
48
+ const output = new RotatingLogWriter(path.join(jobDirectory, "output.log"));
49
+ const prepared = prepareShellCommand(spec.command, process.platform);
50
+ const child = spawn(prepared.command, prepared.args, {
51
+ cwd: spec.cwd,
52
+ detached: process.platform !== "win32",
53
+ env: process.env,
54
+ stdio: ["ignore", "pipe", "pipe"],
55
+ windowsHide: true,
56
+ });
57
+ let cancellationRequested = false;
58
+ let settled = false;
59
+ let forceKillTimer;
60
+ writeStatus({
61
+ status: "running",
62
+ startedAt: spec.createdAt,
63
+ updatedAt: Date.now(),
64
+ runnerPid: process.pid,
65
+ ...(child.pid ? { childPid: child.pid } : {}),
66
+ });
67
+ child.stdout.on("data", (chunk) => output.append(chunk));
68
+ child.stderr.on("data", (chunk) => output.append(chunk));
69
+ child.once("error", (error) => finish("failed", null, error.message));
70
+ child.once("close", (exitCode) => {
71
+ finish(cancellationRequested ? "cancelled" : exitCode === 0 ? "completed" : "failed", exitCode);
72
+ });
73
+ const cancelPoll = setInterval(() => {
74
+ if (settled || cancellationRequested || !fs.existsSync(cancelPath))
75
+ return;
76
+ cancellationRequested = true;
77
+ void terminateProcessTree(child.pid);
78
+ forceKillTimer = setTimeout(() => forceKillProcessTree(child.pid), FORCE_KILL_DELAY_MS);
79
+ forceKillTimer.unref?.();
80
+ }, CANCEL_POLL_INTERVAL_MS);
81
+ cancelPoll.unref?.();
82
+ process.on("SIGTERM", () => {
83
+ if (settled || cancellationRequested)
84
+ return;
85
+ cancellationRequested = true;
86
+ void terminateProcessTree(child.pid);
87
+ });
88
+ function finish(status, exitCode, error) {
89
+ if (settled)
90
+ return;
91
+ settled = true;
92
+ clearInterval(cancelPoll);
93
+ if (forceKillTimer)
94
+ clearTimeout(forceKillTimer);
95
+ output.close();
96
+ writeStatus({
97
+ status,
98
+ startedAt: spec.createdAt,
99
+ updatedAt: Date.now(),
100
+ runnerPid: process.pid,
101
+ ...(child.pid ? { childPid: child.pid } : {}),
102
+ completedAt: Date.now(),
103
+ exitCode,
104
+ ...(error ? { error } : {}),
105
+ });
106
+ process.exitCode = status === "completed" ? 0 : 1;
107
+ }
108
+ async function terminateProcessTree(pid) {
109
+ if (!pid)
110
+ return;
111
+ if (process.platform === "win32") {
112
+ await new Promise((resolve) => {
113
+ const killer = spawn("taskkill.exe", ["/PID", String(pid), "/T", "/F"], {
114
+ stdio: "ignore",
115
+ windowsHide: true,
116
+ });
117
+ killer.once("close", () => resolve());
118
+ killer.once("error", () => resolve());
119
+ });
120
+ return;
121
+ }
122
+ try {
123
+ process.kill(-pid, "SIGTERM");
124
+ }
125
+ catch {
126
+ try {
127
+ process.kill(pid, "SIGTERM");
128
+ }
129
+ catch {
130
+ // The command may already have exited.
131
+ }
132
+ }
133
+ }
134
+ function forceKillProcessTree(pid) {
135
+ if (!pid || process.platform === "win32")
136
+ return;
137
+ try {
138
+ process.kill(-pid, "SIGKILL");
139
+ }
140
+ catch {
141
+ try {
142
+ process.kill(pid, "SIGKILL");
143
+ }
144
+ catch {
145
+ // The command may already have exited.
146
+ }
147
+ }
148
+ }
149
+ function writeStatus(status) {
150
+ const temporary = `${statusPath}.${process.pid}.tmp`;
151
+ fs.writeFileSync(temporary, `${JSON.stringify(status, null, 2)}\n`);
152
+ fs.renameSync(temporary, statusPath);
153
+ }
154
+ function readJson(filePath) {
155
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
156
+ }
157
+ //# sourceMappingURL=shellCommandRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellCommandRunner.js","sourceRoot":"","sources":["../../src/shell/shellCommandRunner.ts"],"names":[],"mappings":"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"}
@@ -43,7 +43,7 @@ export function executeShellCommand(command, cwd, options = {}) {
43
43
  });
44
44
  });
45
45
  }
46
- function prepareShellCommand(command, platform) {
46
+ export function prepareShellCommand(command, platform) {
47
47
  if (platform !== "win32")
48
48
  return { command: "/bin/sh", args: ["-lc", command] };
49
49
  const script = `$ProgressPreference = 'SilentlyContinue'; [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new(); ${command}`;
@@ -1 +1 @@
1
- {"version":3,"file":"executeShellCommand.js","sourceRoot":"","sources":["../../src/utils/executeShellCommand.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executeShellCommand.js","sourceRoot":"","sources":["../../src/utils/executeShellCommand.ts"],"names":[],"mappings":"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"}
@@ -147,6 +147,10 @@ feishu:
147
147
  userOpenId: "${FEISHU_USER_OPEN_ID}"
148
148
  respondToOwnerOnly: true
149
149
  respondToAllGroupMessages: true
150
+ groupNameFormat:
151
+ project: "[{agent}] [{project}] {taskname}"
152
+ projectless: "[{agent}] {taskname}"
153
+ dateFormat: "MM-dd"
150
154
  thinkingCardLayout: "grouped"
151
155
 
152
156
  console:
@@ -185,8 +189,23 @@ logging:
185
189
 
186
190
  `/mute` and `/mute on` persist mention-only response mode for the current base group; `/mute off` disables it. The group timeline and every topic share this state. While muted, messages that do not mention the current bot are ignored before event claims, reactions, activity tracking, image downloads, command parsing, or Agent calls. The command that disables mute must itself mention the bot. Private chats do not support `/mute`.
187
191
 
192
+ `feishu.groupNameFormat.project` and `projectless` control names created by NewGroup or ForkGroup for Project and Projectless tasks. Each template must contain exactly one `{taskname}` and may use these variables:
193
+
194
+ | Variable | Value |
195
+ | --- | --- |
196
+ | `{os}` | Current system: `win` on Windows, `mac` on macOS, and `linux` on Linux |
197
+ | `{agent}` | Configured Agent standard name, such as `codex` or `traex` |
198
+ | `{project}` | At most the final two Project path levels, limited to 15 characters; normally omitted from the Projectless template |
199
+ | `{taskname}` | New-task or fork-task title |
200
+ | `{date}` | Local date and time rendered with `dateFormat` |
201
+ | `{date:yyyy-MM-dd}` | A format override for this placeholder only |
202
+
203
+ Date formats support `yyyy`/`yy` for year, `MM`/`M` for month, `dd`/`d` for day, `HH`/`H` for hour, `mm`/`m` for minute, and `ss`/`s` for second. Uppercase `YYYY`, `YY`, `DD`, and `D` are also accepted. Other characters are emitted literally. Feishu's 60-character group-name limit still applies; Agent Bot truncates `{taskname}` first so configured prefixes and suffixes remain visible. The defaults exactly preserve previous group names. Rerunning `agentbot init` adds this section to an existing config without replacing user settings.
204
+
188
205
  `feishu.thinkingCardLayout` defaults to `grouped`. The grouped renderer keeps Commentary and user steering messages visible, uses Commentary as the only execution-group boundary, uses only the latest native reasoning as each group title, and keeps every tool available inside the group. Command panels remove PowerShell launchers and POSIX command-string launchers such as `/bin/zsh -lc`, `/bin/bash -c`, and `/usr/bin/env sh -c` from both their titles and expanded command text without changing the command that is executed. Execution-group status is intentionally non-failing: while any child tool is running the group uses the running treatment, otherwise it settles to the neutral treatment; failed tools retain their own failure icon inside the group. Every execution panel is rendered with a collapsed default and a stable `element_id`; Agent Bot never changes the expanded flag based on tool status, user steering, or later Commentary, allowing the Feishu client to retain a user's manual expansion across full-card updates. Grouped pagination first renders complete tool panels, then fills pages from the newest end according to the rendered UTF-8 JSON size and component count. The activity area is limited to 24KB and 160 components, leaving headroom under Feishu's recommended 30KB card size and 200-component hard limit for the header, plan, files, and actions. Execution groups above eight tools are split into stable subpanels, but every tool keeps its expandable command, result, and image content. History pages are measured separately with complete native reasoning included. Set the option to `timeline` to use the unchanged original renderer and its 40-activity pages while the grouped layout is being refined.
189
206
 
207
+ Feishu local commands beginning with `!` are persisted under `command-jobs/` beside the configured SQLite file and run in detached Runner processes. They have no execution timeout and release the conversation message queue immediately after submission, so multiple commands may run concurrently. Each Runner persists status and writes both stdout and stderr chunks to one `output.log` in observed arrival order; the log compacts its middle after reaching 8 MiB while retaining the beginning and end. The Worker only polls these files and updates the original card, then reattaches to unfinished jobs after restart. The running card's `Cancel` action persists a cancellation request that makes the Runner terminate the command process tree. This background mode applies only to Feishu `!` commands; the synchronous `agentbot task shell` CLI behavior is unchanged.
208
+
190
209
  `agentbot server start` requires both Feishu credentials. The worker starts the SDK's persistent connection without inspecting SDK logs or private connection state, then sends startup status cards as an outbound readiness check. Each startup card includes the Agent Bot version read from the installed package metadata. Every startup sends a card to every known private chat, regardless of recent activity, plus each non-topic group active during the minute before this Worker started. After a safe restart, it also sends to every conversation enrolled in that restart's notification set regardless of activity age. Topic routes retain their originating message anchor across the replacement Supervisor and receive the startup card as a reply in the original topic instead of creating a new root topic in the parent group. Safe-restart progress cards have a narrower audience: only conversations that explicitly requested the current restart receive and update them; recently active chats are not enrolled automatically. If the database has no eligible chat yet, it sends the startup card to `feishu.userOpenId` using an `open_id` private message. When startup notification targets exist, at least one card must be delivered before the server reports ready; individual target failures remain isolated. If neither a known chat nor `feishu.userOpenId` is available, startup continues without the outbound check. With `respondToOwnerOnly: false`, the first subsequent private message can persist the missing user Open ID for later startup notifications and CLI-created groups; the default owner-only mode requires the owner Open ID to be configured first. Missing credentials still fail startup with an initialization hint. `agentbot console` is the explicit local-only path and does not require Feishu credentials.
191
210
 
192
211
  At least one agent must be configured. `defaults.agent` must name a configured agent.
@@ -147,6 +147,10 @@ feishu:
147
147
  userOpenId: "${FEISHU_USER_OPEN_ID}"
148
148
  respondToOwnerOnly: true
149
149
  respondToAllGroupMessages: true
150
+ groupNameFormat:
151
+ project: "[{agent}] [{project}] {taskname}"
152
+ projectless: "[{agent}] {taskname}"
153
+ dateFormat: "MM-dd"
150
154
  thinkingCardLayout: "grouped"
151
155
 
152
156
  console:
@@ -185,8 +189,23 @@ logging:
185
189
 
186
190
  `/mute` 或 `/mute on` 会为当前基础群聊持久化仅 @ 响应模式,`/mute off` 会关闭。群正文及其所有话题共享该状态;静音期间未 @ 当前机器人的消息会在事件去重、reaction、活跃时间、图片下载、命令解析和 Agent 调用之前被忽略。关闭静音的命令本身也必须 @ 机器人。私聊不支持 `/mute`。
187
191
 
192
+ `feishu.groupNameFormat.project` 和 `projectless` 分别控制 Project 与 Projectless 任务通过 NewGroup 或 ForkGroup 创建的群名。每个模板必须且只能包含一个 `{taskname}`,并可使用以下变量:
193
+
194
+ | 变量 | 内容 |
195
+ | --- | --- |
196
+ | `{os}` | 当前系统:Windows 为 `win`、macOS 为 `mac`、Linux 为 `linux` |
197
+ | `{agent}` | Agent 配置标准名,例如 `codex` 或 `traex` |
198
+ | `{project}` | Project 目录末尾最多两级,最长 15 个字符;Projectless 模板通常不使用 |
199
+ | `{taskname}` | 新任务或 Fork 任务的标题 |
200
+ | `{date}` | 按 `dateFormat` 格式化的本地日期时间 |
201
+ | `{date:yyyy-MM-dd}` | 只为当前位置指定日期格式,不修改全局 `dateFormat` |
202
+
203
+ 日期格式支持 `yyyy`/`yy` 年、`MM`/`M` 月、`dd`/`d` 日、`HH`/`H` 时、`mm`/`m` 分和 `ss`/`s` 秒,也兼容大写 `YYYY`、`YY`、`DD`、`D`。其他字符按原样输出。最终群名遵循飞书 60 字符限制;超长时优先截断 `{taskname}`,保留模板的前后固定部分。默认模板与旧版群名完全一致。重新运行 `agentbot init` 会为已有配置补齐这一配置段,不覆盖用户已有设置。
204
+
188
205
  `feishu.thinkingCardLayout` 默认为 `grouped`。分组渲染器保持 Commentary 和用户追加消息可见,只把 Commentary 作为执行组边界;每个执行组只用最新原生思考作为标题,展开后仍可查看组内全部工具。命令面板会从标题和展开后的命令正文中去掉 PowerShell 启动器,以及 `/bin/zsh -lc`、`/bin/bash -c`、`/usr/bin/env sh -c` 等 POSIX 命令字符串启动器,但不会修改实际执行的命令。执行组状态不会聚合为失败:存在运行中工具时使用运行中样式,否则回到中性样式;失败工具仍在组内保留自己的失败图标。所有执行面板都以折叠状态作为默认值,并使用稳定的 `element_id`;Agent Bot 不再根据工具状态、用户追加或后续 Commentary 改写展开属性,让飞书客户端能够在整卡更新时保留用户手动展开的状态。分组分页会先完整渲染工具面板,再根据生成内容的 UTF-8 JSON 大小和组件数量从最新端向前装页。活动区上限为 24KB 和 160 个组件,为飞书建议的 30KB 卡片大小及 200 个组件硬限制预留标题、计划、文件变更和操作按钮空间。超过 8 个工具的单个执行组会拆成标识稳定的子面板,但每个工具都继续保留可展开的命令、结果和图片内容。历史页会包含完整原生思考并独立测量。新版布局完善期间,可将该配置设为 `timeline` 使用保持不变的原版渲染器及其每页 40 条活动规则。
189
206
 
207
+ 以 `!` 开头的飞书本地命令会写入 SQLite 文件同级的 `command-jobs/` 目录,并由脱离 Worker 的独立 Runner 进程执行。命令没有运行超时,提交成功后立即释放当前会话消息队列;不同命令可以并发运行。Runner 将状态持久化到任务目录,并把 stdout 和 stderr 数据块按照观察到的到达顺序写入同一个 `output.log`;日志达到 8 MiB 后保留头尾并压缩中间内容。Worker 只轮询这些文件并更新原卡片,重启后通过未完成状态重新接管监控。运行卡片的 `Cancel` 操作写入持久化取消请求,由 Runner 终止命令进程树。该后台模式仅用于飞书 `!` 命令;CLI 的同步 `agentbot task shell` 行为保持不变。
208
+
190
209
  `agentbot server start` 要求同时配置飞书 `appId` 和 `appSecret`。Worker 启动 SDK 长连接时不读取 SDK 日志或私有连接状态,随后通过发送启动状态卡片检查出站能力。每张启动卡片都会显示从已安装包元数据读取的 Agent Bot 版本。每次启动都会向所有已知私聊发送卡片,不受最近活跃时间影响;同时向本次 Worker 启动前 1 分钟内活跃的非话题群聊发送卡片。安全重启后,还会向所有已加入本次重启通知范围的会话发送,不受活跃时间限制;话题路由及其原始消息锚点会完整经过替换 Supervisor,启动卡以回复形式返回原话题,不会在父群创建新的根话题。安全重启进度卡的范围更窄:只有明确触发本次安全重启的会话会收到并持续更新,最近活跃会话不会被自动加入。数据库里尚无符合条件的会话时,启动卡改用 `feishu.userOpenId`,按 `open_id` 私聊发送。存在启动通知目标时,至少一张卡片发送成功后 Server 才报告就绪,单个目标发送失败仍相互隔离。如果既没有已知会话,也没有 `feishu.userOpenId`,启动会跳过出站检查并继续;仅当 `respondToOwnerOnly: false` 时,之后收到的第一条私聊消息可以补全用户 Open ID,供后续启动通知和 CLI 建群使用。默认的仅拥有者模式要求先配置拥有者 Open ID。缺少凭据时仍会启动失败并提示先初始化。`agentbot console` 是明确的纯本地入口,不需要飞书凭据。
191
210
 
192
211
  必须至少配置一个 Agent,`defaults.agent` 必须指向已配置的 Agent。
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@keyou007/agent-bot",
3
- "version": "0.1.15-alpha.4",
3
+ "version": "0.1.15-alpha.6",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@keyou007/agent-bot",
9
- "version": "0.1.15-alpha.4",
9
+ "version": "0.1.15-alpha.6",
10
10
  "license": "GPL-3.0-only",
11
11
  "dependencies": {
12
12
  "@agentclientprotocol/sdk": "1.2.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keyou007/agent-bot",
3
- "version": "0.1.15-alpha.4",
3
+ "version": "0.1.15-alpha.6",
4
4
  "type": "module",
5
5
  "description": "Use Codex, TraeX, and compatible coding agents from Lark/Feishu.",
6
6
  "license": "GPL-3.0-only",
@@ -5,6 +5,7 @@ export const COMMAND_NAMES = [
5
5
  "archive",
6
6
  "dir",
7
7
  "dismiss",
8
+ "file",
8
9
  "fork",
9
10
  "forkgroup",
10
11
  "goal",
@@ -56,6 +57,11 @@ export class CommandRouter {
56
57
  switch (command) {
57
58
  case "dir":
58
59
  return { type: "dir", directory: args.join(" ").trim() || undefined };
60
+ case "file": {
61
+ const filePath = args.join(" ").trim();
62
+ if (!filePath) throw new Error("请输入文件路径,例如:/file ./report.pdf。");
63
+ return { type: "file", filePath };
64
+ }
59
65
  case "new":
60
66
  return parseNewCommand(args);
61
67
  case "newgroup":
@@ -3,6 +3,7 @@ export type Command =
3
3
  | { type: "new"; title?: string; cwd?: string; projectless?: boolean }
4
4
  | { type: "newgroup"; title?: string; cwd?: string; projectless?: boolean }
5
5
  | { type: "dir"; directory?: string }
6
+ | { type: "file"; filePath: string }
6
7
  | { type: "forkgroup"; title?: string }
7
8
  | { type: "fork"; sessionId?: string }
8
9
  | { type: "title"; title: string }
@@ -17,6 +17,10 @@ const DEFAULT_CONFIG = `feishu:
17
17
  userOpenId: "\${FEISHU_USER_OPEN_ID}"
18
18
  respondToOwnerOnly: true
19
19
  respondToAllGroupMessages: true
20
+ groupNameFormat:
21
+ project: "[{agent}] [{project}] {taskname}"
22
+ projectless: "[{agent}] {taskname}"
23
+ dateFormat: "MM-dd"
20
24
  thinkingCardLayout: "grouped"
21
25
 
22
26
  console: