speccore 8.3.147 → 8.3.148
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/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +9 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +4 -1
- package/dist/commands/update.js.map +1 -1
- package/package.json +3 -2
- package/templates/api-design-example.md +338 -0
- package/templates/ci/github-actions.yml +44 -0
- package/templates/dashboard.html +425 -0
- package/templates/database-example.md +223 -0
- package/templates/deploy-docker/README.md +284 -0
- package/templates/deploy-docker/deploy-remote.sh +79 -0
- package/templates/deploy-docker/docker-compose.yml +113 -0
- package/templates/deploy-docker/frontend.Dockerfile +43 -0
- package/templates/deploy-docker/nginx.conf +30 -0
- package/templates/deploy-examples.yaml +436 -0
- package/templates/deploy-java/Dockerfile +50 -0
- package/templates/deploy-java/README.md +212 -0
- package/templates/deploy-java/deploy.sh +120 -0
- package/templates/deploy-java/spring-boot.service +35 -0
- package/templates/html/speccore-ask-explain.html +10 -0
- package/templates/html/speccore-ask-guide.html +10 -0
- package/templates/html/speccore-ask-match.html +10 -0
- package/templates/html/speccore-ask-pipeline.html +1 -0
- package/templates/html/speccore-ask-result.html +10 -0
- package/templates/html/speccore-demo.html +449 -0
- package/templates/html/speccore-dev.html +202 -0
- package/templates/html/speccore-help.html +1 -0
- package/templates/html/speccore-knowledge-graph.html +656 -0
- package/templates/html/speccore-retro-T-001.html +1 -0
- package/templates/html/speccore-setup-guide.html +289 -0
- package/templates/html/speccore-welcome.html +1 -0
- package/templates/security-example.md +226 -0
- package/templates/verify-spec-example.yaml +138 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Java 后端部署指南
|
|
2
|
+
|
|
3
|
+
> 本目录提供 Java(Spring Boot)后端服务的部署模板和示例脚本。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 目录结构
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
deploy-java/
|
|
11
|
+
├── spring-boot.service # systemd service 文件模板
|
|
12
|
+
├── deploy.sh # 服务器端部署脚本(备份 → 替换 → 重启 → 健康检查)
|
|
13
|
+
├── Dockerfile # 多阶段构建 Dockerfile 示例
|
|
14
|
+
└── README.md # 本文件
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 部署方式一:systemd + SSH(推荐测试环境)
|
|
20
|
+
|
|
21
|
+
### 1. 服务器端准备(只需一次)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# 创建部署目录
|
|
25
|
+
sudo mkdir -p /opt/services/order-service
|
|
26
|
+
sudo mkdir -p /var/log/order-service
|
|
27
|
+
|
|
28
|
+
# 复制 service 文件(将 spring-boot.service 中的占位符替换后复制)
|
|
29
|
+
# 注意:文件名必须与 PROJECT.yaml 中的 platform.name 一致
|
|
30
|
+
sudo cp spring-boot.service /etc/systemd/system/order-service.service
|
|
31
|
+
|
|
32
|
+
# 重载 systemd
|
|
33
|
+
sudo systemctl daemon-reload
|
|
34
|
+
sudo systemctl enable order-service
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. 替换 service 文件中的占位符
|
|
38
|
+
|
|
39
|
+
| 占位符 | 示例值 | 说明 |
|
|
40
|
+
|--------|--------|------|
|
|
41
|
+
| `{{APP_NAME}}` | `order-service` | 应用名,与 platform.name 一致 |
|
|
42
|
+
| `{{DEPLOY_USER}}` | `deployer` | 运行服务的系统用户 |
|
|
43
|
+
| `{{DEPLOY_DIR}}` | `/opt/services/order-service` | jar 文件所在目录 |
|
|
44
|
+
| `{{PROFILE}}` | `staging` | Spring Boot profile |
|
|
45
|
+
| `{{JVM_XMS}}` | `512m` | JVM 初始堆内存 |
|
|
46
|
+
| `{{JVM_XMX}}` | `1024m` | JVM 最大堆内存 |
|
|
47
|
+
|
|
48
|
+
### 3. PROJECT.yaml 配置
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
platforms:
|
|
52
|
+
- name: order-service
|
|
53
|
+
type: backend
|
|
54
|
+
code_path: ./order-service
|
|
55
|
+
default_branch: main
|
|
56
|
+
deploy:
|
|
57
|
+
staging:
|
|
58
|
+
type: ssh
|
|
59
|
+
build_cmd: mvn clean package -DskipTests -P staging
|
|
60
|
+
output_dir: target
|
|
61
|
+
host: deployer@staging-server.example.com:22
|
|
62
|
+
key: ~/.ssh/id_rsa
|
|
63
|
+
remote_dir: /opt/services/order-service
|
|
64
|
+
script: sudo systemctl restart order-service
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 4. 数据库 / Redis 配置切换
|
|
68
|
+
|
|
69
|
+
**方式 A:Spring Boot Profiles(推荐)**
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
# src/main/resources/application-staging.yml
|
|
73
|
+
spring:
|
|
74
|
+
datasource:
|
|
75
|
+
url: jdbc:mysql://staging-db:3306/order_db
|
|
76
|
+
username: ${DB_USER}
|
|
77
|
+
password: ${DB_PASS}
|
|
78
|
+
data:
|
|
79
|
+
redis:
|
|
80
|
+
host: staging-redis
|
|
81
|
+
port: 6379
|
|
82
|
+
password: ${REDIS_PASS}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**方式 B:环境变量注入(配合 systemd)**
|
|
86
|
+
|
|
87
|
+
在 `spring-boot.service` 的 `[Service]` 段增加:
|
|
88
|
+
```ini
|
|
89
|
+
Environment="DB_USER=order_user"
|
|
90
|
+
Environment="DB_PASS=secret"
|
|
91
|
+
Environment="REDIS_PASS=redis_secret"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
在 `application.yml` 中引用:
|
|
95
|
+
```yaml
|
|
96
|
+
spring:
|
|
97
|
+
datasource:
|
|
98
|
+
username: ${DB_USER}
|
|
99
|
+
password: ${DB_PASS}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 5. 部署流程
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
speccore deploy --env staging --platform order-service
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
执行流程:
|
|
109
|
+
1. 本地执行 `mvn clean package -DskipTests -P staging`
|
|
110
|
+
2. SCP 上传 `target/*.jar` 到服务器 `/opt/services/order-service/`
|
|
111
|
+
3. SSH 执行 `sudo systemctl restart order-service`
|
|
112
|
+
4. systemd 自动完成:停止旧进程 → 启动新 jar → 写入日志
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 部署方式二:Docker(推荐生产环境)
|
|
117
|
+
|
|
118
|
+
### 1. 准备 Dockerfile
|
|
119
|
+
|
|
120
|
+
将 `Dockerfile` 复制到 Java 工程根目录(与 `pom.xml` 同级)。
|
|
121
|
+
|
|
122
|
+
### 2. PROJECT.yaml 配置
|
|
123
|
+
|
|
124
|
+
```yaml
|
|
125
|
+
platforms:
|
|
126
|
+
- name: order-service
|
|
127
|
+
type: backend
|
|
128
|
+
code_path: ./order-service
|
|
129
|
+
default_branch: main
|
|
130
|
+
deploy:
|
|
131
|
+
production:
|
|
132
|
+
type: docker
|
|
133
|
+
dockerfile: ./Dockerfile
|
|
134
|
+
registry: registry.example.com
|
|
135
|
+
image: my-project/order-service
|
|
136
|
+
tag: production
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 3. 部署流程
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
speccore deploy --env production --platform order-service
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
执行流程:
|
|
146
|
+
1. 本地 `docker build`
|
|
147
|
+
2. 推送到镜像仓库 `registry.example.com/my-project/order-service:production`
|
|
148
|
+
3. 服务器端拉取镜像并运行(需配合额外的部署脚本或 CI/CD)
|
|
149
|
+
|
|
150
|
+
> 提示:如果服务器需要 SSH 登录后执行 `docker pull && docker run`,可将 deploy 类型改为 `script`,编写自定义脚本。
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 部署方式三:自定义脚本(最灵活)
|
|
155
|
+
|
|
156
|
+
如果 systemd 和 Docker 都不满足需求,使用 `script` 类型:
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
deploy:
|
|
160
|
+
staging:
|
|
161
|
+
type: script
|
|
162
|
+
build_cmd: mvn clean package -DskipTests
|
|
163
|
+
script: ./scripts/deploy-custom.sh
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 数据库 / Redis 连接检查清单
|
|
169
|
+
|
|
170
|
+
| 检查项 | 说明 |
|
|
171
|
+
|--------|------|
|
|
172
|
+
| 网络连通性 | 服务器能否 ping 通数据库和 Redis 主机 |
|
|
173
|
+
| 防火墙 / 安全组 | 数据库端口(3306/5432)和 Redis 端口(6379)是否开放 |
|
|
174
|
+
| 用户名密码 | 确认 staging / production 环境的凭据正确 |
|
|
175
|
+
| 数据库存在性 | 目标数据库是否已创建 |
|
|
176
|
+
| 连接池配置 | HikariCP 的最大连接数是否超过数据库限制 |
|
|
177
|
+
| 时区 | JVM 时区、数据库时区、应用时区是否一致 |
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## 常见问题
|
|
182
|
+
|
|
183
|
+
**Q: 部署后服务起不来,怎么排查?**
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# 查看服务状态
|
|
187
|
+
sudo systemctl status order-service --no-pager
|
|
188
|
+
|
|
189
|
+
# 查看日志
|
|
190
|
+
sudo journalctl -u order-service -f
|
|
191
|
+
|
|
192
|
+
# 查看应用日志
|
|
193
|
+
tail -f /var/log/order-service/app.log
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Q: 如何回滚到上一个版本?**
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
cd /opt/services/order-service
|
|
200
|
+
# 找到最新备份
|
|
201
|
+
LATEST=$(ls -t backups/*.jar | head -1)
|
|
202
|
+
cp "$LATEST" order-service.jar
|
|
203
|
+
sudo systemctl restart order-service
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Q: 多个环境(staging / production)如何管理配置?**
|
|
207
|
+
|
|
208
|
+
使用 Spring Boot profiles:
|
|
209
|
+
- `application-staging.yml` — 测试环境
|
|
210
|
+
- `application-production.yml` — 生产环境
|
|
211
|
+
- 打包时激活 profile:`-P staging`
|
|
212
|
+
- 运行时激活 profile:`--spring.profiles.active=staging`
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ═══════════════════════════════════════════════════════════
|
|
3
|
+
# Java 后端部署脚本(服务器端执行)
|
|
4
|
+
# ═══════════════════════════════════════════════════════════
|
|
5
|
+
#
|
|
6
|
+
# 用法:
|
|
7
|
+
# ./deploy.sh <app-name> [profile]
|
|
8
|
+
#
|
|
9
|
+
# 示例:
|
|
10
|
+
# ./deploy.sh order-service staging
|
|
11
|
+
# ./deploy.sh order-service production
|
|
12
|
+
#
|
|
13
|
+
# 该脚本由 speccore deploy 通过 SSH 调用,也可手动在服务器上执行。
|
|
14
|
+
# 功能:备份旧 jar → 替换新 jar → 重启 systemd 服务 → 健康检查
|
|
15
|
+
# ═══════════════════════════════════════════════════════════
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
APP_NAME="${1:-}"
|
|
20
|
+
PROFILE="${2:-staging}"
|
|
21
|
+
|
|
22
|
+
if [ -z "$APP_NAME" ]; then
|
|
23
|
+
echo "用法: $0 <app-name> [profile]"
|
|
24
|
+
echo "示例: $0 order-service staging"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
DEPLOY_DIR="/opt/services/$APP_NAME"
|
|
29
|
+
BACKUP_DIR="$DEPLOY_DIR/backups"
|
|
30
|
+
LOG_DIR="/var/log/$APP_NAME"
|
|
31
|
+
JAR_FILE="$DEPLOY_DIR/$APP_NAME.jar"
|
|
32
|
+
NEW_JAR="$DEPLOY_DIR/$APP_NAME-new.jar"
|
|
33
|
+
HEALTH_URL="http://localhost:8080/actuator/health" # 根据实际端口和路径修改
|
|
34
|
+
|
|
35
|
+
echo "========================================"
|
|
36
|
+
echo "部署应用: $APP_NAME"
|
|
37
|
+
echo "环境: $PROFILE"
|
|
38
|
+
echo "========================================"
|
|
39
|
+
|
|
40
|
+
# ── 1. 预检 ──
|
|
41
|
+
if [ ! -f "$NEW_JAR" ]; then
|
|
42
|
+
echo "❌ 错误:未找到新 jar 文件: $NEW_JAR"
|
|
43
|
+
echo " 请确保 speccore deploy 已成功上传 jar 到该路径"
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# ── 2. 创建必要目录 ──
|
|
48
|
+
mkdir -p "$BACKUP_DIR" "$LOG_DIR"
|
|
49
|
+
|
|
50
|
+
# ── 3. 备份旧版本 ──
|
|
51
|
+
if [ -f "$JAR_FILE" ]; then
|
|
52
|
+
BACKUP_NAME="$BACKUP_DIR/$APP_NAME-$(date +%Y%m%d-%H%M%S).jar"
|
|
53
|
+
cp "$JAR_FILE" "$BACKUP_NAME"
|
|
54
|
+
echo "✅ 旧版本已备份: $BACKUP_NAME"
|
|
55
|
+
|
|
56
|
+
# 只保留最近 5 个备份
|
|
57
|
+
ls -t "$BACKUP_DIR"/*.jar 2>/dev/null | tail -n +6 | xargs -r rm -f
|
|
58
|
+
echo "🧹 已清理旧备份(保留最近 5 个)"
|
|
59
|
+
else
|
|
60
|
+
echo "ℹ️ 首次部署,无旧版本需要备份"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# ── 4. 替换 jar ──
|
|
64
|
+
mv "$NEW_JAR" "$JAR_FILE"
|
|
65
|
+
echo "✅ 已替换 jar: $JAR_FILE"
|
|
66
|
+
|
|
67
|
+
# ── 5. 确保 systemd service 文件存在 ──
|
|
68
|
+
SERVICE_FILE="/etc/systemd/system/$APP_NAME.service"
|
|
69
|
+
if [ ! -f "$SERVICE_FILE" ]; then
|
|
70
|
+
echo "⚠️ 警告:systemd service 文件不存在: $SERVICE_FILE"
|
|
71
|
+
echo " 请从 templates/deploy-java/spring-boot.service 复制并修改后部署到该路径"
|
|
72
|
+
echo " 然后执行: sudo systemctl daemon-reload && sudo systemctl enable $APP_NAME"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# ── 6. 重启服务 ──
|
|
77
|
+
echo "🔄 重启服务..."
|
|
78
|
+
sudo systemctl daemon-reload
|
|
79
|
+
sudo systemctl restart "$APP_NAME"
|
|
80
|
+
|
|
81
|
+
# ── 7. 等待启动 ──
|
|
82
|
+
echo "⏳ 等待服务启动(最多 30 秒)..."
|
|
83
|
+
for i in {1..30}; do
|
|
84
|
+
sleep 1
|
|
85
|
+
if systemctl is-active --quiet "$APP_NAME"; then
|
|
86
|
+
echo "✅ 服务已启动"
|
|
87
|
+
break
|
|
88
|
+
fi
|
|
89
|
+
if [ "$i" -eq 30 ]; then
|
|
90
|
+
echo "❌ 服务启动超时"
|
|
91
|
+
echo "📋 日志 tail -n 50:"
|
|
92
|
+
sudo journalctl -u "$APP_NAME" --no-pager -n 50 || true
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
done
|
|
96
|
+
|
|
97
|
+
# ── 8. 健康检查 ──
|
|
98
|
+
echo "🏥 执行健康检查..."
|
|
99
|
+
for i in {1..10}; do
|
|
100
|
+
sleep 2
|
|
101
|
+
if curl -sf "$HEALTH_URL" >/dev/null 2>&1; then
|
|
102
|
+
echo "✅ 健康检查通过: $HEALTH_URL"
|
|
103
|
+
break
|
|
104
|
+
fi
|
|
105
|
+
if [ "$i" -eq 10 ]; then
|
|
106
|
+
echo "⚠️ 健康检查未通过,但服务已启动"
|
|
107
|
+
echo " 请手动检查: curl $HEALTH_URL"
|
|
108
|
+
fi
|
|
109
|
+
done
|
|
110
|
+
|
|
111
|
+
# ── 9. 显示状态 ──
|
|
112
|
+
echo ""
|
|
113
|
+
echo "========================================"
|
|
114
|
+
echo "📋 部署完成"
|
|
115
|
+
echo "========================================"
|
|
116
|
+
sudo systemctl status "$APP_NAME" --no-pager || true
|
|
117
|
+
echo ""
|
|
118
|
+
echo "日志查看:"
|
|
119
|
+
echo " journalctl -u $APP_NAME -f"
|
|
120
|
+
echo " tail -f $LOG_DIR/app.log"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description={{APP_NAME}}
|
|
3
|
+
After=network.target
|
|
4
|
+
|
|
5
|
+
[Service]
|
|
6
|
+
Type=simple
|
|
7
|
+
User={{DEPLOY_USER}}
|
|
8
|
+
Group={{DEPLOY_USER}}
|
|
9
|
+
WorkingDirectory={{DEPLOY_DIR}}
|
|
10
|
+
|
|
11
|
+
# Spring Boot Profile(按环境切换:staging / production / test)
|
|
12
|
+
Environment="SPRING_PROFILES_ACTIVE={{PROFILE}}"
|
|
13
|
+
|
|
14
|
+
# JVM 参数
|
|
15
|
+
Environment="JAVA_OPTS=-Xms{{JVM_XMS}} -Xmx{{JVM_XMX}} -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom"
|
|
16
|
+
|
|
17
|
+
# 启动命令
|
|
18
|
+
ExecStart=/usr/bin/java $JAVA_OPTS -jar {{APP_NAME}}.jar
|
|
19
|
+
|
|
20
|
+
# 优雅停止(SIGTERM 触发 Spring Boot 的 shutdown hook)
|
|
21
|
+
ExecStop=/bin/kill -SIGTERM $MAINPID
|
|
22
|
+
|
|
23
|
+
# 进程管理
|
|
24
|
+
Restart=on-failure
|
|
25
|
+
RestartSec=10
|
|
26
|
+
StartLimitInterval=60s
|
|
27
|
+
StartLimitBurst=3
|
|
28
|
+
|
|
29
|
+
# 日志输出(systemd 240+ 支持 append 模式)
|
|
30
|
+
# 旧版本 systemd 可改用:StandardOutput=file:/var/log/{{APP_NAME}}/app.log
|
|
31
|
+
StandardOutput=append:/var/log/{{APP_NAME}}/app.log
|
|
32
|
+
StandardError=append:/var/log/{{APP_NAME}}/error.log
|
|
33
|
+
|
|
34
|
+
[Install]
|
|
35
|
+
WantedBy=multi-user.target
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · dashboard怎么用</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.query{color:var(--muted);font-size:12px;margin:8px 0 16px}.badge{display:inline-block;padding:4px 14px;border-radius:20px;font-size:11px;font-weight:600;background:#14b8a622;color:#14b8a6;border:1px solid #14b8a644;margin-bottom:20px}code{background:rgba(14,165,233,.1);padding:2px 8px;border-radius:4px;color:var(--cyan);font-size:12px;display:inline-block;margin:4px 4px 4px 0}.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:10px;background:rgba(20,184,166,.1);color:var(--green);margin:2px}
|
|
2
|
+
/* Explain */
|
|
3
|
+
.explain-box{padding:10px 0}.explain-desc{font-size:13px;margin-bottom:16px}.explain-usage,.explain-examples,.explain-related{margin:10px 0}.label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-right:8px}
|
|
4
|
+
/* Guide */
|
|
5
|
+
.guide-title{font-weight:600;margin-bottom:16px}.guide-steps{display:flex;flex-direction:column;gap:8px}.guide-step{display:flex;gap:14px;padding:12px 14px;background:rgba(249,115,22,.04);border-left:2px solid var(--orange);border-radius:0 8px 8px 0}.guide-step .step-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--orange);min-width:30px}.guide-step .step-cmd{font-weight:600;color:var(--text)}.guide-step .step-desc{color:var(--muted);font-size:10px;margin-top:4px}
|
|
6
|
+
/* Match */
|
|
7
|
+
.match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
|
|
8
|
+
/* Pipeline */
|
|
9
|
+
.pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
|
|
10
|
+
.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{text-shadow:0 0 20px rgba(14,165,233,.35),0 0 60px rgba(14,165,233,.12)!important}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"dashboard怎么用"</div><div class="badge">📖 命令解释</div><div class="explain-box"><div class="explain-desc">项目仪表盘:期次状态/进度/健康度,--scope global 全量视图</div><div class="explain-usage"><span class="label">用法</span><code>speccore dashboard [--scope global|iteration] [--export html] [--health] [--lifecycle]</code></div><div class="explain-related"><span class="label">关联</span><span class="tag">analyze</span> <span class="tag">health</span></div></div><div style="text-align:center;margin-top:16px"><a href="speccore-welcome.html" style="color:var(--cyan);font-size:11px;text-decoration:none">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · 2026-08-31</div></div></body></html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · 我想做一个登录功能</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.query{color:var(--muted);font-size:12px;margin:8px 0 16px}.badge{display:inline-block;padding:4px 14px;border-radius:20px;font-size:11px;font-weight:600;background:#f9731622;color:#f97316;border:1px solid #f9731644;margin-bottom:20px}code{background:rgba(14,165,233,.1);padding:2px 8px;border-radius:4px;color:var(--cyan);font-size:12px;display:inline-block;margin:4px 4px 4px 0}.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:10px;background:rgba(20,184,166,.1);color:var(--green);margin:2px}
|
|
2
|
+
/* Explain */
|
|
3
|
+
.explain-box{padding:10px 0}.explain-desc{font-size:13px;margin-bottom:16px}.explain-usage,.explain-examples,.explain-related{margin:10px 0}.label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-right:8px}
|
|
4
|
+
/* Guide */
|
|
5
|
+
.guide-title{font-weight:600;margin-bottom:16px}.guide-steps{display:flex;flex-direction:column;gap:8px}.guide-step{display:flex;gap:14px;padding:12px 14px;background:rgba(249,115,22,.04);border-left:2px solid var(--orange);border-radius:0 8px 8px 0}.guide-step .step-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--orange);min-width:30px}.guide-step .step-cmd{font-weight:600;color:var(--text)}.guide-step .step-desc{color:var(--muted);font-size:10px;margin-top:4px}
|
|
6
|
+
/* Match */
|
|
7
|
+
.match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
|
|
8
|
+
/* Pipeline */
|
|
9
|
+
.pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
|
|
10
|
+
.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{text-shadow:0 0 20px rgba(14,165,233,.35),0 0 60px rgba(14,165,233,.12)!important}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"我想做一个登录功能"</div><div class="badge">🗺️ 任务指引</div><div class="guide-title">已为你规划「新功能开发全流程」(8 步)</div><div class="guide-steps"><div class="guide-step"><div class="step-num">1</div><div class="step-body"><div class="step-cmd">speccore init</div><div class="step-desc">初始化项目(如果还没有)</div></div></div><div class="guide-step"><div class="step-num">2</div><div class="step-body"><div class="step-cmd">speccore doc2spec -f PRD.docx --iter {iteration}</div><div class="step-desc">导入 PRD 文档,AI 分析生成需求规格</div></div></div><div class="guide-step"><div class="step-num">3</div><div class="step-body"><div class="step-cmd">speccore analyze --iteration {iteration} --audit</div><div class="step-desc">AI 分析需求,生成审计报告</div></div></div><div class="guide-step"><div class="step-num">4</div><div class="step-body"><div class="step-cmd">speccore split -f REQUIREMENT.md</div><div class="step-desc">将需求拆分为独立开发任务</div></div></div><div class="guide-step"><div class="step-num">5</div><div class="step-body"><div class="step-cmd">speccore plan --all</div><div class="step-desc">生成任务执行计划,确定优先级和依赖</div></div></div><div class="guide-step"><div class="step-num">6</div><div class="step-body"><div class="step-cmd">speccore execute --auto</div><div class="step-desc">按计划依次执行开发任务</div></div></div><div class="guide-step"><div class="step-num">7</div><div class="step-body"><div class="step-cmd">speccore pr --auto</div><div class="step-desc">代码提交后创建 Pull Request</div></div></div><div class="guide-step"><div class="step-num">8</div><div class="step-body"><div class="step-cmd">speccore done --all</div><div class="step-desc">全部完成后归档收尾</div></div></div></div><div style="text-align:center;margin-top:16px"><a href="speccore-welcome.html" style="color:var(--cyan);font-size:11px;text-decoration:none">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.148 · 2026-08-31</div></div></body></html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · 查看进度</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:24px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.query{color:var(--muted);font-size:12px;margin:8px 0 16px}.badge{display:inline-block;padding:4px 14px;border-radius:20px;font-size:11px;font-weight:600;background:#0ea5e922;color:#0ea5e9;border:1px solid #0ea5e944;margin-bottom:20px}code{background:rgba(14,165,233,.1);padding:2px 8px;border-radius:4px;color:var(--cyan);font-size:12px;display:inline-block;margin:4px 4px 4px 0}.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:10px;background:rgba(20,184,166,.1);color:var(--green);margin:2px}
|
|
2
|
+
/* Explain */
|
|
3
|
+
.explain-box{padding:10px 0}.explain-desc{font-size:13px;margin-bottom:16px}.explain-usage,.explain-examples,.explain-related{margin:10px 0}.label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-right:8px}
|
|
4
|
+
/* Guide */
|
|
5
|
+
.guide-title{font-weight:600;margin-bottom:16px}.guide-steps{display:flex;flex-direction:column;gap:8px}.guide-step{display:flex;gap:14px;padding:12px 14px;background:rgba(249,115,22,.04);border-left:2px solid var(--orange);border-radius:0 8px 8px 0}.guide-step .step-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--orange);min-width:30px}.guide-step .step-cmd{font-weight:600;color:var(--text)}.guide-step .step-desc{color:var(--muted);font-size:10px;margin-top:4px}
|
|
6
|
+
/* Match */
|
|
7
|
+
.match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
|
|
8
|
+
/* Pipeline */
|
|
9
|
+
.pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
|
|
10
|
+
.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}h1{text-shadow:0 0 20px rgba(14,165,233,.35),0 0 60px rgba(14,165,233,.12)!important}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"查看进度"</div><div class="badge">🎯 意图匹配</div><div class="match-result"><div class="match-summary">✅ 推荐: dashboard</div><div class="match-detail">🎯 推荐命令: <code>speccore dashboard<br>项目仪表盘:期次状态/进度/健康度,--scope</code> global 全量视图<br><br>用法: <code>speccore dashboard</code> [--scope global|iteration] [--export html] [--health] [--lifecycle]<br><br>示例:<br> $ <code>speccore dashboard<br></code> $ <code>speccore dashboard</code> --scope global --export html</div></div><div style="text-align:center;margin-top:16px"><a href="speccore-welcome.html" style="color:var(--cyan);font-size:11px;text-decoration:none">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · 2026-08-31</div></div></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · ask --pipeline</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:900px;width:100%;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:32px;position:relative;overflow:hidden;z-index:1}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.page-title{font-family:'Orbitron',sans-serif;font-size:22px;font-weight:700;text-align:center;color:var(--cyan);margin-bottom:32px;letter-spacing:1px;text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}.page-title span{color:var(--text);font-weight:500}.flow-chart{display:flex;align-items:stretch;gap:0;margin-bottom:28px}.flow-node{flex:1;background:rgba(13,31,56,.7);border:1px solid;border-radius:10px;padding:14px 8px;text-align:center;position:relative}.flow-node .icon{font-size:18px;margin-bottom:6px}.flow-node .name{font-size:12px;font-weight:600;margin-bottom:4px}.flow-node .desc{font-size:10px;color:var(--muted)}.flow-node.n1{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n2{border-color:rgba(99,102,241,.4);color:var(--purple)}.flow-node.n3{border-color:rgba(14,165,233,.4);color:var(--cyan)}.flow-node.n4{border-color:rgba(20,184,166,.4);color:var(--green)}.flow-connector{width:24px;display:flex;align-items:center;justify-content:center}.flow-connector::after{content:'';width:100%;height:1px;background:linear-gradient(90deg,var(--border),var(--cyan),var(--border))}.example-box{border:1px dashed rgba(14,165,233,.3);border-radius:12px;padding:16px 20px;margin-bottom:24px;background:rgba(14,165,233,.03)}.example-label{font-size:13px;font-weight:600;color:var(--cyan);margin-bottom:8px}.example-query{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text)}.example-query code{color:var(--green);font-weight:600}.steps{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.step{background:rgba(13,31,56,.8);border:1px solid rgba(14,165,233,.12);border-radius:10px;padding:14px 18px}.step-num{font-family:'Orbitron',sans-serif;font-size:14px;font-weight:700;color:var(--green);margin-bottom:6px}.step-cmd{font-family:'JetBrains Mono',monospace;font-size:14px;color:var(--text);margin-bottom:6px}.step-cmd .cmd-name{color:var(--green)}.step-cmd .cmd-args{color:var(--muted)}.step-parse{font-size:12px;color:var(--muted);line-height:1.5}.step-parse::before{content:'→ 解析:';color:var(--cyan)}.confirm-btn{display:block;width:100%;max-width:420px;margin:0 auto 16px;text-align:center;padding:16px;background:linear-gradient(135deg,var(--cyan),#0284c7);border:none;border-radius:40px;color:#fff;font-size:15px;font-weight:600;cursor:pointer;box-shadow:0 0 30px rgba(14,165,233,.3)}.legend{display:flex;justify-content:center;gap:20px;font-size:11px;color:var(--muted);margin-bottom:16px;flex-wrap:wrap}.legend-item{display:flex;align-items:center;gap:4px}.legend-dot{width:8px;height:8px;border-radius:50%;display:inline-block}.legend-dot.required{background:var(--cyan)}.legend-dot.generated{background:var(--green)}.legend-dot.pending{background:rgba(255,255,255,.3)}.back-link{text-align:center;margin-top:12px}.back-link a{color:var(--cyan);font-size:11px;text-decoration:none}.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:20px}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><div class="page-title">ask --pipeline <span>多步骤编排引擎</span></div><div class="flow-chart"><div class="flow-node n1"><div class="icon">🧠</div><div class="name">AI 意图分解</div><div class="desc">LLM 分解多步骤</div></div><div class="flow-connector"></div><div class="flow-node n2"><div class="icon">📐</div><div class="name">命令匹配</div><div class="desc">意图→命令图</div></div><div class="flow-connector"></div><div class="flow-node n3"><div class="icon">🔗</div><div class="name">依赖解析</div><div class="desc">顺序/并行/参数</div></div><div class="flow-connector"></div><div class="flow-node n4"><div class="icon">✅</div><div class="name">预览</div><div class="desc">展示给用户</div></div></div><div class="example-box"><div class="example-label">📋 示例:<span class="example-query"><code>/spec-ask "本期迭代:从 PRD 导入到代码提交,跑完整开发流程"</code></span></div></div><div class="steps"><div class="step"><div class="step-num">1.</div><div class="step-cmd"><span class="cmd-name">speccore doc2spec</span> <span class="cmd-args">-f PRD.docx --iter {iteration}</span></div><div class="step-parse">导入 PRD 文档,AI 分析生成需求规格说明书</div></div><div class="step"><div class="step-num">2.</div><div class="step-cmd"><span class="cmd-name">speccore analyze</span> <span class="cmd-args">--iteration {iteration} --audit</span></div><div class="step-parse">AI 深度分析需求,生成审计报告和可行性评估</div></div><div class="step"><div class="step-num">3.</div><div class="step-cmd"><span class="cmd-name">speccore split</span> <span class="cmd-args">-f REQUIREMENT.md</span></div><div class="step-parse">将需求拆分为独立开发任务,确定优先级和依赖关系</div></div><div class="step"><div class="step-num">4.</div><div class="step-cmd"><span class="cmd-name">speccore execute</span> <span class="cmd-args">--auto</span></div><div class="step-parse">按任务计划依次自动执行开发、测试和代码生成</div></div><div class="step"><div class="step-num">5.</div><div class="step-cmd"><span class="cmd-name">speccore pr</span> <span class="cmd-args">--auto</span></div><div class="step-parse">代码提交后自动创建 Pull Request,完成交付</div></div></div><div class="confirm-btn">确认执行? (y/N) 或修改参数</div><div class="legend"><div class="legend-item"><span class="legend-dot required"></span> = 必选步骤</div><div class="legend-item"><span class="legend-dot generated"></span> = 已生成</div><div class="legend-item"><span class="legend-dot pending"></span> = 待执行</div><div class="legend-item">→ = 依赖传递</div></div><div class="back-link"><a href="speccore-welcome.html">← 返回 ask 引导页</a></div><div class="footer">由 SpecCore 驱动 · v8.3.148 · 2026-08-31</div></div></body></html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN" data-theme="ocean"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>SpecCore · dashboard</title><style>@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700;900&family=JetBrains+Mono:wght@400;600;700&display=swap');[data-theme="ocean"]{--cyan:#0ea5e9;--bg:#0b1929;--card:rgba(13,31,56,.95);--border:rgba(14,165,233,.15);--text:#bae6fd;--muted:#5b7fa5;--green:#14b8a6;--orange:#f97316;--purple:#6366f1}*{margin:0;padding:0;box-sizing:border-box}body{font-family:'JetBrains Mono',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}.scanlines{position:fixed;inset:0;pointer-events:none;z-index:99;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,240,255,.01) 2px,rgba(0,240,255,.01) 4px)}.card{max-width:800px;margin:0 auto;background:var(--card);border:1px solid var(--border);border-radius:16px;padding:36px;position:relative;overflow:hidden}.card::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX 3s linear infinite}.card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--cyan),transparent);animation:scanX-rev 3s linear infinite}@keyframes scanX{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}@keyframes scanX-rev{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}@keyframes scanY{0%{transform:translateY(-100%)}100%{transform:translateY(100%)}}@keyframes scanY-rev{0%{transform:translateY(100%)}100%{transform:translateY(-100%)}}.vline{position:absolute;top:0;width:1px;bottom:0;pointer-events:none}.vline.l{left:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY-rev 3s linear infinite}.vline.r{right:0;background:linear-gradient(180deg,transparent,var(--cyan),transparent);animation:scanY 3s linear infinite}h1{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:900;background:linear-gradient(135deg,var(--cyan),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;letter-spacing:2px}.query{color:var(--muted);font-size:12px;margin:8px 0 16px}.badge{display:inline-block;padding:4px 14px;border-radius:20px;font-size:11px;font-weight:600;background:#0ea5e922;color:#0ea5e9;border:1px solid #0ea5e944;margin-bottom:20px}code{background:rgba(14,165,233,.1);padding:2px 8px;border-radius:4px;color:var(--cyan);font-size:12px;display:inline-block;margin:4px 4px 4px 0}.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:10px;background:rgba(20,184,166,.1);color:var(--green);margin:2px}
|
|
2
|
+
/* Explain */
|
|
3
|
+
.explain-box{padding:10px 0}.explain-desc{font-size:13px;margin-bottom:16px}.explain-usage,.explain-examples,.explain-related{margin:10px 0}.label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-right:8px}
|
|
4
|
+
/* Guide */
|
|
5
|
+
.guide-title{font-weight:600;margin-bottom:16px}.guide-steps{display:flex;flex-direction:column;gap:8px}.guide-step{display:flex;gap:14px;padding:12px 14px;background:rgba(249,115,22,.04);border-left:2px solid var(--orange);border-radius:0 8px 8px 0}.guide-step .step-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--orange);min-width:30px}.guide-step .step-cmd{font-weight:600;color:var(--text)}.guide-step .step-desc{color:var(--muted);font-size:10px;margin-top:4px}
|
|
6
|
+
/* Match */
|
|
7
|
+
.match-result{padding:10px 0}.match-summary{font-weight:600;font-size:14px;margin-bottom:12px}.match-detail{color:var(--muted);font-size:12px;line-height:1.6}
|
|
8
|
+
/* Pipeline */
|
|
9
|
+
.pipeline-title{font-weight:600;margin-bottom:16px}.pipeline-steps{display:flex;flex-direction:column;gap:10px}.pipe-step{display:flex;gap:14px;padding:12px 14px;background:rgba(99,102,241,.04);border-left:2px solid var(--purple);border-radius:0 8px 8px 0}.pipe-step .pipe-num{font-family:Orbitron;font-size:20px;font-weight:900;color:var(--purple);min-width:36px}.pipe-step .pipe-cmd{font-weight:600;color:var(--green)}.pipe-step .pipe-args{color:var(--muted);font-size:11px}.pipe-step .pipe-desc{color:var(--muted);font-size:10px;margin-top:4px}.pipe-step .pipe-dep{font-size:9px;color:var(--orange);margin-top:4px}.confirm-bar{text-align:center;padding:14px;margin-top:16px;background:rgba(99,102,241,.08);border:1px dashed rgba(99,102,241,.2);border-radius:8px;color:var(--purple);font-size:12px}
|
|
10
|
+
.footer{text-align:center;color:var(--muted);font-size:10px;margin-top:24px;padding-top:16px;border-top:1px solid rgba(255,255,255,.04)}@keyframes cardGlow{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}.card-bg{position:absolute;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse at 25% 10%,rgba(14,165,233,.25) 0%,transparent 70%);animation:cardGlow 3s ease-in-out infinite;transform-origin:top center}@keyframes titleGlow{0%,100%{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15)}50%{text-shadow:0 0 30px rgba(14,165,233,.7),0 0 80px rgba(14,165,233,.3)}}h1,h2{text-shadow:0 0 20px rgba(14,165,233,.4),0 0 60px rgba(14,165,233,.15);animation:titleGlow 3s ease-in-out infinite}</style></head><body><div class="scanlines"></div><div class="card"><div class="card-bg"></div><div class="vline l"></div><div class="vline r"></div><h1>SPECCORE ASK</h1><div class="query">"dashboard"</div><div class="badge">🎯 意图匹配</div><div class="match-result"><div class="match-summary">✅ 推荐: dashboard</div><div class="match-detail">🎯 推荐命令: <code>speccore dashboard<br>项目仪表盘:期次状态/进度/健康度,--scope</code> global 全量视图<br><br>用法: <code>speccore dashboard</code> [--scope global|iteration] [--export html] [--health] [--lifecycle]<br><br>示例:<br> $ <code>speccore dashboard<br></code> $ <code>speccore dashboard</code> --scope global --export html</div></div><div class="footer">由 SpecCore 驱动 v8.3.148 · 2026-08-31</div></div></body></html>
|