dsh-lark-bot 0.1.4 → 0.2.1

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/README.md CHANGED
@@ -83,10 +83,14 @@ dsh-lark-bot start \
83
83
  | `/ws save <name>` | 保存当前工作空间 |
84
84
  | `/ws use <name>` | 切换到命名工作空间 |
85
85
  | `/status` | 查看当前状态 |
86
+ | `/resume` | 查看当前会话最近上下文 |
86
87
  | `/stop` | 终止当前任务 |
87
88
  | `/timeout [N|off|default]` | 查看或设置当前会话运行超时 |
89
+ | `/invite user|admin|group <id>` | 管理访问白名单 |
88
90
  | `/help` | 查看帮助 |
89
91
 
92
+ 飞书消息中的图片会下载到本地 media 目录并传给 dsh;文本类文件会读取内容并注入任务上下文。
93
+
90
94
  ### 4. 卸载
91
95
 
92
96
  ```bash
@@ -134,6 +138,8 @@ rm -rf ~/.dsh-lark
134
138
 
135
139
  会话运行在 Git 仓库中时,会自动在 `~/.dsh-lark/profiles/<profile>/worktrees/<scope>/` 创建隔离 worktree,并复制项目级 `AGENTS.md`。
136
140
 
141
+ 每个飞书 scope 会保存最近 40 条对话消息,下一次消息会作为上下文传入 dsh headless,从而在无状态 headless 子进程上实现会话记忆。
142
+
137
143
  当前核心环境变量:
138
144
 
139
145
  | 变量 | 默认值 | 说明 |
@@ -162,7 +168,7 @@ rm -rf ~/.dsh-lark
162
168
 
163
169
  ## 排障 · Troubleshooting
164
170
 
165
- 先运行 `dsh-lark-bot doctor`,它会检查 profile、工作目录和本机 `dsh` 可用性。
171
+ 先运行 `dsh-lark-bot doctor`,它会检查 profile、工作目录,并实际调用本机 dsh 的 `--version` 确认可用性。
166
172
 
167
173
  常见问题:
168
174
 
package/dist/cli.js CHANGED
@@ -7,10 +7,12 @@ import { stat } from "fs/promises";
7
7
 
8
8
  // src/adapters/dsh/availability.ts
9
9
  import { spawn } from "cross-spawn";
10
+ import { existsSync } from "fs";
10
11
  async function checkDshAvailability(options) {
11
12
  const timeoutMs = options.timeoutMs ?? 5e3;
13
+ const versionArgs = options.command === "node" && options.args?.[0] && existsSync(options.args[0]) ? [options.args[0], "--version"] : ["--version"];
12
14
  return new Promise((resolve4) => {
13
- const child = spawn(options.command, ["--version"], {
15
+ const child = spawn(options.command, versionArgs, {
14
16
  stdio: ["ignore", "pipe", "pipe"]
15
17
  });
16
18
  let stdout = "";
@@ -78,11 +80,11 @@ import { join as join3, resolve as resolve2 } from "path";
78
80
  import { homedir as homedir2 } from "os";
79
81
 
80
82
  // src/config/dsh-runtime.ts
81
- import { existsSync, readdirSync } from "fs";
83
+ import { existsSync as existsSync2, readdirSync } from "fs";
82
84
  import { join as join2 } from "path";
83
85
  var DS_HARNESS_RELATIVE = join2("@deepseek-ai", "dsh", "lib", "bin.js");
84
86
  function firstExisting(...paths) {
85
- return paths.find((path) => existsSync(path));
87
+ return paths.find((path) => existsSync2(path));
86
88
  }
87
89
  function children(root) {
88
90
  try {
@@ -104,7 +106,7 @@ function discoverDshBin(home, env = process.env) {
104
106
  for (const root of [join2(home, ".npm", "_npx"), join2(home, ".cache", "pnpm", "dlx")]) {
105
107
  for (const child of children(root)) {
106
108
  const path = join2(child, "node_modules", DS_HARNESS_RELATIVE);
107
- if (existsSync(path)) return path;
109
+ if (existsSync2(path)) return path;
108
110
  }
109
111
  }
110
112
  return void 0;
@@ -243,7 +245,19 @@ var ConfigStore = class {
243
245
  this.data = {
244
246
  schemaVersion: 1,
245
247
  activeProfile: parsed.activeProfile ?? "default",
246
- profiles: parsed.profiles ?? {}
248
+ profiles: Object.fromEntries(
249
+ Object.entries(parsed.profiles ?? {}).map(([name, profile]) => [
250
+ name,
251
+ {
252
+ ...profile,
253
+ access: {
254
+ allowedUsers: profile.access?.allowedUsers ?? [],
255
+ allowedChats: profile.access?.allowedChats ?? [],
256
+ admins: profile.access?.admins ?? []
257
+ }
258
+ }
259
+ ])
260
+ )
247
261
  };
248
262
  } catch (error) {
249
263
  if (error.code !== "ENOENT") throw error;
@@ -281,8 +295,17 @@ var ConfigStore = class {
281
295
  model: input.model ?? existing?.preferences.model ?? void 0,
282
296
  stopGraceMs: input.stopGraceMs ?? existing?.preferences.stopGraceMs ?? void 0,
283
297
  runTimeoutMs: input.runTimeoutMs ?? existing?.preferences.runTimeoutMs ?? void 0
298
+ },
299
+ access: {
300
+ allowedUsers: input.access?.allowedUsers ?? existing?.access?.allowedUsers ?? [],
301
+ allowedChats: input.access?.allowedChats ?? existing?.access?.allowedChats ?? [],
302
+ admins: input.access?.admins ?? existing?.access?.admins ?? []
284
303
  }
285
304
  };
305
+ if (input.operatorOpenId && !profile.access.allowedUsers.includes(input.operatorOpenId)) {
306
+ profile.access.allowedUsers.push(input.operatorOpenId);
307
+ profile.access.admins.push(input.operatorOpenId);
308
+ }
286
309
  data.profiles[name] = profile;
287
310
  data.activeProfile = name;
288
311
  await this.persist();
@@ -348,7 +371,10 @@ async function runDoctor(options) {
348
371
  } catch {
349
372
  lines.push(`workspace: ${workspace} (missing)`);
350
373
  }
351
- const availability = await checkDshAvailability({ command: env.dshCommand });
374
+ const availability = await checkDshAvailability({
375
+ command: env.dshCommand,
376
+ args: env.dshArgs
377
+ });
352
378
  if (availability.ok) {
353
379
  lines.push(`dsh: ok${availability.version ? ` (${availability.version})` : ""}`);
354
380
  } else {
@@ -362,7 +388,7 @@ async function runDoctor(options) {
362
388
  }
363
389
 
364
390
  // src/cli/commands/start.ts
365
- import { mkdir as mkdir4 } from "fs/promises";
391
+ import { mkdir as mkdir5 } from "fs/promises";
366
392
 
367
393
  // src/adapters/dsh/adapter.ts
368
394
  import { spawn as spawn2 } from "cross-spawn";
@@ -459,12 +485,16 @@ var DshAdapter = class {
459
485
  return (await this.checkAvailability()).ok;
460
486
  }
461
487
  checkAvailability() {
462
- return checkDshAvailability({ command: this.command });
488
+ return checkDshAvailability({ command: this.command, args: this.args });
463
489
  }
464
490
  run(options) {
491
+ const prompt = options.images?.length ? `${options.prompt}
492
+
493
+ Image files attached to this message:
494
+ ${options.images.join("\n")}` : options.prompt;
465
495
  const child = spawn2(
466
496
  this.command,
467
- [...this.args, options.prompt],
497
+ [...this.args, prompt],
468
498
  {
469
499
  cwd: options.cwd,
470
500
  stdio: ["pipe", "pipe", "pipe"]
@@ -695,6 +725,33 @@ import { createLarkChannel } from "@larksuite/channel";
695
725
 
696
726
  // src/commands/index.ts
697
727
  import { resolve as resolve3 } from "path";
728
+
729
+ // src/card/workspace-card.ts
730
+ function renderWorkspaceCard(input) {
731
+ const entries = Object.entries(input.named);
732
+ const markdown2 = [
733
+ `**\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55**
734
+ \`${input.current}\``,
735
+ "",
736
+ ...entries.length > 0 ? entries.map(([name, cwd]) => `- **${name}** \u2192 \`${cwd}\``) : ["\u6682\u65E0\u547D\u540D\u5DE5\u4F5C\u7A7A\u95F4\u3002"]
737
+ ].join("\n");
738
+ return {
739
+ schema: "2.0",
740
+ config: {
741
+ summary: { content: "\u5DE5\u4F5C\u7A7A\u95F4\u5BFC\u822A" }
742
+ },
743
+ body: {
744
+ elements: [
745
+ {
746
+ tag: "markdown",
747
+ content: markdown2
748
+ }
749
+ ]
750
+ }
751
+ };
752
+ }
753
+
754
+ // src/commands/index.ts
698
755
  var HELP = [
699
756
  "**dsh-lark-bot \u547D\u4EE4**",
700
757
  "",
@@ -702,8 +759,10 @@ var HELP = [
702
759
  "- `/cd <path>` \u2014 \u5207\u6362\u5DE5\u4F5C\u76EE\u5F55\u5E76\u91CD\u7F6E\u4F1A\u8BDD",
703
760
  "- `/ws list|save <name>|use <name>|remove <name>` \u2014 \u7BA1\u7406\u5DE5\u4F5C\u7A7A\u95F4",
704
761
  "- `/status` \u2014 \u67E5\u770B\u5F53\u524D\u72B6\u6001",
762
+ "- `/resume` \u2014 \u67E5\u770B\u5F53\u524D\u4F1A\u8BDD\u6700\u8FD1\u4E0A\u4E0B\u6587",
705
763
  "- `/stop` \u2014 \u7EC8\u6B62\u5F53\u524D\u4EFB\u52A1",
706
764
  "- `/timeout [N|off|default]` \u2014 \u67E5\u770B\u6216\u8BBE\u7F6E\u5F53\u524D\u4F1A\u8BDD\u8FD0\u884C\u8D85\u65F6",
765
+ "- `/invite user|admin|group <id>` \u2014 \u7BA1\u7406\u8BBF\u95EE\u767D\u540D\u5355",
707
766
  "- `/help` \u2014 \u663E\u793A\u672C\u5E2E\u52A9"
708
767
  ].join("\n");
709
768
  async function reply(ctx, markdown2) {
@@ -734,6 +793,10 @@ async function handleWs(args, ctx) {
734
793
  if (!sub || sub === "list") {
735
794
  const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;
736
795
  const named = ctx.workspaces.listNamed();
796
+ if (ctx.channel.sendCard) {
797
+ await ctx.channel.sendCard(ctx.chatId, renderWorkspaceCard({ current, named }));
798
+ return;
799
+ }
737
800
  const lines = Object.entries(named).map(
738
801
  ([key, value]) => `- **${key}** \u2192 \`${value}\`${value === current ? " \u2190 \u5F53\u524D" : ""}`
739
802
  );
@@ -799,6 +862,19 @@ async function handleStatus(_args, ctx) {
799
862
  ].join("\n")
800
863
  );
801
864
  }
865
+ async function handleResume(_args, ctx) {
866
+ const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;
867
+ const history = ctx.sessions.historyFor(ctx.scope, cwd);
868
+ if (history.length === 0) {
869
+ await reply(ctx, "\u5F53\u524D\u4F1A\u8BDD\u6CA1\u6709\u5386\u53F2\u4E0A\u4E0B\u6587\u3002");
870
+ return;
871
+ }
872
+ const recent = history.slice(-6).map((message) => {
873
+ const speaker = message.role === "user" ? "\u{1F464}" : "\u{1F916}";
874
+ return `${speaker} ${message.content.slice(0, 300)}`;
875
+ });
876
+ await reply(ctx, [`\u5F53\u524D scope\uFF1A\`${ctx.scope}\``, "", ...recent].join("\n"));
877
+ }
802
878
  async function handleStop(_args, ctx) {
803
879
  const stopped = await ctx.activeRuns.interrupt(ctx.scope);
804
880
  await reply(ctx, stopped ? "\u5DF2\u8BF7\u6C42\u7EC8\u6B62\u5F53\u524D\u4EFB\u52A1\u3002" : "\u5F53\u524D\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u4EFB\u52A1\u3002");
@@ -832,6 +908,30 @@ async function handleTimeout(args, ctx) {
832
908
  ctx.runPolicies.set(ctx.scope, minutes * 6e4);
833
909
  await reply(ctx, `\u5DF2\u8BBE\u7F6E\u5F53\u524D\u4F1A\u8BDD\u8FD0\u884C\u8D85\u65F6\uFF1A${minutes} \u5206\u949F\u3002`);
834
910
  }
911
+ async function handleInvite(args, ctx) {
912
+ const [kind, ...rest] = args.trim().split(/\s+/);
913
+ const id = rest.join(" ").trim();
914
+ if (!kind || !id) {
915
+ await reply(ctx, "\u7528\u6CD5\uFF1A`/invite user <id>`\u3001`/invite admin <id>`\u3001`/invite group <chatId>`");
916
+ return;
917
+ }
918
+ if (kind === "user") {
919
+ await ctx.accessManager.addUser(id);
920
+ await reply(ctx, `\u5DF2\u5141\u8BB8\u7528\u6237\uFF1A\`${id}\``);
921
+ return;
922
+ }
923
+ if (kind === "admin") {
924
+ await ctx.accessManager.addAdmin(id);
925
+ await reply(ctx, `\u5DF2\u8BBE\u4E3A\u7BA1\u7406\u5458\uFF1A\`${id}\``);
926
+ return;
927
+ }
928
+ if (kind === "group") {
929
+ await ctx.accessManager.addChat(id);
930
+ await reply(ctx, `\u5DF2\u5141\u8BB8\u7FA4\u804A\uFF1A\`${id}\``);
931
+ return;
932
+ }
933
+ await reply(ctx, "\u672A\u77E5 `/invite` \u7C7B\u578B\uFF0C\u8BF7\u4F7F\u7528 user / admin / group\u3002");
934
+ }
835
935
  async function handleHelp(_args, ctx) {
836
936
  await reply(ctx, HELP);
837
937
  }
@@ -841,8 +941,10 @@ var handlers = {
841
941
  "/cd": handleCd,
842
942
  "/ws": handleWs,
843
943
  "/status": handleStatus,
944
+ "/resume": handleResume,
844
945
  "/stop": handleStop,
845
946
  "/timeout": handleTimeout,
947
+ "/invite": handleInvite,
846
948
  "/help": handleHelp
847
949
  };
848
950
  async function tryHandleCommand(text, ctx) {
@@ -914,6 +1016,9 @@ function adaptLarkChannel(channel) {
914
1016
  };
915
1017
  return {
916
1018
  ...base,
1019
+ async sendCard(chatId, card) {
1020
+ await channel.send(chatId, { card }, {});
1021
+ },
917
1022
  async streamCard(chatId, initial, producer, options) {
918
1023
  const sendOptions = {};
919
1024
  if (options?.replyTo) sendOptions.replyTo = options.replyTo;
@@ -941,9 +1046,11 @@ async function startChannel(deps) {
941
1046
  domain: deps.tenant === "lark" ? "https://open.larksuite.com" : "https://open.feishu.cn",
942
1047
  source: "dsh-lark-bot",
943
1048
  policy: {
944
- dmMode: "open",
1049
+ dmMode: deps.allowedUsers?.length ? "allowlist" : "open",
945
1050
  requireMention: true,
946
- respondToMentionAll: false
1051
+ respondToMentionAll: false,
1052
+ ...deps.allowedUsers ? { dmAllowlist: deps.allowedUsers } : {},
1053
+ ...deps.allowedChats ? { groupAllowlist: deps.allowedChats } : {}
947
1054
  },
948
1055
  safety: {
949
1056
  chatQueue: { enabled: false }
@@ -972,6 +1079,7 @@ async function startChannel(deps) {
972
1079
  activeRuns: deps.activeRuns,
973
1080
  runPolicies: deps.runPolicies,
974
1081
  defaultRunTimeoutMs: deps.defaultRunTimeoutMs,
1082
+ accessManager: deps.accessManager,
975
1083
  channel: commandChannel,
976
1084
  defaultWorkspace: deps.defaultWorkspace
977
1085
  };
@@ -1245,7 +1353,7 @@ async function runAgentBatch(input) {
1245
1353
  cwd,
1246
1354
  sessionId,
1247
1355
  model: input.model,
1248
- images: void 0,
1356
+ images: input.images,
1249
1357
  stopGraceMs: input.stopGraceMs
1250
1358
  });
1251
1359
  input.activeRuns.set(input.scope, { runId, stop: run.stop });
@@ -1336,6 +1444,65 @@ function errorMessage(error) {
1336
1444
  return error instanceof Error ? error.message : String(error);
1337
1445
  }
1338
1446
 
1447
+ // src/config/access-manager.ts
1448
+ var AccessManager = class {
1449
+ constructor(store, profileName) {
1450
+ this.store = store;
1451
+ this.profileName = profileName;
1452
+ }
1453
+ store;
1454
+ profileName;
1455
+ snapshot() {
1456
+ const profile = this.profile();
1457
+ return {
1458
+ allowedUsers: [...profile.access.allowedUsers],
1459
+ allowedChats: [...profile.access.allowedChats],
1460
+ admins: [...profile.access.admins]
1461
+ };
1462
+ }
1463
+ async addUser(id) {
1464
+ const snapshot = this.snapshot();
1465
+ if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);
1466
+ await this.persist(snapshot);
1467
+ }
1468
+ async addAdmin(id) {
1469
+ const snapshot = this.snapshot();
1470
+ if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);
1471
+ if (!snapshot.admins.includes(id)) snapshot.admins.push(id);
1472
+ await this.persist(snapshot);
1473
+ }
1474
+ async addChat(chatId) {
1475
+ const snapshot = this.snapshot();
1476
+ if (!snapshot.allowedChats.includes(chatId)) snapshot.allowedChats.push(chatId);
1477
+ await this.persist(snapshot);
1478
+ }
1479
+ async removeUser(id) {
1480
+ const snapshot = this.snapshot();
1481
+ snapshot.allowedUsers = snapshot.allowedUsers.filter((item) => item !== id);
1482
+ snapshot.admins = snapshot.admins.filter((item) => item !== id);
1483
+ await this.persist(snapshot);
1484
+ }
1485
+ async removeChat(chatId) {
1486
+ const snapshot = this.snapshot();
1487
+ snapshot.allowedChats = snapshot.allowedChats.filter((item) => item !== chatId);
1488
+ await this.persist(snapshot);
1489
+ }
1490
+ profile() {
1491
+ const profile = this.store.getProfile(this.profileName);
1492
+ if (!profile) throw new Error(`profile not found: ${this.profileName}`);
1493
+ return profile;
1494
+ }
1495
+ async persist(snapshot) {
1496
+ const profile = this.profile();
1497
+ await this.store.saveProfile(this.profileName, {
1498
+ tenant: profile.tenant,
1499
+ appId: profile.accounts.appId,
1500
+ appSecret: profile.accounts.appSecret,
1501
+ access: snapshot
1502
+ });
1503
+ }
1504
+ };
1505
+
1339
1506
  // src/onboard/registration.ts
1340
1507
  import { registerApp } from "@larksuite/channel";
1341
1508
  import qrcode from "qrcode-terminal";
@@ -1377,12 +1544,47 @@ async function onboardPersonalAgent(deps = {}) {
1377
1544
  return {
1378
1545
  appId: result.client_id,
1379
1546
  appSecret: result.client_secret,
1380
- tenant
1547
+ tenant,
1548
+ operatorOpenId: result.user_info?.open_id
1381
1549
  };
1382
1550
  }
1383
1551
 
1552
+ // src/media/attachments.ts
1553
+ import { mkdir as mkdir3, readFile as readFile2, stat as stat2 } from "fs/promises";
1554
+ import { join as join5 } from "path";
1555
+ var MAX_TEXT_FILE_BYTES = 256e3;
1556
+ async function prepareAttachments(channel, message, mediaDir) {
1557
+ await mkdir3(mediaDir, { recursive: true });
1558
+ const result = { imagePaths: [], textFileNotes: [] };
1559
+ for (const resource of message.resources) {
1560
+ if (!channel || resource.type !== "image" && resource.type !== "file") continue;
1561
+ const destination = join5(mediaDir, `${message.messageId}-${resource.fileKey}`);
1562
+ await channel.downloadResourceToFile(
1563
+ message.messageId,
1564
+ resource.fileKey,
1565
+ resource.type,
1566
+ destination
1567
+ );
1568
+ if (resource.type === "image") {
1569
+ result.imagePaths.push(destination);
1570
+ continue;
1571
+ }
1572
+ const info = await stat2(destination);
1573
+ if (info.size > MAX_TEXT_FILE_BYTES) {
1574
+ result.textFileNotes.push(`[attachment: ${resource.fileName ?? resource.fileKey}] ${destination}`);
1575
+ continue;
1576
+ }
1577
+ const content = await readFile2(destination, "utf8");
1578
+ result.textFileNotes.push(
1579
+ `[attachment: ${resource.fileName ?? resource.fileKey}]
1580
+ ${content}`
1581
+ );
1582
+ }
1583
+ return result;
1584
+ }
1585
+
1384
1586
  // src/session/store.ts
1385
- import { readFile as readFile2 } from "fs/promises";
1587
+ import { readFile as readFile3 } from "fs/promises";
1386
1588
  var SessionStore = class {
1387
1589
  data = { chats: {} };
1388
1590
  saving = Promise.resolve();
@@ -1392,7 +1594,7 @@ var SessionStore = class {
1392
1594
  }
1393
1595
  async load() {
1394
1596
  try {
1395
- const raw = await readFile2(this.path, "utf8");
1597
+ const raw = await readFile3(this.path, "utf8");
1396
1598
  const parsed = JSON.parse(raw);
1397
1599
  this.data = {
1398
1600
  chats: parsed.chats ?? {}
@@ -1476,8 +1678,8 @@ var SessionStore = class {
1476
1678
  // src/workspace/git-worktree.ts
1477
1679
  import { execFile } from "child_process";
1478
1680
  import { randomBytes as randomBytes2 } from "crypto";
1479
- import { access, copyFile, mkdir as mkdir3 } from "fs/promises";
1480
- import { dirname as dirname3, join as join5 } from "path";
1681
+ import { access, copyFile, mkdir as mkdir4 } from "fs/promises";
1682
+ import { dirname as dirname3, join as join6 } from "path";
1481
1683
  import { promisify } from "util";
1482
1684
  var execFileAsync = promisify(execFile);
1483
1685
  async function defaultRunGit(args, cwd) {
@@ -1496,7 +1698,7 @@ async function exists(path) {
1496
1698
  }
1497
1699
  }
1498
1700
  async function defaultCopyRulesFile(source, target) {
1499
- await mkdir3(dirname3(target), { recursive: true });
1701
+ await mkdir4(dirname3(target), { recursive: true });
1500
1702
  await copyFile(source, target);
1501
1703
  }
1502
1704
  function slugify(scope) {
@@ -1516,13 +1718,13 @@ var GitWorktreeManager = class {
1516
1718
  const isGit = await this.isGitRepository(base);
1517
1719
  if (!isGit) return { cwd: base, created: false };
1518
1720
  const slug = slugify(scope);
1519
- const target = join5(this.options.worktreesRoot, slug);
1721
+ const target = join6(this.options.worktreesRoot, slug);
1520
1722
  if (await exists(target)) {
1521
1723
  await this.ensureProjectRules(base, target);
1522
1724
  return { cwd: target, created: false };
1523
1725
  }
1524
1726
  const branch = `dsh-lark/${slug}-${Date.now().toString(36)}-${randomBytes2(3).toString("hex")}`;
1525
- await mkdir3(this.options.worktreesRoot, { recursive: true });
1727
+ await mkdir4(this.options.worktreesRoot, { recursive: true });
1526
1728
  await this.runGit(["worktree", "add", "-b", branch, target, "HEAD"], base);
1527
1729
  await this.ensureProjectRules(base, target);
1528
1730
  return { cwd: target, created: true, branch };
@@ -1536,9 +1738,9 @@ var GitWorktreeManager = class {
1536
1738
  }
1537
1739
  }
1538
1740
  async ensureProjectRules(base, target) {
1539
- const destination = join5(target, "AGENTS.md");
1741
+ const destination = join6(target, "AGENTS.md");
1540
1742
  if (await exists(destination)) return;
1541
- const sourceCandidates = [join5(base, ".dsh-lark", "AGENTS.md"), join5(base, "AGENTS.md")];
1743
+ const sourceCandidates = [join6(base, ".dsh-lark", "AGENTS.md"), join6(base, "AGENTS.md")];
1542
1744
  for (const source of sourceCandidates) {
1543
1745
  if (await exists(source)) {
1544
1746
  await this.copyRulesFile(source, destination);
@@ -1549,7 +1751,7 @@ var GitWorktreeManager = class {
1549
1751
  };
1550
1752
 
1551
1753
  // src/workspace/store.ts
1552
- import { readFile as readFile3 } from "fs/promises";
1754
+ import { readFile as readFile4 } from "fs/promises";
1553
1755
  var WorkspaceStore = class {
1554
1756
  data = { chats: {}, named: {} };
1555
1757
  saving = Promise.resolve();
@@ -1559,7 +1761,7 @@ var WorkspaceStore = class {
1559
1761
  }
1560
1762
  async load() {
1561
1763
  try {
1562
- const raw = await readFile3(this.path, "utf8");
1764
+ const raw = await readFile4(this.path, "utf8");
1563
1765
  const parsed = JSON.parse(raw);
1564
1766
  this.data = {
1565
1767
  chats: parsed.chats ?? {},
@@ -1632,6 +1834,7 @@ async function runStart(options) {
1632
1834
  const profileName = options.profile ?? "default";
1633
1835
  const configStore = new ConfigStore(paths.configFile);
1634
1836
  await configStore.load();
1837
+ const accessManager = new AccessManager(configStore, profileName);
1635
1838
  if (env.appId && env.appSecret) {
1636
1839
  const profileInput = {
1637
1840
  tenant: env.tenant,
@@ -1656,6 +1859,9 @@ async function runStart(options) {
1656
1859
  stopGraceMs: env.stopGraceMs,
1657
1860
  runTimeoutMs: env.runTimeoutMs
1658
1861
  };
1862
+ if (created.operatorOpenId !== void 0) {
1863
+ onboardingProfile.operatorOpenId = created.operatorOpenId;
1864
+ }
1659
1865
  if (env.workspace !== void 0) onboardingProfile.workspace = env.workspace;
1660
1866
  await configStore.saveProfile(profileName, onboardingProfile);
1661
1867
  } catch (error) {
@@ -1672,7 +1878,7 @@ async function runStart(options) {
1672
1878
  return;
1673
1879
  }
1674
1880
  const defaultWorkspace = options.workspace ?? activeProfile.workspaces.default ?? env.workspace ?? paths.profilePath(profileName, "workspace");
1675
- await mkdir4(defaultWorkspace, { recursive: true });
1881
+ await mkdir5(defaultWorkspace, { recursive: true });
1676
1882
  const sessions = new SessionStore(paths.sessionsFile(profileName));
1677
1883
  const workspaces = new WorkspaceStore(paths.workspacesFile(profileName));
1678
1884
  const worktreeManager = new GitWorktreeManager({
@@ -1691,16 +1897,26 @@ async function runStart(options) {
1691
1897
  const activeRuns = new ActiveRuns();
1692
1898
  const runPolicies = new RunPolicyStore();
1693
1899
  let streaming;
1900
+ let larkChannel;
1694
1901
  const pending = new PendingQueue(DEBOUNCE_MS, async (scope, batch) => {
1695
1902
  if (!streaming) return;
1696
1903
  const first = batch[0];
1697
1904
  if (!first) return;
1698
1905
  pending.block(scope);
1699
1906
  try {
1907
+ const attachments = await prepareAttachments(
1908
+ larkChannel,
1909
+ first,
1910
+ paths.mediaDir(profileName)
1911
+ );
1912
+ const messages = [
1913
+ first.content,
1914
+ ...attachments.textFileNotes
1915
+ ].filter(Boolean);
1700
1916
  const runInput = {
1701
1917
  scope,
1702
1918
  chatId: first.chatId,
1703
- messages: batch.map((message) => message.content),
1919
+ messages,
1704
1920
  adapter,
1705
1921
  sessions,
1706
1922
  workspaces,
@@ -1710,7 +1926,8 @@ async function runStart(options) {
1710
1926
  channel: streaming,
1711
1927
  defaultWorkspace,
1712
1928
  replyTo: first.messageId,
1713
- runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs
1929
+ runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,
1930
+ images: attachments.imagePaths
1714
1931
  };
1715
1932
  if (activeProfile.preferences.model !== void 0) runInput.model = activeProfile.preferences.model;
1716
1933
  if (activeProfile.preferences.stopGraceMs !== void 0) {
@@ -1731,8 +1948,11 @@ async function runStart(options) {
1731
1948
  activeRuns,
1732
1949
  runPolicies,
1733
1950
  defaultRunTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,
1951
+ accessManager,
1734
1952
  pending,
1735
- defaultWorkspace
1953
+ defaultWorkspace,
1954
+ allowedUsers: activeProfile.access.allowedUsers,
1955
+ allowedChats: activeProfile.access.allowedChats
1736
1956
  };
1737
1957
  if (activeProfile.preferences.model !== void 0) channelInput.model = activeProfile.preferences.model;
1738
1958
  if (activeProfile.preferences.stopGraceMs !== void 0) {
@@ -1740,6 +1960,7 @@ async function runStart(options) {
1740
1960
  }
1741
1961
  const bridge = await startChannel(channelInput);
1742
1962
  streaming = adaptLarkChannel(bridge.channel);
1963
+ larkChannel = bridge.channel;
1743
1964
  log.info("cli", "started", {
1744
1965
  profile: profileName,
1745
1966
  home: paths.root,
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/cli/commands/doctor.ts","../src/adapters/dsh/availability.ts","../src/config/app-paths.ts","../src/config/env.ts","../src/config/dsh-runtime.ts","../src/config/profile-store.ts","../src/platform/atomic-write.ts","../src/cli/commands/start.ts","../src/adapters/dsh/adapter.ts","../src/adapters/dsh/translate.ts","../src/bot/active-runs.ts","../src/bot/pending-queue.ts","../src/bot/run-policy.ts","../src/bridge/channel.ts","../src/commands/index.ts","../src/core/logger.ts","../src/bridge/lark-channel.ts","../src/bridge/run-flow.ts","../src/card/run-state.ts","../src/card/run-renderer.ts","../src/onboard/registration.ts","../src/session/store.ts","../src/workspace/git-worktree.ts","../src/workspace/store.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { runDoctor } from './cli/commands/doctor.js';\nimport { runStart } from './cli/commands/start.js';\n\nfunction packageVersion(): string {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n}\n\nexport interface StartOptions {\n profile?: string;\n workspace?: string;\n appId?: string;\n appSecret?: string;\n tenant?: string;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name('dsh-lark-bot')\n .description('Bridge DeepSeek Harness into Feishu / Lark')\n .version(packageVersion(), '-v, --version');\n\n program\n .command('start')\n .description('Start the bridge in the foreground')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runStart(opts);\n });\n\n program\n .command('doctor')\n .description('Run local diagnostics')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runDoctor({ ...opts, version: packageVersion() });\n });\n\n return program;\n}\n\nexport async function main(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync([...argv]);\n}\n","import { stat } from 'node:fs/promises';\nimport { checkDshAvailability } from '../../adapters/dsh/availability.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport type { StartOptions } from '../../cli.js';\n\nexport interface DoctorOptions extends StartOptions {\n version?: string;\n output?: (text: string) => void;\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const store = new ConfigStore(paths.configFile);\n await store.load();\n const profile = store.getProfile(profileName);\n\n const lines: string[] = [\n 'dsh-lark-bot doctor',\n `version: ${options.version ?? 'unknown'}`,\n `node: ${process.version}`,\n `profile: ${profileName}`,\n `home: ${paths.root}`,\n `dsh_command: ${env.dshCommand}`,\n `dsh_args: ${env.dshArgs.join(',')}`,\n ];\n\n let critical = false;\n\n if (!profile) {\n lines.push('config: missing');\n critical = true;\n } else {\n lines.push(\n [\n 'config: ok',\n `tenant=${profile.tenant}`,\n `app_id=${profile.accounts.appId}`,\n `app_secret=${profile.accounts.appSecret ? 'present' : 'missing'}`,\n ].join(' '),\n );\n if (!profile.accounts.appId || !profile.accounts.appSecret) critical = true;\n }\n\n const workspace =\n options.workspace ??\n profile?.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n try {\n const info = await stat(workspace);\n lines.push(`workspace: ${workspace} (${info.isDirectory() ? 'directory' : 'not-directory'})`);\n } catch {\n lines.push(`workspace: ${workspace} (missing)`);\n }\n\n const availability = await checkDshAvailability({ command: env.dshCommand });\n if (availability.ok) {\n lines.push(`dsh: ok${availability.version ? ` (${availability.version})` : ''}`);\n } else {\n lines.push(`dsh: unavailable (${availability.error ?? 'unknown'})`);\n critical = true;\n }\n\n const output = options.output ?? ((text: string) => process.stdout.write(text));\n output(`${lines.join('\\n')}\\n`);\n if (critical) process.exitCode = 1;\n}\n","import { spawn } from 'cross-spawn';\nimport type { AgentAvailability } from '../types.js';\n\nexport interface AvailabilityCheckOptions {\n command: string;\n timeoutMs?: number;\n}\n\nexport async function checkDshAvailability(\n options: AvailabilityCheckOptions,\n): Promise<AgentAvailability> {\n const timeoutMs = options.timeoutMs ?? 5_000;\n\n return new Promise((resolve) => {\n const child = spawn(options.command, ['--version'], {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const finish = (result: AgentAvailability): void => {\n if (settled) return;\n settled = true;\n resolve(result);\n };\n\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n finish({ ok: false, error: `timed out after ${timeoutMs}ms`, version: undefined });\n }, timeoutMs);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n clearTimeout(timer);\n finish({ ok: false, error: error.message, version: undefined });\n });\n child.on('exit', (code) => {\n clearTimeout(timer);\n const version = stdout.trim();\n if (code !== 0 && !version) {\n finish({ ok: false, error: stderr.trim() || `exited with code ${String(code)}`, version: undefined });\n return;\n }\n finish({ ok: true, error: undefined, version: version || undefined });\n });\n });\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface AppPaths {\n root: string;\n configFile: string;\n activeProfileFile: string;\n profileDir: (profile: string) => string;\n profilePath: (profile: string, ...parts: string[]) => string;\n sessionsFile: (profile: string) => string;\n sessionCatalogFile: (profile: string) => string;\n workspacesFile: (profile: string) => string;\n mediaDir: (profile: string) => string;\n logsDir: (profile: string) => string;\n registryFile: string;\n locksDir: string;\n}\n\nexport function defaultHome(): string {\n const override = process.env.DSH_LARK_HOME?.trim();\n return override ? resolve(override) : join(homedir(), '.dsh-lark');\n}\n\nexport function resolveAppPaths(root: string = defaultHome()): AppPaths {\n const profileDir = (profile: string): string => join(root, 'profiles', profile);\n const profilePath = (profile: string, ...parts: string[]): string =>\n join(profileDir(profile), ...parts);\n\n return {\n root,\n configFile: join(root, 'config.json'),\n activeProfileFile: join(root, 'active-profile'),\n profileDir,\n profilePath,\n sessionsFile: (profile) => profilePath(profile, 'sessions.json'),\n sessionCatalogFile: (profile) => profilePath(profile, 'sessions.json.catalog.json'),\n workspacesFile: (profile) => profilePath(profile, 'workspaces.json'),\n mediaDir: (profile) => profilePath(profile, 'media'),\n logsDir: (profile) => profilePath(profile, 'logs'),\n registryFile: join(root, 'registry', 'processes.json'),\n locksDir: join(root, 'registry', 'locks'),\n };\n}\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { resolveDshRuntime } from './dsh-runtime.js';\n\nexport type LarkTenant = 'feishu' | 'lark';\n\nexport interface RuntimeEnv {\n home: string;\n tenant: LarkTenant;\n appId: string | undefined;\n appSecret: string | undefined;\n workspace: string | undefined;\n dshCommand: string;\n dshArgs: string[];\n provider: string;\n model: string;\n runTimeoutMs: number;\n stopGraceMs: number;\n}\n\nconst DEFAULTS = {\n tenant: 'feishu' as const,\n provider: 'deepseek-official',\n model: 'deepseek-v4-flash',\n runTimeoutMs: 300_000,\n stopGraceMs: 5_000,\n};\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction parseTenant(value: string | undefined): LarkTenant {\n const tenant = nonEmpty(value) ?? DEFAULTS.tenant;\n if (tenant !== 'feishu' && tenant !== 'lark') {\n throw new Error(`DSH_LARK_TENANT must be \"feishu\" or \"lark\", got \"${tenant}\"`);\n }\n return tenant;\n}\n\nfunction parseDshArgs(value: string | undefined): string[] {\n const raw = value?.trim();\n if (!raw) return [];\n return raw\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction parseTimeout(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.runTimeoutMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_RUN_TIMEOUT_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseStopGrace(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.stopGraceMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_STOP_GRACE_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nexport function loadRuntimeEnv(\n source: NodeJS.ProcessEnv = process.env,\n): RuntimeEnv {\n const homeOverride = nonEmpty(source.DSH_LARK_HOME);\n const workspace = nonEmpty(source.DSH_LARK_WORKSPACE);\n const home = homeOverride ? resolve(homeOverride) : join(homedir(), '.dsh-lark');\n const osHome = homedir();\n const dshCommand = nonEmpty(source.DSH_LARK_DSH_COMMAND);\n const rawDshArgs = nonEmpty(source.DSH_LARK_DSH_ARGS);\n const dshRuntime = resolveDshRuntime({\n home: osHome,\n env: source,\n ...(dshCommand ? { command: dshCommand } : {}),\n ...(rawDshArgs ? { args: parseDshArgs(rawDshArgs) } : {}),\n });\n\n return {\n home,\n tenant: parseTenant(source.DSH_LARK_TENANT),\n appId: nonEmpty(source.DSH_LARK_APP_ID),\n appSecret: nonEmpty(source.DSH_LARK_APP_SECRET),\n workspace: workspace ? resolve(workspace) : undefined,\n dshCommand: dshRuntime.command,\n dshArgs: dshRuntime.args,\n provider: nonEmpty(source.DSH_LARK_PROVIDER) ?? DEFAULTS.provider,\n model: nonEmpty(source.DSH_LARK_MODEL) ?? DEFAULTS.model,\n runTimeoutMs: parseTimeout(source.DSH_LARK_RUN_TIMEOUT_MS),\n stopGraceMs: parseStopGrace(source.DSH_LARK_STOP_GRACE_MS),\n };\n}\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface DshRuntimeSpec {\n command: string;\n args: string[];\n bin?: string;\n}\n\nconst DS_HARNESS_RELATIVE = join('@deepseek-ai', 'dsh', 'lib', 'bin.js');\n\nfunction firstExisting(...paths: string[]): string | undefined {\n return paths.find((path) => existsSync(path));\n}\n\nfunction children(root: string): string[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n .map((entry) => join(root, entry.name));\n } catch {\n return [];\n }\n}\n\nexport function discoverDshBin(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const dshHome = env.DSH_HOME?.trim() || join(home, '.dsh');\n\n const candidates = [\n join(dshHome, 'profiles', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.npm', '_npx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.cache', 'pnpm', 'dlx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.local', 'share', 'pnpm', 'node_modules', DS_HARNESS_RELATIVE),\n ];\n\n const direct = firstExisting(...candidates);\n if (direct) return direct;\n\n for (const root of [join(home, '.npm', '_npx'), join(home, '.cache', 'pnpm', 'dlx')]) {\n for (const child of children(root)) {\n const path = join(child, 'node_modules', DS_HARNESS_RELATIVE);\n if (existsSync(path)) return path;\n }\n }\n\n return undefined;\n}\n\nexport function resolveDshRuntime(\n input: {\n command?: string;\n args?: string[];\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n): DshRuntimeSpec {\n if (input.command || input.args) {\n return {\n command: input.command ?? 'node',\n args: input.args ?? ['--profile', 'headless'],\n };\n }\n\n const bin = discoverDshBin(input.home, input.env);\n if (bin) {\n return {\n command: 'node',\n args: [bin, '--profile', 'headless'],\n bin,\n };\n }\n\n return {\n command: 'dsh',\n args: ['--profile', 'headless'],\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport type { LarkTenant } from './env.js';\n\nexport interface ProfileConfig {\n schemaVersion: 1;\n agentKind: 'dsh';\n tenant: LarkTenant;\n accounts: {\n appId: string;\n appSecret: string;\n };\n workspaces: {\n default: string | undefined;\n };\n preferences: {\n model: string | undefined;\n stopGraceMs: number | undefined;\n runTimeoutMs: number | undefined;\n };\n}\n\nexport interface RootConfig {\n schemaVersion: 1;\n activeProfile: string;\n profiles: Record<string, ProfileConfig>;\n}\n\nexport class ConfigStore {\n private data: RootConfig | undefined;\n\n constructor(private readonly path: string) {}\n\n async load(): Promise<RootConfig> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RootConfig>;\n this.data = {\n schemaVersion: 1,\n activeProfile: parsed.activeProfile ?? 'default',\n profiles: parsed.profiles ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = {\n schemaVersion: 1,\n activeProfile: 'default',\n profiles: {},\n };\n }\n return this.data;\n }\n\n getActiveProfile(): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[data.activeProfile];\n }\n\n getProfile(name: string): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[name];\n }\n\n async saveProfile(\n name: string,\n input: {\n tenant: LarkTenant;\n appId: string;\n appSecret: string;\n workspace?: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n },\n ): Promise<void> {\n const data = this.getData();\n const existing = data.profiles[name];\n const profile: ProfileConfig = {\n schemaVersion: 1,\n agentKind: 'dsh',\n tenant: input.tenant,\n accounts: {\n appId: input.appId,\n appSecret: input.appSecret,\n },\n workspaces: {\n default: input.workspace ?? existing?.workspaces.default ?? undefined,\n },\n preferences: {\n model: input.model ?? existing?.preferences.model ?? undefined,\n stopGraceMs: input.stopGraceMs ?? existing?.preferences.stopGraceMs ?? undefined,\n runTimeoutMs: input.runTimeoutMs ?? existing?.preferences.runTimeoutMs ?? undefined,\n },\n };\n data.profiles[name] = profile;\n data.activeProfile = name;\n await this.persist();\n }\n\n private getData(): RootConfig {\n if (!this.data) {\n throw new Error('ConfigStore must be loaded before use');\n }\n return this.data;\n }\n\n private async persist(): Promise<void> {\n const data = this.getData();\n await mkdir(dirname(this.path), { recursive: true });\n await writeFileAtomic(this.path, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number;\n}\n\nexport async function writeFileAtomic(\n target: string,\n data: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n const directory = dirname(target);\n await mkdir(directory, { recursive: true });\n const temporary = join(directory, `.${randomBytes(8).toString('hex')}.tmp`);\n\n try {\n await writeFile(temporary, data, options.mode === undefined ? undefined : { mode: options.mode });\n await rename(temporary, target);\n } catch (error) {\n await rmSilently(temporary);\n throw error;\n }\n}\n\nasync function rmSilently(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n try {\n await rm(path, { force: true });\n } catch {\n // best effort cleanup only\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { NormalizedMessage } from '@larksuite/channel';\nimport { DshAdapter } from '../../adapters/dsh/adapter.js';\nimport { ActiveRuns } from '../../bot/active-runs.js';\nimport { PendingQueue } from '../../bot/pending-queue.js';\nimport { RunPolicyStore } from '../../bot/run-policy.js';\nimport { startChannel } from '../../bridge/channel.js';\nimport { adaptLarkChannel } from '../../bridge/lark-channel.js';\nimport { runAgentBatch } from '../../bridge/run-flow.js';\nimport type { StreamingChannel } from '../../bridge/types.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport { log } from '../../core/logger.js';\nimport { onboardPersonalAgent } from '../../onboard/registration.js';\nimport { SessionStore } from '../../session/store.js';\nimport { GitWorktreeManager } from '../../workspace/git-worktree.js';\nimport { WorkspaceStore } from '../../workspace/store.js';\nimport type { StartOptions } from '../../cli.js';\n\nconst DEBOUNCE_MS = 600;\n\nexport async function runStart(options: StartOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const configStore = new ConfigStore(paths.configFile);\n await configStore.load();\n\n if (env.appId && env.appSecret) {\n const profileInput: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: env.tenant,\n appId: env.appId,\n appSecret: env.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (env.workspace !== undefined) profileInput.workspace = env.workspace;\n await configStore.saveProfile(profileName, profileInput);\n }\n\n const profile = configStore.getProfile(profileName);\n if (!profile) {\n try {\n const created = await onboardPersonalAgent();\n const onboardingProfile: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: created.tenant,\n appId: created.appId,\n appSecret: created.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (env.workspace !== undefined) onboardingProfile.workspace = env.workspace;\n await configStore.saveProfile(profileName, onboardingProfile);\n } catch (error) {\n log.fail('onboarding', error);\n process.stderr.write('扫码创建应用失败,未写入本地配置。\\n');\n process.exitCode = 1;\n return;\n }\n }\n\n const activeProfile = configStore.getProfile(profileName);\n if (!activeProfile) {\n process.stderr.write('本地配置读取失败,请检查后重试。\\n');\n process.exitCode = 1;\n return;\n }\n\n const defaultWorkspace =\n options.workspace ??\n activeProfile.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n await mkdir(defaultWorkspace, { recursive: true });\n\n const sessions = new SessionStore(paths.sessionsFile(profileName));\n const workspaces = new WorkspaceStore(paths.workspacesFile(profileName));\n const worktreeManager = new GitWorktreeManager({\n worktreesRoot: paths.profilePath(profileName, 'worktrees'),\n });\n await Promise.all([sessions.load(), workspaces.load()]);\n\n const adapterOptions: { command: string; args: string[]; stopGraceMs?: number } = {\n command: env.dshCommand,\n args: env.dshArgs,\n stopGraceMs: env.stopGraceMs,\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n Object.assign(adapterOptions, { stopGraceMs: activeProfile.preferences.stopGraceMs });\n }\n const adapter = new DshAdapter(adapterOptions);\n const activeRuns = new ActiveRuns();\n const runPolicies = new RunPolicyStore();\n let streaming: StreamingChannel | undefined;\n\n const pending = new PendingQueue<NormalizedMessage>(DEBOUNCE_MS, async (scope, batch) => {\n if (!streaming) return;\n const first = batch[0];\n if (!first) return;\n pending.block(scope);\n try {\n const runInput: Parameters<typeof runAgentBatch>[0] = {\n scope,\n chatId: first.chatId,\n messages: batch.map((message) => message.content),\n adapter,\n sessions,\n workspaces,\n workspaceManager: worktreeManager,\n activeRuns,\n runPolicies,\n channel: streaming,\n defaultWorkspace,\n replyTo: first.messageId,\n runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n };\n if (activeProfile.preferences.model !== undefined) runInput.model = activeProfile.preferences.model;\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n runInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n await runAgentBatch(runInput);\n } finally {\n pending.unblock(scope);\n }\n });\n\n const channelInput: Parameters<typeof startChannel>[0] = {\n appId: activeProfile.accounts.appId,\n appSecret: activeProfile.accounts.appSecret,\n tenant: activeProfile.tenant,\n adapter,\n sessions,\n workspaces,\n activeRuns,\n runPolicies,\n defaultRunTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n pending,\n defaultWorkspace,\n };\n if (activeProfile.preferences.model !== undefined) channelInput.model = activeProfile.preferences.model;\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n channelInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n const bridge = await startChannel(channelInput);\n streaming = adaptLarkChannel(bridge.channel);\n\n log.info('cli', 'started', {\n profile: profileName,\n home: paths.root,\n tenant: activeProfile.tenant,\n workspace: defaultWorkspace,\n });\n process.stdout.write(`dsh-lark-bot 已启动,profile=${profileName}\\n`);\n\n await waitForShutdown();\n await bridge.disconnect();\n await Promise.all([sessions.flush(), workspaces.flush()]);\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n const shutdown = (): void => {\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { spawn } from 'cross-spawn';\nimport { createInterface } from 'node:readline';\nimport type { ChildProcess } from 'node:child_process';\nimport { checkDshAvailability } from './availability.js';\nimport { plainOutputEvent, translateDshLine } from './translate.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\n\nexport interface DshAdapterOptions {\n command?: string;\n args?: string[];\n stopGraceMs?: number;\n}\n\ntype DshChild = ChildProcess;\n\nexport class DshAdapter implements AgentAdapter {\n readonly id = 'dsh';\n readonly displayName = 'DeepSeek Harness';\n\n private readonly command: string;\n private readonly args: string[];\n private readonly stopGraceMs: number;\n\n constructor(options: DshAdapterOptions = {}) {\n this.command = options.command ?? 'dsh';\n this.args = options.args ?? ['--profile', 'headless'];\n this.stopGraceMs = options.stopGraceMs ?? 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n checkAvailability(): Promise<AgentAvailability> {\n return checkDshAvailability({ command: this.command });\n }\n\n run(options: AgentRunOptions): AgentRun {\n const child = spawn(\n this.command,\n [...this.args, options.prompt],\n {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n ) as DshChild;\n\n child.stdin?.end();\n\n const stderrChunks: Buffer[] = [];\n let runtimeError: Error | null = null;\n child.stderr?.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n child.on('error', (error: Error) => {\n runtimeError = error;\n });\n\n return {\n runId: options.runId,\n events: createEventStream(child, stderrChunks, () => runtimeError, {\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n }),\n stop: () => stopChild(child, this.stopGraceMs),\n waitForExit: (timeoutMs) => waitForChildExit(child, timeoutMs),\n };\n }\n}\n\nasync function* createEventStream(\n child: DshChild,\n stderrChunks: Buffer[],\n getError: () => Error | null,\n system: {\n sessionId: string | undefined;\n cwd: string | undefined;\n model: string | undefined;\n },\n): AsyncGenerator<AgentEvent> {\n if (!child.pid) {\n const error = getError();\n yield {\n type: 'error',\n message: error ? `failed to spawn dsh: ${error.message}` : 'spawn returned no pid',\n terminationReason: 'failed',\n };\n return;\n }\n\n yield {\n type: 'system',\n sessionId: system.sessionId,\n cwd: system.cwd,\n model: system.model,\n };\n\n if (!child.stdout) {\n yield {\n type: 'error',\n message: 'dsh stdout stream is unavailable',\n terminationReason: 'failed',\n };\n return;\n }\n\n const lines = createInterface({ input: child.stdout, crlfDelay: Infinity });\n const plainLines: string[] = [];\n let emittedProtocol = false;\n let terminalEmitted = false;\n\n for await (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const events = translateDshLine(trimmed);\n if (events.length > 0) {\n emittedProtocol = true;\n for (const event of events) {\n if (event.type === 'done' || event.type === 'error') terminalEmitted = true;\n yield event;\n }\n } else {\n plainLines.push(trimmed);\n }\n }\n\n const exitCode = await waitForExitResult(child, 0).then((value) => value.code);\n const runtimeError = getError();\n\n if (!terminalEmitted) {\n if (exitCode !== null && exitCode !== 0) {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();\n const detail = stderr ? `: ${stderr.slice(0, 500)}` : '';\n yield {\n type: 'error',\n message: `dsh exited with code ${exitCode}${detail}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (runtimeError) {\n yield {\n type: 'error',\n message: `dsh runtime error: ${runtimeError.message}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (emittedProtocol) {\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n } else {\n yield* plainOutputEvent(plainLines.join('\\n'));\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n }\n }\n}\n\nasync function waitForExitResult(\n child: DshChild,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return { code: child.exitCode, timedOut: false };\n }\n\n return new Promise((resolve) => {\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n child.once('exit', onExit);\n });\n}\n\nasync function stopChild(child: DshChild, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.kill('SIGTERM');\n const stopped = await waitForExitResult(child, graceMs);\n if (!stopped.timedOut) return;\n child.kill('SIGKILL');\n}\n\nasync function waitForChildExit(child: DshChild, timeoutMs: number): Promise<boolean> {\n const result = await waitForExitResult(child, timeoutMs);\n return !result.timedOut && result.code !== null;\n}\n","import type { AgentEvent } from '../types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function translateDshLine(line: string): AgentEvent[] {\n const trimmed = line.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') return [];\n\n switch (parsed.type) {\n case 'system':\n return [\n {\n type: 'system',\n sessionId: stringValue(parsed.sessionId),\n cwd: stringValue(parsed.cwd),\n model: stringValue(parsed.model),\n },\n ];\n case 'text':\n return [{ type: 'text', delta: stringValue(parsed.delta) ?? '' }];\n case 'final_text':\n return [{ type: 'final_text', content: stringValue(parsed.content) ?? '' }];\n case 'thinking':\n return [{ type: 'thinking', delta: stringValue(parsed.delta) ?? '' }];\n case 'tool_use':\n return [\n {\n type: 'tool_use',\n id: stringValue(parsed.id) ?? 'unknown',\n name: stringValue(parsed.name) ?? 'tool',\n input: parsed.input,\n },\n ];\n case 'tool_result':\n return [\n {\n type: 'tool_result',\n id: stringValue(parsed.id) ?? 'unknown',\n output: stringValue(parsed.output) ?? '',\n isError: parsed.isError === true,\n },\n ];\n case 'done':\n return [\n {\n type: 'done',\n sessionId: stringValue(parsed.sessionId),\n terminationReason: 'normal',\n },\n ];\n case 'error':\n return [\n {\n type: 'error',\n message: stringValue(parsed.message) ?? 'dsh failed',\n terminationReason: 'failed',\n },\n ];\n default:\n return [];\n }\n } catch {\n return [];\n }\n}\n\nexport function plainOutputEvent(output: string): AgentEvent[] {\n const trimmed = output.trim();\n return trimmed ? [{ type: 'final_text', content: trimmed }] : [];\n}\n","export interface ActiveRunHandle {\n runId: string;\n stop(): Promise<void>;\n}\n\nexport class ActiveRuns {\n private readonly runs = new Map<string, ActiveRunHandle>();\n\n set(scope: string, handle: ActiveRunHandle): void {\n this.runs.set(scope, handle);\n }\n\n get(scope: string): ActiveRunHandle | undefined {\n return this.runs.get(scope);\n }\n\n delete(scope: string): boolean {\n return this.runs.delete(scope);\n }\n\n async interrupt(scope: string): Promise<boolean> {\n const handle = this.runs.get(scope);\n if (!handle) return false;\n this.runs.delete(scope);\n await handle.stop();\n return true;\n }\n}\n","export type PendingFlush<T> = (scope: string, batch: T[]) => void | Promise<void>;\n\nexport class PendingQueue<T> {\n private readonly pending = new Map<string, T[]>();\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly blocked = new Set<string>();\n private readonly flushing = new Set<string>();\n\n constructor(\n private readonly quietMs: number,\n private readonly onFlush: PendingFlush<T>,\n ) {}\n\n push(scope: string, item: T): void {\n const batch = this.pending.get(scope) ?? [];\n batch.push(item);\n this.pending.set(scope, batch);\n this.schedule(scope);\n }\n\n block(scope: string): void {\n this.blocked.add(scope);\n this.clearTimer(scope);\n }\n\n unblock(scope: string): void {\n this.blocked.delete(scope);\n this.schedule(scope);\n }\n\n async flushNow(scope: string): Promise<void> {\n this.clearTimer(scope);\n if (this.flushing.has(scope)) return;\n\n const batch = this.pending.get(scope) ?? [];\n this.pending.delete(scope);\n if (batch.length === 0) return;\n\n this.flushing.add(scope);\n try {\n await this.onFlush(scope, batch);\n } finally {\n this.flushing.delete(scope);\n }\n }\n\n hasPending(scope: string): boolean {\n return (this.pending.get(scope)?.length ?? 0) > 0;\n }\n\n isBlocked(scope: string): boolean {\n return this.blocked.has(scope);\n }\n\n private schedule(scope: string): void {\n if (this.blocked.has(scope) || this.flushing.has(scope)) return;\n if (this.timers.has(scope)) return;\n if (!this.hasPending(scope)) return;\n\n this.timers.set(\n scope,\n setTimeout(() => {\n this.timers.delete(scope);\n void this.flushNow(scope);\n }, this.quietMs),\n );\n }\n\n private clearTimer(scope: string): void {\n const timer = this.timers.get(scope);\n if (timer === undefined) return;\n clearTimeout(timer);\n this.timers.delete(scope);\n }\n}\n","export class RunPolicyStore {\n private readonly timeouts = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.timeouts.get(scope);\n }\n\n set(scope: string, runTimeoutMs: number): void {\n this.timeouts.set(scope, runTimeoutMs);\n }\n\n clear(scope: string): boolean {\n return this.timeouts.delete(scope);\n }\n}\n","import { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { PendingQueue } from '../bot/pending-queue.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport { tryHandleCommand, type CommandChannel } from '../commands/index.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { adaptLarkChannel } from './lark-channel.js';\n\nexport interface StartChannelDeps {\n appId: string;\n appSecret: string;\n tenant: 'feishu' | 'lark';\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n defaultRunTimeoutMs: number;\n pending: PendingQueue<NormalizedMessage>;\n defaultWorkspace: string;\n model?: string;\n stopGraceMs?: number;\n createChannel?: typeof createLarkChannel;\n}\n\nexport interface BridgeChannel {\n channel: LarkChannel;\n disconnect(): Promise<void>;\n}\n\nexport async function startChannel(deps: StartChannelDeps): Promise<BridgeChannel> {\n const channel = (deps.createChannel ?? createLarkChannel)({\n appId: deps.appId,\n appSecret: deps.appSecret,\n domain:\n deps.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot',\n policy: {\n dmMode: 'open',\n requireMention: true,\n respondToMentionAll: false,\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n const streaming = adaptLarkChannel(channel);\n const commandChannel: CommandChannel = streaming;\n\n channel.on({\n message: async (msg) => {\n const scope = scopeForMessage(msg);\n const context = {\n scope,\n chatId: msg.chatId,\n messageId: msg.messageId,\n threadId: msg.threadId,\n chatMode: msg.chatMode ?? msg.chatType,\n sessions: deps.sessions,\n workspaces: deps.workspaces,\n activeRuns: deps.activeRuns,\n runPolicies: deps.runPolicies,\n defaultRunTimeoutMs: deps.defaultRunTimeoutMs,\n channel: commandChannel,\n defaultWorkspace: deps.defaultWorkspace,\n };\n\n const handled = await tryHandleCommand(msg.content, context).catch((error: unknown) => {\n log.fail('channel-command', error, { scope });\n return false;\n });\n if (!handled) deps.pending.push(scope, msg);\n },\n cardAction: async (event) => {\n const value =\n event.action.value && typeof event.action.value === 'object'\n ? (event.action.value as Record<string, unknown>)\n : undefined;\n if (value?.cmd === 'stop') {\n const scope = event.raw\n ? await resolveCardScope(event.chatId, event.raw as { message?: { thread_id?: string } })\n : event.chatId;\n await deps.activeRuns.interrupt(scope);\n }\n },\n reconnecting: () => {\n log.warn('channel', 'reconnecting', {});\n },\n reconnected: () => {\n log.info('channel', 'reconnected', {});\n },\n error: (error) => {\n log.fail('channel', error);\n },\n });\n\n await channel.connect();\n return {\n channel,\n disconnect: () => channel.disconnect(),\n };\n}\n\nfunction scopeForMessage(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n}\n\nasync function resolveCardScope(\n chatId: string,\n raw: { message?: { thread_id?: string } },\n): Promise<string> {\n return raw.message?.thread_id ? `${chatId}:${raw.message.thread_id}` : chatId;\n}\n","import { resolve } from 'node:path';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\n\nexport interface CommandChannel {\n sendMarkdown(\n chatId: string,\n markdown: string,\n options?: { replyTo?: string },\n ): Promise<void>;\n}\n\nexport interface CommandContext {\n scope: string;\n chatId: string;\n messageId: string;\n threadId: string | undefined;\n chatMode: 'p2p' | 'group' | 'topic';\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n defaultRunTimeoutMs: number;\n channel: CommandChannel;\n defaultWorkspace: string;\n}\n\ntype Handler = (args: string, ctx: CommandContext) => Promise<void>;\n\nconst HELP = [\n '**dsh-lark-bot 命令**',\n '',\n '- `/new` `/reset` — 开始新会话',\n '- `/cd <path>` — 切换工作目录并重置会话',\n '- `/ws list|save <name>|use <name>|remove <name>` — 管理工作空间',\n '- `/status` — 查看当前状态',\n '- `/stop` — 终止当前任务',\n '- `/timeout [N|off|default]` — 查看或设置当前会话运行超时',\n '- `/help` — 显示本帮助',\n].join('\\n');\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nasync function handleNew(_args: string, ctx: CommandContext): Promise<void> {\n const wasRunning = await ctx.activeRuns.interrupt(ctx.scope);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, wasRunning ? '已中断当前任务并开始新会话。' : '已开始新会话。');\n}\n\nasync function handleCd(args: string, ctx: CommandContext): Promise<void> {\n const path = args.trim();\n if (!path) {\n await reply(ctx, '用法:`/cd <path>`');\n return;\n }\n const cwd = resolve(path);\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换工作目录:\\`${cwd}\\`,会话已重置。`);\n}\n\nasync function handleWs(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const name = rest.join(' ').trim();\n\n if (!sub || sub === 'list') {\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const named = ctx.workspaces.listNamed();\n const lines = Object.entries(named).map(\n ([key, value]) => `- **${key}** → \\`${value}\\`${value === current ? ' ← 当前' : ''}`,\n );\n await reply(\n ctx,\n [\n `当前 cwd:\\`${current}\\``,\n '',\n ...(lines.length > 0 ? lines : ['暂无命名工作空间。']),\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'save') {\n if (!name) {\n await reply(ctx, '用法:`/ws save <name>`');\n return;\n }\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n ctx.workspaces.saveNamed(name, current);\n await reply(ctx, `已保存工作空间:**${name}** → \\`${current}\\``);\n return;\n }\n\n if (sub === 'use') {\n if (!name) {\n await reply(ctx, '用法:`/ws use <name>`');\n return;\n }\n const cwd = ctx.workspaces.getNamed(name);\n if (!cwd) {\n await reply(ctx, `未找到工作空间:**${name}**`);\n return;\n }\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换到工作空间:**${name}** → \\`${cwd}\\``);\n return;\n }\n\n if (sub === 'remove') {\n if (!name) {\n await reply(ctx, '用法:`/ws remove <name>`');\n return;\n }\n const removed = ctx.workspaces.removeNamed(name);\n await reply(ctx, removed ? `已删除工作空间:**${name}**` : `未找到工作空间:**${name}**`);\n return;\n }\n\n await reply(ctx, '未知 `/ws` 子命令,请使用 list / save / use / remove。');\n}\n\nasync function handleStatus(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const session = ctx.sessions.getRaw(ctx.scope)?.sessionId ?? '(无)';\n const running = Boolean(ctx.activeRuns.get(ctx.scope));\n const scopeLabel =\n ctx.chatMode === 'topic' ? `${ctx.scope}(话题独立 session)` : ctx.scope;\n\n await reply(\n ctx,\n [\n `🧭 **scope**: \\`${scopeLabel}\\``,\n `📁 **cwd**: \\`${cwd}\\``,\n `🔗 **session**: \\`${session}\\``,\n `🏃 **active run**: ${running ? 'yes' : 'no'}`,\n ].join('\\n'),\n );\n}\n\nasync function handleStop(_args: string, ctx: CommandContext): Promise<void> {\n const stopped = await ctx.activeRuns.interrupt(ctx.scope);\n await reply(ctx, stopped ? '已请求终止当前任务。' : '当前没有运行中的任务。');\n}\n\nasync function handleTimeout(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effectiveMs = ctx.runPolicies.get(ctx.scope) ?? ctx.defaultRunTimeoutMs;\n\n if (!input) {\n const minutes = effectiveMs > 0 ? Math.round(effectiveMs / 60_000) : 0;\n await reply(\n ctx,\n minutes > 0\n ? `当前会话运行超时:${minutes} 分钟。可用 \\`/timeout <N|off|default>\\` 调整。`\n : '当前会话运行超时:关闭。',\n );\n return;\n }\n\n if (input === 'off') {\n ctx.runPolicies.set(ctx.scope, 0);\n await reply(ctx, '已关闭当前会话运行超时。');\n return;\n }\n\n if (input === 'default') {\n ctx.runPolicies.clear(ctx.scope);\n await reply(ctx, '已恢复默认运行超时。');\n return;\n }\n\n const minutes = Number(input);\n if (!Number.isInteger(minutes) || minutes <= 0) {\n await reply(ctx, '用法:`/timeout <N|off|default>`,N 为大于 0 的分钟数。');\n return;\n }\n\n ctx.runPolicies.set(ctx.scope, minutes * 60_000);\n await reply(ctx, `已设置当前会话运行超时:${minutes} 分钟。`);\n}\n\nasync function handleHelp(_args: string, ctx: CommandContext): Promise<void> {\n await reply(ctx, HELP);\n}\n\nconst handlers: Record<string, Handler> = {\n '/new': handleNew,\n '/reset': handleNew,\n '/cd': handleCd,\n '/ws': handleWs,\n '/status': handleStatus,\n '/stop': handleStop,\n '/timeout': handleTimeout,\n '/help': handleHelp,\n};\n\nexport async function tryHandleCommand(text: string, ctx: CommandContext): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed.startsWith('/')) return false;\n const [command, ...rest] = trimmed.split(/\\s+/);\n const handler = handlers[command ?? ''];\n if (!handler) return false;\n await handler(rest.join(' '), ctx);\n return true;\n}\n","import type { Writable } from 'node:stream';\n\ntype LogLevel = 'info' | 'warn' | 'error';\n\nexport interface LogFields {\n [key: string]: unknown;\n}\n\nconst REDACTED = '[redacted]';\nconst SENSITIVE_KEY = /(secret|token|password|api[_-]?key)/i;\n\nfunction redactValue(value: unknown, key: string, depth: number): unknown {\n if (SENSITIVE_KEY.test(key)) return REDACTED;\n if (depth === 0) return value;\n if (Array.isArray(value)) {\n return value.map((item, index) => redactValue(item, `${key}.${index}`, depth - 1));\n }\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactValue(childValue, childKey, depth - 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactFields(fields: LogFields, depth = 4): LogFields {\n return redactValue(fields, '', depth) as LogFields;\n}\n\nfunction serializeMessage(\n level: LogLevel,\n category: string,\n event: string,\n fields: LogFields,\n): string {\n const entry = {\n time: new Date().toISOString(),\n level,\n category,\n event,\n fields: redactFields(fields),\n };\n return JSON.stringify(entry);\n}\n\nexport interface Logger {\n info(category: string, event: string, fields?: LogFields): void;\n warn(category: string, event: string, fields?: LogFields): void;\n error(category: string, event: string, fields?: LogFields): void;\n fail(category: string, error: unknown, fields?: LogFields): void;\n}\n\nexport function createLogger(output: Writable = process.stderr): Logger {\n const write = (level: LogLevel, category: string, event: string, fields: LogFields): void => {\n output.write(`${serializeMessage(level, category, event, fields)}\\n`);\n };\n\n return {\n info: (category, event, fields = {}) => write('info', category, event, fields),\n warn: (category, event, fields = {}) => write('warn', category, event, fields),\n error: (category, event, fields = {}) => write('error', category, event, fields),\n fail(category, error, fields = {}) {\n const message = error instanceof Error ? error.message : String(error);\n write('error', category, 'fail', { message, ...fields });\n },\n };\n}\n\nexport const log = createLogger();\n","import type {\n CardStreamController as LarkCardStreamController,\n LarkChannel,\n SendOptions,\n} from '@larksuite/channel';\nimport type { CommandChannel } from '../commands/index.js';\nimport type { StreamingChannel } from './types.js';\n\nexport function adaptLarkChannel(channel: LarkChannel): StreamingChannel {\n const base: CommandChannel = {\n async sendMarkdown(chatId, markdown, options) {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n await channel.send(chatId, { markdown }, sendOptions);\n },\n };\n\n return {\n ...base,\n async streamCard(chatId, initial, producer, options) {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n await channel.stream(\n chatId,\n {\n card: {\n initial,\n producer: async (controller: LarkCardStreamController) => {\n await producer(controller);\n },\n },\n },\n sendOptions,\n );\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AgentAdapter, AgentEvent } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport {\n finalizeIfRunning,\n initialState,\n markIdleTimeout,\n markInterrupted,\n reduce,\n type RunState,\n} from '../card/run-state.js';\nimport { renderCard } from '../card/run-renderer.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport type { GitWorktreeManager } from '../workspace/git-worktree.js';\nimport type { StreamingChannel } from './types.js';\n\nexport interface RunFlowInput {\n scope: string;\n chatId: string;\n messages: string[];\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n workspaceManager?: GitWorktreeManager;\n activeRuns: ActiveRuns;\n runPolicies?: RunPolicyStore;\n channel: StreamingChannel;\n defaultWorkspace: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n replyTo?: string;\n}\n\nexport async function runAgentBatch(input: RunFlowInput): Promise<void> {\n const replyOptions = input.replyTo ? { replyTo: input.replyTo } : {};\n\n if (input.activeRuns.get(input.scope)) {\n await input.channel.sendMarkdown(input.chatId, '当前会话已有任务正在运行,请先 `/stop` 或等待完成。', {\n ...replyOptions,\n });\n return;\n }\n\n const requestedCwd = input.workspaces.cwdFor(input.scope) ?? input.defaultWorkspace;\n const workspace = input.workspaceManager\n ? await input.workspaceManager.ensure(input.scope, requestedCwd)\n : { cwd: requestedCwd };\n const cwd = workspace.cwd;\n const sessionId = input.sessions.resumeFor(input.scope, cwd);\n const history = input.sessions.historyFor(input.scope, cwd);\n const prompt = buildPrompt(history, input.messages);\n const runId = randomUUID();\n\n const run = input.adapter.run({\n runId,\n prompt,\n cwd,\n sessionId,\n model: input.model,\n images: undefined,\n stopGraceMs: input.stopGraceMs,\n });\n input.activeRuns.set(input.scope, { runId, stop: run.stop });\n\n let state: RunState = initialState;\n const stopRequested = { value: false };\n const timeoutMs = input.runPolicies?.get(input.scope) ?? input.runTimeoutMs ?? 0;\n let timedOut = false;\n let assistantOutput = '';\n\n try {\n await input.channel.streamCard(\n input.chatId,\n renderCard(state),\n async (controller) => {\n const consume = async (): Promise<void> => {\n for await (const event of run.events) {\n if (timedOut) return;\n state = applyEvent(state, event, stopRequested);\n if (event.type === 'final_text') {\n assistantOutput = event.content;\n } else if (event.type === 'text') {\n assistantOutput += event.delta;\n }\n if (event.type === 'system' && event.sessionId) {\n input.sessions.set(input.scope, event.sessionId, event.cwd ?? cwd);\n }\n await controller.update(renderCard(state));\n }\n };\n\n let timeoutTimer: NodeJS.Timeout | undefined;\n const timeoutPromise =\n timeoutMs > 0\n ? new Promise<void>((resolve) => {\n timeoutTimer = setTimeout(() => {\n timedOut = true;\n void run.stop();\n resolve();\n }, timeoutMs);\n })\n : undefined;\n\n try {\n if (timeoutPromise) {\n await Promise.race([consume(), timeoutPromise]);\n } else {\n await consume();\n }\n\n state = timedOut\n ? markIdleTimeout(state, timeoutMs / 60_000)\n : finalizeIfRunning(state);\n await controller.update(renderCard(state));\n } finally {\n if (timeoutTimer !== undefined) clearTimeout(timeoutTimer);\n }\n },\n replyOptions,\n );\n input.sessions.recordExchange(input.scope, cwd, input.messages, assistantOutput);\n } catch (error) {\n log.fail('run-flow', error, { scope: input.scope, runId });\n state = markInterrupted(state);\n try {\n await input.channel.sendMarkdown(input.chatId, `⚠️ agent 运行失败:${errorMessage(error)}`, {\n ...replyOptions,\n });\n } catch {\n // best effort; the card may already have failed\n }\n } finally {\n input.activeRuns.delete(input.scope);\n }\n}\n\nfunction buildPrompt(\n history: Array<{ role: 'user' | 'assistant'; content: string }>,\n messages: string[],\n): string {\n if (history.length === 0) return messages.join('\\n\\n');\n\n const transcript = history\n .map((message) => `${message.role === 'user' ? 'User' : 'Assistant'}: ${message.content}`)\n .join('\\n\\n');\n\n return [\n 'Continue the conversation using the history below.',\n '',\n transcript,\n '',\n `Current user message:\\n${messages.join('\\n\\n')}`,\n ].join('\\n');\n}\n\nfunction applyEvent(\n state: RunState,\n event: AgentEvent,\n stopRequested: { value: boolean },\n): RunState {\n if (event.type === 'done' && event.terminationReason === 'interrupted') {\n stopRequested.value = true;\n return markInterrupted(state);\n }\n if (event.type === 'error' && event.terminationReason === 'timeout') {\n return markIdleTimeout(state, 0);\n }\n return reduce(state, event);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { AgentEvent } from '../adapters/types.js';\n\nexport type ToolStatus = 'running' | 'done' | 'error';\n\nexport interface ToolEntry {\n id: string;\n name: string;\n input: unknown;\n status: ToolStatus;\n output?: string;\n}\n\nexport type Block =\n | { kind: 'text'; content: string; streaming: boolean }\n | { kind: 'tool'; tool: ToolEntry };\n\nexport type FooterStatus = 'thinking' | 'tool_running' | 'streaming' | null;\nexport type Terminal = 'running' | 'done' | 'interrupted' | 'error' | 'idle_timeout';\n\nexport interface RunState {\n blocks: Block[];\n reasoning: { content: string; active: boolean };\n footer: FooterStatus;\n terminal: Terminal;\n errorMsg: string | undefined;\n idleTimeoutMinutes: number | undefined;\n}\n\nexport const initialState: RunState = {\n blocks: [],\n reasoning: { content: '', active: false },\n footer: 'thinking',\n terminal: 'running',\n errorMsg: undefined,\n idleTimeoutMinutes: undefined,\n};\n\nfunction closeStreamingText(blocks: Block[]): Block[] {\n return blocks.map((block) =>\n block.kind === 'text' && block.streaming ? { ...block, streaming: false } : block,\n );\n}\n\nexport function reduce(state: RunState, event: AgentEvent): RunState {\n switch (event.type) {\n case 'text': {\n const last = state.blocks[state.blocks.length - 1];\n if (last?.kind === 'text' && last.streaming) {\n return {\n ...state,\n blocks: [\n ...state.blocks.slice(0, -1),\n { ...last, content: last.content + event.delta },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n return {\n ...state,\n blocks: [...state.blocks, { kind: 'text', content: event.delta, streaming: true }],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n\n case 'thinking':\n return {\n ...state,\n reasoning: {\n content: state.reasoning.content + event.delta,\n active: true,\n },\n footer: 'thinking',\n };\n\n case 'final_text':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n { kind: 'text', content: event.content, streaming: false },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: null,\n };\n\n case 'tool_use':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n {\n kind: 'tool',\n tool: {\n id: event.id,\n name: event.name,\n input: event.input,\n status: 'running',\n },\n },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'tool_running',\n };\n\n case 'tool_result':\n return {\n ...state,\n blocks: state.blocks.map((block) => {\n if (block.kind !== 'tool' || block.tool.id !== event.id) return block;\n return {\n ...block,\n tool: {\n ...block.tool,\n status: event.isError ? 'error' : 'done',\n output: event.output,\n },\n };\n }),\n };\n\n case 'error':\n return {\n ...state,\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'error',\n errorMsg: event.terminationReason === 'failed' ? event.message : undefined,\n idleTimeoutMinutes: undefined,\n footer: null,\n };\n\n case 'done':\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'done',\n footer: null,\n };\n\n default:\n return state;\n }\n}\n\nexport function markInterrupted(state: RunState): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'interrupted',\n footer: null,\n };\n}\n\nexport function markIdleTimeout(state: RunState, minutes: number): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'idle_timeout',\n footer: null,\n idleTimeoutMinutes: minutes,\n };\n}\n\nexport function finalizeIfRunning(state: RunState): RunState {\n if (state.terminal !== 'running') return state;\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'done',\n footer: null,\n };\n}\n","import type { Block, FooterStatus, RunState, ToolEntry } from './run-state.js';\n\nfunction markdown(content: string): object {\n return { tag: 'markdown', content };\n}\n\nfunction noteMd(content: string): object {\n return { tag: 'markdown', content, text_size: 'notation' };\n}\n\nfunction footerStatus(status: Exclude<FooterStatus, null>): object {\n const text =\n status === 'thinking'\n ? '🧠 正在思考'\n : status === 'tool_running'\n ? '🧰 正在调用工具'\n : '✍️ 正在输出';\n return noteMd(text);\n}\n\nfunction summaryText(state: RunState): string {\n if (state.terminal === 'interrupted') return '已中断';\n if (state.terminal === 'idle_timeout') return '已超时';\n if (state.terminal === 'error') return '出错';\n if (state.terminal === 'done') return '已完成';\n if (state.footer === 'tool_running') return '正在调用工具';\n if (state.footer === 'streaming') return '正在输出';\n return '思考中';\n}\n\nfunction stopButton(): object {\n return {\n tag: 'button',\n text: { tag: 'plain_text', content: '⏹ 终止' },\n type: 'danger',\n value: { cmd: 'stop' },\n };\n}\n\nfunction textBlock(block: Extract<Block, { kind: 'text' }>): object {\n return markdown(block.content);\n}\n\nfunction toolBlock(tool: ToolEntry): object {\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n return markdown(`${icon} **${tool.name}**`);\n}\n\nexport function renderCard(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 思考完成:${state.reasoning.content.slice(0, 300)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n elements.push(block.kind === 'text' ? textBlock(block) : toolBlock(block.tool));\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done' && elements.length === 0) {\n elements.push(noteMd('_(未返回内容)_'));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n","import { registerApp, type RegisterAppOptions, type RegisterAppResult } from '@larksuite/channel';\nimport qrcode from 'qrcode-terminal';\nimport type { LarkTenant } from '../config/env.js';\n\nexport interface OnboardedApp {\n appId: string;\n appSecret: string;\n tenant: LarkTenant;\n}\n\nexport interface RegistrationDeps {\n register?: (options: RegisterAppOptions) => Promise<RegisterAppResult>;\n renderQr?: (value: string) => void;\n print?: (line: string) => void;\n source?: string;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_SOURCE = 'dsh-lark-bot';\n\nexport async function onboardPersonalAgent(\n deps: RegistrationDeps = {},\n): Promise<OnboardedApp> {\n const register = deps.register ?? registerApp;\n const renderQr = deps.renderQr ?? ((value) => qrcode.generate(value, { small: true }));\n const print = deps.print ?? ((line) => process.stdout.write(`${line}\\n`));\n\n print('');\n print('未检测到飞书 / Lark 应用凭据,进入扫码创建向导。');\n print('');\n\n const result = await register({\n source: deps.source ?? DEFAULT_SOURCE,\n ...(deps.signal ? { signal: deps.signal } : {}),\n onQRCodeReady: (info) => {\n print('请使用飞书 / Lark App 扫描以下二维码,创建或选择 PersonalAgent 应用:');\n print('');\n renderQr(info.url);\n print('');\n const minutes = Math.max(1, Math.round(info.expireIn / 60));\n print(`二维码有效期约 ${minutes} 分钟。`);\n print(`也可以直接在浏览器打开:${info.url}`);\n print('');\n },\n onStatusChange: (info) => {\n if (info.status === 'domain_switched') {\n print('已识别到国际版租户,自动切换到 larksuite.com 域名。');\n } else if (info.status === 'slow_down') {\n print('轮询速度过快,已自动降速。');\n }\n },\n });\n\n const tenant: LarkTenant = result.user_info?.tenant_brand === 'lark' ? 'lark' : 'feishu';\n\n print('✓ PersonalAgent 应用创建 / 绑定成功。');\n print(` App ID: ${result.client_id}`);\n print(` Tenant: ${tenant}`);\n print('');\n\n return {\n appId: result.client_id,\n appSecret: result.client_secret,\n tenant,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface SessionRecord {\n sessionId: string | undefined;\n cwd: string;\n messages: ChatMessage[];\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface SessionData {\n chats: Record<string, SessionRecord>;\n}\n\nexport class SessionStore {\n private data: SessionData = { chats: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<SessionData>;\n this.data = {\n chats: parsed.chats ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n getRaw(scopeId: string): SessionRecord | undefined {\n return this.data.chats[scopeId];\n }\n\n set(scopeId: string, sessionId: string | undefined, cwd: string): void {\n const existing = this.data.chats[scopeId];\n this.data.chats[scopeId] = {\n sessionId: sessionId ?? existing?.sessionId,\n cwd,\n messages: existing?.messages ?? [],\n };\n this.schedulePersist();\n }\n\n historyFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.messages : [];\n }\n\n recordExchange(\n scopeId: string,\n cwd: string,\n userMessages: string[],\n assistantMessage: string | undefined,\n ): void {\n const existing = this.data.chats[scopeId];\n const next: ChatMessage[] = [...(existing?.messages ?? [])];\n\n for (const content of userMessages) {\n if (content.trim()) next.push({ role: 'user', content });\n }\n\n if (assistantMessage?.trim()) {\n next.push({ role: 'assistant', content: assistantMessage });\n }\n\n this.data.chats[scopeId] = {\n sessionId: existing?.sessionId,\n cwd,\n messages: next.slice(-40),\n };\n this.schedulePersist();\n }\n\n clear(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n resumeFor(scopeId: string, cwd: string): string | undefined {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.sessionId : undefined;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = this.snapshot();\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('session', error, { step: 'persist' });\n });\n }\n\n private snapshot(): SessionData {\n return {\n chats: Object.fromEntries(\n Object.entries(this.data.chats).map(([key, record]) => [\n key,\n {\n ...record,\n messages: [...record.messages],\n },\n ]),\n ),\n };\n }\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\nexport type GitRunner = (args: string[], cwd: string) => Promise<string>;\n\nexport interface WorktreeEnsureResult {\n cwd: string;\n created: boolean;\n branch?: string;\n}\n\nexport interface GitWorktreeOptions {\n worktreesRoot: string;\n runGit?: GitRunner;\n copyRulesFile?: (source: string, target: string) => Promise<void>;\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, {\n cwd,\n encoding: 'utf8',\n });\n return result.stdout;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function defaultCopyRulesFile(source: string, target: string): Promise<void> {\n await mkdir(dirname(target), { recursive: true });\n await copyFile(source, target);\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nexport class GitWorktreeManager {\n private readonly runGit: GitRunner;\n private readonly copyRulesFile: (source: string, target: string) => Promise<void>;\n\n constructor(private readonly options: GitWorktreeOptions) {\n this.runGit = options.runGit ?? defaultRunGit;\n this.copyRulesFile = options.copyRulesFile ?? defaultCopyRulesFile;\n }\n\n async ensure(scope: string, base: string): Promise<WorktreeEnsureResult> {\n const isGit = await this.isGitRepository(base);\n if (!isGit) return { cwd: base, created: false };\n\n const slug = slugify(scope);\n const target = join(this.options.worktreesRoot, slug);\n if (await exists(target)) {\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: false };\n }\n\n const branch = `dsh-lark/${slug}-${Date.now().toString(36)}-${randomBytes(3).toString('hex')}`;\n await mkdir(this.options.worktreesRoot, { recursive: true });\n await this.runGit(['worktree', 'add', '-b', branch, target, 'HEAD'], base);\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: true, branch };\n }\n\n async isGitRepository(cwd: string): Promise<boolean> {\n try {\n const result = await this.runGit(['rev-parse', '--is-inside-work-tree'], cwd);\n return result.trim() === 'true';\n } catch {\n return false;\n }\n }\n\n private async ensureProjectRules(base: string, target: string): Promise<void> {\n const destination = join(target, 'AGENTS.md');\n if (await exists(destination)) return;\n\n const sourceCandidates = [join(base, '.dsh-lark', 'AGENTS.md'), join(base, 'AGENTS.md')];\n for (const source of sourceCandidates) {\n if (await exists(source)) {\n await this.copyRulesFile(source, destination);\n return;\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\ninterface WorkspaceData {\n chats: Record<string, { cwd: string }>;\n named: Record<string, string>;\n}\n\nexport class WorkspaceStore {\n private data: WorkspaceData = { chats: {}, named: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<WorkspaceData>;\n this.data = {\n chats: parsed.chats ?? {},\n named: parsed.named ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n cwdFor(scopeId: string): string | undefined {\n return this.data.chats[scopeId]?.cwd;\n }\n\n setCwd(scopeId: string, cwd: string): void {\n this.data.chats[scopeId] = { cwd };\n this.schedulePersist();\n }\n\n removeCwd(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n listNamed(): Record<string, string> {\n return { ...this.data.named };\n }\n\n getNamed(name: string): string | undefined {\n return this.data.named[name];\n }\n\n saveNamed(name: string, cwd: string): void {\n this.data.named[name] = cwd;\n this.schedulePersist();\n }\n\n removeNamed(name: string): boolean {\n if (!(name in this.data.named)) return false;\n delete this.data.named[name];\n this.schedulePersist();\n return true;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot: WorkspaceData = {\n chats: { ...this.data.chats },\n named: { ...this.data.named },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('workspace', error, { step: 'persist' });\n });\n }\n}\n"],"mappings":"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","names":["resolve","join","resolve","homedir","join","resolve","join","homedir","mkdir","dirname","join","mkdir","dirname","mkdir","spawn","spawn","resolve","resolve","markdown","minutes","markdown","resolve","readFile","readFile","randomBytes","mkdir","dirname","join","readFile","readFile","mkdir","resolve"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/cli/commands/doctor.ts","../src/adapters/dsh/availability.ts","../src/config/app-paths.ts","../src/config/env.ts","../src/config/dsh-runtime.ts","../src/config/profile-store.ts","../src/platform/atomic-write.ts","../src/cli/commands/start.ts","../src/adapters/dsh/adapter.ts","../src/adapters/dsh/translate.ts","../src/bot/active-runs.ts","../src/bot/pending-queue.ts","../src/bot/run-policy.ts","../src/bridge/channel.ts","../src/commands/index.ts","../src/card/workspace-card.ts","../src/core/logger.ts","../src/bridge/lark-channel.ts","../src/bridge/run-flow.ts","../src/card/run-state.ts","../src/card/run-renderer.ts","../src/config/access-manager.ts","../src/onboard/registration.ts","../src/media/attachments.ts","../src/session/store.ts","../src/workspace/git-worktree.ts","../src/workspace/store.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { runDoctor } from './cli/commands/doctor.js';\nimport { runStart } from './cli/commands/start.js';\n\nfunction packageVersion(): string {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n}\n\nexport interface StartOptions {\n profile?: string;\n workspace?: string;\n appId?: string;\n appSecret?: string;\n tenant?: string;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name('dsh-lark-bot')\n .description('Bridge DeepSeek Harness into Feishu / Lark')\n .version(packageVersion(), '-v, --version');\n\n program\n .command('start')\n .description('Start the bridge in the foreground')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runStart(opts);\n });\n\n program\n .command('doctor')\n .description('Run local diagnostics')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runDoctor({ ...opts, version: packageVersion() });\n });\n\n return program;\n}\n\nexport async function main(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync([...argv]);\n}\n","import { stat } from 'node:fs/promises';\nimport { checkDshAvailability } from '../../adapters/dsh/availability.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport type { StartOptions } from '../../cli.js';\n\nexport interface DoctorOptions extends StartOptions {\n version?: string;\n output?: (text: string) => void;\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const store = new ConfigStore(paths.configFile);\n await store.load();\n const profile = store.getProfile(profileName);\n\n const lines: string[] = [\n 'dsh-lark-bot doctor',\n `version: ${options.version ?? 'unknown'}`,\n `node: ${process.version}`,\n `profile: ${profileName}`,\n `home: ${paths.root}`,\n `dsh_command: ${env.dshCommand}`,\n `dsh_args: ${env.dshArgs.join(',')}`,\n ];\n\n let critical = false;\n\n if (!profile) {\n lines.push('config: missing');\n critical = true;\n } else {\n lines.push(\n [\n 'config: ok',\n `tenant=${profile.tenant}`,\n `app_id=${profile.accounts.appId}`,\n `app_secret=${profile.accounts.appSecret ? 'present' : 'missing'}`,\n ].join(' '),\n );\n if (!profile.accounts.appId || !profile.accounts.appSecret) critical = true;\n }\n\n const workspace =\n options.workspace ??\n profile?.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n try {\n const info = await stat(workspace);\n lines.push(`workspace: ${workspace} (${info.isDirectory() ? 'directory' : 'not-directory'})`);\n } catch {\n lines.push(`workspace: ${workspace} (missing)`);\n }\n\n const availability = await checkDshAvailability({\n command: env.dshCommand,\n args: env.dshArgs,\n });\n if (availability.ok) {\n lines.push(`dsh: ok${availability.version ? ` (${availability.version})` : ''}`);\n } else {\n lines.push(`dsh: unavailable (${availability.error ?? 'unknown'})`);\n critical = true;\n }\n\n const output = options.output ?? ((text: string) => process.stdout.write(text));\n output(`${lines.join('\\n')}\\n`);\n if (critical) process.exitCode = 1;\n}\n","import { spawn } from 'cross-spawn';\nimport { existsSync } from 'node:fs';\nimport type { AgentAvailability } from '../types.js';\n\nexport interface AvailabilityCheckOptions {\n command: string;\n args?: string[];\n timeoutMs?: number;\n}\n\nexport async function checkDshAvailability(\n options: AvailabilityCheckOptions,\n): Promise<AgentAvailability> {\n const timeoutMs = options.timeoutMs ?? 5_000;\n const versionArgs = options.command === 'node' && options.args?.[0] && existsSync(options.args[0])\n ? [options.args[0], '--version']\n : ['--version'];\n\n return new Promise((resolve) => {\n const child = spawn(options.command, versionArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const finish = (result: AgentAvailability): void => {\n if (settled) return;\n settled = true;\n resolve(result);\n };\n\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n finish({ ok: false, error: `timed out after ${timeoutMs}ms`, version: undefined });\n }, timeoutMs);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n clearTimeout(timer);\n finish({ ok: false, error: error.message, version: undefined });\n });\n child.on('exit', (code) => {\n clearTimeout(timer);\n const version = stdout.trim();\n if (code !== 0 && !version) {\n finish({ ok: false, error: stderr.trim() || `exited with code ${String(code)}`, version: undefined });\n return;\n }\n finish({ ok: true, error: undefined, version: version || undefined });\n });\n });\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface AppPaths {\n root: string;\n configFile: string;\n activeProfileFile: string;\n profileDir: (profile: string) => string;\n profilePath: (profile: string, ...parts: string[]) => string;\n sessionsFile: (profile: string) => string;\n sessionCatalogFile: (profile: string) => string;\n workspacesFile: (profile: string) => string;\n mediaDir: (profile: string) => string;\n logsDir: (profile: string) => string;\n registryFile: string;\n locksDir: string;\n}\n\nexport function defaultHome(): string {\n const override = process.env.DSH_LARK_HOME?.trim();\n return override ? resolve(override) : join(homedir(), '.dsh-lark');\n}\n\nexport function resolveAppPaths(root: string = defaultHome()): AppPaths {\n const profileDir = (profile: string): string => join(root, 'profiles', profile);\n const profilePath = (profile: string, ...parts: string[]): string =>\n join(profileDir(profile), ...parts);\n\n return {\n root,\n configFile: join(root, 'config.json'),\n activeProfileFile: join(root, 'active-profile'),\n profileDir,\n profilePath,\n sessionsFile: (profile) => profilePath(profile, 'sessions.json'),\n sessionCatalogFile: (profile) => profilePath(profile, 'sessions.json.catalog.json'),\n workspacesFile: (profile) => profilePath(profile, 'workspaces.json'),\n mediaDir: (profile) => profilePath(profile, 'media'),\n logsDir: (profile) => profilePath(profile, 'logs'),\n registryFile: join(root, 'registry', 'processes.json'),\n locksDir: join(root, 'registry', 'locks'),\n };\n}\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { resolveDshRuntime } from './dsh-runtime.js';\n\nexport type LarkTenant = 'feishu' | 'lark';\n\nexport interface RuntimeEnv {\n home: string;\n tenant: LarkTenant;\n appId: string | undefined;\n appSecret: string | undefined;\n workspace: string | undefined;\n dshCommand: string;\n dshArgs: string[];\n provider: string;\n model: string;\n runTimeoutMs: number;\n stopGraceMs: number;\n}\n\nconst DEFAULTS = {\n tenant: 'feishu' as const,\n provider: 'deepseek-official',\n model: 'deepseek-v4-flash',\n runTimeoutMs: 300_000,\n stopGraceMs: 5_000,\n};\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction parseTenant(value: string | undefined): LarkTenant {\n const tenant = nonEmpty(value) ?? DEFAULTS.tenant;\n if (tenant !== 'feishu' && tenant !== 'lark') {\n throw new Error(`DSH_LARK_TENANT must be \"feishu\" or \"lark\", got \"${tenant}\"`);\n }\n return tenant;\n}\n\nfunction parseDshArgs(value: string | undefined): string[] {\n const raw = value?.trim();\n if (!raw) return [];\n return raw\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction parseTimeout(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.runTimeoutMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_RUN_TIMEOUT_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseStopGrace(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.stopGraceMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_STOP_GRACE_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nexport function loadRuntimeEnv(\n source: NodeJS.ProcessEnv = process.env,\n): RuntimeEnv {\n const homeOverride = nonEmpty(source.DSH_LARK_HOME);\n const workspace = nonEmpty(source.DSH_LARK_WORKSPACE);\n const home = homeOverride ? resolve(homeOverride) : join(homedir(), '.dsh-lark');\n const osHome = homedir();\n const dshCommand = nonEmpty(source.DSH_LARK_DSH_COMMAND);\n const rawDshArgs = nonEmpty(source.DSH_LARK_DSH_ARGS);\n const dshRuntime = resolveDshRuntime({\n home: osHome,\n env: source,\n ...(dshCommand ? { command: dshCommand } : {}),\n ...(rawDshArgs ? { args: parseDshArgs(rawDshArgs) } : {}),\n });\n\n return {\n home,\n tenant: parseTenant(source.DSH_LARK_TENANT),\n appId: nonEmpty(source.DSH_LARK_APP_ID),\n appSecret: nonEmpty(source.DSH_LARK_APP_SECRET),\n workspace: workspace ? resolve(workspace) : undefined,\n dshCommand: dshRuntime.command,\n dshArgs: dshRuntime.args,\n provider: nonEmpty(source.DSH_LARK_PROVIDER) ?? DEFAULTS.provider,\n model: nonEmpty(source.DSH_LARK_MODEL) ?? DEFAULTS.model,\n runTimeoutMs: parseTimeout(source.DSH_LARK_RUN_TIMEOUT_MS),\n stopGraceMs: parseStopGrace(source.DSH_LARK_STOP_GRACE_MS),\n };\n}\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface DshRuntimeSpec {\n command: string;\n args: string[];\n bin?: string;\n}\n\nconst DS_HARNESS_RELATIVE = join('@deepseek-ai', 'dsh', 'lib', 'bin.js');\n\nfunction firstExisting(...paths: string[]): string | undefined {\n return paths.find((path) => existsSync(path));\n}\n\nfunction children(root: string): string[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n .map((entry) => join(root, entry.name));\n } catch {\n return [];\n }\n}\n\nexport function discoverDshBin(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const dshHome = env.DSH_HOME?.trim() || join(home, '.dsh');\n\n const candidates = [\n join(dshHome, 'profiles', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.npm', '_npx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.cache', 'pnpm', 'dlx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.local', 'share', 'pnpm', 'node_modules', DS_HARNESS_RELATIVE),\n ];\n\n const direct = firstExisting(...candidates);\n if (direct) return direct;\n\n for (const root of [join(home, '.npm', '_npx'), join(home, '.cache', 'pnpm', 'dlx')]) {\n for (const child of children(root)) {\n const path = join(child, 'node_modules', DS_HARNESS_RELATIVE);\n if (existsSync(path)) return path;\n }\n }\n\n return undefined;\n}\n\nexport function resolveDshRuntime(\n input: {\n command?: string;\n args?: string[];\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n): DshRuntimeSpec {\n if (input.command || input.args) {\n return {\n command: input.command ?? 'node',\n args: input.args ?? ['--profile', 'headless'],\n };\n }\n\n const bin = discoverDshBin(input.home, input.env);\n if (bin) {\n return {\n command: 'node',\n args: [bin, '--profile', 'headless'],\n bin,\n };\n }\n\n return {\n command: 'dsh',\n args: ['--profile', 'headless'],\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport type { LarkTenant } from './env.js';\n\nexport interface ProfileConfig {\n schemaVersion: 1;\n agentKind: 'dsh';\n tenant: LarkTenant;\n accounts: {\n appId: string;\n appSecret: string;\n };\n workspaces: {\n default: string | undefined;\n };\n preferences: {\n model: string | undefined;\n stopGraceMs: number | undefined;\n runTimeoutMs: number | undefined;\n };\n access: {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n };\n}\n\nexport interface RootConfig {\n schemaVersion: 1;\n activeProfile: string;\n profiles: Record<string, ProfileConfig>;\n}\n\nexport class ConfigStore {\n private data: RootConfig | undefined;\n\n constructor(private readonly path: string) {}\n\n async load(): Promise<RootConfig> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RootConfig>;\n this.data = {\n schemaVersion: 1,\n activeProfile: parsed.activeProfile ?? 'default',\n profiles: Object.fromEntries(\n Object.entries(parsed.profiles ?? {}).map(([name, profile]) => [\n name,\n {\n ...profile,\n access: {\n allowedUsers: profile.access?.allowedUsers ?? [],\n allowedChats: profile.access?.allowedChats ?? [],\n admins: profile.access?.admins ?? [],\n },\n },\n ]),\n ),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = {\n schemaVersion: 1,\n activeProfile: 'default',\n profiles: {},\n };\n }\n return this.data;\n }\n\n getActiveProfile(): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[data.activeProfile];\n }\n\n getProfile(name: string): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[name];\n }\n\n async saveProfile(\n name: string,\n input: {\n tenant: LarkTenant;\n appId: string;\n appSecret: string;\n workspace?: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n operatorOpenId?: string;\n access?: {\n allowedUsers?: string[];\n allowedChats?: string[];\n admins?: string[];\n };\n },\n ): Promise<void> {\n const data = this.getData();\n const existing = data.profiles[name];\n const profile: ProfileConfig = {\n schemaVersion: 1,\n agentKind: 'dsh',\n tenant: input.tenant,\n accounts: {\n appId: input.appId,\n appSecret: input.appSecret,\n },\n workspaces: {\n default: input.workspace ?? existing?.workspaces.default ?? undefined,\n },\n preferences: {\n model: input.model ?? existing?.preferences.model ?? undefined,\n stopGraceMs: input.stopGraceMs ?? existing?.preferences.stopGraceMs ?? undefined,\n runTimeoutMs: input.runTimeoutMs ?? existing?.preferences.runTimeoutMs ?? undefined,\n },\n access: {\n allowedUsers: input.access?.allowedUsers ?? existing?.access?.allowedUsers ?? [],\n allowedChats: input.access?.allowedChats ?? existing?.access?.allowedChats ?? [],\n admins: input.access?.admins ?? existing?.access?.admins ?? [],\n },\n };\n if (input.operatorOpenId && !profile.access.allowedUsers.includes(input.operatorOpenId)) {\n profile.access.allowedUsers.push(input.operatorOpenId);\n profile.access.admins.push(input.operatorOpenId);\n }\n data.profiles[name] = profile;\n data.activeProfile = name;\n await this.persist();\n }\n\n private getData(): RootConfig {\n if (!this.data) {\n throw new Error('ConfigStore must be loaded before use');\n }\n return this.data;\n }\n\n private async persist(): Promise<void> {\n const data = this.getData();\n await mkdir(dirname(this.path), { recursive: true });\n await writeFileAtomic(this.path, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number;\n}\n\nexport async function writeFileAtomic(\n target: string,\n data: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n const directory = dirname(target);\n await mkdir(directory, { recursive: true });\n const temporary = join(directory, `.${randomBytes(8).toString('hex')}.tmp`);\n\n try {\n await writeFile(temporary, data, options.mode === undefined ? undefined : { mode: options.mode });\n await rename(temporary, target);\n } catch (error) {\n await rmSilently(temporary);\n throw error;\n }\n}\n\nasync function rmSilently(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n try {\n await rm(path, { force: true });\n } catch {\n // best effort cleanup only\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { LarkChannel, NormalizedMessage } from '@larksuite/channel';\nimport { DshAdapter } from '../../adapters/dsh/adapter.js';\nimport { ActiveRuns } from '../../bot/active-runs.js';\nimport { PendingQueue } from '../../bot/pending-queue.js';\nimport { RunPolicyStore } from '../../bot/run-policy.js';\nimport { startChannel } from '../../bridge/channel.js';\nimport { adaptLarkChannel } from '../../bridge/lark-channel.js';\nimport { runAgentBatch } from '../../bridge/run-flow.js';\nimport type { StreamingChannel } from '../../bridge/types.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { AccessManager } from '../../config/access-manager.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport { log } from '../../core/logger.js';\nimport { onboardPersonalAgent } from '../../onboard/registration.js';\nimport { prepareAttachments } from '../../media/attachments.js';\nimport { SessionStore } from '../../session/store.js';\nimport { GitWorktreeManager } from '../../workspace/git-worktree.js';\nimport { WorkspaceStore } from '../../workspace/store.js';\nimport type { StartOptions } from '../../cli.js';\n\nconst DEBOUNCE_MS = 600;\n\nexport async function runStart(options: StartOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const configStore = new ConfigStore(paths.configFile);\n await configStore.load();\n const accessManager = new AccessManager(configStore, profileName);\n\n if (env.appId && env.appSecret) {\n const profileInput: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: env.tenant,\n appId: env.appId,\n appSecret: env.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (env.workspace !== undefined) profileInput.workspace = env.workspace;\n await configStore.saveProfile(profileName, profileInput);\n }\n\n const profile = configStore.getProfile(profileName);\n if (!profile) {\n try {\n const created = await onboardPersonalAgent();\n const onboardingProfile: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: created.tenant,\n appId: created.appId,\n appSecret: created.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (created.operatorOpenId !== undefined) {\n onboardingProfile.operatorOpenId = created.operatorOpenId;\n }\n if (env.workspace !== undefined) onboardingProfile.workspace = env.workspace;\n await configStore.saveProfile(profileName, onboardingProfile);\n } catch (error) {\n log.fail('onboarding', error);\n process.stderr.write('扫码创建应用失败,未写入本地配置。\\n');\n process.exitCode = 1;\n return;\n }\n }\n\n const activeProfile = configStore.getProfile(profileName);\n if (!activeProfile) {\n process.stderr.write('本地配置读取失败,请检查后重试。\\n');\n process.exitCode = 1;\n return;\n }\n\n const defaultWorkspace =\n options.workspace ??\n activeProfile.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n await mkdir(defaultWorkspace, { recursive: true });\n\n const sessions = new SessionStore(paths.sessionsFile(profileName));\n const workspaces = new WorkspaceStore(paths.workspacesFile(profileName));\n const worktreeManager = new GitWorktreeManager({\n worktreesRoot: paths.profilePath(profileName, 'worktrees'),\n });\n await Promise.all([sessions.load(), workspaces.load()]);\n\n const adapterOptions: { command: string; args: string[]; stopGraceMs?: number } = {\n command: env.dshCommand,\n args: env.dshArgs,\n stopGraceMs: env.stopGraceMs,\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n Object.assign(adapterOptions, { stopGraceMs: activeProfile.preferences.stopGraceMs });\n }\n const adapter = new DshAdapter(adapterOptions);\n const activeRuns = new ActiveRuns();\n const runPolicies = new RunPolicyStore();\n let streaming: StreamingChannel | undefined;\n let larkChannel: LarkChannel | undefined;\n\n const pending = new PendingQueue<NormalizedMessage>(DEBOUNCE_MS, async (scope, batch) => {\n if (!streaming) return;\n const first = batch[0];\n if (!first) return;\n pending.block(scope);\n try {\n const attachments = await prepareAttachments(\n larkChannel,\n first,\n paths.mediaDir(profileName),\n );\n const messages = [\n first.content,\n ...attachments.textFileNotes,\n ].filter(Boolean);\n const runInput: Parameters<typeof runAgentBatch>[0] = {\n scope,\n chatId: first.chatId,\n messages,\n adapter,\n sessions,\n workspaces,\n workspaceManager: worktreeManager,\n activeRuns,\n runPolicies,\n channel: streaming,\n defaultWorkspace,\n replyTo: first.messageId,\n runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n images: attachments.imagePaths,\n };\n if (activeProfile.preferences.model !== undefined) runInput.model = activeProfile.preferences.model;\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n runInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n await runAgentBatch(runInput);\n } finally {\n pending.unblock(scope);\n }\n });\n\n const channelInput: Parameters<typeof startChannel>[0] = {\n appId: activeProfile.accounts.appId,\n appSecret: activeProfile.accounts.appSecret,\n tenant: activeProfile.tenant,\n adapter,\n sessions,\n workspaces,\n activeRuns,\n runPolicies,\n defaultRunTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n accessManager,\n pending,\n defaultWorkspace,\n allowedUsers: activeProfile.access.allowedUsers,\n allowedChats: activeProfile.access.allowedChats,\n };\n if (activeProfile.preferences.model !== undefined) channelInput.model = activeProfile.preferences.model;\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n channelInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n const bridge = await startChannel(channelInput);\n streaming = adaptLarkChannel(bridge.channel);\n larkChannel = bridge.channel;\n\n log.info('cli', 'started', {\n profile: profileName,\n home: paths.root,\n tenant: activeProfile.tenant,\n workspace: defaultWorkspace,\n });\n process.stdout.write(`dsh-lark-bot 已启动,profile=${profileName}\\n`);\n\n await waitForShutdown();\n await bridge.disconnect();\n await Promise.all([sessions.flush(), workspaces.flush()]);\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n const shutdown = (): void => {\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { spawn } from 'cross-spawn';\nimport { createInterface } from 'node:readline';\nimport type { ChildProcess } from 'node:child_process';\nimport { checkDshAvailability } from './availability.js';\nimport { plainOutputEvent, translateDshLine } from './translate.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\n\nexport interface DshAdapterOptions {\n command?: string;\n args?: string[];\n stopGraceMs?: number;\n}\n\ntype DshChild = ChildProcess;\n\nexport class DshAdapter implements AgentAdapter {\n readonly id = 'dsh';\n readonly displayName = 'DeepSeek Harness';\n\n private readonly command: string;\n private readonly args: string[];\n private readonly stopGraceMs: number;\n\n constructor(options: DshAdapterOptions = {}) {\n this.command = options.command ?? 'dsh';\n this.args = options.args ?? ['--profile', 'headless'];\n this.stopGraceMs = options.stopGraceMs ?? 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n checkAvailability(): Promise<AgentAvailability> {\n return checkDshAvailability({ command: this.command, args: this.args });\n }\n\n run(options: AgentRunOptions): AgentRun {\n const prompt =\n options.images?.length\n ? `${options.prompt}\\n\\nImage files attached to this message:\\n${options.images.join('\\n')}`\n : options.prompt;\n\n const child = spawn(\n this.command,\n [...this.args, prompt],\n {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n ) as DshChild;\n\n child.stdin?.end();\n\n const stderrChunks: Buffer[] = [];\n let runtimeError: Error | null = null;\n child.stderr?.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n child.on('error', (error: Error) => {\n runtimeError = error;\n });\n\n return {\n runId: options.runId,\n events: createEventStream(child, stderrChunks, () => runtimeError, {\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n }),\n stop: () => stopChild(child, this.stopGraceMs),\n waitForExit: (timeoutMs) => waitForChildExit(child, timeoutMs),\n };\n }\n}\n\nasync function* createEventStream(\n child: DshChild,\n stderrChunks: Buffer[],\n getError: () => Error | null,\n system: {\n sessionId: string | undefined;\n cwd: string | undefined;\n model: string | undefined;\n },\n): AsyncGenerator<AgentEvent> {\n if (!child.pid) {\n const error = getError();\n yield {\n type: 'error',\n message: error ? `failed to spawn dsh: ${error.message}` : 'spawn returned no pid',\n terminationReason: 'failed',\n };\n return;\n }\n\n yield {\n type: 'system',\n sessionId: system.sessionId,\n cwd: system.cwd,\n model: system.model,\n };\n\n if (!child.stdout) {\n yield {\n type: 'error',\n message: 'dsh stdout stream is unavailable',\n terminationReason: 'failed',\n };\n return;\n }\n\n const lines = createInterface({ input: child.stdout, crlfDelay: Infinity });\n const plainLines: string[] = [];\n let emittedProtocol = false;\n let terminalEmitted = false;\n\n for await (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const events = translateDshLine(trimmed);\n if (events.length > 0) {\n emittedProtocol = true;\n for (const event of events) {\n if (event.type === 'done' || event.type === 'error') terminalEmitted = true;\n yield event;\n }\n } else {\n plainLines.push(trimmed);\n }\n }\n\n const exitCode = await waitForExitResult(child, 0).then((value) => value.code);\n const runtimeError = getError();\n\n if (!terminalEmitted) {\n if (exitCode !== null && exitCode !== 0) {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();\n const detail = stderr ? `: ${stderr.slice(0, 500)}` : '';\n yield {\n type: 'error',\n message: `dsh exited with code ${exitCode}${detail}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (runtimeError) {\n yield {\n type: 'error',\n message: `dsh runtime error: ${runtimeError.message}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (emittedProtocol) {\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n } else {\n yield* plainOutputEvent(plainLines.join('\\n'));\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n }\n }\n}\n\nasync function waitForExitResult(\n child: DshChild,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return { code: child.exitCode, timedOut: false };\n }\n\n return new Promise((resolve) => {\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n child.once('exit', onExit);\n });\n}\n\nasync function stopChild(child: DshChild, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.kill('SIGTERM');\n const stopped = await waitForExitResult(child, graceMs);\n if (!stopped.timedOut) return;\n child.kill('SIGKILL');\n}\n\nasync function waitForChildExit(child: DshChild, timeoutMs: number): Promise<boolean> {\n const result = await waitForExitResult(child, timeoutMs);\n return !result.timedOut && result.code !== null;\n}\n","import type { AgentEvent } from '../types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function translateDshLine(line: string): AgentEvent[] {\n const trimmed = line.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') return [];\n\n switch (parsed.type) {\n case 'system':\n return [\n {\n type: 'system',\n sessionId: stringValue(parsed.sessionId),\n cwd: stringValue(parsed.cwd),\n model: stringValue(parsed.model),\n },\n ];\n case 'text':\n return [{ type: 'text', delta: stringValue(parsed.delta) ?? '' }];\n case 'final_text':\n return [{ type: 'final_text', content: stringValue(parsed.content) ?? '' }];\n case 'thinking':\n return [{ type: 'thinking', delta: stringValue(parsed.delta) ?? '' }];\n case 'tool_use':\n return [\n {\n type: 'tool_use',\n id: stringValue(parsed.id) ?? 'unknown',\n name: stringValue(parsed.name) ?? 'tool',\n input: parsed.input,\n },\n ];\n case 'tool_result':\n return [\n {\n type: 'tool_result',\n id: stringValue(parsed.id) ?? 'unknown',\n output: stringValue(parsed.output) ?? '',\n isError: parsed.isError === true,\n },\n ];\n case 'done':\n return [\n {\n type: 'done',\n sessionId: stringValue(parsed.sessionId),\n terminationReason: 'normal',\n },\n ];\n case 'error':\n return [\n {\n type: 'error',\n message: stringValue(parsed.message) ?? 'dsh failed',\n terminationReason: 'failed',\n },\n ];\n default:\n return [];\n }\n } catch {\n return [];\n }\n}\n\nexport function plainOutputEvent(output: string): AgentEvent[] {\n const trimmed = output.trim();\n return trimmed ? [{ type: 'final_text', content: trimmed }] : [];\n}\n","export interface ActiveRunHandle {\n runId: string;\n stop(): Promise<void>;\n}\n\nexport class ActiveRuns {\n private readonly runs = new Map<string, ActiveRunHandle>();\n\n set(scope: string, handle: ActiveRunHandle): void {\n this.runs.set(scope, handle);\n }\n\n get(scope: string): ActiveRunHandle | undefined {\n return this.runs.get(scope);\n }\n\n delete(scope: string): boolean {\n return this.runs.delete(scope);\n }\n\n async interrupt(scope: string): Promise<boolean> {\n const handle = this.runs.get(scope);\n if (!handle) return false;\n this.runs.delete(scope);\n await handle.stop();\n return true;\n }\n}\n","export type PendingFlush<T> = (scope: string, batch: T[]) => void | Promise<void>;\n\nexport class PendingQueue<T> {\n private readonly pending = new Map<string, T[]>();\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly blocked = new Set<string>();\n private readonly flushing = new Set<string>();\n\n constructor(\n private readonly quietMs: number,\n private readonly onFlush: PendingFlush<T>,\n ) {}\n\n push(scope: string, item: T): void {\n const batch = this.pending.get(scope) ?? [];\n batch.push(item);\n this.pending.set(scope, batch);\n this.schedule(scope);\n }\n\n block(scope: string): void {\n this.blocked.add(scope);\n this.clearTimer(scope);\n }\n\n unblock(scope: string): void {\n this.blocked.delete(scope);\n this.schedule(scope);\n }\n\n async flushNow(scope: string): Promise<void> {\n this.clearTimer(scope);\n if (this.flushing.has(scope)) return;\n\n const batch = this.pending.get(scope) ?? [];\n this.pending.delete(scope);\n if (batch.length === 0) return;\n\n this.flushing.add(scope);\n try {\n await this.onFlush(scope, batch);\n } finally {\n this.flushing.delete(scope);\n }\n }\n\n hasPending(scope: string): boolean {\n return (this.pending.get(scope)?.length ?? 0) > 0;\n }\n\n isBlocked(scope: string): boolean {\n return this.blocked.has(scope);\n }\n\n private schedule(scope: string): void {\n if (this.blocked.has(scope) || this.flushing.has(scope)) return;\n if (this.timers.has(scope)) return;\n if (!this.hasPending(scope)) return;\n\n this.timers.set(\n scope,\n setTimeout(() => {\n this.timers.delete(scope);\n void this.flushNow(scope);\n }, this.quietMs),\n );\n }\n\n private clearTimer(scope: string): void {\n const timer = this.timers.get(scope);\n if (timer === undefined) return;\n clearTimeout(timer);\n this.timers.delete(scope);\n }\n}\n","export class RunPolicyStore {\n private readonly timeouts = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.timeouts.get(scope);\n }\n\n set(scope: string, runTimeoutMs: number): void {\n this.timeouts.set(scope, runTimeoutMs);\n }\n\n clear(scope: string): boolean {\n return this.timeouts.delete(scope);\n }\n}\n","import { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { PendingQueue } from '../bot/pending-queue.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport { tryHandleCommand, type CommandChannel } from '../commands/index.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { adaptLarkChannel } from './lark-channel.js';\n\nexport interface StartChannelDeps {\n appId: string;\n appSecret: string;\n tenant: 'feishu' | 'lark';\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n defaultRunTimeoutMs: number;\n accessManager: AccessManager;\n pending: PendingQueue<NormalizedMessage>;\n defaultWorkspace: string;\n allowedUsers?: string[];\n allowedChats?: string[];\n model?: string;\n stopGraceMs?: number;\n createChannel?: typeof createLarkChannel;\n}\n\nexport interface BridgeChannel {\n channel: LarkChannel;\n disconnect(): Promise<void>;\n}\n\nexport async function startChannel(deps: StartChannelDeps): Promise<BridgeChannel> {\n const channel = (deps.createChannel ?? createLarkChannel)({\n appId: deps.appId,\n appSecret: deps.appSecret,\n domain:\n deps.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot',\n policy: {\n dmMode: deps.allowedUsers?.length ? 'allowlist' : 'open',\n requireMention: true,\n respondToMentionAll: false,\n ...(deps.allowedUsers ? { dmAllowlist: deps.allowedUsers } : {}),\n ...(deps.allowedChats ? { groupAllowlist: deps.allowedChats } : {}),\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n const streaming = adaptLarkChannel(channel);\n const commandChannel: CommandChannel = streaming;\n\n channel.on({\n message: async (msg) => {\n const scope = scopeForMessage(msg);\n const context = {\n scope,\n chatId: msg.chatId,\n messageId: msg.messageId,\n threadId: msg.threadId,\n chatMode: msg.chatMode ?? msg.chatType,\n sessions: deps.sessions,\n workspaces: deps.workspaces,\n activeRuns: deps.activeRuns,\n runPolicies: deps.runPolicies,\n defaultRunTimeoutMs: deps.defaultRunTimeoutMs,\n accessManager: deps.accessManager,\n channel: commandChannel,\n defaultWorkspace: deps.defaultWorkspace,\n };\n\n const handled = await tryHandleCommand(msg.content, context).catch((error: unknown) => {\n log.fail('channel-command', error, { scope });\n return false;\n });\n if (!handled) deps.pending.push(scope, msg);\n },\n cardAction: async (event) => {\n const value =\n event.action.value && typeof event.action.value === 'object'\n ? (event.action.value as Record<string, unknown>)\n : undefined;\n if (value?.cmd === 'stop') {\n const scope = event.raw\n ? await resolveCardScope(event.chatId, event.raw as { message?: { thread_id?: string } })\n : event.chatId;\n await deps.activeRuns.interrupt(scope);\n }\n },\n reconnecting: () => {\n log.warn('channel', 'reconnecting', {});\n },\n reconnected: () => {\n log.info('channel', 'reconnected', {});\n },\n error: (error) => {\n log.fail('channel', error);\n },\n });\n\n await channel.connect();\n return {\n channel,\n disconnect: () => channel.disconnect(),\n };\n}\n\nfunction scopeForMessage(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n}\n\nasync function resolveCardScope(\n chatId: string,\n raw: { message?: { thread_id?: string } },\n): Promise<string> {\n return raw.message?.thread_id ? `${chatId}:${raw.message.thread_id}` : chatId;\n}\n","import { resolve } from 'node:path';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { renderWorkspaceCard } from '../card/workspace-card.js';\n\nexport interface CommandChannel {\n sendMarkdown(\n chatId: string,\n markdown: string,\n options?: { replyTo?: string },\n ): Promise<void>;\n sendCard?(chatId: string, card: object): Promise<void>;\n}\n\nexport interface CommandContext {\n scope: string;\n chatId: string;\n messageId: string;\n threadId: string | undefined;\n chatMode: 'p2p' | 'group' | 'topic';\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n defaultRunTimeoutMs: number;\n accessManager: AccessManager;\n channel: CommandChannel;\n defaultWorkspace: string;\n}\n\ntype Handler = (args: string, ctx: CommandContext) => Promise<void>;\n\nconst HELP = [\n '**dsh-lark-bot 命令**',\n '',\n '- `/new` `/reset` — 开始新会话',\n '- `/cd <path>` — 切换工作目录并重置会话',\n '- `/ws list|save <name>|use <name>|remove <name>` — 管理工作空间',\n '- `/status` — 查看当前状态',\n '- `/resume` — 查看当前会话最近上下文',\n '- `/stop` — 终止当前任务',\n '- `/timeout [N|off|default]` — 查看或设置当前会话运行超时',\n '- `/invite user|admin|group <id>` — 管理访问白名单',\n '- `/help` — 显示本帮助',\n].join('\\n');\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nasync function handleNew(_args: string, ctx: CommandContext): Promise<void> {\n const wasRunning = await ctx.activeRuns.interrupt(ctx.scope);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, wasRunning ? '已中断当前任务并开始新会话。' : '已开始新会话。');\n}\n\nasync function handleCd(args: string, ctx: CommandContext): Promise<void> {\n const path = args.trim();\n if (!path) {\n await reply(ctx, '用法:`/cd <path>`');\n return;\n }\n const cwd = resolve(path);\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换工作目录:\\`${cwd}\\`,会话已重置。`);\n}\n\nasync function handleWs(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const name = rest.join(' ').trim();\n\n if (!sub || sub === 'list') {\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const named = ctx.workspaces.listNamed();\n if (ctx.channel.sendCard) {\n await ctx.channel.sendCard(ctx.chatId, renderWorkspaceCard({ current, named }));\n return;\n }\n const lines = Object.entries(named).map(\n ([key, value]) => `- **${key}** → \\`${value}\\`${value === current ? ' ← 当前' : ''}`,\n );\n await reply(\n ctx,\n [\n `当前 cwd:\\`${current}\\``,\n '',\n ...(lines.length > 0 ? lines : ['暂无命名工作空间。']),\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'save') {\n if (!name) {\n await reply(ctx, '用法:`/ws save <name>`');\n return;\n }\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n ctx.workspaces.saveNamed(name, current);\n await reply(ctx, `已保存工作空间:**${name}** → \\`${current}\\``);\n return;\n }\n\n if (sub === 'use') {\n if (!name) {\n await reply(ctx, '用法:`/ws use <name>`');\n return;\n }\n const cwd = ctx.workspaces.getNamed(name);\n if (!cwd) {\n await reply(ctx, `未找到工作空间:**${name}**`);\n return;\n }\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换到工作空间:**${name}** → \\`${cwd}\\``);\n return;\n }\n\n if (sub === 'remove') {\n if (!name) {\n await reply(ctx, '用法:`/ws remove <name>`');\n return;\n }\n const removed = ctx.workspaces.removeNamed(name);\n await reply(ctx, removed ? `已删除工作空间:**${name}**` : `未找到工作空间:**${name}**`);\n return;\n }\n\n await reply(ctx, '未知 `/ws` 子命令,请使用 list / save / use / remove。');\n}\n\nasync function handleStatus(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const session = ctx.sessions.getRaw(ctx.scope)?.sessionId ?? '(无)';\n const running = Boolean(ctx.activeRuns.get(ctx.scope));\n const scopeLabel =\n ctx.chatMode === 'topic' ? `${ctx.scope}(话题独立 session)` : ctx.scope;\n\n await reply(\n ctx,\n [\n `🧭 **scope**: \\`${scopeLabel}\\``,\n `📁 **cwd**: \\`${cwd}\\``,\n `🔗 **session**: \\`${session}\\``,\n `🏃 **active run**: ${running ? 'yes' : 'no'}`,\n ].join('\\n'),\n );\n}\n\nasync function handleResume(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const history = ctx.sessions.historyFor(ctx.scope, cwd);\n if (history.length === 0) {\n await reply(ctx, '当前会话没有历史上下文。');\n return;\n }\n\n const recent = history.slice(-6).map((message) => {\n const speaker = message.role === 'user' ? '👤' : '🤖';\n return `${speaker} ${message.content.slice(0, 300)}`;\n });\n\n await reply(ctx, [`当前 scope:\\`${ctx.scope}\\``, '', ...recent].join('\\n'));\n}\n\nasync function handleStop(_args: string, ctx: CommandContext): Promise<void> {\n const stopped = await ctx.activeRuns.interrupt(ctx.scope);\n await reply(ctx, stopped ? '已请求终止当前任务。' : '当前没有运行中的任务。');\n}\n\nasync function handleTimeout(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effectiveMs = ctx.runPolicies.get(ctx.scope) ?? ctx.defaultRunTimeoutMs;\n\n if (!input) {\n const minutes = effectiveMs > 0 ? Math.round(effectiveMs / 60_000) : 0;\n await reply(\n ctx,\n minutes > 0\n ? `当前会话运行超时:${minutes} 分钟。可用 \\`/timeout <N|off|default>\\` 调整。`\n : '当前会话运行超时:关闭。',\n );\n return;\n }\n\n if (input === 'off') {\n ctx.runPolicies.set(ctx.scope, 0);\n await reply(ctx, '已关闭当前会话运行超时。');\n return;\n }\n\n if (input === 'default') {\n ctx.runPolicies.clear(ctx.scope);\n await reply(ctx, '已恢复默认运行超时。');\n return;\n }\n\n const minutes = Number(input);\n if (!Number.isInteger(minutes) || minutes <= 0) {\n await reply(ctx, '用法:`/timeout <N|off|default>`,N 为大于 0 的分钟数。');\n return;\n }\n\n ctx.runPolicies.set(ctx.scope, minutes * 60_000);\n await reply(ctx, `已设置当前会话运行超时:${minutes} 分钟。`);\n}\n\nasync function handleInvite(args: string, ctx: CommandContext): Promise<void> {\n const [kind, ...rest] = args.trim().split(/\\s+/);\n const id = rest.join(' ').trim();\n if (!kind || !id) {\n await reply(ctx, '用法:`/invite user <id>`、`/invite admin <id>`、`/invite group <chatId>`');\n return;\n }\n\n if (kind === 'user') {\n await ctx.accessManager.addUser(id);\n await reply(ctx, `已允许用户:\\`${id}\\``);\n return;\n }\n\n if (kind === 'admin') {\n await ctx.accessManager.addAdmin(id);\n await reply(ctx, `已设为管理员:\\`${id}\\``);\n return;\n }\n\n if (kind === 'group') {\n await ctx.accessManager.addChat(id);\n await reply(ctx, `已允许群聊:\\`${id}\\``);\n return;\n }\n\n await reply(ctx, '未知 `/invite` 类型,请使用 user / admin / group。');\n}\n\nasync function handleHelp(_args: string, ctx: CommandContext): Promise<void> {\n await reply(ctx, HELP);\n}\n\nconst handlers: Record<string, Handler> = {\n '/new': handleNew,\n '/reset': handleNew,\n '/cd': handleCd,\n '/ws': handleWs,\n '/status': handleStatus,\n '/resume': handleResume,\n '/stop': handleStop,\n '/timeout': handleTimeout,\n '/invite': handleInvite,\n '/help': handleHelp,\n};\n\nexport async function tryHandleCommand(text: string, ctx: CommandContext): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed.startsWith('/')) return false;\n const [command, ...rest] = trimmed.split(/\\s+/);\n const handler = handlers[command ?? ''];\n if (!handler) return false;\n await handler(rest.join(' '), ctx);\n return true;\n}\n","export function renderWorkspaceCard(input: {\n current: string;\n named: Record<string, string>;\n}): object {\n const entries = Object.entries(input.named);\n const markdown = [\n `**当前工作目录**\\n\\`${input.current}\\``,\n '',\n ...(entries.length > 0\n ? entries.map(([name, cwd]) => `- **${name}** → \\`${cwd}\\``)\n : ['暂无命名工作空间。']),\n ].join('\\n');\n\n return {\n schema: '2.0',\n config: {\n summary: { content: '工作空间导航' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: markdown,\n },\n ],\n },\n };\n}\n","import type { Writable } from 'node:stream';\n\ntype LogLevel = 'info' | 'warn' | 'error';\n\nexport interface LogFields {\n [key: string]: unknown;\n}\n\nconst REDACTED = '[redacted]';\nconst SENSITIVE_KEY = /(secret|token|password|api[_-]?key)/i;\n\nfunction redactValue(value: unknown, key: string, depth: number): unknown {\n if (SENSITIVE_KEY.test(key)) return REDACTED;\n if (depth === 0) return value;\n if (Array.isArray(value)) {\n return value.map((item, index) => redactValue(item, `${key}.${index}`, depth - 1));\n }\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactValue(childValue, childKey, depth - 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactFields(fields: LogFields, depth = 4): LogFields {\n return redactValue(fields, '', depth) as LogFields;\n}\n\nfunction serializeMessage(\n level: LogLevel,\n category: string,\n event: string,\n fields: LogFields,\n): string {\n const entry = {\n time: new Date().toISOString(),\n level,\n category,\n event,\n fields: redactFields(fields),\n };\n return JSON.stringify(entry);\n}\n\nexport interface Logger {\n info(category: string, event: string, fields?: LogFields): void;\n warn(category: string, event: string, fields?: LogFields): void;\n error(category: string, event: string, fields?: LogFields): void;\n fail(category: string, error: unknown, fields?: LogFields): void;\n}\n\nexport function createLogger(output: Writable = process.stderr): Logger {\n const write = (level: LogLevel, category: string, event: string, fields: LogFields): void => {\n output.write(`${serializeMessage(level, category, event, fields)}\\n`);\n };\n\n return {\n info: (category, event, fields = {}) => write('info', category, event, fields),\n warn: (category, event, fields = {}) => write('warn', category, event, fields),\n error: (category, event, fields = {}) => write('error', category, event, fields),\n fail(category, error, fields = {}) {\n const message = error instanceof Error ? error.message : String(error);\n write('error', category, 'fail', { message, ...fields });\n },\n };\n}\n\nexport const log = createLogger();\n","import type {\n CardStreamController as LarkCardStreamController,\n LarkChannel,\n SendOptions,\n} from '@larksuite/channel';\nimport type { CommandChannel } from '../commands/index.js';\nimport type { StreamingChannel } from './types.js';\n\nexport function adaptLarkChannel(channel: LarkChannel): StreamingChannel {\n const base: CommandChannel = {\n async sendMarkdown(chatId, markdown, options) {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n await channel.send(chatId, { markdown }, sendOptions);\n },\n };\n\n return {\n ...base,\n async sendCard(chatId, card) {\n await channel.send(chatId, { card }, {});\n },\n async streamCard(chatId, initial, producer, options) {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n await channel.stream(\n chatId,\n {\n card: {\n initial,\n producer: async (controller: LarkCardStreamController) => {\n await producer(controller);\n },\n },\n },\n sendOptions,\n );\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AgentAdapter, AgentEvent } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport {\n finalizeIfRunning,\n initialState,\n markIdleTimeout,\n markInterrupted,\n reduce,\n type RunState,\n} from '../card/run-state.js';\nimport { renderCard } from '../card/run-renderer.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport type { GitWorktreeManager } from '../workspace/git-worktree.js';\nimport type { StreamingChannel } from './types.js';\n\nexport interface RunFlowInput {\n scope: string;\n chatId: string;\n messages: string[];\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n workspaceManager?: GitWorktreeManager;\n activeRuns: ActiveRuns;\n runPolicies?: RunPolicyStore;\n channel: StreamingChannel;\n defaultWorkspace: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n images?: string[];\n replyTo?: string;\n}\n\nexport async function runAgentBatch(input: RunFlowInput): Promise<void> {\n const replyOptions = input.replyTo ? { replyTo: input.replyTo } : {};\n\n if (input.activeRuns.get(input.scope)) {\n await input.channel.sendMarkdown(input.chatId, '当前会话已有任务正在运行,请先 `/stop` 或等待完成。', {\n ...replyOptions,\n });\n return;\n }\n\n const requestedCwd = input.workspaces.cwdFor(input.scope) ?? input.defaultWorkspace;\n const workspace = input.workspaceManager\n ? await input.workspaceManager.ensure(input.scope, requestedCwd)\n : { cwd: requestedCwd };\n const cwd = workspace.cwd;\n const sessionId = input.sessions.resumeFor(input.scope, cwd);\n const history = input.sessions.historyFor(input.scope, cwd);\n const prompt = buildPrompt(history, input.messages);\n const runId = randomUUID();\n\n const run = input.adapter.run({\n runId,\n prompt,\n cwd,\n sessionId,\n model: input.model,\n images: input.images,\n stopGraceMs: input.stopGraceMs,\n });\n input.activeRuns.set(input.scope, { runId, stop: run.stop });\n\n let state: RunState = initialState;\n const stopRequested = { value: false };\n const timeoutMs = input.runPolicies?.get(input.scope) ?? input.runTimeoutMs ?? 0;\n let timedOut = false;\n let assistantOutput = '';\n\n try {\n await input.channel.streamCard(\n input.chatId,\n renderCard(state),\n async (controller) => {\n const consume = async (): Promise<void> => {\n for await (const event of run.events) {\n if (timedOut) return;\n state = applyEvent(state, event, stopRequested);\n if (event.type === 'final_text') {\n assistantOutput = event.content;\n } else if (event.type === 'text') {\n assistantOutput += event.delta;\n }\n if (event.type === 'system' && event.sessionId) {\n input.sessions.set(input.scope, event.sessionId, event.cwd ?? cwd);\n }\n await controller.update(renderCard(state));\n }\n };\n\n let timeoutTimer: NodeJS.Timeout | undefined;\n const timeoutPromise =\n timeoutMs > 0\n ? new Promise<void>((resolve) => {\n timeoutTimer = setTimeout(() => {\n timedOut = true;\n void run.stop();\n resolve();\n }, timeoutMs);\n })\n : undefined;\n\n try {\n if (timeoutPromise) {\n await Promise.race([consume(), timeoutPromise]);\n } else {\n await consume();\n }\n\n state = timedOut\n ? markIdleTimeout(state, timeoutMs / 60_000)\n : finalizeIfRunning(state);\n await controller.update(renderCard(state));\n } finally {\n if (timeoutTimer !== undefined) clearTimeout(timeoutTimer);\n }\n },\n replyOptions,\n );\n input.sessions.recordExchange(input.scope, cwd, input.messages, assistantOutput);\n } catch (error) {\n log.fail('run-flow', error, { scope: input.scope, runId });\n state = markInterrupted(state);\n try {\n await input.channel.sendMarkdown(input.chatId, `⚠️ agent 运行失败:${errorMessage(error)}`, {\n ...replyOptions,\n });\n } catch {\n // best effort; the card may already have failed\n }\n } finally {\n input.activeRuns.delete(input.scope);\n }\n}\n\nfunction buildPrompt(\n history: Array<{ role: 'user' | 'assistant'; content: string }>,\n messages: string[],\n): string {\n if (history.length === 0) return messages.join('\\n\\n');\n\n const transcript = history\n .map((message) => `${message.role === 'user' ? 'User' : 'Assistant'}: ${message.content}`)\n .join('\\n\\n');\n\n return [\n 'Continue the conversation using the history below.',\n '',\n transcript,\n '',\n `Current user message:\\n${messages.join('\\n\\n')}`,\n ].join('\\n');\n}\n\nfunction applyEvent(\n state: RunState,\n event: AgentEvent,\n stopRequested: { value: boolean },\n): RunState {\n if (event.type === 'done' && event.terminationReason === 'interrupted') {\n stopRequested.value = true;\n return markInterrupted(state);\n }\n if (event.type === 'error' && event.terminationReason === 'timeout') {\n return markIdleTimeout(state, 0);\n }\n return reduce(state, event);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { AgentEvent } from '../adapters/types.js';\n\nexport type ToolStatus = 'running' | 'done' | 'error';\n\nexport interface ToolEntry {\n id: string;\n name: string;\n input: unknown;\n status: ToolStatus;\n output?: string;\n}\n\nexport type Block =\n | { kind: 'text'; content: string; streaming: boolean }\n | { kind: 'tool'; tool: ToolEntry };\n\nexport type FooterStatus = 'thinking' | 'tool_running' | 'streaming' | null;\nexport type Terminal = 'running' | 'done' | 'interrupted' | 'error' | 'idle_timeout';\n\nexport interface RunState {\n blocks: Block[];\n reasoning: { content: string; active: boolean };\n footer: FooterStatus;\n terminal: Terminal;\n errorMsg: string | undefined;\n idleTimeoutMinutes: number | undefined;\n}\n\nexport const initialState: RunState = {\n blocks: [],\n reasoning: { content: '', active: false },\n footer: 'thinking',\n terminal: 'running',\n errorMsg: undefined,\n idleTimeoutMinutes: undefined,\n};\n\nfunction closeStreamingText(blocks: Block[]): Block[] {\n return blocks.map((block) =>\n block.kind === 'text' && block.streaming ? { ...block, streaming: false } : block,\n );\n}\n\nexport function reduce(state: RunState, event: AgentEvent): RunState {\n switch (event.type) {\n case 'text': {\n const last = state.blocks[state.blocks.length - 1];\n if (last?.kind === 'text' && last.streaming) {\n return {\n ...state,\n blocks: [\n ...state.blocks.slice(0, -1),\n { ...last, content: last.content + event.delta },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n return {\n ...state,\n blocks: [...state.blocks, { kind: 'text', content: event.delta, streaming: true }],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n\n case 'thinking':\n return {\n ...state,\n reasoning: {\n content: state.reasoning.content + event.delta,\n active: true,\n },\n footer: 'thinking',\n };\n\n case 'final_text':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n { kind: 'text', content: event.content, streaming: false },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: null,\n };\n\n case 'tool_use':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n {\n kind: 'tool',\n tool: {\n id: event.id,\n name: event.name,\n input: event.input,\n status: 'running',\n },\n },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'tool_running',\n };\n\n case 'tool_result':\n return {\n ...state,\n blocks: state.blocks.map((block) => {\n if (block.kind !== 'tool' || block.tool.id !== event.id) return block;\n return {\n ...block,\n tool: {\n ...block.tool,\n status: event.isError ? 'error' : 'done',\n output: event.output,\n },\n };\n }),\n };\n\n case 'error':\n return {\n ...state,\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'error',\n errorMsg: event.terminationReason === 'failed' ? event.message : undefined,\n idleTimeoutMinutes: undefined,\n footer: null,\n };\n\n case 'done':\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'done',\n footer: null,\n };\n\n default:\n return state;\n }\n}\n\nexport function markInterrupted(state: RunState): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'interrupted',\n footer: null,\n };\n}\n\nexport function markIdleTimeout(state: RunState, minutes: number): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'idle_timeout',\n footer: null,\n idleTimeoutMinutes: minutes,\n };\n}\n\nexport function finalizeIfRunning(state: RunState): RunState {\n if (state.terminal !== 'running') return state;\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'done',\n footer: null,\n };\n}\n","import type { Block, FooterStatus, RunState, ToolEntry } from './run-state.js';\n\nfunction markdown(content: string): object {\n return { tag: 'markdown', content };\n}\n\nfunction noteMd(content: string): object {\n return { tag: 'markdown', content, text_size: 'notation' };\n}\n\nfunction footerStatus(status: Exclude<FooterStatus, null>): object {\n const text =\n status === 'thinking'\n ? '🧠 正在思考'\n : status === 'tool_running'\n ? '🧰 正在调用工具'\n : '✍️ 正在输出';\n return noteMd(text);\n}\n\nfunction summaryText(state: RunState): string {\n if (state.terminal === 'interrupted') return '已中断';\n if (state.terminal === 'idle_timeout') return '已超时';\n if (state.terminal === 'error') return '出错';\n if (state.terminal === 'done') return '已完成';\n if (state.footer === 'tool_running') return '正在调用工具';\n if (state.footer === 'streaming') return '正在输出';\n return '思考中';\n}\n\nfunction stopButton(): object {\n return {\n tag: 'button',\n text: { tag: 'plain_text', content: '⏹ 终止' },\n type: 'danger',\n value: { cmd: 'stop' },\n };\n}\n\nfunction textBlock(block: Extract<Block, { kind: 'text' }>): object {\n return markdown(block.content);\n}\n\nfunction toolBlock(tool: ToolEntry): object {\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n return markdown(`${icon} **${tool.name}**`);\n}\n\nexport function renderCard(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 思考完成:${state.reasoning.content.slice(0, 300)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n elements.push(block.kind === 'text' ? textBlock(block) : toolBlock(block.tool));\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done' && elements.length === 0) {\n elements.push(noteMd('_(未返回内容)_'));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n","import type { ConfigStore, ProfileConfig } from './profile-store.js';\n\nexport interface AccessSnapshot {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n}\n\nexport class AccessManager {\n constructor(\n private readonly store: ConfigStore,\n private readonly profileName: string,\n ) {}\n\n snapshot(): AccessSnapshot {\n const profile = this.profile();\n return {\n allowedUsers: [...profile.access.allowedUsers],\n allowedChats: [...profile.access.allowedChats],\n admins: [...profile.access.admins],\n };\n }\n\n async addUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n await this.persist(snapshot);\n }\n\n async addAdmin(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n if (!snapshot.admins.includes(id)) snapshot.admins.push(id);\n await this.persist(snapshot);\n }\n\n async addChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedChats.includes(chatId)) snapshot.allowedChats.push(chatId);\n await this.persist(snapshot);\n }\n\n async removeUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedUsers = snapshot.allowedUsers.filter((item) => item !== id);\n snapshot.admins = snapshot.admins.filter((item) => item !== id);\n await this.persist(snapshot);\n }\n\n async removeChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedChats = snapshot.allowedChats.filter((item) => item !== chatId);\n await this.persist(snapshot);\n }\n\n private profile(): ProfileConfig {\n const profile = this.store.getProfile(this.profileName);\n if (!profile) throw new Error(`profile not found: ${this.profileName}`);\n return profile;\n }\n\n private async persist(snapshot: AccessSnapshot): Promise<void> {\n const profile = this.profile();\n await this.store.saveProfile(this.profileName, {\n tenant: profile.tenant,\n appId: profile.accounts.appId,\n appSecret: profile.accounts.appSecret,\n access: snapshot,\n });\n }\n}\n","import { registerApp, type RegisterAppOptions, type RegisterAppResult } from '@larksuite/channel';\nimport qrcode from 'qrcode-terminal';\nimport type { LarkTenant } from '../config/env.js';\n\nexport interface OnboardedApp {\n appId: string;\n appSecret: string;\n tenant: LarkTenant;\n operatorOpenId: string | undefined;\n}\n\nexport interface RegistrationDeps {\n register?: (options: RegisterAppOptions) => Promise<RegisterAppResult>;\n renderQr?: (value: string) => void;\n print?: (line: string) => void;\n source?: string;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_SOURCE = 'dsh-lark-bot';\n\nexport async function onboardPersonalAgent(\n deps: RegistrationDeps = {},\n): Promise<OnboardedApp> {\n const register = deps.register ?? registerApp;\n const renderQr = deps.renderQr ?? ((value) => qrcode.generate(value, { small: true }));\n const print = deps.print ?? ((line) => process.stdout.write(`${line}\\n`));\n\n print('');\n print('未检测到飞书 / Lark 应用凭据,进入扫码创建向导。');\n print('');\n\n const result = await register({\n source: deps.source ?? DEFAULT_SOURCE,\n ...(deps.signal ? { signal: deps.signal } : {}),\n onQRCodeReady: (info) => {\n print('请使用飞书 / Lark App 扫描以下二维码,创建或选择 PersonalAgent 应用:');\n print('');\n renderQr(info.url);\n print('');\n const minutes = Math.max(1, Math.round(info.expireIn / 60));\n print(`二维码有效期约 ${minutes} 分钟。`);\n print(`也可以直接在浏览器打开:${info.url}`);\n print('');\n },\n onStatusChange: (info) => {\n if (info.status === 'domain_switched') {\n print('已识别到国际版租户,自动切换到 larksuite.com 域名。');\n } else if (info.status === 'slow_down') {\n print('轮询速度过快,已自动降速。');\n }\n },\n });\n\n const tenant: LarkTenant = result.user_info?.tenant_brand === 'lark' ? 'lark' : 'feishu';\n\n print('✓ PersonalAgent 应用创建 / 绑定成功。');\n print(` App ID: ${result.client_id}`);\n print(` Tenant: ${tenant}`);\n print('');\n\n return {\n appId: result.client_id,\n appSecret: result.client_secret,\n tenant,\n operatorOpenId: result.user_info?.open_id,\n };\n}\n","import { mkdir, readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type {\n LarkChannel,\n NormalizedMessage,\n} from '@larksuite/channel';\n\nexport interface PreparedAttachments {\n imagePaths: string[];\n textFileNotes: string[];\n}\n\nconst MAX_TEXT_FILE_BYTES = 256_000;\n\nexport async function prepareAttachments(\n channel: LarkChannel | undefined,\n message: NormalizedMessage,\n mediaDir: string,\n): Promise<PreparedAttachments> {\n await mkdir(mediaDir, { recursive: true });\n const result: PreparedAttachments = { imagePaths: [], textFileNotes: [] };\n\n for (const resource of message.resources) {\n if (!channel || resource.type !== 'image' && resource.type !== 'file') continue;\n const destination = join(mediaDir, `${message.messageId}-${resource.fileKey}`);\n await channel.downloadResourceToFile(\n message.messageId,\n resource.fileKey,\n resource.type,\n destination,\n );\n\n if (resource.type === 'image') {\n result.imagePaths.push(destination);\n continue;\n }\n\n const info = await stat(destination);\n if (info.size > MAX_TEXT_FILE_BYTES) {\n result.textFileNotes.push(`[attachment: ${resource.fileName ?? resource.fileKey}] ${destination}`);\n continue;\n }\n\n const content = await readFile(destination, 'utf8');\n result.textFileNotes.push(\n `[attachment: ${resource.fileName ?? resource.fileKey}]\\n${content}`,\n );\n }\n\n return result;\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface SessionRecord {\n sessionId: string | undefined;\n cwd: string;\n messages: ChatMessage[];\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\ninterface SessionData {\n chats: Record<string, SessionRecord>;\n}\n\nexport class SessionStore {\n private data: SessionData = { chats: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<SessionData>;\n this.data = {\n chats: parsed.chats ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n getRaw(scopeId: string): SessionRecord | undefined {\n return this.data.chats[scopeId];\n }\n\n set(scopeId: string, sessionId: string | undefined, cwd: string): void {\n const existing = this.data.chats[scopeId];\n this.data.chats[scopeId] = {\n sessionId: sessionId ?? existing?.sessionId,\n cwd,\n messages: existing?.messages ?? [],\n };\n this.schedulePersist();\n }\n\n historyFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.messages : [];\n }\n\n recordExchange(\n scopeId: string,\n cwd: string,\n userMessages: string[],\n assistantMessage: string | undefined,\n ): void {\n const existing = this.data.chats[scopeId];\n const next: ChatMessage[] = [...(existing?.messages ?? [])];\n\n for (const content of userMessages) {\n if (content.trim()) next.push({ role: 'user', content });\n }\n\n if (assistantMessage?.trim()) {\n next.push({ role: 'assistant', content: assistantMessage });\n }\n\n this.data.chats[scopeId] = {\n sessionId: existing?.sessionId,\n cwd,\n messages: next.slice(-40),\n };\n this.schedulePersist();\n }\n\n clear(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n resumeFor(scopeId: string, cwd: string): string | undefined {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.sessionId : undefined;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = this.snapshot();\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('session', error, { step: 'persist' });\n });\n }\n\n private snapshot(): SessionData {\n return {\n chats: Object.fromEntries(\n Object.entries(this.data.chats).map(([key, record]) => [\n key,\n {\n ...record,\n messages: [...record.messages],\n },\n ]),\n ),\n };\n }\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\nexport type GitRunner = (args: string[], cwd: string) => Promise<string>;\n\nexport interface WorktreeEnsureResult {\n cwd: string;\n created: boolean;\n branch?: string;\n}\n\nexport interface GitWorktreeOptions {\n worktreesRoot: string;\n runGit?: GitRunner;\n copyRulesFile?: (source: string, target: string) => Promise<void>;\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, {\n cwd,\n encoding: 'utf8',\n });\n return result.stdout;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function defaultCopyRulesFile(source: string, target: string): Promise<void> {\n await mkdir(dirname(target), { recursive: true });\n await copyFile(source, target);\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nexport class GitWorktreeManager {\n private readonly runGit: GitRunner;\n private readonly copyRulesFile: (source: string, target: string) => Promise<void>;\n\n constructor(private readonly options: GitWorktreeOptions) {\n this.runGit = options.runGit ?? defaultRunGit;\n this.copyRulesFile = options.copyRulesFile ?? defaultCopyRulesFile;\n }\n\n async ensure(scope: string, base: string): Promise<WorktreeEnsureResult> {\n const isGit = await this.isGitRepository(base);\n if (!isGit) return { cwd: base, created: false };\n\n const slug = slugify(scope);\n const target = join(this.options.worktreesRoot, slug);\n if (await exists(target)) {\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: false };\n }\n\n const branch = `dsh-lark/${slug}-${Date.now().toString(36)}-${randomBytes(3).toString('hex')}`;\n await mkdir(this.options.worktreesRoot, { recursive: true });\n await this.runGit(['worktree', 'add', '-b', branch, target, 'HEAD'], base);\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: true, branch };\n }\n\n async isGitRepository(cwd: string): Promise<boolean> {\n try {\n const result = await this.runGit(['rev-parse', '--is-inside-work-tree'], cwd);\n return result.trim() === 'true';\n } catch {\n return false;\n }\n }\n\n private async ensureProjectRules(base: string, target: string): Promise<void> {\n const destination = join(target, 'AGENTS.md');\n if (await exists(destination)) return;\n\n const sourceCandidates = [join(base, '.dsh-lark', 'AGENTS.md'), join(base, 'AGENTS.md')];\n for (const source of sourceCandidates) {\n if (await exists(source)) {\n await this.copyRulesFile(source, destination);\n return;\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\ninterface WorkspaceData {\n chats: Record<string, { cwd: string }>;\n named: Record<string, string>;\n}\n\nexport class WorkspaceStore {\n private data: WorkspaceData = { chats: {}, named: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<WorkspaceData>;\n this.data = {\n chats: parsed.chats ?? {},\n named: parsed.named ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n cwdFor(scopeId: string): string | undefined {\n return this.data.chats[scopeId]?.cwd;\n }\n\n setCwd(scopeId: string, cwd: string): void {\n this.data.chats[scopeId] = { cwd };\n this.schedulePersist();\n }\n\n removeCwd(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n listNamed(): Record<string, string> {\n return { ...this.data.named };\n }\n\n getNamed(name: string): string | undefined {\n return this.data.named[name];\n }\n\n saveNamed(name: string, cwd: string): void {\n this.data.named[name] = cwd;\n this.schedulePersist();\n }\n\n removeNamed(name: string): boolean {\n if (!(name in this.data.named)) return false;\n delete this.data.named[name];\n this.schedulePersist();\n return true;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot: WorkspaceData = {\n chats: { ...this.data.chats },\n named: { ...this.data.named },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('workspace', error, { step: 'persist' });\n });\n }\n}\n"],"mappings":"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","names":["resolve","join","resolve","homedir","existsSync","join","resolve","join","homedir","mkdir","dirname","join","mkdir","dirname","mkdir","spawn","spawn","resolve","resolve","markdown","markdown","resolve","minutes","markdown","resolve","mkdir","readFile","stat","join","readFile","readFile","randomBytes","mkdir","dirname","join","readFile","readFile","mkdir","resolve"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-lark-bot",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "Bridge DeepSeek Harness (dsh) into Feishu / Lark with streaming cards, project workspaces, approvals and scheduling",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",