work-agent 0.1.0
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.
- package/README.md +234 -0
- package/app/(admin)/approvals/page.tsx +16 -0
- package/app/(admin)/audit/page.tsx +18 -0
- package/app/(admin)/layout.tsx +47 -0
- package/app/(admin)/scheduled-tasks/page.tsx +17 -0
- package/app/(admin)/settings/page.tsx +46 -0
- package/app/(admin)/skills/[name]/page.tsx +378 -0
- package/app/(admin)/skills/page.tsx +406 -0
- package/app/(admin)/statistics/page.tsx +416 -0
- package/app/(admin)/tickets/[id]/page.tsx +348 -0
- package/app/(admin)/tickets/new/page.tsx +309 -0
- package/app/(admin)/tickets/page.tsx +27 -0
- package/app/api/audit/route.ts +30 -0
- package/app/api/auth/feishu/callback/route.ts +72 -0
- package/app/api/auth/feishu/login/route.ts +17 -0
- package/app/api/auth/feishu/sso/route.ts +78 -0
- package/app/api/auth/login/route.ts +85 -0
- package/app/api/auth/oauth/route.ts +168 -0
- package/app/api/config/providers/route.ts +105 -0
- package/app/api/config/route.ts +115 -0
- package/app/api/config/status/route.ts +56 -0
- package/app/api/config/test/route.ts +212 -0
- package/app/api/documents/[id]/route.ts +88 -0
- package/app/api/documents/route.ts +53 -0
- package/app/api/health/route.ts +32 -0
- package/app/api/knowledge/[id]/route.ts +152 -0
- package/app/api/knowledge/from-session/route.ts +27 -0
- package/app/api/knowledge/route.ts +100 -0
- package/app/api/market/knowledge/[id]/route.ts +92 -0
- package/app/api/market/knowledge/route.ts +130 -0
- package/app/api/marketplace/skills/[id]/approve/route.ts +68 -0
- package/app/api/marketplace/skills/[id]/certify/route.ts +54 -0
- package/app/api/marketplace/skills/[id]/install/route.ts +180 -0
- package/app/api/marketplace/skills/[id]/promote-to-system/route.ts +219 -0
- package/app/api/marketplace/skills/[id]/rate/route.ts +90 -0
- package/app/api/marketplace/skills/[id]/ratings/route.ts +55 -0
- package/app/api/marketplace/skills/[id]/reject/route.ts +68 -0
- package/app/api/marketplace/skills/[id]/route.ts +177 -0
- package/app/api/marketplace/skills/route.ts +235 -0
- package/app/api/memory/route.ts +40 -0
- package/app/api/my/files/[id]/route.ts +52 -0
- package/app/api/my/files/route.ts +230 -0
- package/app/api/my/knowledge/route.ts +36 -0
- package/app/api/pi-chat/route.ts +443 -0
- package/app/api/recommend/route.ts +38 -0
- package/app/api/scheduled-tasks/[id]/execute/route.ts +132 -0
- package/app/api/scheduled-tasks/[id]/route.ts +165 -0
- package/app/api/scheduled-tasks/[id]/toggle/route.ts +53 -0
- package/app/api/scheduled-tasks/route.ts +101 -0
- package/app/api/sessions/[id]/messages/route.ts +212 -0
- package/app/api/sessions/route.ts +101 -0
- package/app/api/share/file/[id]/route.ts +37 -0
- package/app/api/skills/[name]/execute/route.ts +121 -0
- package/app/api/skills/[name]/route.ts +167 -0
- package/app/api/skills/create/route.ts +65 -0
- package/app/api/skills/generate/route.ts +405 -0
- package/app/api/skills/installed/route.ts +151 -0
- package/app/api/skills/route.ts +174 -0
- package/app/api/skills/translate/route.ts +40 -0
- package/app/api/skills/user/[name]/route.ts +159 -0
- package/app/api/skills/user/route.ts +90 -0
- package/app/api/statistics/route.ts +94 -0
- package/app/api/task-executions/[id]/route.ts +34 -0
- package/app/api/task-executions/route.ts +29 -0
- package/app/api/tickets/[id]/approve/route.ts +129 -0
- package/app/api/tickets/[id]/execute/route.ts +201 -0
- package/app/api/tickets/[id]/route.ts +127 -0
- package/app/api/tickets/route.ts +103 -0
- package/app/api/user/skills/route.ts +175 -0
- package/app/api/users/route.ts +80 -0
- package/app/chat/page.tsx +5 -0
- package/app/globals.css +84 -0
- package/app/h5/layout.tsx +5 -0
- package/app/h5/mobile-approvals-page.tsx +167 -0
- package/app/h5/mobile-chat-page.tsx +951 -0
- package/app/h5/mobile-profile-page.tsx +147 -0
- package/app/h5/mobile-tickets-page.tsx +121 -0
- package/app/h5/page.tsx +23 -0
- package/app/h5/ticket-action-buttons.tsx +80 -0
- package/app/layout.tsx +26 -0
- package/app/login/page.tsx +318 -0
- package/app/market/knowledge/[id]/page.tsx +77 -0
- package/app/market/knowledge/page.tsx +358 -0
- package/app/market/layout.tsx +29 -0
- package/app/market/page.tsx +18 -0
- package/app/market/skills/page.tsx +397 -0
- package/app/my/files/page.tsx +511 -0
- package/app/my/knowledge/[id]/page.tsx +271 -0
- package/app/my/knowledge/new/page.tsx +234 -0
- package/app/my/knowledge/page.tsx +248 -0
- package/app/my/layout.tsx +32 -0
- package/app/my/memory/page.tsx +164 -0
- package/app/my/page.tsx +18 -0
- package/app/my/scheduled-tasks/[id]/edit/page.tsx +290 -0
- package/app/my/scheduled-tasks/[id]/executions/page.tsx +275 -0
- package/app/my/scheduled-tasks/[id]/page.tsx +284 -0
- package/app/my/scheduled-tasks/new/page.tsx +230 -0
- package/app/my/scheduled-tasks/page.tsx +27 -0
- package/app/my/skills/[name]/page.tsx +320 -0
- package/app/my/skills/new/page.tsx +394 -0
- package/app/my/skills/page.tsx +303 -0
- package/app/page.tsx +2288 -0
- package/app/share/[sessionId]/page.tsx +226 -0
- package/app/share/file/[id]/page.tsx +140 -0
- package/bin/README.md +63 -0
- package/bin/generate-api-system +300 -0
- package/bin/postinstall.js +95 -0
- package/bin/work-agent.js +173 -0
- package/components/ai-elements/agent.tsx +142 -0
- package/components/ai-elements/artifact.tsx +149 -0
- package/components/ai-elements/attachments.tsx +427 -0
- package/components/ai-elements/audio-player.tsx +232 -0
- package/components/ai-elements/canvas.tsx +26 -0
- package/components/ai-elements/chain-of-thought.tsx +223 -0
- package/components/ai-elements/checkpoint.tsx +72 -0
- package/components/ai-elements/code-block.tsx +555 -0
- package/components/ai-elements/commit.tsx +449 -0
- package/components/ai-elements/confirmation.tsx +173 -0
- package/components/ai-elements/connection.tsx +28 -0
- package/components/ai-elements/context.tsx +410 -0
- package/components/ai-elements/controls.tsx +19 -0
- package/components/ai-elements/conversation.tsx +167 -0
- package/components/ai-elements/edge.tsx +144 -0
- package/components/ai-elements/environment-variables.tsx +325 -0
- package/components/ai-elements/file-tree.tsx +298 -0
- package/components/ai-elements/image.tsx +25 -0
- package/components/ai-elements/inline-citation.tsx +294 -0
- package/components/ai-elements/jsx-preview.tsx +250 -0
- package/components/ai-elements/message.tsx +367 -0
- package/components/ai-elements/mic-selector.tsx +372 -0
- package/components/ai-elements/model-selector.tsx +214 -0
- package/components/ai-elements/node.tsx +72 -0
- package/components/ai-elements/open-in-chat.tsx +367 -0
- package/components/ai-elements/package-info.tsx +235 -0
- package/components/ai-elements/panel.tsx +16 -0
- package/components/ai-elements/persona.tsx +280 -0
- package/components/ai-elements/plan.tsx +144 -0
- package/components/ai-elements/prompt-input.tsx +1341 -0
- package/components/ai-elements/queue.tsx +275 -0
- package/components/ai-elements/reasoning.tsx +355 -0
- package/components/ai-elements/sandbox.tsx +133 -0
- package/components/ai-elements/schema-display.tsx +473 -0
- package/components/ai-elements/shimmer.tsx +78 -0
- package/components/ai-elements/snippet.tsx +141 -0
- package/components/ai-elements/sources.tsx +78 -0
- package/components/ai-elements/speech-input.tsx +324 -0
- package/components/ai-elements/stack-trace.tsx +531 -0
- package/components/ai-elements/suggestion.tsx +58 -0
- package/components/ai-elements/task.tsx +88 -0
- package/components/ai-elements/terminal.tsx +277 -0
- package/components/ai-elements/test-results.tsx +497 -0
- package/components/ai-elements/tool.tsx +174 -0
- package/components/ai-elements/toolbar.tsx +17 -0
- package/components/ai-elements/transcription.tsx +126 -0
- package/components/ai-elements/voice-selector.tsx +525 -0
- package/components/ai-elements/web-preview.tsx +282 -0
- package/components/audit-log-list.tsx +114 -0
- package/components/chat/EmptyPreviewState.tsx +12 -0
- package/components/chat/KnowledgePickerDialog.tsx +464 -0
- package/components/chat/KnowledgePreview.tsx +70 -0
- package/components/chat/KnowledgePreviewPanel.tsx +86 -0
- package/components/chat/MentionInput.tsx +309 -0
- package/components/chat/OrganizeDialog.tsx +258 -0
- package/components/chat/RecommendationBanner.tsx +94 -0
- package/components/chat/SaveToKnowledgeDialog.tsx +193 -0
- package/components/chat/SkillSelector.tsx +305 -0
- package/components/chat/SkillSwitcher.tsx +163 -0
- package/components/client-layout.tsx +15 -0
- package/components/knowledge/KnowledgeMetadataPanel.tsx +293 -0
- package/components/layout-wrapper.tsx +18 -0
- package/components/mobile-layout.tsx +62 -0
- package/components/scheduled-task-list.tsx +356 -0
- package/components/setup-guide.tsx +484 -0
- package/components/sub-nav.tsx +54 -0
- package/components/ticket-detail-content.tsx +383 -0
- package/components/ticket-list.tsx +366 -0
- package/components/top-nav.tsx +132 -0
- package/components/ui/accordion.tsx +58 -0
- package/components/ui/alert.tsx +59 -0
- package/components/ui/avatar.tsx +50 -0
- package/components/ui/badge.tsx +36 -0
- package/components/ui/button-group.tsx +83 -0
- package/components/ui/button.tsx +57 -0
- package/components/ui/card.tsx +91 -0
- package/components/ui/carousel.tsx +262 -0
- package/components/ui/collapsible.tsx +11 -0
- package/components/ui/command.tsx +153 -0
- package/components/ui/dialog.tsx +122 -0
- package/components/ui/dropdown-menu.tsx +200 -0
- package/components/ui/hover-card.tsx +29 -0
- package/components/ui/input-group.tsx +170 -0
- package/components/ui/input.tsx +22 -0
- package/components/ui/label.tsx +26 -0
- package/components/ui/popover.tsx +31 -0
- package/components/ui/progress.tsx +28 -0
- package/components/ui/scroll-area.tsx +48 -0
- package/components/ui/select.tsx +174 -0
- package/components/ui/separator.tsx +31 -0
- package/components/ui/spinner.tsx +16 -0
- package/components/ui/switch.tsx +29 -0
- package/components/ui/table.tsx +120 -0
- package/components/ui/tabs.tsx +55 -0
- package/components/ui/textarea.tsx +22 -0
- package/components/ui/tooltip.tsx +30 -0
- package/components/welcome-guide.tsx +182 -0
- package/components.json +24 -0
- package/lib/command-parser.ts +331 -0
- package/lib/dangerous-commands.ts +672 -0
- package/lib/db.ts +2250 -0
- package/lib/feishu-auth.ts +135 -0
- package/lib/file-storage.ts +306 -0
- package/lib/file-tool.ts +583 -0
- package/lib/knowledge-tool.ts +152 -0
- package/lib/knowledge-types.ts +66 -0
- package/lib/market-client.ts +313 -0
- package/lib/market-db.ts +736 -0
- package/lib/market-types.ts +51 -0
- package/lib/memory-tool.ts +211 -0
- package/lib/memory.ts +197 -0
- package/lib/pi-config.ts +436 -0
- package/lib/pi-session.ts +799 -0
- package/lib/pinyin.ts +13 -0
- package/lib/recommendation.ts +227 -0
- package/lib/risk-estimator.ts +350 -0
- package/lib/scheduled-task-tool.ts +184 -0
- package/lib/scheduler-init.ts +43 -0
- package/lib/scheduler.ts +416 -0
- package/lib/secure-bash-tool.ts +413 -0
- package/lib/skill-engine.ts +396 -0
- package/lib/skill-generator.ts +269 -0
- package/lib/skill-loader.ts +234 -0
- package/lib/skill-tool.ts +188 -0
- package/lib/skill-types.ts +82 -0
- package/lib/skills-init.ts +58 -0
- package/lib/ticket-tool.ts +246 -0
- package/lib/user-skill-types.ts +30 -0
- package/lib/user-skills.ts +362 -0
- package/lib/utils.ts +6 -0
- package/lib/workflow.ts +154 -0
- package/lib/zip-tool.ts +191 -0
- package/next.config.js +8 -0
- package/package.json +106 -0
- package/public/.gitkeep +1 -0
- package/public/icon.svg +1 -0
- package/tsconfig.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# 智能助手
|
|
2
|
+
|
|
3
|
+
基于 **Code as Action** 设计理念的通用智能助手,通过与 AI 对话分析问题、生成代码并安全执行。
|
|
4
|
+
|
|
5
|
+
## 核心设计理念
|
|
6
|
+
|
|
7
|
+
### Code as Action
|
|
8
|
+
系统通过代码执行来解决问题,AI 分析用户需求后生成并执行相应的命令或脚本。所有执行都是可追溯、可审计的。
|
|
9
|
+
|
|
10
|
+
### Skill 扩展系统
|
|
11
|
+
通过 Skill 定义垂直领域的专业能力,每个 Skill 包含:
|
|
12
|
+
- 能力描述和使用指南
|
|
13
|
+
- 领域特定的命令模板
|
|
14
|
+
- 风险评估规则
|
|
15
|
+
|
|
16
|
+
### 安全执行机制
|
|
17
|
+
- **危险命令拦截**:高危操作(如 kubectl delete、rm -rf)自动拦截
|
|
18
|
+
- **工单审批流程**:危险操作必须创建工单,经人工审批后执行
|
|
19
|
+
- **审计日志**:所有操作都有完整的审计记录
|
|
20
|
+
|
|
21
|
+
## 技术架构
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ 用户界面层 │
|
|
26
|
+
│ (Next.js 15 + React 19 + Tailwind CSS) │
|
|
27
|
+
├─────────────────────────────────────────────────────────────┤
|
|
28
|
+
│ API 层 │
|
|
29
|
+
│ /api/pi-chat - AI 对话接口 │
|
|
30
|
+
│ /api/tickets - 工单管理 │
|
|
31
|
+
│ /api/skills - Skill 管理 │
|
|
32
|
+
├─────────────────────────────────────────────────────────────┤
|
|
33
|
+
│ 核心引擎 │
|
|
34
|
+
│ pi-session - AI 会话管理 (pi-coding-agent) │
|
|
35
|
+
│ secure-bash - 安全命令执行 (spawnHook 拦截) │
|
|
36
|
+
│ skill-engine - Skill 执行引擎 │
|
|
37
|
+
├─────────────────────────────────────────────────────────────┤
|
|
38
|
+
│ 安全层 │
|
|
39
|
+
│ dangerous-commands - 危险命令检测规则 │
|
|
40
|
+
│ ticket-tool - 工单创建工具 │
|
|
41
|
+
│ workflow - 工单状态流转 │
|
|
42
|
+
├─────────────────────────────────────────────────────────────┤
|
|
43
|
+
│ 数据层 │
|
|
44
|
+
│ sql.js (SQLite) - 工单、审计日志存储 │
|
|
45
|
+
└─────────────────────────────────────────────────────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 技术栈
|
|
49
|
+
|
|
50
|
+
- **前端**: Next.js 15 (App Router) + React 19 + Tailwind CSS v4
|
|
51
|
+
- **AI 引擎**: pi-coding-agent (基于 Claude/GPT 等 LLM)
|
|
52
|
+
- **数据库**: sql.js (SQLite 纯 JavaScript 实现)
|
|
53
|
+
- **安全**: 危险命令检测 + 工单审批流程
|
|
54
|
+
|
|
55
|
+
## 快速开始
|
|
56
|
+
|
|
57
|
+
### 本地开发
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# 安装依赖
|
|
61
|
+
npm install
|
|
62
|
+
|
|
63
|
+
# 配置 AI 模型 (方式1: 环境变量)
|
|
64
|
+
export AI_PROVIDER=anthropic
|
|
65
|
+
export AI_API_KEY=your-api-key
|
|
66
|
+
|
|
67
|
+
# 或创建 models.json (方式2: 配置文件)
|
|
68
|
+
mkdir -p ~/.pi/agent
|
|
69
|
+
cat > ~/.pi/agent/models.json << EOF
|
|
70
|
+
{
|
|
71
|
+
"providers": {
|
|
72
|
+
"anthropic": {
|
|
73
|
+
"baseUrl": "https://api.anthropic.com",
|
|
74
|
+
"api": "anthropic-messages",
|
|
75
|
+
"apiKey": "your-api-key",
|
|
76
|
+
"models": [{ "id": "claude-sonnet-4-20250514" }]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
EOF
|
|
81
|
+
|
|
82
|
+
# 启动开发服务器
|
|
83
|
+
npm run dev
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
访问 [http://localhost:3000](http://localhost:3000)
|
|
87
|
+
|
|
88
|
+
### Docker 部署
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 一键部署 (推荐: 使用环境变量)
|
|
92
|
+
docker run -d \
|
|
93
|
+
--name work-agent \
|
|
94
|
+
-p 11024:11024 \
|
|
95
|
+
-v ./data:/app/data \
|
|
96
|
+
-e AI_PROVIDER=zhipu \
|
|
97
|
+
-e AI_API_KEY=your-api-key-here \
|
|
98
|
+
work-agent:latest
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**支持的 AI 提供商环境变量:**
|
|
102
|
+
|
|
103
|
+
| 变量 | 说明 | 示例 |
|
|
104
|
+
|------|------|------|
|
|
105
|
+
| `AI_PROVIDER` | 提供商 ID | `zhipu`, `anthropic`, `deepseek`, `openai` |
|
|
106
|
+
| `AI_API_KEY` | API 密钥 | `your-key-here` |
|
|
107
|
+
| `AI_MODEL` | 模型 ID (可选) | `glm-4.7`, `claude-sonnet-4-20250514` |
|
|
108
|
+
| `AI_BASE_URL` | 自定义 API 地址 (可选) | `https://...` |
|
|
109
|
+
|
|
110
|
+
详细部署文档请查看 [docs/DEPLOY.md](docs/DEPLOY.md)
|
|
111
|
+
|
|
112
|
+
## 工作流程
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
用户请求 → AI 分析 → 判断风险等级
|
|
116
|
+
│
|
|
117
|
+
┌──────────────┼──────────────┐
|
|
118
|
+
↓ ↓ ↓
|
|
119
|
+
安全命令 危险命令 API 调用
|
|
120
|
+
直接执行 创建工单 拦截阻止
|
|
121
|
+
│ │
|
|
122
|
+
↓ ↓
|
|
123
|
+
返回结果 等待审批
|
|
124
|
+
│
|
|
125
|
+
┌────┴────┐
|
|
126
|
+
↓ ↓
|
|
127
|
+
批准 拒绝
|
|
128
|
+
│
|
|
129
|
+
↓
|
|
130
|
+
执行命令
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 工单状态流转
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
draft → pending → approved → executing → completed
|
|
137
|
+
│ │
|
|
138
|
+
└──→ rejected └──→ failed
|
|
139
|
+
│
|
|
140
|
+
└──→ pending (可重新提交)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Skill 系统
|
|
144
|
+
|
|
145
|
+
### Skill 目录结构
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
.pi/skills/
|
|
149
|
+
├── k8s-ops/
|
|
150
|
+
│ ├── SKILL.json # Skill 元数据
|
|
151
|
+
│ └── SKILL.md # Skill 描述和使用指南
|
|
152
|
+
├── sim/
|
|
153
|
+
│ ├── SKILL.json
|
|
154
|
+
│ └── SKILL.md
|
|
155
|
+
└── ...
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 创建新 Skill
|
|
159
|
+
|
|
160
|
+
1. 在 `.pi/skills/` 下创建目录
|
|
161
|
+
2. 创建 `SKILL.json` 定义元数据
|
|
162
|
+
3. 创建 `SKILL.md` 描述能力和用法
|
|
163
|
+
|
|
164
|
+
## 安全机制
|
|
165
|
+
|
|
166
|
+
### 危险命令规则
|
|
167
|
+
|
|
168
|
+
系统内置了丰富的危险命令检测规则:
|
|
169
|
+
- **容器编排**: kubectl delete/apply/create/scale 等
|
|
170
|
+
- **文件系统**: rm -rf、chmod 777 等
|
|
171
|
+
- **系统操作**: shutdown、reboot 等
|
|
172
|
+
- **数据库**: DROP TABLE、TRUNCATE 等
|
|
173
|
+
|
|
174
|
+
### 自定义规则
|
|
175
|
+
|
|
176
|
+
在 `.pi/dangerous-commands.json` 中添加自定义规则:
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"rules": [
|
|
181
|
+
{
|
|
182
|
+
"pattern": "your-custom-pattern",
|
|
183
|
+
"description": "规则描述",
|
|
184
|
+
"riskLevel": "high"
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 项目结构
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
assistant-system/
|
|
194
|
+
├── app/ # Next.js App Router
|
|
195
|
+
│ ├── api/ # API 路由
|
|
196
|
+
│ │ ├── pi-chat/ # AI 对话 API
|
|
197
|
+
│ │ ├── tickets/ # 工单 API
|
|
198
|
+
│ │ └── skills/ # Skill API
|
|
199
|
+
│ ├── tickets/ # 工单管理页面
|
|
200
|
+
│ └── skills/ # Skill 管理页面
|
|
201
|
+
├── components/ # React 组件
|
|
202
|
+
├── lib/ # 核心库
|
|
203
|
+
│ ├── pi-session.ts # AI 会话管理
|
|
204
|
+
│ ├── secure-bash-tool.ts # 安全命令执行
|
|
205
|
+
│ ├── ticket-tool.ts # 工单创建工具
|
|
206
|
+
│ ├── scheduled-task-tool.ts # 定时任务工具
|
|
207
|
+
│ ├── dangerous-commands.ts # 危险命令检测
|
|
208
|
+
│ ├── skill-engine.ts # Skill 执行引擎
|
|
209
|
+
│ ├── scheduler.ts # 定时任务调度器
|
|
210
|
+
│ ├── db.ts # 数据库层
|
|
211
|
+
│ └── workflow.ts # 工单工作流
|
|
212
|
+
├── .pi/ # PI 配置目录
|
|
213
|
+
│ ├── skills/ # Skill 定义
|
|
214
|
+
│ └── dangerous-commands.json # 危险命令配置
|
|
215
|
+
└── data/ # SQLite 数据库文件
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## 命令
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# 开发
|
|
222
|
+
npm run dev # 启动开发服务器
|
|
223
|
+
|
|
224
|
+
# 构建
|
|
225
|
+
npm run build # 构建生产版本
|
|
226
|
+
npm start # 启动生产服务器
|
|
227
|
+
|
|
228
|
+
# 代码检查
|
|
229
|
+
npm run lint # 运行 ESLint
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TicketList } from '@/components/ticket-list';
|
|
2
|
+
|
|
3
|
+
export default function ApprovalsPage() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="p-6">
|
|
6
|
+
<div className="max-w-7xl mx-auto">
|
|
7
|
+
<div className="mb-6">
|
|
8
|
+
<h1 className="text-2xl font-bold">审核队列</h1>
|
|
9
|
+
<p className="text-muted-foreground text-sm mt-1">审核待执行的操作</p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<TicketList status="pending" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AuditLogList } from '@/components/audit-log-list';
|
|
2
|
+
|
|
3
|
+
export default function AuditPage() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="p-6">
|
|
6
|
+
<div className="max-w-7xl mx-auto">
|
|
7
|
+
<div className="mb-6">
|
|
8
|
+
<h1 className="text-2xl font-bold">审计日志</h1>
|
|
9
|
+
<p className="text-muted-foreground text-sm mt-1">完整的系统操作审计记录</p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div className="bg-card rounded-xl border shadow-sm">
|
|
13
|
+
<AuditLogList />
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { redirect } from 'next/navigation';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { ClipboardList, CheckCircle, Clock, FileText, Settings, Puzzle, BarChart3 } from 'lucide-react';
|
|
6
|
+
import { SubNav, type NavItem } from '@/components/sub-nav';
|
|
7
|
+
|
|
8
|
+
const adminNavItems: NavItem[] = [
|
|
9
|
+
{ href: '/tickets', label: '工单管理', icon: ClipboardList },
|
|
10
|
+
{ href: '/approvals', label: '审核队列', icon: CheckCircle },
|
|
11
|
+
{ href: '/scheduled-tasks', label: '定时任务', icon: Clock },
|
|
12
|
+
{ href: '/skills', label: 'Skill管理', icon: Puzzle },
|
|
13
|
+
{ href: '/statistics', label: '统计分析', icon: BarChart3 },
|
|
14
|
+
{ href: '/audit', label: '审计日志', icon: FileText },
|
|
15
|
+
{ href: '/settings', label: '系统设置', icon: Settings },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export default function AdminLayout({ children }: { children: React.ReactNode }) {
|
|
19
|
+
const [role, setRole] = useState<'admin' | 'guest'>('guest');
|
|
20
|
+
const [mounted, setMounted] = useState(false);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const savedRole = localStorage.getItem('role');
|
|
24
|
+
setRole(savedRole === 'admin' ? 'admin' : 'guest');
|
|
25
|
+
setMounted(true);
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
if (!mounted) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (role !== 'admin') {
|
|
33
|
+
redirect('/');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className="flex min-h-[calc(100vh-3rem)] bg-gray-50">
|
|
38
|
+
<div className="w-48 flex-shrink-0 border-r bg-white">
|
|
39
|
+
<div className="py-4 px-3 border-b">
|
|
40
|
+
<h2 className="text-sm font-semibold text-gray-900">系统管理</h2>
|
|
41
|
+
</div>
|
|
42
|
+
<SubNav items={adminNavItems} />
|
|
43
|
+
</div>
|
|
44
|
+
<main className="flex-1 overflow-auto">{children}</main>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Clock } from 'lucide-react';
|
|
2
|
+
import { ScheduledTaskList } from '@/components/scheduled-task-list';
|
|
3
|
+
|
|
4
|
+
export default function AdminScheduledTasksPage() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="p-6">
|
|
7
|
+
<div className="max-w-7xl mx-auto">
|
|
8
|
+
<div className="mb-6">
|
|
9
|
+
<h1 className="text-2xl font-bold">定时任务</h1>
|
|
10
|
+
<p className="text-muted-foreground text-sm mt-1">查看和管理所有定时执行的命令任务</p>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<ScheduledTaskList />
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
5
|
+
import { AlertCircle } from 'lucide-react';
|
|
6
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
7
|
+
import { SetupGuide } from '@/components/setup-guide';
|
|
8
|
+
|
|
9
|
+
export default function SettingsPage() {
|
|
10
|
+
const router = useRouter();
|
|
11
|
+
const [role, setRole] = useState<string | null>(null);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const savedRole = localStorage.getItem('role');
|
|
15
|
+
setRole(savedRole);
|
|
16
|
+
|
|
17
|
+
if (savedRole !== 'admin') {
|
|
18
|
+
router.push('/');
|
|
19
|
+
}
|
|
20
|
+
}, [router]);
|
|
21
|
+
|
|
22
|
+
if (role !== 'admin') {
|
|
23
|
+
return (
|
|
24
|
+
<div className="min-h-screen bg-background flex items-center justify-center p-4">
|
|
25
|
+
<Card className="max-w-md w-full">
|
|
26
|
+
<CardHeader className="text-center">
|
|
27
|
+
<div className="mx-auto w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mb-4">
|
|
28
|
+
<AlertCircle className="w-6 h-6 text-red-600" />
|
|
29
|
+
</div>
|
|
30
|
+
<CardTitle className="text-xl">无权限访问</CardTitle>
|
|
31
|
+
</CardHeader>
|
|
32
|
+
<CardContent className="text-center text-gray-500">
|
|
33
|
+
<p>系统设置仅限管理员访问</p>
|
|
34
|
+
<p className="text-sm mt-2">请使用管理员账号登录</p>
|
|
35
|
+
</CardContent>
|
|
36
|
+
</Card>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className="min-h-screen bg-background">
|
|
43
|
+
<SetupGuide mode="settings" />
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|