Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,6 @@ on:
branches: [main]

jobs:
backend:
name: 后端(Java)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: temurin
cache: maven
# 单测均为纯单元测试,不依赖 MySQL,可直接跑
- name: 编译 + 单测
run: ./mvnw -B clean test

app:
name: 桌面端(Flutter)
runs-on: ubuntu-latest
Expand All @@ -40,26 +25,3 @@ jobs:
run: flutter analyze
- name: 单测
run: flutter test

cli:
name: CLI(Node)
runs-on: ubuntu-latest
defaults:
run:
working-directory: clients/cli
steps:
- uses: actions/checkout@v4
- name: 安装 Node 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
cache-dependency-path: clients/cli/package-lock.json
- name: 装依赖
run: npm ci
- name: 类型检查
run: npm run typecheck
- name: 单测
run: npm test
- name: 构建
run: npm run build
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,14 @@ logs/
# CLI 客户端(Node)构建产物与依赖
clients/cli/node_modules/
clients/cli/dist/

# 本地保留的私有实现:不再提交到远程仓库
/src/
/pom.xml
/.mvn/
/mvnw
/mvnw.cmd
/Dockerfile
/docker-compose.yml
/.env.example
/clients/cli/
Binary file removed .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
19 changes: 0 additions & 19 deletions .mvn/wrapper/maven-wrapper.properties

This file was deleted.

107 changes: 23 additions & 84 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,45 @@
# 贡献指南

感谢你对 LowenSSH 的兴趣。这份指南帮你快速上手本地开发、了解项目约定与提交流程。

## 项目结构速览

LowenSSH 是「同一套理念、三种独立形态」的项目,三端互不依赖:

| 形态 | 目录 | 技术栈 |
|------|------|--------|
| 后端服务 | `src/` | Java 17 · Spring Boot 3.4 · Spring AI |
| 桌面客户端 | `clients/app/` | Flutter(macOS / Windows) |
| CLI 客户端 | `clients/cli/` | Node 20 · Ink(TUI) |

核心理念(手写 Agent loop + Deny/Ask/Allow 安全门禁 + 上下文管理)在三端各自实现,**门禁规则与事件语义需手动对齐**。改动涉及核心逻辑时,请留意是否需要同步到其他端。

设计取舍详见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
感谢你对 LowenSSH 的兴趣。远程仓库当前仅维护 [`clients/app/`](clients/app/) 下的 Flutter 桌面客户端。

## 本地开发环境

### 后端(`src/`)

需要 JDK 17。项目自带 Maven Wrapper,无需预装 Maven。

```bash
export MYSQL_PASSWORD='你的MySQL密码'
export GLM_API_KEY='你的智谱AI key' # https://open.bigmodel.cn 申请

# 初始化数据库
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS lowenssh DEFAULT CHARSET utf8mb4;"
mysql -u root -p lowenssh < src/main/resources/schema.sql

./mvnw spring-boot:run # Windows 用 mvnw.cmd
```

运行测试:

```bash
./mvnw test
```

### 桌面端(`clients/app/`)

需要 Flutter SDK 3.12+。详见 [clients/app/README.md](clients/app/README.md)。
需要 Flutter SDK 3.12+。macOS 构建需要 Xcode;Windows 构建需要 Visual Studio,并安装“使用 C++ 的桌面开发”工作负载。

```bash
cd clients/app
flutter pub get
flutter run -d macos # 或 -d windows
flutter analyze # 提交前确保零问题
flutter run -d macos # 或 flutter run -d windows
flutter analyze
flutter test
```

### CLI(`clients/cli/`)

需要 Node 20+。详见 [clients/cli/README.md](clients/cli/README.md)。
完整运行、打包和模型配置说明见 [`clients/app/README.md`](clients/app/README.md)。

## 代码约定

- **注释用中文,标识符(变量/函数/类名)用英文**
- 优先可读性,不做过度优化;改动范围尽量小,不顺手重构无关代码
- 后端 Java 用 Java 17 语法,不用过时写法
- Flutter 优先 Composition 风格的 Widget 拆分,复用动画/组件放对应封装文件
- 涉及安全门禁规则改动,必须补充或更新对应单元测试
- 注释使用中文,标识符使用英文
- 优先可读性,不重构与当前任务无关的代码
- Widget 保持职责清晰,可复用动画和组件放入对应封装文件
- 修改安全门禁、凭据保存或 SSH 执行逻辑时,必须补充相应测试
- 不提交 API Key、密码、`.env`、本机构建产物和日志

## 提交前检查

- 后端:`./mvnw test` 全绿。
- 桌面端:`flutter analyze` 零问题,`flutter build macos --debug`(或 windows)可编译。
- CLI:按 `clients/cli/README.md` 的检查方式验证。
- 不提交任何明文密钥、`.env` 文件、本地构建产物。

## 提交信息规范

- 用简洁的中文描述「做了什么」,必要时补充「为什么」。
- 前缀标明影响范围,例如 `app:`、`cli:`、`backend:`、`docs:`。
- 一个提交聚焦一件事,避免把无关改动混在一起。

示例:

```
app: 修复切主题时终端不变色

终端配色从冻结的顶层 final 改为按当前 palette 实时计算。
```bash
cd clients/app
flutter analyze
flutter test
flutter build macos --debug # Windows 使用对应构建命令
```

## Pull Request 流程

1. 从 `main` 切出 feature 分支(如 `feature/xxx`、`fix/xxx`),**不要直接提交到 main**。
2. 完成开发并通过提交前检查。
3. 推送分支并发起 PR,目标分支为 `main`。
4. PR 描述请包含:改了什么、为什么、如何测试、是否涉及多端对齐。
5. 等待 review,合并后删除 feature 分支。

## 安全相关改动

本项目的安全门禁(高危命令拦截)是真实防护,不是演示。涉及以下改动请在 PR 中重点说明:

- 修改 deny / ask 规则名单。
- 调整命令拆段、正则匹配逻辑。
- 改动密码加密、密钥读取、审计落库相关代码。
## 提交与 Pull Request

发现安全漏洞请不要直接提 public issue,先通过私下渠道联系维护者。
1. 从 `main` 创建功能分支,不直接提交到 `main`。
2. 一个提交只处理一类问题,提交信息使用简洁中文。
3. 推送分支后创建 PR,目标分支为 `main`。
4. PR 说明应包含改动内容、原因、验证方式和安全影响。

## 报告问题
## 安全问题

提 issue 时请尽量包含:复现步骤、预期与实际行为、运行环境(操作系统、形态、版本)、相关日志或截图
安全门禁和凭据保护属于真实防护。发现可导致未授权命令执行、凭据泄露或安全规则绕过的问题时,请先通过私下渠道联系维护者,不要直接公开利用细节
20 changes: 0 additions & 20 deletions Dockerfile

This file was deleted.

123 changes: 28 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,129 +1,62 @@
# LowenSSH

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Java 17](https://img.shields.io/badge/Java-17-orange.svg)](https://openjdk.org/projects/jdk/17/)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-6DB33F.svg)](https://spring.io/projects/spring-boot)
[![Flutter](https://img.shields.io/badge/Flutter-macOS%20%7C%20Windows-02569B.svg)](https://flutter.dev)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)

AI 驱动的 SSH 智能运维 Agent。给它一个运维目标和一台服务器,它会像工程师一样一步步排查:自己决定跑什么命令、读结果、调整思路,直到给出结论。危险命令会被安全门禁实时拦截
AI 驱动的 SSH 智能运维 Agent。用户给出运维目标和目标服务器后,Agent 会自主选择工具、读取执行结果并持续调整方案;危险命令在实际执行前经过安全门禁

核心看点是「看得见 AI 在干什么,也看得见安全护栏起作用」——整个 agentic loop 是从零手写的,不套用任何编排框架。
## 仓库范围

## 界面预览
公开仓库仅维护 Flutter 桌面客户端,代码位于 [`clients/app/`](clients/app/)。客户端内置 SSH 连接、Agent loop、安全门禁、上下文管理和大模型调用能力,可以独立运行。

> 截图待补充。桌面端运行界面、解锁动画、智能体面板与安全门禁可视化效果。
>
> <!-- 截图放到 docs/images/ 下,按下方格式引用:
> ![桌面端主界面](docs/images/app-main.png)
> ![智能体面板](docs/images/app-agent.png)
> -->
Java 后端与 Node CLI 为本地实现,不再包含在远程仓库当前版本中。

## 三种形态
## 核心能力

同一套「Agent loop + 安全门禁 + 上下文管理」理念,落地为三个独立实现,按需选用:

| 形态 | 目录 | 技术栈 | 说明 |
|------|------|--------|------|
| **后端服务** | `src/` | Java 17 · Spring Boot 3.4 · Spring AI | REST + SSE API,参考实现,逻辑最完整 |
| **桌面客户端** | `clients/app/` | Flutter(macOS / Windows) | 独立桌面应用,内置全套逻辑,直连大模型 |
| **CLI 客户端** | `clients/cli/` | Node 20 · Ink(TUI) | 终端里跑,类 Claude Code 的交互,内置全套逻辑 |

三者**互不依赖**:桌面端和 CLI 各自内置 SSH + Agent loop + 门禁 + 大模型调用,不需要先起后端。门禁规则与事件语义在三端手动对齐。

> 想了解手写 agentic loop、安全门禁、上下文管理的设计取舍,见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。

## 能力

- **手写 Agentic Loop**:不依赖 LangChain 之类的编排框架,自己实现「模型决策 → 调工具 → 喂回结果 → 再决策」的循环,逻辑完全可控、可读。
- **安全门禁三态**:每条命令在执行前经过 `deny / ask / allow` 判定。`rm -rf`、`find -delete` 等高危操作直接拦截,模型被拦后会自主改用安全方式。
- **流式可视化**:实时推送多类事件(模型 token、要跑的命令、命令结果、被拦截、最终结论、错误),逐字渲染整个排查过程。
- **上下文管理**:多轮对话爆 context 时,自动做大工具结果截断 + 全量 LLM 摘要,复用消息表持久化。
- **全程审计**:每次连接、每条命令、每个拦截决策都落库,可追溯。
- **手写 Agent Loop**:实现“模型决策 → 工具调用 → 结果回灌 → 再决策”的循环。
- **安全门禁**:命令执行前进行 `deny / ask / allow` 判定,高风险操作需要人工确认。
- **流式过程展示**:区分模型输出、工具调用、工具结果、安全拦截和最终结论。
- **上下文治理**:对大工具结果进行截断,并在历史过长时生成摘要。
- **SSH 工具集**:支持命令执行、日志读取、文件管理、监控和端口转发。

## 技术栈

**后端**:Java 17 · Spring Boot 3.4 · Spring AI 1.1 · JSch(SSH)· MyBatis-Plus · MySQL · GLM-4.6(OpenAI 兼容协议,可换任意兼容模型)

**桌面端**:Flutter · Dart(macOS / Windows 桌面)

**CLI**:Node 20 · TypeScript · Ink · ssh2 · openai SDK

## 快速开始(后端服务)

后端提供 REST + SSE API。客户端的运行方式见各自目录的 README([桌面端](clients/app/README.md) · [CLI](clients/cli/README.md))。

### 方式一:Docker 一键启动(推荐)

需要 Docker。两个密钥走环境变量,不写进任何文件:

```bash
export MYSQL_PASSWORD='给MySQL容器设的root密码'
export GLM_API_KEY='你的智谱AI key' # https://open.bigmodel.cn 申请
docker compose up --build
```

compose 会自动起 MySQL(建库 + 执行 schema.sql 建表)、构建后端、等 DB 就绪后启动应用。API 监听 http://localhost:8081。

### 方式二:本地手动启动

#### 1. 准备环境变量

应用读取两个环境变量,源码里不含任何明文密钥:

```bash
export MYSQL_PASSWORD='你的MySQL密码' # 本机 MySQL root 密码,空密码则设为 ''
export GLM_API_KEY='你的智谱AI key' # https://open.bigmodel.cn 申请
```

> 不设这两个变量,启动会因连不上 MySQL(500)或鉴权失败(401)而报错。
Flutter · Dart · Riverpod · dartssh2 · Dio · PointyCastle · Secure Storage · xterm · docking

#### 2. 初始化数据库
## 快速开始

先建库,再执行建表脚本:
环境要求:Flutter SDK 3.12+;macOS 构建需要 Xcode,Windows 构建需要 Visual Studio 桌面开发组件。

```bash
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS lowenssh DEFAULT CHARSET utf8mb4;"
mysql -u root -p lowenssh < src/main/resources/schema.sql
cd clients/app
flutter pub get
flutter run -d macos # macOS
flutter run -d windows # Windows
```

#### 3. 启动后端

项目自带 Maven Wrapper,无需预装 Maven:

```bash
./mvnw spring-boot:run # Windows 用 mvnw.cmd
```

API 监听 http://localhost:8081。
更多配置、打包方式和模型接入说明见 [`clients/app/README.md`](clients/app/README.md)。

## 项目结构

```
```text
LowenSSH/
├── src/main/java/com/lowenssh/
│ ├── agent/ # Agent 核心:loop、SSE 事件、上下文管理、安全门禁
│ ├── ssh/ # JSch SSH 执行
│ └── ...
├── src/main/resources/
│ ├── application.yml # 配置(密钥走环境变量)
│ └── schema.sql # 建表脚本
├── clients/
│ ├── app/ # Flutter 桌面客户端(见 clients/app/README.md)
│ └── cli/ # Node CLI 客户端(见 clients/cli/README.md)
└── DESIGN.md # 设计规范
├── clients/app/ # Flutter 桌面客户端
├── docs/ # 架构与项目文档
├── DESIGN.md # 设计规范
└── CONTRIBUTING.md # 贡献指南
```

## 安全说明

- 所有密钥走环境变量,源码无任何明文凭据
- 客户端密码字段不写入明文持久化(AES-GCM 加密落库),不打印到控制台
- 安全门禁的高危命令规则(含 `rm -rf`、`find -delete` 等变体)是真实防护,请勿在生产前移除
- 这是一个运维 Agent,会真实在目标服务器执行命令。请只连接你有权操作的服务器
- 主机密码经 AES-GCM 加密后保存,不记录明文
- 端口转发默认只绑定 `127.0.0.1`
- 危险命令执行前必须经过安全策略和人工确认
- 本项目会在目标服务器执行真实操作,请只连接你有权管理的服务器

## 贡献

欢迎提 issue 和 PR。开发环境搭建、代码约定、提交规范见 [CONTRIBUTING.md](CONTRIBUTING.md)。
欢迎提交 Issue 和 PR。开发环境、代码约定和提交流程见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## License

Expand Down
4 changes: 0 additions & 4 deletions clients/cli/.gitignore

This file was deleted.

Loading
Loading