nexforge-cli 0.2.4__tar.gz → 0.2.6__tar.gz
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.
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/PKG-INFO +2 -2
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/README.md +1 -1
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/221/275/344/273/244/344/270/216/345/277/253/346/215/267/351/224/256.md +1 -1
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//346/200/273/350/247/210.md +1 -1
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/pyproject.toml +1 -1
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/session.py +20 -1
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/shell.py +6 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/.gitignore +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/= +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/INSTALL.md +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/agent.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/cost.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/edit.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/err.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/file.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/model.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/ok.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/read.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/running.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/search.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/shell.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/thinking.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/web.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/assets/icons/write.svg +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/config.example.toml +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/devlog/2026-07-07.md +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//344/274/232/350/257/235/347/256/241/347/220/206.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/256/211/350/243/205/344/270/216/351/205/215/347/275/256.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/257/271/346/257/224/345/210/206/346/236/220.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/267/245/345/205/267/345/217/202/350/200/203.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//346/235/203/351/231/220/347/263/273/347/273/237.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//350/256/241/345/210/222/346/250/241/345/274/217.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//351/253/230/347/272/247/345/212/237/350/203/275.md" +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/scripts/publish.sh +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/scripts/smoke_provider.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/scripts/smoke_tui.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/__main__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/app.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/cli.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/config.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/agent.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/jobs.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/permissions.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/router.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/core/types.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/icons.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/mcp/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/provider/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/provider/balance.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/provider/deepseek.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/skills/loader.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/store/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/store/plan_store.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/store/session_store.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/theme.tcss +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/_paths.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/background.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/base.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/edit_file.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/fs_ops.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/git.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/list_dir.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/multi_edit.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/read_file.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/registry.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/search_content.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/search_files.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/web.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/tools/write_file.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/screens/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/screens/chat.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/apikey_modal.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/banner.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/confirm_modal.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/diff_modal.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/messages.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/mode_warning.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/multiline_modal.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/multiline_prompt.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/plan_sidebar.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/sidebar.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/ui/widgets/statusbar.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/web/__init__.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/web/server.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/src/nexforge/web/static/index.html +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_approval.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_config.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_icons.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_m2_tools.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_sidebar.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_sidebar_actions.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_tools.py +0 -0
- {nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/tests/test_tui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nexforge-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: NexForgeCLI — 一个面向 DeepSeek V4 的终端智能体(TUI + CLI 双模式)
|
|
5
5
|
Project-URL: Homepage, https://gitee.com/Lighthorn/nexforgecli
|
|
6
6
|
Author: NexForge
|
|
@@ -48,7 +48,7 @@ Description-Content-Type: text/markdown
|
|
|
48
48
|
|
|
49
49
|
NexForgeCLI 是一个运行在终端里的智能体助手,专为 **DeepSeek V4** 打造。既能作为全屏 TUI 交互式对话/编码,也能作为 one-shot 命令行工具嵌进脚本和管道。
|
|
50
50
|
|
|
51
|
-
> 当前版本:**v0.2.
|
|
51
|
+
> 当前版本:**v0.2.5** · PyPI: `pip install nexforge-cli`
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -16,7 +16,17 @@ DEFAULT_SYSTEM = (
|
|
|
16
16
|
"回答用简洁的中文;修改文件用 edit_file 工具;需要执行命令用 run_shell。\n"
|
|
17
17
|
"完成任务后用一两句话总结你做了什么。\n"
|
|
18
18
|
"不要用 emoji(📦🌤等),用纯文本或 Markdown 列表/表格表示信息。\n"
|
|
19
|
-
"执行 Shell 命令前先用 run_shell 探测操作系统(Windows用cmd命令,Linux/macOS用bash命令)
|
|
19
|
+
"执行 Shell 命令前先用 run_shell 探测操作系统(Windows用cmd命令,Linux/macOS用bash命令)。\n"
|
|
20
|
+
"\n"
|
|
21
|
+
"【UTF-8 编码安全】\n"
|
|
22
|
+
"在 Windows PowerShell 中,Set-Content/Out-File 默认输出 ANSI 编码会损坏中文。\n"
|
|
23
|
+
"必须遵守以下规则:\n"
|
|
24
|
+
"- 优先使用 Git Bash 执行命令: \"C:\\Program Files\\Git\\bin\\bash.exe\" -c \"命令\"\n"
|
|
25
|
+
"- 若必须用 PowerShell,写文件命令必须加 -Encoding UTF8\n"
|
|
26
|
+
" 例: ... | Set-Content path.txt -Encoding UTF8\n"
|
|
27
|
+
"- Python 写文件必须指定: open(path, 'w', encoding='utf-8')\n"
|
|
28
|
+
"- CMD 的 echo/type 无编码问题,可直接使用\n"
|
|
29
|
+
"- 避免在 PowerShell 中做文本替换后写回文件"
|
|
20
30
|
)
|
|
21
31
|
|
|
22
32
|
|
|
@@ -31,6 +41,15 @@ class Session:
|
|
|
31
41
|
self.messages.append({"role": "system", "content": self.system_prompt})
|
|
32
42
|
|
|
33
43
|
def add_user(self, text: str) -> None:
|
|
44
|
+
# 中断恢复:若上一条 assistant 有未完成 tool_calls,补 tool 错误
|
|
45
|
+
if self.messages and self.messages[-1].get("role") == "assistant":
|
|
46
|
+
pending = self.messages[-1].get("tool_calls", [])
|
|
47
|
+
for tc in pending:
|
|
48
|
+
self.messages.append({
|
|
49
|
+
"role": "tool",
|
|
50
|
+
"tool_call_id": tc.get("id", ""),
|
|
51
|
+
"content": "已取消(用户中断)。",
|
|
52
|
+
})
|
|
34
53
|
self.messages.append({"role": "user", "content": text})
|
|
35
54
|
|
|
36
55
|
def add_assistant(self, msg: AssistantMessage) -> None:
|
|
@@ -30,6 +30,12 @@ class ShellTool(BaseTool):
|
|
|
30
30
|
return f"run_shell($ {cmd[:60]})"
|
|
31
31
|
|
|
32
32
|
def run(self, command: str, timeout: int = 30) -> ToolResult:
|
|
33
|
+
# PowerShell UTF-8 防护:自动给写文件命令加 -Encoding UTF8
|
|
34
|
+
import sys
|
|
35
|
+
if sys.platform == "win32" and "powershell" in command.lower():
|
|
36
|
+
for cmd in ("Set-Content", "Out-File", "Export-Csv", "Export-Clixml"):
|
|
37
|
+
if cmd.lower() in command.lower() and "-Encoding" not in command:
|
|
38
|
+
command = command.replace(cmd, f"{cmd} -Encoding UTF8")
|
|
33
39
|
low = command.strip().lower()
|
|
34
40
|
if any(d in low for d in _DANGER):
|
|
35
41
|
return ToolResult(ok=False, error="命令被安全策略拦截(高危操作)")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//344/274/232/350/257/235/347/256/241/347/220/206.md"
RENAMED
|
File without changes
|
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/257/271/346/257/224/345/210/206/346/236/220.md"
RENAMED
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//345/267/245/345/205/267/345/217/202/350/200/203.md"
RENAMED
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//346/235/203/351/231/220/347/263/273/347/273/237.md"
RENAMED
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//350/256/241/345/210/222/346/250/241/345/274/217.md"
RENAMED
|
File without changes
|
{nexforge_cli-0.2.4 → nexforge_cli-0.2.6}/doc//351/253/230/347/272/247/345/212/237/350/203/275.md"
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|