Skip to content

Commit a7e2bdc

Browse files
authored
Merge pull request #36 from itmisx/feature/exec_mode
✨ exec mode
2 parents 07d4104 + 551ad04 commit a7e2bdc

6 files changed

Lines changed: 189 additions & 12 deletions

File tree

README.en.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- **💾 Lossless session persistence** — gob preserves `tool_calls` / tool results / `reasoning_content`, so restarts resume seamlessly; auto layered compaction when the window fills.
3030
- **🔌 MCP + skill ecosystem** — native MCP; compatible with Claude's skill directories, reuse what you have.
3131
- **🛡️ Review mode** — file writes / shell run behind human confirmation by default.
32+
- **⚡ Non-interactive `exec` mode**`deepx exec "task"` runs once and prints the result straight to stdout; pipe data in, redirect output, drop it into scripts / CI / cron — **no TUI needed** (see the section below).
3233

3334
## 📊 vs Claude Code
3435

@@ -64,11 +65,16 @@ irm https://raw.githubusercontent.com/itmisx/deepx-code/main/scripts/install.ps1
6465

6566
Installs to `~/.local/bin/deepx`; upgrade any time with `deepx upgrade`.
6667

67-
**2. Enter a project and launch**
68+
**2. Open a terminal in your project and launch**
69+
70+
deepx is a **terminal program**: open a terminal, `cd` into your project, and run `deepx` to enter the interactive UI.
71+
72+
- Any terminal works: macOS Terminal / iTerm2, a Linux terminal, Windows Terminal / PowerShell.
73+
- The **VS Code integrated terminal** is recommended too (`Terminal → New Terminal`, or `` Ctrl+` ``): it already sits in your open project, so `deepx` works right against it and edits show up live in the editor.
6874

6975
```bash
70-
cd <your-project>
71-
deepx
76+
cd <your-project> # VS Code's integrated terminal is usually already at the project root
77+
deepx # enter the interactive TUI
7278
```
7379

7480
**3. Configure**
@@ -80,6 +86,16 @@ deepx
8086
| Skills | Drop into `<workspace>/.deepx/skills/`, or reuse `~/.claude/skills/` etc. |
8187
| MCP | Add via `/mcp-add` inside the TUI; list with `/mcp-list`. |
8288

89+
## ⚡ Non-interactive execution (`deepx exec`)
90+
91+
When you'd rather not enter the full TUI and want to drop deepx into a script, use `deepx exec "<task>"`: it runs the task, prints the result straight to your terminal (stdout), then exits — result only, no intermediate noise.
92+
93+
```bash
94+
deepx exec "Translate the feature list in README to English and write it to README.en.md"
95+
```
96+
97+
Piping data in is also supported (`cat error.log | deepx exec "analyze this error"`). Configure your API key once via the interactive `deepx` first.
98+
8399
## 🧠 How It Works
84100

85101
<details>

README.ja.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- **💾 ロスレスなセッション永続化** —— gob が `tool_calls` / ツール結果 / `reasoning_content` を完全保持し、再起動後もシームレスに継続。ウィンドウが埋まると自動で階層圧縮。
3030
- **🔌 MCP + Skill エコシステム** —— MCP ネイティブ対応。Claude の skill ディレクトリと互換で、既存の skill をそのまま再利用。
3131
- **🛡️ レビューモード** —— ファイル書き込み / Shell 実行はデフォルトで人間の確認を要求。
32+
- **⚡ 非対話 `exec` モード** —— `deepx exec "タスク"` は一度だけ実行して結果を stdout に直接出力。パイプで入力、出力をリダイレクト、スクリプト / CI / cron に組み込み可能で、**TUI に入る必要なし**(下記参照)。
3233

3334
## 📊 Claude Code との比較
3435

@@ -64,11 +65,16 @@ irm https://raw.githubusercontent.com/itmisx/deepx-code/main/scripts/install.ps1
6465

6566
`~/.local/bin/deepx` にインストールされます。`deepx upgrade` でいつでも更新可能。
6667

67-
**2. プロジェクトに入って起動**
68+
**2. ターミナルでプロジェクトに入って起動**
69+
70+
deepx は**ターミナルプログラム**です。ターミナルを開き、プロジェクトに `cd` して `deepx` を実行すると対話 UI に入ります。
71+
72+
- どのターミナルでも OK:macOS の Terminal / iTerm2、Linux のターミナル、Windows Terminal / PowerShell。
73+
- **VS Code 内蔵ターミナル**もおすすめ(`Terminal → New Terminal`、または `` Ctrl+` ``):開いているプロジェクトのディレクトリにいるので、`deepx` がそのプロジェクトに対して動き、編集はエディタに即座に反映されます。
6874

6975
```bash
70-
cd <あなたのプロジェクト>
71-
deepx
76+
cd <あなたのプロジェクト> # VS Code の内蔵ターミナルなら通常すでにプロジェクト直下
77+
deepx # 対話型 TUI に入る
7278
```
7379

7480
**3. 設定**
@@ -80,6 +86,16 @@ deepx
8086
| Skill | `<ワークスペース>/.deepx/skills/` に配置、または `~/.claude/skills/` などを再利用。 |
8187
| MCP | TUI 内で `/mcp-add` で追加、`/mcp-list` で一覧。 |
8288

89+
## ⚡ 非対話実行(`deepx exec`
90+
91+
フル TUI に入らず deepx をスクリプトに組み込みたいときは `deepx exec "<タスク>"` を使います。タスクを実行し、結果をそのままターミナル(stdout)に出力して終了します。結果のみ、途中の出力はありません。
92+
93+
```bash
94+
deepx exec "README の機能リストを英語に翻訳して README.en.md に書き込む"
95+
```
96+
97+
パイプ入力にも対応(`cat error.log | deepx exec "このエラーを分析して"`)。先に対話型 `deepx` で API キーを設定しておいてください。
98+
8399
## 🧠 仕組み
84100

85101
<details>

README.ko.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- **💾 무손실 세션 영속화** —— gob가 `tool_calls` / 도구 결과 / `reasoning_content`를 완전 보존해 재시작 후에도 매끄럽게 이어감. 윈도가 차면 자동 계층 압축.
3030
- **🔌 MCP + Skill 생태계** —— MCP 네이티브 지원. Claude의 skill 디렉터리와 호환되어 기존 skill을 그대로 재사용.
3131
- **🛡️ 검토 모드** —— 파일 쓰기 / Shell 실행은 기본적으로 사람의 확인을 요구.
32+
- **⚡ 비대화형 `exec` 모드** —— `deepx exec "작업"` 은 한 번 실행하고 결과를 바로 stdout으로 출력. 파이프로 입력하고, 출력을 리다이렉트하고, 스크립트 / CI / cron에 넣을 수 있어 **TUI에 들어갈 필요 없음**(아래 참조).
3233

3334
## 📊 Claude Code 비교
3435

@@ -64,11 +65,16 @@ irm https://raw.githubusercontent.com/itmisx/deepx-code/main/scripts/install.ps1
6465

6566
`~/.local/bin/deepx`에 설치됩니다. `deepx upgrade`로 언제든 업데이트.
6667

67-
**2. 프로젝트로 이동해 실행**
68+
**2. 터미널에서 프로젝트로 이동해 실행**
69+
70+
deepx는 **터미널 프로그램**입니다. 터미널을 열고 프로젝트로 `cd` 한 뒤 `deepx` 를 실행하면 대화형 UI로 들어갑니다.
71+
72+
- 어떤 터미널이든 OK: macOS Terminal / iTerm2, Linux 터미널, Windows Terminal / PowerShell.
73+
- **VS Code 내장 터미널**도 추천(`Terminal → New Terminal`, 또는 `` Ctrl+` ``): 열려 있는 프로젝트 디렉터리에 이미 있어서 `deepx` 가 그 프로젝트를 대상으로 동작하고, 수정 사항이 에디터에 즉시 반영됩니다.
6874

6975
```bash
70-
cd <당신의 프로젝트>
71-
deepx
76+
cd <당신의 프로젝트> # VS Code 내장 터미널이면 보통 이미 프로젝트 루트에 있음
77+
deepx # 대화형 TUI 진입
7278
```
7379

7480
**3. 설정**
@@ -80,6 +86,16 @@ deepx
8086
| Skill | `<워크스페이스>/.deepx/skills/`에 두거나 `~/.claude/skills/` 등 재사용. |
8187
| MCP | TUI에서 `/mcp-add`로 추가, `/mcp-list`로 목록 확인. |
8288

89+
## ⚡ 비대화형 실행(`deepx exec`
90+
91+
전체 TUI에 들어가지 않고 deepx를 스크립트에 넣고 싶을 때는 `deepx exec "<작업>"` 을 사용하세요. 작업을 실행하고 결과를 그대로 터미널(stdout)에 출력한 뒤 종료합니다. 결과만 나오고 중간 과정은 표시되지 않습니다.
92+
93+
```bash
94+
deepx exec "README의 기능 목록을 영어로 번역해 README.en.md에 작성"
95+
```
96+
97+
파이프 입력도 지원합니다(`cat error.log | deepx exec "이 에러를 분석해줘"`). 먼저 대화형 `deepx`로 API 키를 설정해 두세요.
98+
8399
## 🧠 동작 원리
84100

85101
<details>

README.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- **💾 无损会话持久化** —— gob 完整保留 `tool_calls` / `tool results` / `reasoning_content`,重启无缝续接;超窗自动分层压缩。
3030
- **🔌 MCP + Skill 生态** —— 原生 MCP;兼容 Claude 的 skill 目录,已有 skill 直接复用。
3131
- **🛡️ 审核模式** —— 写文件 / 执行 Shell 默认需人工确认,安全可控。
32+
- **⚡ 非交互 `exec` 模式** —— `deepx exec "任务"` 一次性跑完直接把结果打到 stdout,支持管道喂数据、重定向输出、塞进脚本 / CI / cron,**不必进 TUI**(用法见下方「非交互执行」一节)。
3233

3334
## 📊 对比 Claude Code
3435

@@ -64,11 +65,16 @@ irm https://raw.githubusercontent.com/itmisx/deepx-code/main/scripts/install.ps1
6465

6566
安装到 `~/.local/bin/deepx`,随时用 `deepx upgrade` 升级。
6667

67-
**2. 进入项目并启动**
68+
**2. 在终端里进入项目并启动**
69+
70+
deepx 是个**终端程序**:打开一个终端,`cd` 进你的项目目录,运行 `deepx` 即可进入交互式界面。
71+
72+
- 任何终端都行:macOS 自带 Terminal / iTerm2、Linux 终端、Windows Terminal / PowerShell。
73+
- 也推荐 **VS Code 内置终端**(菜单 `Terminal → New Terminal`,或快捷键 `` Ctrl+` ``):它默认就在当前打开的工程目录,`deepx` 起来直接对着这个项目干活,改完文件 VS Code 里实时可见。
6874

6975
```bash
70-
cd <你的项目目录>
71-
deepx
76+
cd <你的项目目录> # VS Code 内置终端通常已经在项目根,可跳过
77+
deepx # 进入交互式 TUI
7278
```
7379

7480
**3. 配置**
@@ -80,6 +86,16 @@ deepx
8086
| Skill | 放到 `<工作区>/.deepx/skills/`,或复用 `~/.claude/skills/` 等已有目录。 |
8187
| MCP | TUI 内 `/mcp-add` 添加,`/mcp-list` 查看。 |
8288

89+
## ⚡ 非交互执行(`deepx exec`
90+
91+
不想进全屏 TUI、想把 deepx 塞进脚本时,用 `deepx exec "<任务>"`:跑完把结果直接打到终端(stdout)再退出,只输出结果、不显示中间过程。
92+
93+
```bash
94+
deepx exec "把 README 的功能列表翻译成英文,写到 README.en.md"
95+
```
96+
97+
也支持管道喂数据(`cat error.log | deepx exec "分析这段报错"`)。需先用交互式 `deepx` 配好 API key。
98+
8399
## 🧠 核心机制
84100

85101
<details>

main.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"deepx/config"
66
"deepx/tui"
77
"fmt"
8+
"io"
89
"os"
10+
"strings"
911
)
1012

1113
// 由 goreleaser 在 build 时通过 -ldflags "-X main.version=..." 注入。
@@ -28,6 +30,11 @@ func main() {
2830
}
2931
return
3032
}
33+
// deepx exec [--mode plan|auto] "<任务>" —— 非交互一次性执行,结果打到 stdout,可脚本化 / 管道。
34+
// 也可从 stdin 接管道输入(cat x | deepx exec "分析这段")。默认 auto(全工具,不弹审批)。
35+
if len(os.Args) > 1 && os.Args[1] == "exec" {
36+
runExecAndExit(os.Args[2:])
37+
}
3138
cfg, needsSetup, err := loadOrEmptyConfig()
3239
if err != nil {
3340
fmt.Fprintln(os.Stderr, "错误:", err)
@@ -63,3 +70,44 @@ func toAgentConfig(c *config.Config) agent.ModelConfig {
6370
Pro: agent.ModelEntry(c.Pro),
6471
}
6572
}
73+
74+
// runExecAndExit 解析 `deepx exec` 的参数(args = os.Args[2:]),跑非交互执行,然后退出进程。
75+
// 用法:deepx exec "<任务>";也可从 stdin 管道喂输入。固定 auto 模式、只输出结果,无任何参数。
76+
// 退出码:成功 0;用法错误 2;执行/配置错误 1。
77+
func runExecAndExit(args []string) {
78+
prompt := strings.TrimSpace(strings.Join(args, " "))
79+
80+
// stdin 若是管道(非终端),读进来拼到 prompt 后面:prompt 当指令,管道内容当数据。
81+
if fi, _ := os.Stdin.Stat(); fi != nil && (fi.Mode()&os.ModeCharDevice) == 0 {
82+
if data, err := io.ReadAll(os.Stdin); err == nil {
83+
if piped := strings.TrimSpace(string(data)); piped != "" {
84+
if prompt == "" {
85+
prompt = piped
86+
} else {
87+
prompt = prompt + "\n\n" + piped
88+
}
89+
}
90+
}
91+
}
92+
if prompt == "" {
93+
fmt.Fprintln(os.Stderr, `用法: deepx exec "<任务>" (也可通过管道喂输入)`)
94+
os.Exit(2)
95+
}
96+
97+
cfg, needsSetup, err := loadOrEmptyConfig()
98+
if err != nil {
99+
fmt.Fprintln(os.Stderr, "错误:", err)
100+
os.Exit(1)
101+
}
102+
ac := toAgentConfig(cfg)
103+
if needsSetup || (ac.Flash.Model == "" && ac.Pro.Model == "") {
104+
fmt.Fprintln(os.Stderr, "错误: 尚未配置模型 / API key。先运行 `deepx`(交互式)完成配置,再用 exec。")
105+
os.Exit(1)
106+
}
107+
108+
if err := tui.RunExec(ac, prompt); err != nil {
109+
fmt.Fprintln(os.Stderr, "\nexec 失败:", err)
110+
os.Exit(1)
111+
}
112+
os.Exit(0)
113+
}

tui/exec.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package tui
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"os/signal"
8+
"path/filepath"
9+
10+
"deepx/agent"
11+
"deepx/skill"
12+
"deepx/tools"
13+
)
14+
15+
// RunExec 执行一次性非交互任务(`deepx exec "<任务>"`):把 prompt 发给 agent,**只把模型最终
16+
// 结果打到 stdout**,跑完即退出,不启动 TUI。供脚本 / 管道 / CI / cron 使用。
17+
//
18+
// - 固定 auto 模式(全工具,不弹人工审批——非交互下无法确认,这是有意为之)。
19+
// - 工具调用进度 / 思考过程一律不显示,保证 stdout 干净(`> file` 拿到的就是结果)。
20+
// - 出错通过返回值上报,调用方据此给非零退出码。
21+
func RunExec(cfg agent.ModelConfig, prompt string) error {
22+
wd, _ := os.Getwd()
23+
home, _ := os.UserHomeDir()
24+
25+
// skill 发现 + codegraph 绑定,与 TUI 启动时保持一致,保证 exec 下工具能力对齐。
26+
loader := skill.New(
27+
[]string{filepath.Join(wd, ".deepx", "skills")},
28+
[]string{
29+
filepath.Join(home, ".agents", "skills"),
30+
filepath.Join(home, ".claude", "skills"),
31+
filepath.Join(home, ".deepx", "skills"),
32+
},
33+
)
34+
tools.SetSkillLoader(loader)
35+
tools.SetCodeGraphRoot(wd)
36+
skillCatalog := buildSkillCatalog(loader)
37+
38+
// Ctrl+C → 取消 ctx;StartStream 在轮次间 / HTTP 层检测到取消会平滑收尾并 close channel。
39+
ctx, cancel := context.WithCancel(context.Background())
40+
defer cancel()
41+
sigCh := make(chan os.Signal, 1)
42+
signal.Notify(sigCh, os.Interrupt)
43+
go func() {
44+
<-sigCh
45+
cancel()
46+
}()
47+
48+
history := []agent.ChatMessage{{Role: "user", Content: prompt}}
49+
50+
// 固定 auto 模式;forceRole 传 "auto" → 走本地关键词路由(零 token 决定起手模型)。
51+
// summary 空(一次性,无压缩)。
52+
_, ch := agent.StartStream(ctx, cfg, history, agent.AgentMode_Auto, wd, skillCatalog, "", "auto")
53+
54+
var streamErr error
55+
for msg := range ch {
56+
switch m := msg.(type) {
57+
case agent.TokenMsg:
58+
fmt.Print(string(m)) // 只输出模型正式回复 → stdout;工具调用 / 思考一律不打印
59+
case agent.StreamErrMsg:
60+
streamErr = m.Err
61+
}
62+
}
63+
fmt.Println() // 给 stdout 末尾补个换行,终端更整洁(重定向到文件也无害)
64+
return streamErr
65+
}

0 commit comments

Comments
 (0)