dsh-lark-bot 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -43
- package/dist/cli.js +79 -14
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<img src="https://img.shields.io/badge/agent-DeepSeek%20Harness-4D6BFE" alt="Agent">
|
|
10
10
|
<img src="https://img.shields.io/badge/runtime-Node.js%20%E2%89%A5%2022-339933" alt="Node">
|
|
11
11
|
<img src="https://img.shields.io/badge/License-AGPLv3-blue" alt="License">
|
|
12
|
-
<img src="https://img.shields.io/badge/status-
|
|
12
|
+
<img src="https://img.shields.io/badge/status-released-blue" alt="Status">
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<br>
|
|
@@ -26,72 +26,104 @@
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## 快速开始 · Quick Start(普通用户先看这里)
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
### 1. 安装
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
两个包名内容完全一致,任选一个即可:
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
```bash
|
|
36
|
+
# 推荐
|
|
37
|
+
npm install -g dsh-lark-bot
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
# 或飞书命名版本
|
|
40
|
+
npm install -g dsh-feishu-bot
|
|
41
|
+
```
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
安装完成后,对应命令分别为 `dsh-lark-bot` 和 `dsh-feishu-bot`。
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
- **飞书原生体验**:流式卡片、交互按钮、图片 / 文件、文档评论,全程双语。
|
|
43
|
-
- **完整工作区管理**:多项目隔离、git worktree、项目级规则注入、上下文持久化。
|
|
45
|
+
### 2. 启动并绑定飞书
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
47
|
+
```bash
|
|
48
|
+
dsh-lark-bot start
|
|
49
|
+
```
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
或:
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
- 当前 adapter 采用 **headless 子进程 fallback**,通过可配置的 `dsh` 命令与参数驱动,尚未锁定具体 dsh mainline commit;接入 ACP / SDK 的正式版本将在 P2 锁版后声明。
|
|
53
|
+
```bash
|
|
54
|
+
dsh-feishu-bot start
|
|
55
|
+
```
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
首次启动会:
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
1. 在终端显示二维码。
|
|
60
|
+
2. 用飞书 / Lark App 扫码。
|
|
61
|
+
3. 选择或创建 PersonalAgent 应用。
|
|
62
|
+
4. 绑定成功后,bot 会向你的私聊发送欢迎卡片。
|
|
63
|
+
5. 私聊直接发消息;群聊或话题里 `@bot`。
|
|
64
|
+
|
|
65
|
+
如果你已经有 PersonalAgent 应用,也可以跳过扫码:
|
|
59
66
|
|
|
60
67
|
```bash
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
pnpm start
|
|
68
|
+
dsh-lark-bot start \
|
|
69
|
+
--app-id cli_xxx \
|
|
70
|
+
--app-secret <secret> \
|
|
71
|
+
--tenant feishu
|
|
66
72
|
```
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
### 3. 基本使用
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
npm install -g dsh-lark-bot
|
|
72
|
-
dsh-lark-bot start
|
|
73
|
-
```
|
|
76
|
+
在飞书里向 bot 发送普通消息即可开始工作,常用命令:
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
| 命令 | 作用 |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `/new` `/reset` | 开始新会话 |
|
|
81
|
+
| `/cd <path>` | 切换工作目录并重置会话 |
|
|
82
|
+
| `/ws list` | 查看命名工作空间 |
|
|
83
|
+
| `/ws save <name>` | 保存当前工作空间 |
|
|
84
|
+
| `/ws use <name>` | 切换到命名工作空间 |
|
|
85
|
+
| `/status` | 查看当前状态 |
|
|
86
|
+
| `/stop` | 终止当前任务 |
|
|
87
|
+
| `/timeout [N|off|default]` | 查看或设置当前会话运行超时 |
|
|
88
|
+
| `/help` | 查看帮助 |
|
|
89
|
+
|
|
90
|
+
### 4. 卸载
|
|
76
91
|
|
|
77
92
|
```bash
|
|
78
93
|
npm uninstall -g dsh-lark-bot
|
|
79
94
|
rm -rf ~/.dsh-lark
|
|
80
95
|
```
|
|
81
96
|
|
|
82
|
-
|
|
97
|
+
更详细的安装、状态目录、日志和排障说明见 [`docs/QUICK_START.md`](docs/QUICK_START.md)。
|
|
83
98
|
|
|
84
|
-
|
|
85
|
-
dsh-lark-bot start
|
|
86
|
-
```
|
|
99
|
+
---
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
## 关键词 · Keywords
|
|
102
|
+
|
|
103
|
+
`dsh` · `deepseek` · `deepseek harness` · `feishu` · `lark` · `bridge` · `bot`
|
|
104
|
+
|
|
105
|
+
## 这是什么 · What it is
|
|
106
|
+
|
|
107
|
+
**dsh-lark-bot** 是一个轻量桥接工具,把本机的 DeepSeek Harness(`dsh`)接入飞书 / Lark,复刻当年 OpenCode Telegram Bot / MiMoCode Telegram Bot 的体验——在 IM 里与 coding agent 对话、收流式卡片、审阅 diff,并在此基础上叠加**完整的项目工作区管理**。
|
|
108
|
+
|
|
109
|
+
**dsh-lark-bot** is a lightweight bridge that connects your local DeepSeek Harness (`dsh`) into Feishu / Lark, recreating the beloved OpenCode / MiMoCode Telegram-bot experience — chat with your coding agent, receive streaming cards, review diffs — and adds **full project workspace management** on top.
|
|
93
110
|
|
|
94
|
-
|
|
111
|
+
## 目标 · Goals
|
|
112
|
+
|
|
113
|
+
- **一条命令启动**:clone 后一键安装运行,最终发布到 npm,`npx dsh-lark-bot` 即可拉起。
|
|
114
|
+
- **飞书原生体验**:流式卡片、交互按钮、图片 / 文件、文档评论,全程双语。
|
|
115
|
+
- **完整工作区管理**:多项目隔离、git worktree、项目级规则注入、上下文持久化。
|
|
116
|
+
|
|
117
|
+
- **One-command start**: clone and run in one step, eventually published to npm as `npx dsh-lark-bot`.
|
|
118
|
+
- **Native Feishu experience**: streaming cards, interactive buttons, images / files, doc comments.
|
|
119
|
+
- **Full workspace management**: multi-project isolation, git worktrees, per-project rules, persistent context.
|
|
120
|
+
|
|
121
|
+
## 兼容性 · Compatibility
|
|
122
|
+
|
|
123
|
+
- **DeepSeek Harness(`dsh`)**:developer preview(v0.1,2026-08 发布),通过 ACP / JSON-RPC SDK 接入。
|
|
124
|
+
- **运行时**:Node.js ≥ 22(桥接层要求 ≥ 20.12,统一采用 ≥ 22)。
|
|
125
|
+
- **平台**:Linux / macOS / Windows(飞书 WebSocket 出站长连接,免公网服务器 / 域名 / 内网穿透)。
|
|
126
|
+
- 当前 adapter 采用 **headless 子进程 fallback**,通过可配置的 `dsh` 命令与参数驱动,尚未锁定具体 dsh mainline commit;接入 ACP / SDK 的正式版本将在 P2 锁版后声明。
|
|
95
127
|
|
|
96
128
|
## 配置 · Configuration
|
|
97
129
|
|
|
@@ -108,13 +140,15 @@ dsh-lark-bot start
|
|
|
108
140
|
| :--- | :--- | :--- |
|
|
109
141
|
| `DSH_LARK_HOME` | `~/.dsh-lark` | 本地状态根目录 |
|
|
110
142
|
| `DSH_LARK_TENANT` | `feishu` | `feishu` 或 `lark` |
|
|
111
|
-
| `DSH_LARK_DSH_COMMAND` |
|
|
112
|
-
| `DSH_LARK_DSH_ARGS` |
|
|
143
|
+
| `DSH_LARK_DSH_COMMAND` | `自动发现` | dsh 启动命令;通常无需设置 |
|
|
144
|
+
| `DSH_LARK_DSH_ARGS` | `自动发现` | dsh 启动参数,逗号分隔;通常无需设置 |
|
|
113
145
|
| `DSH_LARK_PROVIDER` | `deepseek-official` | 模型 provider |
|
|
114
146
|
| `DSH_LARK_MODEL` | `deepseek-v4-flash` | 默认模型 |
|
|
115
147
|
| `DSH_LARK_RUN_TIMEOUT_MS` | `300000` | 单次运行墙钟超时 |
|
|
116
148
|
| `DSH_LARK_STOP_GRACE_MS` | `5000` | SIGTERM 后等待优雅退出再 SIGKILL 的宽限期 |
|
|
117
149
|
|
|
150
|
+
启动时会自动查找本机常见的 `@deepseek-ai/dsh` 安装位置。只有自动发现失败或需要指定特殊 profile 时,才需要设置这两个变量。
|
|
151
|
+
|
|
118
152
|
## 权限与数据 · Permissions & Data
|
|
119
153
|
|
|
120
154
|
本工具在**本机**运行,安装前请知悉它会访问:
|
package/dist/cli.js
CHANGED
|
@@ -74,12 +74,65 @@ function resolveAppPaths(root = defaultHome()) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// src/config/env.ts
|
|
77
|
-
import { join as
|
|
77
|
+
import { join as join3, resolve as resolve2 } from "path";
|
|
78
78
|
import { homedir as homedir2 } from "os";
|
|
79
|
+
|
|
80
|
+
// src/config/dsh-runtime.ts
|
|
81
|
+
import { existsSync, readdirSync } from "fs";
|
|
82
|
+
import { join as join2 } from "path";
|
|
83
|
+
var DS_HARNESS_RELATIVE = join2("@deepseek-ai", "dsh", "lib", "bin.js");
|
|
84
|
+
function firstExisting(...paths) {
|
|
85
|
+
return paths.find((path) => existsSync(path));
|
|
86
|
+
}
|
|
87
|
+
function children(root) {
|
|
88
|
+
try {
|
|
89
|
+
return readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() || entry.isSymbolicLink()).map((entry) => join2(root, entry.name));
|
|
90
|
+
} catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function discoverDshBin(home, env = process.env) {
|
|
95
|
+
const dshHome = env.DSH_HOME?.trim() || join2(home, ".dsh");
|
|
96
|
+
const candidates = [
|
|
97
|
+
join2(dshHome, "profiles", "node_modules", DS_HARNESS_RELATIVE),
|
|
98
|
+
join2(home, ".npm", "_npx", "node_modules", DS_HARNESS_RELATIVE),
|
|
99
|
+
join2(home, ".cache", "pnpm", "dlx", "node_modules", DS_HARNESS_RELATIVE),
|
|
100
|
+
join2(home, ".local", "share", "pnpm", "node_modules", DS_HARNESS_RELATIVE)
|
|
101
|
+
];
|
|
102
|
+
const direct = firstExisting(...candidates);
|
|
103
|
+
if (direct) return direct;
|
|
104
|
+
for (const root of [join2(home, ".npm", "_npx"), join2(home, ".cache", "pnpm", "dlx")]) {
|
|
105
|
+
for (const child of children(root)) {
|
|
106
|
+
const path = join2(child, "node_modules", DS_HARNESS_RELATIVE);
|
|
107
|
+
if (existsSync(path)) return path;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
function resolveDshRuntime(input) {
|
|
113
|
+
if (input.command || input.args) {
|
|
114
|
+
return {
|
|
115
|
+
command: input.command ?? "node",
|
|
116
|
+
args: input.args ?? ["--profile", "headless"]
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const bin = discoverDshBin(input.home, input.env);
|
|
120
|
+
if (bin) {
|
|
121
|
+
return {
|
|
122
|
+
command: "node",
|
|
123
|
+
args: [bin, "--profile", "headless"],
|
|
124
|
+
bin
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
command: "dsh",
|
|
129
|
+
args: ["--profile", "headless"]
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/config/env.ts
|
|
79
134
|
var DEFAULTS = {
|
|
80
135
|
tenant: "feishu",
|
|
81
|
-
dshCommand: "node",
|
|
82
|
-
dshArgs: ["lib/bin.js", "cordis.yml"],
|
|
83
136
|
provider: "deepseek-official",
|
|
84
137
|
model: "deepseek-v4-flash",
|
|
85
138
|
runTimeoutMs: 3e5,
|
|
@@ -98,7 +151,7 @@ function parseTenant(value) {
|
|
|
98
151
|
}
|
|
99
152
|
function parseDshArgs(value) {
|
|
100
153
|
const raw = value?.trim();
|
|
101
|
-
if (!raw) return [
|
|
154
|
+
if (!raw) return [];
|
|
102
155
|
return raw.split(",").map((item) => item.trim()).filter(Boolean);
|
|
103
156
|
}
|
|
104
157
|
function parseTimeout(value) {
|
|
@@ -122,14 +175,24 @@ function parseStopGrace(value) {
|
|
|
122
175
|
function loadRuntimeEnv(source = process.env) {
|
|
123
176
|
const homeOverride = nonEmpty(source.DSH_LARK_HOME);
|
|
124
177
|
const workspace = nonEmpty(source.DSH_LARK_WORKSPACE);
|
|
178
|
+
const home = homeOverride ? resolve2(homeOverride) : join3(homedir2(), ".dsh-lark");
|
|
179
|
+
const osHome = homedir2();
|
|
180
|
+
const dshCommand = nonEmpty(source.DSH_LARK_DSH_COMMAND);
|
|
181
|
+
const rawDshArgs = nonEmpty(source.DSH_LARK_DSH_ARGS);
|
|
182
|
+
const dshRuntime = resolveDshRuntime({
|
|
183
|
+
home: osHome,
|
|
184
|
+
env: source,
|
|
185
|
+
...dshCommand ? { command: dshCommand } : {},
|
|
186
|
+
...rawDshArgs ? { args: parseDshArgs(rawDshArgs) } : {}
|
|
187
|
+
});
|
|
125
188
|
return {
|
|
126
|
-
home
|
|
189
|
+
home,
|
|
127
190
|
tenant: parseTenant(source.DSH_LARK_TENANT),
|
|
128
191
|
appId: nonEmpty(source.DSH_LARK_APP_ID),
|
|
129
192
|
appSecret: nonEmpty(source.DSH_LARK_APP_SECRET),
|
|
130
193
|
workspace: workspace ? resolve2(workspace) : void 0,
|
|
131
|
-
dshCommand:
|
|
132
|
-
dshArgs:
|
|
194
|
+
dshCommand: dshRuntime.command,
|
|
195
|
+
dshArgs: dshRuntime.args,
|
|
133
196
|
provider: nonEmpty(source.DSH_LARK_PROVIDER) ?? DEFAULTS.provider,
|
|
134
197
|
model: nonEmpty(source.DSH_LARK_MODEL) ?? DEFAULTS.model,
|
|
135
198
|
runTimeoutMs: parseTimeout(source.DSH_LARK_RUN_TIMEOUT_MS),
|
|
@@ -145,11 +208,11 @@ import { dirname as dirname2 } from "path";
|
|
|
145
208
|
// src/platform/atomic-write.ts
|
|
146
209
|
import { randomBytes } from "crypto";
|
|
147
210
|
import { mkdir, rename, writeFile } from "fs/promises";
|
|
148
|
-
import { dirname, join as
|
|
211
|
+
import { dirname, join as join4 } from "path";
|
|
149
212
|
async function writeFileAtomic(target, data, options = {}) {
|
|
150
213
|
const directory = dirname(target);
|
|
151
214
|
await mkdir(directory, { recursive: true });
|
|
152
|
-
const temporary =
|
|
215
|
+
const temporary = join4(directory, `.${randomBytes(8).toString("hex")}.tmp`);
|
|
153
216
|
try {
|
|
154
217
|
await writeFile(temporary, data, options.mode === void 0 ? void 0 : { mode: options.mode });
|
|
155
218
|
await rename(temporary, target);
|
|
@@ -259,7 +322,9 @@ async function runDoctor(options) {
|
|
|
259
322
|
`version: ${options.version ?? "unknown"}`,
|
|
260
323
|
`node: ${process.version}`,
|
|
261
324
|
`profile: ${profileName}`,
|
|
262
|
-
`home: ${paths.root}
|
|
325
|
+
`home: ${paths.root}`,
|
|
326
|
+
`dsh_command: ${env.dshCommand}`,
|
|
327
|
+
`dsh_args: ${env.dshArgs.join(",")}`
|
|
263
328
|
];
|
|
264
329
|
let critical = false;
|
|
265
330
|
if (!profile) {
|
|
@@ -1349,7 +1414,7 @@ var SessionStore = class {
|
|
|
1349
1414
|
import { execFile } from "child_process";
|
|
1350
1415
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
1351
1416
|
import { access, copyFile, mkdir as mkdir3 } from "fs/promises";
|
|
1352
|
-
import { dirname as dirname3, join as
|
|
1417
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
1353
1418
|
import { promisify } from "util";
|
|
1354
1419
|
var execFileAsync = promisify(execFile);
|
|
1355
1420
|
async function defaultRunGit(args, cwd) {
|
|
@@ -1388,7 +1453,7 @@ var GitWorktreeManager = class {
|
|
|
1388
1453
|
const isGit = await this.isGitRepository(base);
|
|
1389
1454
|
if (!isGit) return { cwd: base, created: false };
|
|
1390
1455
|
const slug = slugify(scope);
|
|
1391
|
-
const target =
|
|
1456
|
+
const target = join5(this.options.worktreesRoot, slug);
|
|
1392
1457
|
if (await exists(target)) {
|
|
1393
1458
|
await this.ensureProjectRules(base, target);
|
|
1394
1459
|
return { cwd: target, created: false };
|
|
@@ -1408,9 +1473,9 @@ var GitWorktreeManager = class {
|
|
|
1408
1473
|
}
|
|
1409
1474
|
}
|
|
1410
1475
|
async ensureProjectRules(base, target) {
|
|
1411
|
-
const destination =
|
|
1476
|
+
const destination = join5(target, "AGENTS.md");
|
|
1412
1477
|
if (await exists(destination)) return;
|
|
1413
|
-
const sourceCandidates = [
|
|
1478
|
+
const sourceCandidates = [join5(base, ".dsh-lark", "AGENTS.md"), join5(base, "AGENTS.md")];
|
|
1414
1479
|
for (const source of sourceCandidates) {
|
|
1415
1480
|
if (await exists(source)) {
|
|
1416
1481
|
await this.copyRulesFile(source, destination);
|
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/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 ];\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';\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 dshCommand: 'node',\n dshArgs: ['lib/bin.js', 'cordis.yml'],\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 [...DEFAULTS.dshArgs];\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\n return {\n home: homeOverride ? resolve(homeOverride) : join(homedir(), '.dsh-lark'),\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: nonEmpty(source.DSH_LARK_DSH_COMMAND) ?? DEFAULTS.dshCommand,\n dshArgs: parseDshArgs(source.DSH_LARK_DSH_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 { 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 prompt = input.messages.join('\\n\\n');\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\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 === '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 } 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 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 '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;\n cwd: 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, cwd: string): void {\n this.data.chats[scopeId] = { sessionId, cwd };\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: { ...this.data.chats },\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","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/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 prompt = input.messages.join('\\n\\n');\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\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 === '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 } 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 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 '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;\n cwd: 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, cwd: string): void {\n this.data.chats[scopeId] = { sessionId, cwd };\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: { ...this.data.chats },\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"]}
|
package/package.json
CHANGED