让终端「听懂人话」:在 IntelliJ IDEA 内置终端用自然语言生成 Shell 命令
让终端「听懂人话」:在 IntelliJ IDEA 内置终端用自然语言生成 Shell 命令
dong4j现有方案的痛点
终端里的大量操作有一个共同特征:高频、临时、简单。查个端口、扫个日志、打包个镜像,难的不是算法,是「这条 one-liner 参数怎么拼」。市面上的解决方案各有各的问题:
通用 AI 工具(ChatGPT、Cursor 等):你得切换窗口、描述需求、从一大段解释里抠出那一行命令。而且通用 AI 工具加载了大量 Agent、MCP、Skill 上下文,你只是想生成一行 find,也要消耗大量 token。
重型 AI CLI(Claude Code、Codex CLI 等):非常适合复杂任务和多步推理,但为了「删七天前的日志」这种小事进入一整套交互会话,心智与路径都偏重。
查文档 / 搜索引擎:每次都要离开终端、搜索、复制、粘贴,打断心流。
这个场景的 AI 调用其实非常简单:输入是自然语言描述,输出是可执行的 Shell 命令,一轮问答就够了。把这种极简的 AI 调用直接嵌到 IDE 内置终端里,不需要离开编辑器,不多消耗一个 token。
功能一览
| 功能 | 入口 | 说明 |
|---|---|---|
| TAB 生成命令 | 终端输入行 + TAB | 以触发前缀(默认 #)开头时拦截 TAB,用 AI 生成命令替换当前行 |
| Quick Prompt 弹窗 | Ctrl+I | 弹出输入框,输入自然语言后生成命令,支持插入/运行/复制/新文件/编辑器插入 |
| 上下文感知 | 可选开启 | 自动注入 OS、Shell、当前目录、Git 仓库、Docker/K8s、技术栈、AI 历史 |
| 流式输出 | 可选开启 | 开启后 AI 响应以流式方式返回,延迟更低 |
| 历史记录 | Quick Prompt 弹窗 | 保存最近的提问和生成结果,支持查看和复制 |
| Tab 标题装饰 | 自动 | 终端 Tab 标题前加 🤖 标识,表明启用了 Terminal AI |
| 状态栏快捷设置 | 状态栏弹窗 | 快速切换 AI 服务商、触发前缀、开关 Terminal AI/流式输出/上下文 |
支持 UNIX(bash/zsh/fish)和 Windows(PowerShell/cmd),通过 IntelliAI Engine 统一调用 OpenAI、Anthropic、Ollama 等多种 AI 后端。
核心架构
插件的完整数据流:
flowchart TD
A["用户在终端输入行"] --> B{"以触发前缀开头?"}
B -->|否| C["TAB 执行默认补全"]
B -->|是| D["拦截 TAB 键"]
D --> E["提取输入内容<br/>去除前缀 + Shell Prompt"]
E --> F{"启用上下文?"}
F -->|是| G["TerminalContextService<br/>注入 OS/Shell/Git/技术栈/历史"]
F -->|否| H["直接使用输入"]
G --> I["构建 Prompt"]
H --> I
I --> J["AIService<br/>(IntelliAI Engine)"]
J --> K{"流式输出?"}
K -->|是| L["TerminalAIStreamResponseListener<br/>累积流式数据块"]
K -->|否| M["TerminalAIResponseListener<br/>接收完整响应"]
L --> N["extractCommand()<br/>提取可执行命令"]
M --> N
N --> O{"命令合法?"}
O -->|是| P["替换终端当前行"]
O -->|否| Q["显示错误提示"]
双终端视图兼容
IntelliJ 的 Terminal 栈在迭代过程中存在两种实现:TerminalView(新终端前端)和 JBTerminalWidget(旧终端组件)。同一套「取当前行 / 写回当前行」的逻辑,必须在两种 API 上都能跑通。
1 | // TerminalAiGenerateAction.java - getTerminalView() |
获取到终端实例后,根据是 TerminalView 还是 JBTerminalWidget 走不同的输入提取和行替换路径:
1 | // TerminalAiGenerateAction.java - actionPerformed() |
TAB 触发机制
TAB 键是全世界最忙的键——默认绑定着终端补全。插件通过 TerminalAllowedActionsProvider 扩展点,把 TAB 的 AI 生成动作约束在「满足前缀条件时才认领」,不抢走默认行为。
1 | // TerminalAiAllowedActionsProvider.java |
触发条件:当前输入行以 triggerPrefix(默认 #)开头时,TAB 才进入 AI 生成语义:
1 | // TerminalAiGenerateAction.java - extractPrompt() |
前缀可以从状态栏快速切换,预设选项:#、::、??,也支持自定义输入。
输入提取逻辑
从终端提取用户输入比想象中复杂。终端输出包含 Shell Prompt($、>、PS ...>),还可能有多行续行(以 \ 结尾)。插件做了多层处理:
去除 Shell Prompt 前缀
1 | // TerminalAiGenerateAction.java - stripPromptPrefix() |
续行合并
当用户输入了以 \ 结尾的多行命令时,插件会向前遍历终端输出,将多行合并为一条逻辑行:
1 | // TerminalAiGenerateAction.java - getLastLogicalLine() |
AI 请求构建与上下文注入
提取到用户输入后,插件会根据是否启用了上下文检测来构建请求。
sequenceDiagram
participant User as 用户输入
participant Action as TerminalAiGenerateAction
participant Context as TerminalContextService
participant Engine as AIService (Engine)
User->>Action: "# 查找7天前的日志"
Action->>Action: 去除前缀 → "查找7天前的日志"
alt 启用上下文
Action->>Context: buildUserPrompt("查找7天前的日志", terminalView)
Context->>Context: collectContext() → OS/Shell/Git/技术栈/历史
Context-->>Action: 增强后的 Prompt
else 未启用上下文
Action->>Action: 直接使用原始输入
end
Action->>Action: terminalTemplate.replace("{content}", userContent)
Action->>Engine: AIChatRequest(systemPrompt, userPrompt)
Engine-->>Action: AI 生成的命令
终端上下文服务
TerminalContextService 是一个 Project 级别的服务,负责收集当前终端的环境信息。这些信息会以结构化格式注入到 prompt 中,让 AI 理解当前环境:
1 | // TerminalContextService.java - buildPrompt() |
上下文检测的具体范围:
| 检测项 | 来源 | 说明 |
|---|---|---|
| OS | System.getProperty("os.name") | linux / mac os x / windows |
| Shell | System.getenv("SHELL") | zsh / bash / fish |
| 当前目录 | terminalView.getCurrentDirectory() | 终端实际所在目录 |
| Git 仓库 | 向上查找 .git 目录 | 读取 .git/config(截断 600 字符) |
| Dockerfile | 检查当前目录下 Dockerfile | boolean |
| Docker Compose | 检查 docker-compose.yml / .yaml | boolean |
| Kubernetes | 检查 k8s/、manifests/、.kube/、.helm/ | boolean |
| 构建工具 | pom.xml → maven,build.gradle → gradle,package.json → npm,go.mod → go,pyproject.toml → pip | 优先级按顺序匹配 |
| 语言 | 由构建工具推断 | java / javascript / go / python |
| AI 历史 | 内存队列,最多 5 条 | 格式化为 Q/A 对注入 |
上下文结果会按当前目录路径缓存,避免重复扫描文件系统。
流式与非流式响应
插件支持两种响应模式,在设置中切换:
非流式(默认)
直接调用 aiService.generateContent(),等待完整响应返回后一次性处理:
1 | // TerminalAiGenerateAction.java |
流式
使用 CountDownLatch 等待流式完成,最大超时 2 分钟。TerminalAIStreamResponseListener 在 onChunk 中累积数据,onComplete 中统一处理:
1 | // TerminalAIStreamResponseListener.java |
流式模式下,发送请求、接收数据、处理完成等每个阶段都会通过 ProgressIndicator 更新进度状态。
响应清理与命令提取
AI 返回的文本不能直接插入终端。插件在写回终端前做了多层清洗:
1 | // TerminalAiGenerateAction.java - extractCommand() |
提取到命令后,还会做合法性校验:
1 | // TerminalAiGenerateAction.java - isValidShellOutput() |
通过校验的命令才会替换到终端当前行。
Shell 类型感知
通过 TerminalShellDetector 检测当前操作系统,区分 UNIX 和 Windows 两种行为分支:
1 | // TerminalShellDetector.java |
Shell 类型影响三个行为:
- Prompt 前缀去除:UNIX 去除
$/>,Windows 去除PS xxx>或> - 命令合法性校验:Windows 允许
\和&开头 - 当前行替换:Windows 额外发送
(Ctrl+C)取消当前输入
当前行替换
命令通过校验后,替换终端当前行。核心思路是先清行、再写入:
1 | // TerminalAiGenerateAction.java - replaceCurrentLine() [TerminalView] |
JBTerminalWidget 的替换通过 widget.getTtyConnector().write() 实现,逻辑一致。
替换完成后,用户看到的是 AI 生成的命令出现在当前行,可以审阅后回车执行。同时命令和原始问题会被记录到 AI 历史(最多 5 条),供后续上下文注入使用。
Quick Prompt 弹窗
除了 TAB 触发,插件还提供了 Ctrl+I 快捷键打开的 Quick Prompt 弹窗,适用于不想修改当前输入行内容的场景。弹窗包含:
- 输入框:输入自然语言需求
- 生成按钮:调用 AI 生成命令
- 插入按钮:将命令插入到终端当前行(不执行)
- 运行按钮:将命令插入到终端并立即执行(追加
\n) - 更多菜单:复制到剪贴板、在新编辑器中打开、插入到当前编辑器、查看历史记录
Quick Prompt 弹窗内部调用的是同一个 AI 生成链路,但因为弹窗本身可以展示生成结果,用户可以先看到命令再决定是否应用。
Tab 标题装饰
插件通过 ProjectActivity 在项目启动时监听终端 Tab 的创建事件,自动在标题前添加 🤖 标识:
1 | // TerminalTabTitleDecorator.java |
装饰只在 enableTerminalAI 开启时生效,关闭后不再装饰新 Tab。使用 WeakHashMap 和 Key<Boolean> 避免内存泄漏和重复装饰。
设置页面配置
设置面板位于 Settings → Tools → IntelliAI Engine → IntelliAI Terminal,包含以下配置项:
AI 服务商选择
从全局已配置的 AI 服务商列表中选择 Terminal 插件使用的默认服务商。配置在 Engine 的全局设置中管理,Terminal 插件只做选择。
基础设置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| 启用 Terminal AI | 复选框 | ✅ 开启 | 总开关,控制是否在终端中拦截触发前缀并执行 AI 生成 |
| 启用流式输出 | 复选框 | ❌ 关闭 | 开启后 AI 响应以流式方式返回 |
| 启用上下文检测 | 复选框 | ❌ 关闭 | 注入 OS/Shell/Git/技术栈等上下文信息,可能增加延迟 |
| 触发前缀 | 下拉框(可编辑) | # | 只有输入行以此前缀开头时才触发 AI 生成。预设选项:#、::、?? |
高级设置(Prompt 模板)
点击「显示高级设置」后展开,包含两个 Tab:
- 系统提示词:设定 AI 的角色和行为准则。默认提示词严格约束 AI「只输出可执行的 shell 命令,不允许输出解释、注释、Markdown、代码块标记、占位符」
- 用户提示词模板:使用
{content}占位符拼接用户输入。默认模板为「根据下面的描述,生成最合适的一条 shell 命令」
两个模板都有「重置为默认值」按钮。如果用户修改后又改回默认值,会自动同步提示词模板版本号。
提示词模板版本管理
内置提示词更新时,PROMPT_TEMPLATE_VERSION 会递增。插件在启动时检测版本差异,通过 PromptTemplateVersionNotifier 提示用户关注模板变更,避免用户使用过时的默认提示词。
状态栏快捷设置
除了设置面板,插件还在状态栏提供了快捷操作菜单:
- AI 服务商切换:快速切换 Terminal 使用的 AI 服务商
- 触发前缀切换:快速切换
#、::、?? - Terminal AI 开关:一键启用/禁用
- 流式输出开关:一键启用/禁用
- 上下文检测开关:一键启用/禁用
- 打开设置:跳转到完整设置面板
模块结构
1 | intelli-ai-terminal/src/main/java/ |
相关文章:
- IntelliAI Engine - 统一接入 30+ AI 服务商的底层平台
- IntelliAI JavaDoc - AI 驱动的 JavaDoc 自动生成插件
- IntelliAI Changelog - AI 一键生成 Changelog、日报、周报


















