Skip to content

Commit dec8b07

Browse files
committed
Merge branch 'main' into feature/notify-env-context
2 parents 479606f + e4d9b44 commit dec8b07

30 files changed

Lines changed: 1381 additions & 487 deletions

README_en.md renamed to README-en.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
1-
# Deep Code CLI
1+
<div align="center">
2+
<br/>
3+
<br/>
4+
<p align="center">
5+
<a href='https://deepcode.vegamo.cn/'>
6+
<img src='https://avatars.githubusercontent.com/u/118287711?s=200&v=4' width='100' alt="deepcode-cli"/>
7+
</a>
8+
</p>
9+
<h1>Deep Code CLI</h1>
10+
11+
English · [中文](./README.md)
12+
13+
<br/>
14+
</div>
215

316
[Deep Code](https://github.com/lessweb/deepcode-cli) is a terminal AI coding assistant optimized for the `deepseek-v4` model, with support for deep thinking, reasoning effort control, Agent Skills, and MCP (Model Context Protocol) integration.
417

18+
519
## Installation
620

721
```bash
@@ -53,6 +67,7 @@ Deep Code CLI supports agent skills that allow you to extend the assistant's cap
5367
| `/new` | Start a fresh conversation |
5468
| `/resume` | Choose a previous conversation to continue |
5569
| `/model` | Switch model, thinking mode, and reasoning effort |
70+
| `/raw` | Toggle display mode (Normal / Lite / Raw scrollback) |
5671
| `/init` | Initialize an AGENTS.md file (LLM project instructions) |
5772
| `/skills` | List available skills |
5873
| `/mcp` | View MCP server status and available tools |

README_cn.md renamed to README-zh_CN.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
# Deep Code CLI
1+
<div align="center">
2+
<br/>
3+
<br/>
4+
<p align="center">
5+
<a href='https://deepcode.vegamo.cn/'>
6+
<img src='https://avatars.githubusercontent.com/u/118287711?s=200&v=4' width='100' alt="deepcode-cli"/>
7+
</a>
8+
</p>
9+
<h1>Deep Code CLI</h1>
10+
11+
[English](README-en.md) · 中文
12+
13+
<br/>
14+
</div>
215

316
[Deep Code](https://github.com/lessweb/deepcode-cli) 是专为 `deepseek-v4` 模型优化的终端 AI 编码助手,支持深度思考、推理强度控制、Agent Skills 以及 MCP 集成。
417

@@ -53,6 +66,7 @@ Deep Code CLI 支持 agent skills,允许您扩展助手的能力:
5366
| `/new` | 开始新对话 |
5467
| `/resume` | 选择历史对话继续 |
5568
| `/model` | 切换模型、思考模式和推理强度 |
69+
| `/raw` | 切换显示模式(Normal / Lite / Raw 滚动回溯)|
5670
| `/init` | 初始化 AGENTS.md 文件 |
5771
| `/skills` | 列出可用 skills |
5872
| `/mcp` | 查看 MCP 服务器状态和可用工具 |

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
# Deep Code CLI
1+
<div align="center">
2+
<br/>
3+
<br/>
4+
<p align="center">
5+
<a href='https://deepcode.vegamo.cn/'>
6+
<img src='https://avatars.githubusercontent.com/u/118287711?s=200&v=4' width='100' alt="deepcode-cli"/>
7+
</a>
8+
</p>
9+
<h1>Deep Code CLI</h1>
10+
11+
[English](README-en.md) · 中文
12+
13+
<br/>
14+
</div>
215

316
[Deep Code](https://github.com/lessweb/deepcode-cli) 是专为 `deepseek-v4` 模型优化的终端 AI 编码助手,支持深度思考、推理强度控制、Agent Skills 以及 MCP 集成。
417

@@ -53,6 +66,7 @@ Deep Code CLI 支持 agent skills,允许您扩展助手的能力:
5366
| `/new` | 开始新对话 |
5467
| `/resume` | 选择历史对话继续 |
5568
| `/model` | 切换模型、思考模式和推理强度 |
69+
| `/raw` | 切换显示模式(Normal / Lite / Raw 滚动回溯)|
5670
| `/init` | 初始化 AGENTS.md 文件 |
5771
| `/skills` | 列出可用 skills |
5872
| `/mcp` | 查看 MCP 服务器状态和可用工具 |

src/cli.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from "react";
22
import { render } from "ink";
3-
import { App } from "./ui";
43
import { setShellIfWindows } from "./common/shell-utils";
54
import { checkForNpmUpdate, promptForPendingUpdate, type PackageInfo } from "./updateCheck";
5+
import { AppContainer } from "./ui";
66

77
const args = process.argv.slice(2);
88
const packageInfo = readPackageInfo();
@@ -81,7 +81,7 @@ async function main(): Promise<void> {
8181
const appInitialPrompt = initialPrompt;
8282
initialPrompt = undefined;
8383
const inkInstance = render(
84-
<App
84+
<AppContainer
8585
projectRoot={projectRoot}
8686
version={packageInfo.version}
8787
initialPrompt={appInitialPrompt}

src/common/process-tree.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { spawnSync } from "child_process";
2+
3+
type TaskkillSpawnSync = (
4+
command: string,
5+
args: string[],
6+
options: { stdio: "ignore"; windowsHide: true }
7+
) => { status: number | null; error?: Error };
8+
9+
export type KillProcessTreeDeps = {
10+
platform?: NodeJS.Platform;
11+
killPid?: (pid: number, signal: NodeJS.Signals) => void;
12+
runTaskkill?: (pid: number) => boolean;
13+
killGroupOnNonWindows?: boolean;
14+
};
15+
16+
export function killProcessTree(
17+
pid: number,
18+
signal: NodeJS.Signals = "SIGKILL",
19+
deps: KillProcessTreeDeps = {}
20+
): boolean {
21+
if (!Number.isInteger(pid) || pid <= 0) {
22+
return false;
23+
}
24+
25+
const platform = deps.platform ?? process.platform;
26+
const killPid = deps.killPid ?? ((targetPid, targetSignal) => process.kill(targetPid, targetSignal));
27+
28+
if (platform === "win32") {
29+
const runTaskkill = deps.runTaskkill ?? runWindowsTaskkill;
30+
if (runTaskkill(pid)) {
31+
return true;
32+
}
33+
return killDirectProcess(pid, signal, killPid);
34+
}
35+
36+
if (deps.killGroupOnNonWindows !== false && killDirectProcess(-pid, signal, killPid)) {
37+
return true;
38+
}
39+
return killDirectProcess(pid, signal, killPid);
40+
}
41+
42+
export function runWindowsTaskkill(pid: number, spawnSyncImpl: TaskkillSpawnSync = spawnSync): boolean {
43+
const result = spawnSyncImpl("taskkill", ["/PID", String(pid), "/T", "/F"], {
44+
stdio: "ignore",
45+
windowsHide: true,
46+
});
47+
return !result.error && result.status === 0;
48+
}
49+
50+
function killDirectProcess(
51+
pid: number,
52+
signal: NodeJS.Signals,
53+
killPid: (pid: number, signal: NodeJS.Signals) => void
54+
): boolean {
55+
try {
56+
killPid(pid, signal);
57+
return true;
58+
} catch {
59+
return false;
60+
}
61+
}

src/mcp/mcp-client.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { spawn, type ChildProcess } from "child_process";
22
import { createInterface, type Interface } from "readline";
33
import * as os from "os";
44
import * as path from "path";
5+
import { killProcessTree } from "../common/process-tree";
56

67
type JsonRpcRequest = {
78
jsonrpc: "2.0";
@@ -268,7 +269,11 @@ export class McpClient {
268269
this.reader = null;
269270
}
270271
if (this.process) {
271-
this.process.kill();
272+
if (typeof this.process.pid === "number") {
273+
killProcessTree(this.process.pid, "SIGTERM", { killGroupOnNonWindows: false });
274+
} else {
275+
this.process.kill();
276+
}
272277
this.process = null;
273278
}
274279
}

src/session.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { McpManager } from "./mcp/mcp-manager";
2222
import type { McpServerConfig } from "./settings";
2323
import { logApiError } from "./common/error-logger";
2424
import { logOpenAIChatCompletionDebug, normalizeDebugError } from "./common/debug-logger";
25+
import { killProcessTree } from "./common/process-tree";
2526

2627
const MAX_SESSION_ENTRIES = 50;
2728
const DEFAULT_NEW_PROMPT_API_URL = "https://deepcode.vegamo.cn/api/plugin/new";
@@ -1359,17 +1360,11 @@ ${skillMd}
13591360
const killedPids: number[] = [];
13601361
const failedPids: number[] = [];
13611362
for (const pid of processIds) {
1362-
const killedGroup = this.killProcessGroup(pid);
1363-
if (killedGroup) {
1363+
if (killProcessTree(pid, "SIGKILL")) {
13641364
killedPids.push(pid);
13651365
continue;
13661366
}
1367-
try {
1368-
process.kill(pid, "SIGKILL");
1369-
killedPids.push(pid);
1370-
} catch {
1371-
failedPids.push(pid);
1372-
}
1367+
failedPids.push(pid);
13731368
}
13741369

13751370
const controller = this.sessionControllers.get(sessionId);
@@ -2202,18 +2197,6 @@ ${skillMd}
22022197
);
22032198
}
22042199

2205-
private killProcessGroup(pid: number): boolean {
2206-
if (process.platform === "win32") {
2207-
return false;
2208-
}
2209-
try {
2210-
process.kill(-pid, "SIGKILL");
2211-
return true;
2212-
} catch {
2213-
return false;
2214-
}
2215-
}
2216-
22172200
private normalizeSessionEntry(entry: unknown): SessionEntry {
22182201
const value = entry && typeof entry === "object" ? (entry as Record<string, unknown>) : {};
22192202
return {

0 commit comments

Comments
 (0)