Compare commits
72 Commits
5176d1357d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 081706f735 | |||
| 3e9f91f54b | |||
| 671db14797 | |||
| afb190003e | |||
| 72d08a3c56 | |||
| 1efd77f07a | |||
| 9fc0b4934e | |||
| d5d0fa3223 | |||
| e30a65b8b5 | |||
| f984a81f86 | |||
| 4a51fb10f7 | |||
| 9aa385db8c | |||
| fea3c05999 | |||
| f3f85a4b32 | |||
| 7ca3bbb668 | |||
| 54c416c01d | |||
| 087e477395 | |||
| 113b2757ee | |||
| 0418ce7f0b | |||
| 88a5d94d12 | |||
| ce84a5387a | |||
| ad0d1675b0 | |||
| 0596043b47 | |||
| a8d40134af | |||
| c40774199e | |||
| 1c87e24ea9 | |||
| e758f977fc | |||
| c4d2b836ca | |||
| 6bcea047db | |||
| 13d13a0f5e | |||
| 3a65c94764 | |||
| b5163d5e0f | |||
| 16bcd94027 | |||
| e561298c97 | |||
| 7e3acf80ce | |||
| 77d8f6098f | |||
| 18e50156df | |||
| bc1a427f22 | |||
| 5b9d2618ad | |||
| eece0773cb | |||
| 3e1fe5cc79 | |||
| d12a46b2a3 | |||
| c01881ade0 | |||
| 35045a9490 | |||
| ea9f12b9b1 | |||
| 2d5e055fc8 | |||
| 52530486d1 | |||
| f61b5ee17f | |||
| 93fe52750c | |||
| 051183bbe7 | |||
| 988cfcec4d | |||
| 6493e72d80 | |||
| 23052db117 | |||
| 5be0f11aac | |||
| 5d20df11e9 | |||
| b688ebd35d | |||
| 1cdd05d554 | |||
| 5ee79e5c5e | |||
| 598900650d | |||
| ac585b09b1 | |||
| 55ac776462 | |||
| 339f9aa126 | |||
| c2b11248d7 | |||
| d6ed523731 | |||
| d7029a1cc7 | |||
| 8d7ca51649 | |||
| 05185c9b21 | |||
| b416c60ae7 | |||
| c2b9242aca | |||
| 27696c70f9 | |||
| 1e7c772f68 | |||
| ca15ab2593 |
Submodule HarborForge.Backend updated: 88931d822d...a2ab541b73
Submodule HarborForge.Cli updated: b3063733a9...cd22642472
Submodule HarborForge.Frontend updated: ce07ee9021...6432255203
Submodule HarborForge.Monitor updated: dc05fa01d1...758d3d1c59
Submodule HarborForge.OpenclawPlugin updated: e7ba982128...58a800a1aa
Submodule HarborForge.Test updated: 23cad37e03...c96d012fef
77
archive/achieve/OPENCLAW_PLUGIN_DEV_PLAN.md
Normal file
77
archive/achieve/OPENCLAW_PLUGIN_DEV_PLAN.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# OpenClaw Plugin 开发计划(当前版)
|
||||||
|
|
||||||
|
**状态**: API Key 方案已落地,challenge / WebSocket 旧方案已废弃。
|
||||||
|
|
||||||
|
## 当前架构
|
||||||
|
|
||||||
|
- HarborForge Monitor Backend 提供服务器注册与遥测接收接口
|
||||||
|
- OpenClaw Gateway 加载 `harbor-forge` 插件
|
||||||
|
- 旧 sidecar (`server/telemetry.mjs`) 已移除
|
||||||
|
- 插件通过 Gateway/runtime 路径直接提供 OpenClaw 元数据
|
||||||
|
- Monitor 可选通过本地 `monitor_port` 桥接读取补充信息
|
||||||
|
|
||||||
|
## 当前后端接口
|
||||||
|
|
||||||
|
### 公开接口
|
||||||
|
- `GET /monitor/public/overview`
|
||||||
|
|
||||||
|
### 管理接口
|
||||||
|
- `GET /monitor/admin/servers`
|
||||||
|
- `POST /monitor/admin/servers`
|
||||||
|
- `DELETE /monitor/admin/servers/{id}`
|
||||||
|
- `POST /monitor/admin/servers/{id}/api-key`
|
||||||
|
- `DELETE /monitor/admin/servers/{id}/api-key`
|
||||||
|
|
||||||
|
### 插件上报接口
|
||||||
|
- `POST /monitor/server/heartbeat-v2`
|
||||||
|
- Header: `X-API-Key`
|
||||||
|
- Body:
|
||||||
|
- `identifier`
|
||||||
|
- `openclaw_version`
|
||||||
|
- `plugin_version`
|
||||||
|
- `agents`
|
||||||
|
- `cpu_pct`
|
||||||
|
- `mem_pct`
|
||||||
|
- `disk_pct`
|
||||||
|
- `swap_pct`
|
||||||
|
- `load_avg`
|
||||||
|
- `uptime_seconds`
|
||||||
|
|
||||||
|
## 数据语义
|
||||||
|
|
||||||
|
- `openclaw_version`: 远程服务器上的 OpenClaw 版本
|
||||||
|
- `plugin_version`: 远程服务器上的 `harbor-forge` 插件版本
|
||||||
|
|
||||||
|
## 已废弃内容
|
||||||
|
|
||||||
|
以下旧方案已经废弃,不再作为实现路径:
|
||||||
|
|
||||||
|
- challenge UUID
|
||||||
|
- `GET /monitor/public/server-public-key`
|
||||||
|
- `POST /monitor/admin/servers/{id}/challenge`
|
||||||
|
- `WS /monitor/server/ws`
|
||||||
|
- challenge / nonce 握手逻辑
|
||||||
|
|
||||||
|
## 前端管理页要求
|
||||||
|
|
||||||
|
Monitor 管理页应提供:
|
||||||
|
|
||||||
|
- Add Server
|
||||||
|
- Generate API Key
|
||||||
|
- Revoke API Key
|
||||||
|
- Delete Server
|
||||||
|
|
||||||
|
不再提供 `Generate Challenge`。
|
||||||
|
|
||||||
|
## 运行流程
|
||||||
|
|
||||||
|
1. 管理员在 Monitor 中注册服务器
|
||||||
|
2. 管理员为服务器生成 API Key
|
||||||
|
3. 将 API Key 写入 `~/.openclaw/openclaw.json`
|
||||||
|
4. 如需本地桥接补充信息,配置 `monitor_port`
|
||||||
|
5. 重启 OpenClaw Gateway
|
||||||
|
6. 插件直接参与遥测链路;若本地桥接可达,则额外提供 OpenClaw 补充元数据
|
||||||
|
|
||||||
|
## 备注
|
||||||
|
|
||||||
|
当前保留了对旧 challenge 数据表的**删除兼容清理**(仅为兼容老数据库中的遗留数据),但不再保留 challenge 功能入口、WebSocket 方案或 sidecar 运行时逻辑。
|
||||||
54
archive/achieve/monitor-server-connector-plan.md
Normal file
54
archive/achieve/monitor-server-connector-plan.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Monitor Server Connector Plan
|
||||||
|
|
||||||
|
## Current design
|
||||||
|
|
||||||
|
The plugin and Monitor communicate over a local bridge port (`monitor_port` / `MONITOR_PORT`).
|
||||||
|
|
||||||
|
### Data flow
|
||||||
|
|
||||||
|
1. **Monitor → Plugin** (GET): Plugin queries `GET /telemetry` on the bridge for host hardware data.
|
||||||
|
2. **Plugin → Monitor** (POST): Plugin pushes OpenClaw metadata via `POST /openclaw` to the bridge.
|
||||||
|
3. **Monitor → Backend**: Monitor heartbeats to `POST /monitor/server/heartbeat-v2` with `X-API-Key`, enriched with any available OpenClaw metadata.
|
||||||
|
|
||||||
|
### Bridge endpoints (on Monitor, 127.0.0.1:MONITOR_PORT)
|
||||||
|
|
||||||
|
| Endpoint | Method | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| `/health` | GET | Health check, returns monitor version and identifier |
|
||||||
|
| `/telemetry` | GET | Latest hardware telemetry snapshot |
|
||||||
|
| `/openclaw` | POST | Receive OpenClaw metadata from plugin |
|
||||||
|
|
||||||
|
### Plugin behavior
|
||||||
|
|
||||||
|
- On `gateway_start`, plugin begins periodic metadata push (aligned with `reportIntervalSec`).
|
||||||
|
- Initial push is delayed 2s to allow Monitor bridge startup.
|
||||||
|
- If bridge is unreachable, pushes fail silently. Plugin remains fully functional.
|
||||||
|
- On `gateway_stop`, periodic push is stopped.
|
||||||
|
|
||||||
|
## No longer used
|
||||||
|
|
||||||
|
The following design has been retired:
|
||||||
|
|
||||||
|
- challenge UUID / RSA handshake / WebSocket telemetry
|
||||||
|
- Plugin-side `server/` sidecar process
|
||||||
|
|
||||||
|
## Heartbeat payload
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"identifier": "vps.t1",
|
||||||
|
"openclaw_version": "OpenClaw 2026.3.13 (61d171a)",
|
||||||
|
"plugin_version": "0.2.0",
|
||||||
|
"agents": [],
|
||||||
|
"cpu_pct": 10.5,
|
||||||
|
"mem_pct": 52.1,
|
||||||
|
"disk_pct": 81.0,
|
||||||
|
"swap_pct": 0.0,
|
||||||
|
"load_avg": [0.12, 0.09, 0.03],
|
||||||
|
"uptime_seconds": 12345,
|
||||||
|
"nginx_installed": true,
|
||||||
|
"nginx_sites": ["default"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`openclaw_version`, `plugin_version`, and `agents` are optional enrichment from the plugin. If plugin never pushes metadata, these fields are omitted and the heartbeat contains only hardware telemetry.
|
||||||
78
archive/achieve/openclaw-monitor-plugin-plan.md
Normal file
78
archive/achieve/openclaw-monitor-plugin-plan.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# HarborForge Monitor / OpenClaw Plugin Connector Plan
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
使用 **API Key + HTTP heartbeat** 连接 HarborForge Monitor 与远程 OpenClaw 节点。
|
||||||
|
|
||||||
|
## 认证方式
|
||||||
|
|
||||||
|
- 管理员为服务器生成 API Key
|
||||||
|
- 插件通过 `X-API-Key` 调用 heartbeat 接口
|
||||||
|
- 不再使用 challenge / RSA 公钥 / WebSocket 握手
|
||||||
|
|
||||||
|
## 上报接口
|
||||||
|
|
||||||
|
`POST /monitor/server/heartbeat-v2`
|
||||||
|
|
||||||
|
### Headers
|
||||||
|
- `X-API-Key: <server-api-key>`
|
||||||
|
|
||||||
|
### Payload
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"identifier": "vps.t1",
|
||||||
|
"openclaw_version": "OpenClaw 2026.3.13 (61d171a)",
|
||||||
|
"plugin_version": "0.1.0",
|
||||||
|
"agents": [
|
||||||
|
{ "id": "agent-bot1", "name": "agent-bot1", "status": "configured" }
|
||||||
|
],
|
||||||
|
"cpu_pct": 12.3,
|
||||||
|
"mem_pct": 45.6,
|
||||||
|
"disk_pct": 78.9,
|
||||||
|
"swap_pct": 0,
|
||||||
|
"load_avg": [0.12, 0.08, 0.03],
|
||||||
|
"uptime_seconds": 12345
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 语义
|
||||||
|
|
||||||
|
- `openclaw_version`: 远程主机上的 OpenClaw 版本
|
||||||
|
- `plugin_version`: `harbor-forge` 插件版本
|
||||||
|
|
||||||
|
## 插件生命周期
|
||||||
|
|
||||||
|
- 插件注册名为 `harbor-forge`
|
||||||
|
- 不再启动独立 `server/telemetry.mjs` sidecar
|
||||||
|
- 插件直接通过 Gateway/runtime 路径暴露 OpenClaw 元数据
|
||||||
|
- 如配置了 `monitor_port`,插件还可通过本地桥接与 HarborForge.Monitor 交互
|
||||||
|
|
||||||
|
## 配置位置
|
||||||
|
|
||||||
|
`~/.openclaw/openclaw.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"entries": {
|
||||||
|
"harbor-forge": {
|
||||||
|
"enabled": true,
|
||||||
|
"config": {
|
||||||
|
"enabled": true,
|
||||||
|
"backendUrl": "http://127.0.0.1:8000",
|
||||||
|
"identifier": "vps.t1",
|
||||||
|
"apiKey": "your-api-key",
|
||||||
|
"monitor_port": 9100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 已废弃
|
||||||
|
|
||||||
|
- challenge UUID
|
||||||
|
- server public key
|
||||||
|
- WebSocket telemetry
|
||||||
|
- encrypted handshake payload
|
||||||
31
docs/BE-PR-001-rename-impact.md
Normal file
31
docs/BE-PR-001-rename-impact.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# BE-PR-001: Propose → Proposal Rename Impact Checklist
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
Unified all backend Python-level naming from `Propose` to `Proposal`. DB table and column names kept unchanged for backward compatibility (no migration needed).
|
||||||
|
|
||||||
|
## Files Changed
|
||||||
|
|
||||||
|
### New Files
|
||||||
|
- `app/models/proposal.py` — Canonical model: `Proposal`, `ProposalStatus`
|
||||||
|
- `app/api/routers/proposals.py` — Canonical router at `/projects/{id}/proposals`
|
||||||
|
|
||||||
|
### Modified Files
|
||||||
|
- `app/models/propose.py` — Now a backward-compat shim re-exporting from `proposal.py`
|
||||||
|
- `app/api/routers/proposes.py` — Now a backward-compat shim delegating to `proposals.py` (legacy `/proposes` URL still works)
|
||||||
|
- `app/schemas/schemas.py` — Renamed: `ProposalStatusEnum`, `ProposalBase`, `ProposalCreate`, `ProposalUpdate`, `ProposalResponse` (old names kept as aliases)
|
||||||
|
- `app/main.py` — Registers both `proposals_router` (canonical) and `proposes_router` (legacy compat)
|
||||||
|
- `app/init_wizard.py` — Updated comments to say "Proposal" (permission names `propose.*` kept for DB compat)
|
||||||
|
- `tests/test_propose.py` — Updated all tests to use `/proposals` URL; added legacy endpoint compat tests
|
||||||
|
|
||||||
|
## What Was Kept for Backward Compatibility
|
||||||
|
| Item | Kept As-Is | Reason |
|
||||||
|
|------|-----------|--------|
|
||||||
|
| DB table name | `proposes` | Avoid DB migration |
|
||||||
|
| DB column | `propose_code` | Avoid DB migration |
|
||||||
|
| Permission names | `propose.accept`, `propose.reject`, `propose.reopen` | Already stored in DB |
|
||||||
|
| Legacy API path | `/projects/{id}/proposes/*` | Client compat |
|
||||||
|
| Python aliases | `Propose`, `ProposeStatus`, `ProposeCreate`, etc. | Import compat |
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
- **Canonical:** `/projects/{project_id}/proposals` (new)
|
||||||
|
- **Legacy:** `/projects/{project_id}/proposes` (still works, delegates to canonical)
|
||||||
263
docs/proposal-essential-story-migration.md
Normal file
263
docs/proposal-essential-story-migration.md
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
# HarborForge — Proposal / Essential / Story Restricted 迁移说明
|
||||||
|
|
||||||
|
> 更新时间:2026-03-29
|
||||||
|
> 本文档描述 Propose → Proposal 重命名、Proposal Accept 语义变更、Essential 新增、以及 story/* restricted 的迁移细节与兼容策略。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、Propose → Proposal 命名调整
|
||||||
|
|
||||||
|
### 1.1 变更范围
|
||||||
|
|
||||||
|
| 层 | 旧命名 | 新命名 | 涉及文件 |
|
||||||
|
|---|--------|--------|---------|
|
||||||
|
| **数据库表** | `proposes` | `proposals`(新表名) | Alembic migration |
|
||||||
|
| **Model** | `Propose`, `ProposeStatus` | `Proposal`, `ProposalStatus` | `models/propose.py` → `models/proposal.py` |
|
||||||
|
| **Schema** | `ProposeCreate`, `ProposeUpdate`, `ProposeResponse`, `ProposeStatusEnum`, `ProposeBase` | `ProposalCreate`, `ProposalUpdate`, `ProposalResponse`, `ProposalStatusEnum`, `ProposalBase` | `schemas/schemas.py` |
|
||||||
|
| **Router** | `proposes.py`, 路由前缀 `/proposes` | `proposals.py`, 路由前缀 `/proposals` | `api/routers/proposes.py` → `api/routers/proposals.py` |
|
||||||
|
| **Helper 函数** | `_find_propose()`, `_serialize_propose()`, `_generate_propose_code()`, `_can_edit_propose()` | `_find_proposal()`, `_serialize_proposal()`, `_generate_proposal_code()`, `_can_edit_proposal()` | 同上 router 文件 |
|
||||||
|
| **Code 字段** | `propose_code` | `proposal_code` | Model、Schema、序列化逻辑 |
|
||||||
|
| **Activity log** | `entity_type="propose"` | `entity_type="proposal"` | `log_activity()` 调用处 |
|
||||||
|
| **权限 key** | `propose.accept`, `propose.reject`, `propose.reopen` | `proposal.accept`, `proposal.reject`, `proposal.reopen` | `check_permission()` 调用处、RBAC 数据 |
|
||||||
|
| **前端** | 页面标题、菜单、API 调用中的 `propose` 文案 | 统一为 `proposal` | 前端组件、路由、API 调用 |
|
||||||
|
| **CLI** | `hf propose`, `hf propose-create`, `hf propose-accept` 等 | `hf proposal`, `hf proposal create`, `hf proposal accept` 等 | CLI 命令注册与 help 文案 |
|
||||||
|
|
||||||
|
### 1.2 数据库迁移策略
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Alembic migration
|
||||||
|
ALTER TABLE proposes RENAME TO proposals;
|
||||||
|
ALTER TABLE proposals CHANGE propose_code proposal_code VARCHAR(64);
|
||||||
|
```
|
||||||
|
|
||||||
|
- `proposal_code` 的已有编码值(如 `HF:P00001`)不变,仅字段名变更
|
||||||
|
- 所有外键引用(如 `proposals.id`)保持不变(表内 PK 不变)
|
||||||
|
|
||||||
|
### 1.3 API 兼容策略
|
||||||
|
|
||||||
|
**方案:直接切换,不保留旧路由**
|
||||||
|
|
||||||
|
理由:
|
||||||
|
- HarborForge 目前为内部系统,无外部消费者
|
||||||
|
- CLI 和前端同步更新,不存在旧客户端兼容问题
|
||||||
|
- 保留兼容别名会增加长期维护负担
|
||||||
|
|
||||||
|
具体做法:
|
||||||
|
1. 后端路由从 `/projects/{pid}/proposes` 切换为 `/projects/{pid}/proposals`
|
||||||
|
2. 前端所有 API 调用同步更新
|
||||||
|
3. CLI 命令同步更新
|
||||||
|
4. **不保留** `/proposes` 旧路由
|
||||||
|
|
||||||
|
> 如果未来需要面向外部提供 API,应在 API 版本化层面处理兼容,而非在路由别名层面。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、Proposal Accept 语义变化
|
||||||
|
|
||||||
|
### 2.1 旧行为
|
||||||
|
|
||||||
|
```
|
||||||
|
Proposal (open) ──accept──▶ Proposal (accepted)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
单个 story/feature Task
|
||||||
|
feat_task_id 回填到 Proposal
|
||||||
|
```
|
||||||
|
|
||||||
|
- Accept 时自动创建 **1 个** `story/feature` task
|
||||||
|
- `feat_task_id` 字段记录生成的 task ID
|
||||||
|
|
||||||
|
### 2.2 新行为
|
||||||
|
|
||||||
|
```
|
||||||
|
Proposal (open)
|
||||||
|
├── Essential (feature) ──┐
|
||||||
|
├── Essential (improvement) ─┤── accept ──▶ Proposal (accepted)
|
||||||
|
└── Essential (refactor) ──┘ │
|
||||||
|
▼
|
||||||
|
story/feature Task ← from Essential(feature)
|
||||||
|
story/improvement Task ← from Essential(improvement)
|
||||||
|
story/refactor Task ← from Essential(refactor)
|
||||||
|
全部落入选定 Milestone
|
||||||
|
```
|
||||||
|
|
||||||
|
- Proposal 下维护多个 **Essential**(可落地核心条目)
|
||||||
|
- Accept 时,遍历该 Proposal 下全部 Essential
|
||||||
|
- 按 Essential.type 映射生成对应 `story/*` task:
|
||||||
|
- `feature` → `story/feature`
|
||||||
|
- `improvement` → `story/improvement`
|
||||||
|
- `refactor` → `story/refactor`
|
||||||
|
- 生成目标 Milestone 在 Accept 时明确选择(与旧行为一致)
|
||||||
|
- **批量创建在同一个数据库事务中完成**
|
||||||
|
|
||||||
|
### 2.3 Accept 前置条件变更
|
||||||
|
|
||||||
|
| 条件 | 旧 | 新 |
|
||||||
|
|------|----|----|
|
||||||
|
| 操作者权限 | `propose.accept` | `proposal.accept` |
|
||||||
|
| 目标 Milestone | 必须选择,状态 `open` | 同上 |
|
||||||
|
| Essential 数量 | 无此概念 | **必须至少 1 个 Essential**,否则 Accept 报错 |
|
||||||
|
|
||||||
|
### 2.4 Accept 返回值变更
|
||||||
|
|
||||||
|
- 旧:返回 Proposal 详情(含 `feat_task_id`)
|
||||||
|
- 新:返回 Proposal 详情 + 嵌套的 Essential 列表 + 每个 Essential 生成的 task 信息
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、story/* 改为 Restricted 的影响面
|
||||||
|
|
||||||
|
### 3.1 当前状态
|
||||||
|
|
||||||
|
后端 `tasks.py` 中已有 restricted 机制:
|
||||||
|
|
||||||
|
```python
|
||||||
|
RESTRICTED_TYPE_SUBTYPES = {
|
||||||
|
("story", "feature"),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
目前仅 `story/feature` 是 restricted。
|
||||||
|
|
||||||
|
### 3.2 变更内容
|
||||||
|
|
||||||
|
将 **所有 `story/*` 组合** 标记为 restricted:
|
||||||
|
|
||||||
|
```python
|
||||||
|
RESTRICTED_TYPE_SUBTYPES = {
|
||||||
|
("story", "feature"),
|
||||||
|
("story", "improvement"),
|
||||||
|
("story", "refactor"),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 影响面
|
||||||
|
|
||||||
|
| 入口 | 影响 | 处理 |
|
||||||
|
|------|------|------|
|
||||||
|
| **通用 Task Create API** (`POST /projects/{pid}/milestones/{mid}/tasks`) | 无法创建任何 `story/*` task | 已有 `_validate_task_type_subtype()` 校验,扩展 restricted 集合即可 |
|
||||||
|
| **Proposal Accept** | 内部受控入口,`allow_restricted=True` | 保留,唯一合法创建 `story/*` 的途径 |
|
||||||
|
| **前端 Task 创建表单** | `story` 类型从选择器中移除或标为不可选 | 前端调整 |
|
||||||
|
| **CLI `hf task create`** | 阻止 `--type story` | CLI 侧校验或依赖后端 403 |
|
||||||
|
| **CSV 导入**(如有) | 阻止 `story/*` 行 | 导入逻辑需加校验 |
|
||||||
|
| **Milestone 下 Task Create** (`milestones.py` 路由) | 已有 `story/feature` 限制逻辑 | 扩展为全部 `story/*` |
|
||||||
|
|
||||||
|
### 3.4 已有数据兼容
|
||||||
|
|
||||||
|
- 历史上通过旧 Accept 创建的 `story/feature` task **保持不变**
|
||||||
|
- 不需要迁移或修改已有 story task
|
||||||
|
- restricted 仅影响 **新建**,不影响已有记录的读取/更新/状态流转
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、旧数据与旧接口兼容策略
|
||||||
|
|
||||||
|
### 4.1 `feat_task_id` 字段
|
||||||
|
|
||||||
|
| 处理方式 | 说明 |
|
||||||
|
|---------|------|
|
||||||
|
| **保留字段,标记为 deprecated** | 数据库列保留,避免破坏已有数据 |
|
||||||
|
| **只读** | API 继续返回 `feat_task_id`(已有 Proposal 的值不丢失) |
|
||||||
|
| **新 Proposal 不再写入** | 新的 Accept 流程不再设置 `feat_task_id` |
|
||||||
|
| **新增追踪方式** | 通过 Essential → Task 的关联关系(`essential_id` 或关联表)替代 |
|
||||||
|
| **未来清理** | 等所有旧 Proposal 迁移完毕后,可选择 DROP 该列 |
|
||||||
|
|
||||||
|
### 4.2 旧 Proposal 数据读取
|
||||||
|
|
||||||
|
- 旧的 `accepted` 状态 Proposal 仍有 `feat_task_id`,前端继续支持 "View Generated Task" 跳转
|
||||||
|
- 旧 Proposal 没有 Essential,详情页 Essential 区域显示空列表
|
||||||
|
- 不需要为旧 Proposal 补建 Essential 记录
|
||||||
|
|
||||||
|
### 4.3 Proposal Code 格式
|
||||||
|
|
||||||
|
- 已有编码如 `HF:P00001` 保持不变
|
||||||
|
- 新 Proposal 继续使用相同格式
|
||||||
|
- 字段名从 `propose_code` 变为 `proposal_code`,但值的格式不变
|
||||||
|
|
||||||
|
### 4.4 权限 Key 迁移
|
||||||
|
|
||||||
|
| 旧 | 新 | 迁移方式 |
|
||||||
|
|----|----|----|
|
||||||
|
| `propose.accept` | `proposal.accept` | 数据库中更新 RBAC permission 记录 |
|
||||||
|
| `propose.reject` | `proposal.reject` | 同上 |
|
||||||
|
| `propose.reopen` | `proposal.reopen` | 同上 |
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- RBAC permission key migration
|
||||||
|
UPDATE permissions SET key = REPLACE(key, 'propose.', 'proposal.') WHERE key LIKE 'propose.%';
|
||||||
|
```
|
||||||
|
|
||||||
|
> 如果权限 key 存储在 code 中而非数据库,则只需修改代码常量。
|
||||||
|
|
||||||
|
### 4.5 Activity Log 兼容
|
||||||
|
|
||||||
|
- 旧 activity log 中 `entity_type="propose"` 的记录保留不动
|
||||||
|
- 前端展示时做兼容映射:`propose` → 显示为 "Proposal"
|
||||||
|
- 新 activity log 统一使用 `entity_type="proposal"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Essential 新增概要
|
||||||
|
|
||||||
|
### 5.1 数据模型
|
||||||
|
|
||||||
|
```
|
||||||
|
Essential
|
||||||
|
├── id (PK)
|
||||||
|
├── essential_code (UNIQUE) — 格式参考 ProjectCode / TaskCode
|
||||||
|
├── proposal_id (FK → proposals.id)
|
||||||
|
├── type (Enum: feature, improvement, refactor)
|
||||||
|
├── title
|
||||||
|
├── description (nullable)
|
||||||
|
├── created_by_id (FK → users.id, nullable)
|
||||||
|
├── created_at
|
||||||
|
└── updated_at
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 EssentialCode 编码
|
||||||
|
|
||||||
|
- 格式:`{proposal_code}:E{i:05x}`
|
||||||
|
- 示例:`HF:P00001:E00001`
|
||||||
|
- 每个 Proposal 独立递增
|
||||||
|
|
||||||
|
### 5.3 Essential 生命周期
|
||||||
|
|
||||||
|
1. Proposal `open` 状态下可创建/编辑/删除 Essential
|
||||||
|
2. Proposal Accept 时,全部 Essential 用于生成 `story/*` task
|
||||||
|
3. Proposal 进入 `accepted`/`rejected` 后,Essential 不可修改
|
||||||
|
|
||||||
|
### 5.4 API 端点
|
||||||
|
|
||||||
|
| 操作 | 方法 | 路径 |
|
||||||
|
|------|------|------|
|
||||||
|
| 列出 | GET | `/projects/{pid}/proposals/{proposal_id}/essentials` |
|
||||||
|
| 创建 | POST | `/projects/{pid}/proposals/{proposal_id}/essentials` |
|
||||||
|
| 详情 | GET | `/projects/{pid}/proposals/{proposal_id}/essentials/{id}` |
|
||||||
|
| 编辑 | PATCH | `/projects/{pid}/proposals/{proposal_id}/essentials/{id}` |
|
||||||
|
| 删除 | DELETE | `/projects/{pid}/proposals/{proposal_id}/essentials/{id}` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、迁移执行顺序
|
||||||
|
|
||||||
|
推荐按以下顺序执行,确保每一步可独立验证:
|
||||||
|
|
||||||
|
1. **后端 Model/Schema 重命名** — `Propose` → `Proposal`(BE-PR-001, BE-PR-002)
|
||||||
|
2. **数据库 migration** — 表名、字段名变更
|
||||||
|
3. **新增 Essential Model/Schema** — (BE-PR-003, BE-PR-004, BE-PR-005)
|
||||||
|
4. **新增 Essential CRUD API** — (BE-PR-006)
|
||||||
|
5. **重构 Accept 逻辑** — (BE-PR-007, BE-PR-008)
|
||||||
|
6. **收紧 story restricted** — (BE-PR-009)
|
||||||
|
7. **清理 feat_task_id** — (BE-PR-010)
|
||||||
|
8. **前端同步更新** — (FE-PR-001 ~ FE-PR-005)
|
||||||
|
9. **CLI 同步更新** — (CLI-PR-001 ~ CLI-PR-004)
|
||||||
|
10. **测试补全** — (BE-PR-011, TEST-BE-PR-001, TEST-FE-PR-001, TEST-CLI-PR-001)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、风险与注意事项
|
||||||
|
|
||||||
|
1. **表重命名的 downtime** — `ALTER TABLE RENAME` 在 MySQL 中是瞬时操作,但需确保无长事务锁表
|
||||||
|
2. **权限 key 更新** — 如果有缓存层,需要在迁移后清理缓存
|
||||||
|
3. **前后端同步部署** — 建议同时部署前后端,避免前端调旧路由 404
|
||||||
|
4. **回滚方案** — 如需回滚,反向执行表重命名和字段重命名即可;Essential 表作为新增表,回滚时 DROP 即可
|
||||||
106
docs/wave-2026-03-scope.md
Normal file
106
docs/wave-2026-03-scope.md
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# 本波开发范围说明
|
||||||
|
|
||||||
|
> Date: 2026-03-29
|
||||||
|
> Wave: 2026-03 (Calendar & Proposal 重构)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、两条功能线概述
|
||||||
|
|
||||||
|
本波开发包含两条独立的功能线:
|
||||||
|
|
||||||
|
### 功能线 1:Calendar 日程系统(独立功能线)
|
||||||
|
|
||||||
|
全新功能模块,为 HarborForge 增加日程调度能力。
|
||||||
|
|
||||||
|
**包含内容:**
|
||||||
|
- `TimeSlot` 日程槽模型与 CRUD API
|
||||||
|
- `SchedulePlan` 周期性计划模型与管理 API
|
||||||
|
- Agent 状态管理(Idle / Busy / OnCall / Exhausted / Offline)
|
||||||
|
- `MinimumWorkload` 最小工作量配置
|
||||||
|
- Plan 虚拟 slot 标识与物化策略
|
||||||
|
- Overlap 校验与 Workload warning 规则
|
||||||
|
- 不可变过去 slot 规则
|
||||||
|
- Agent 心跳唤醒机制与 Exhausted 恢复
|
||||||
|
- 前端 Calendar 页面
|
||||||
|
- CLI `hf calendar` 命令组
|
||||||
|
- OpenClaw 插件 Calendar 心跳联动
|
||||||
|
|
||||||
|
### 功能线 2:Proposal / Essential / Story restricted(项目结构调整线)
|
||||||
|
|
||||||
|
对已有的 Propose 流程进行重构和增强。
|
||||||
|
|
||||||
|
**包含内容:**
|
||||||
|
- `Propose` → `Proposal` 统一重命名
|
||||||
|
- 新增 `Essential` 概念及数据模型
|
||||||
|
- `EssentialCode` 编码规则
|
||||||
|
- Proposal Accept 语义变更:遍历 Essential 批量生成 story task
|
||||||
|
- `story/*` 整个大类设为 restricted,仅允许通过 Proposal Accept 创建
|
||||||
|
- 清理旧 `feat_task_id` 语义
|
||||||
|
- 前端 Proposal 详情页 Essential 管理
|
||||||
|
- CLI Proposal Essential 子命令
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、两条线的交叉点
|
||||||
|
|
||||||
|
两条功能线设计上相互独立,交叉点仅限于以下层面:
|
||||||
|
|
||||||
|
| 交叉点 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| `event_data` | Calendar 的 TimeSlot 通过 `event_data` JSON 字段引用 Task/Essential code,但不直接依赖 Proposal/Essential 的数据模型 |
|
||||||
|
| Agent 调度引用层 | Calendar 心跳唤醒 Agent 执行任务时,任务可能是 story task(由 Proposal Accept 生成),但 Calendar 只关心 task code,不关心其来源 |
|
||||||
|
|
||||||
|
**关键原则:**
|
||||||
|
- Calendar 不直接 FK 到 Essential 或 Proposal 表
|
||||||
|
- Proposal/Essential 不直接 FK 到 TimeSlot 或 SchedulePlan 表
|
||||||
|
- 两者通过 code 引用(字符串)松耦合
|
||||||
|
- 可以独立开发、独立测试、独立部署
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、本波必须完成 vs 仅设计保留
|
||||||
|
|
||||||
|
### ✅ 必须本波完成
|
||||||
|
|
||||||
|
#### Calendar 线
|
||||||
|
|
||||||
|
| 范围 | 任务 ID 区间 | 说明 |
|
||||||
|
|------|-------------|------|
|
||||||
|
| 后端基础模型 | BE-CAL-001 ~ BE-CAL-008 | TimeSlot、SchedulePlan、Agent 扩展、MinimumWorkload、物化策略、overlap/warning/不可变规则 |
|
||||||
|
| 后端 API | BE-CAL-API-001 ~ BE-CAL-API-007 | 日程 CRUD、计划 CRUD、date-list |
|
||||||
|
| 后端 Agent 协作 | BE-AGT-001 ~ BE-AGT-004 | 心跳查询、状态流转、多 slot 竞争、Exhausted 恢复 |
|
||||||
|
| 前端 | FE-CAL-001 ~ FE-CAL-005 | 页面骨架、slot 列表、计划列表、CRUD 交互、状态提示 |
|
||||||
|
| CLI | CLI-CAL-001 ~ CLI-CAL-010 | `hf calendar` 全部子命令 |
|
||||||
|
| 插件 | PLG-CAL-001 ~ PLG-CAL-004 | 心跳格式、唤醒处理、Deferred 分支、ScheduledGatewayRestart |
|
||||||
|
|
||||||
|
#### Proposal 线
|
||||||
|
|
||||||
|
| 范围 | 任务 ID 区间 | 说明 |
|
||||||
|
|------|-------------|------|
|
||||||
|
| 后端 | BE-PR-001 ~ BE-PR-011 | 重命名、Essential 模型/schema/API、Accept 重构、story restricted、测试 |
|
||||||
|
| 前端 | FE-PR-001 ~ FE-PR-005 | 重命名、Essential 列表/表单、Accept milestone 选择、story 限制 |
|
||||||
|
| CLI | CLI-PR-001 ~ CLI-PR-004 | 重命名、Essential 命令、Accept 更新、story 限制 |
|
||||||
|
|
||||||
|
#### 文档与测试
|
||||||
|
|
||||||
|
| 范围 | 任务 ID 区间 | 说明 |
|
||||||
|
|------|-------------|------|
|
||||||
|
| 文档 | DOC-001 ~ DOC-003 | 范围说明、迁移说明、验收清单 |
|
||||||
|
| 测试 | TEST-* | 各子模块测试补充 |
|
||||||
|
|
||||||
|
### 📐 仅设计保留(不在本波实现)
|
||||||
|
|
||||||
|
| 内容 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| Entertainment 事件子类型 | `event_data` 中 Entertainment 的具体结构待设计 |
|
||||||
|
| 用户级时区支持 | 本波统一使用服务器时区 |
|
||||||
|
| 前端日程表详细 UI 设计 | 本波实现基础功能骨架,精细 UI 留后续迭代 |
|
||||||
|
| Agent 唤醒的提示词模板 | 本波实现唤醒机制,提示词模板留后续打磨 |
|
||||||
|
| Proposal/Essential 数据迁移工具 | 旧数据兼容读取即可,自动化迁移工具留后续 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、Bug Fix(附带修复)
|
||||||
|
|
||||||
|
- **acc-mgr 密码修改限制**:后端禁止修改 acc-mgr 用户密码;前端隐藏修改密码入口
|
||||||
169
plans/CALENDAR_ACCEPTANCE_CHECKLIST.md
Normal file
169
plans/CALENDAR_ACCEPTANCE_CHECKLIST.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
# Calendar 验收清单
|
||||||
|
|
||||||
|
> 基于 `NEXT_WAVE_DEV_DIRECTION.md` 设计文档整理
|
||||||
|
> Date: 2026-03-29
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、后端验收项 (Backend)
|
||||||
|
|
||||||
|
### 1.1 数据模型
|
||||||
|
|
||||||
|
- [ ] `TimeSlot` 模型已创建,字段完整(slot_id, user_id, date, slot_type, estimated_duration, scheduled_at, started_at, attended, actual_duration, event_type, event_data, priority, status, plan_id, created_at, updated_at)
|
||||||
|
- [ ] `SchedulePlan` 模型已创建,字段完整(id, user_id, slot_type, estimated_duration, event_type, event_data, at_time, on_day, on_week, on_month, created_at, updated_at)
|
||||||
|
- [ ] Agent 表已扩展字段:status, last_heartbeat, exhausted_at, recovery_at, exhaust_reason
|
||||||
|
- [ ] 枚举类型已定义:SlotType (Work, OnCall, Entertainment, System)、SlotStatus (NotStarted, Ongoing, Deferred, Skipped, Paused, Finished, Aborted)、EventType (Job, Entertainment, SystemEvent)、AgentStatus (Idle, OnCall, Busy, Exhausted, Offline)、ExhaustReason (RateLimit, Billing)
|
||||||
|
- [ ] SchedulePlan 周期参数层级约束已实现(on_month 需 on_week,on_week 需 on_day,at 始终必填)
|
||||||
|
- [ ] MinimumWorkload 存储方案已实现(用户级配置读写)
|
||||||
|
|
||||||
|
### 1.2 Slot ID 策略与物化
|
||||||
|
|
||||||
|
- [ ] 已物化 slot 使用数据库自增 ID
|
||||||
|
- [ ] Plan 虚拟 slot 使用 `plan-{plan_id}-{date}` 标识
|
||||||
|
- [ ] 虚拟 slot 被 edit/cancel 时物化到数据库,断开 plan 关联
|
||||||
|
- [ ] Plan 不预展开,只存规则
|
||||||
|
|
||||||
|
### 1.3 验证规则
|
||||||
|
|
||||||
|
- [ ] Overlap 检测:同日时间重叠 → 拒绝并报错
|
||||||
|
- [ ] Overlap 检测区分 create 与 edit 场景
|
||||||
|
- [ ] MinimumWorkload warning:不满足时返回 warning 但允许提交
|
||||||
|
- [ ] Warning 数据结构统一定义
|
||||||
|
- [ ] 计算 daily / weekly / monthly / yearly 工作量
|
||||||
|
|
||||||
|
### 1.4 不可变性规则
|
||||||
|
|
||||||
|
- [ ] 禁止 edit 过去的 slot
|
||||||
|
- [ ] 禁止 cancel 过去的 slot
|
||||||
|
- [ ] plan-edit / plan-cancel 不追溯过去已物化 slot
|
||||||
|
|
||||||
|
### 1.5 Calendar API
|
||||||
|
|
||||||
|
- [ ] `POST` 单次日程创建:支持 slot_type, scheduled_at, estimated_duration, job/system/event_data,接入 overlap 与 workload warning
|
||||||
|
- [ ] `GET` 某日 Calendar 查询:返回真实 slot + 合成当日 plan 虚拟 slot,统一排序
|
||||||
|
- [ ] `PATCH/PUT` Calendar 编辑:支持真实 slot 编辑 + 虚拟 slot 编辑并触发物化
|
||||||
|
- [ ] `DELETE/POST` Calendar 取消:支持真实 slot cancel + 虚拟 slot cancel 并触发物化,状态字段更新
|
||||||
|
- [ ] `POST` plan-schedule:创建周期性计划
|
||||||
|
- [ ] `GET` plan-list:列出所有计划
|
||||||
|
- [ ] `PATCH/PUT` plan-edit:编辑计划,不追溯过去已物化数据
|
||||||
|
- [ ] `POST/DELETE` plan-cancel:取消计划,不追溯过去已物化数据
|
||||||
|
- [ ] `GET` date-list:仅列出有已物化未来 slot 的日期,排除纯 plan 未物化日期
|
||||||
|
|
||||||
|
### 1.6 Agent / 心跳协作
|
||||||
|
|
||||||
|
- [ ] 心跳查询服务:筛选当天 NotStarted / Deferred 且 scheduled_at 已过的 slot,按优先级排序
|
||||||
|
- [ ] Agent 状态流转:Idle ↔ Busy/OnCall、超时→Offline、API错误→Exhausted
|
||||||
|
- [ ] 多 slot 竞争:选最高 priority 执行,其余 Deferred,Deferred slot priority += 1
|
||||||
|
- [ ] Exhausted 恢复时间解析:解析 retry-after / reset in / resets at,失败默认 5 小时,到期恢复 Idle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、前端验收项 (Frontend)
|
||||||
|
|
||||||
|
### 2.1 页面骨架
|
||||||
|
|
||||||
|
- [ ] Calendar 路由入口已添加
|
||||||
|
- [ ] 侧边栏 Calendar 入口已添加
|
||||||
|
- [ ] Calendar 基础页面布局完成
|
||||||
|
|
||||||
|
### 2.2 日程展示
|
||||||
|
|
||||||
|
- [ ] 某日 slot 列表展示(时间轴或列表视图)
|
||||||
|
- [ ] 区分真实 slot 与 plan 虚拟 slot(视觉区分)
|
||||||
|
- [ ] 展示 status / type / duration / priority 等核心字段
|
||||||
|
|
||||||
|
### 2.3 计划展示
|
||||||
|
|
||||||
|
- [ ] 计划列表展示:规则、周期参数
|
||||||
|
- [ ] 支持从计划列表跳转编辑
|
||||||
|
|
||||||
|
### 2.4 日程操作交互
|
||||||
|
|
||||||
|
- [ ] 新建 slot 表单(含 slot_type, scheduled_at, estimated_duration, event_data 等)
|
||||||
|
- [ ] 编辑 slot 表单
|
||||||
|
- [ ] Cancel 操作确认弹窗
|
||||||
|
- [ ] 展示后端返回的 warning(workload 不足等)
|
||||||
|
|
||||||
|
### 2.5 状态提示
|
||||||
|
|
||||||
|
- [ ] Deferred 状态提示
|
||||||
|
- [ ] Overlap 报错展示
|
||||||
|
- [ ] Workload warning 展示
|
||||||
|
- [ ] Exhausted 状态展示(含预计恢复时间)
|
||||||
|
|
||||||
|
### 2.6 权限
|
||||||
|
|
||||||
|
- [ ] 普通用户仅查看/调整自己的日程表
|
||||||
|
- [ ] Admin 可查看/调整所有用户的日程表
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、CLI 验收项 (CLI)
|
||||||
|
|
||||||
|
### 3.1 命令组
|
||||||
|
|
||||||
|
- [ ] `hf calendar` 命令组已注册,help 正常输出
|
||||||
|
|
||||||
|
### 3.2 日程操作命令
|
||||||
|
|
||||||
|
- [ ] `hf calendar schedule <slot-type> <scheduled-at> <estimated-duration> [--job <code>] [--date <yyyy-mm-dd>]` 正常工作
|
||||||
|
- [ ] `hf calendar show [--date <yyyy-mm-dd>]` 正常展示当日日程(真实 + 虚拟 slot 合并)
|
||||||
|
- [ ] `hf calendar edit [--date] <slot-id> [--slot-type] [--estimated-duration] [--job] [--scheduled-at]` 正常工作
|
||||||
|
- [ ] `hf calendar cancel [--date] <slot-id>` 正常工作
|
||||||
|
- [ ] `hf calendar date-list` 列出有已物化日程的未来日期
|
||||||
|
|
||||||
|
### 3.3 计划操作命令
|
||||||
|
|
||||||
|
- [ ] `hf calendar plan-schedule <slot-type> <estimated-duration> --at <HH:mm> [--on-day] [--on-week] [--on-month]` 正常工作
|
||||||
|
- [ ] `hf calendar plan-list` 列出所有计划
|
||||||
|
- [ ] `hf calendar plan-edit <plan-id> [options]` 正常工作
|
||||||
|
- [ ] `hf calendar plan-cancel <plan-id>` 正常工作
|
||||||
|
|
||||||
|
### 3.4 输出格式
|
||||||
|
|
||||||
|
- [ ] 所有命令支持 JSON 输出(`--json` 或类似选项)
|
||||||
|
- [ ] 错误信息(overlap 等)清晰明确
|
||||||
|
- [ ] Warning 信息(workload 不足等)正常展示
|
||||||
|
|
||||||
|
### 3.5 用户创建扩展
|
||||||
|
|
||||||
|
- [ ] `hf user create` 支持 `--agent-id` + `--claw-identifier` 参数
|
||||||
|
- [ ] 两参数必须同时出现或同时不出现
|
||||||
|
- [ ] pcexec 模式下自动从环境变量 / openclaw config 获取
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、插件联动验收项 (OpenclawPlugin)
|
||||||
|
|
||||||
|
### 4.1 心跳请求
|
||||||
|
|
||||||
|
- [ ] 插件每分钟向 HarborForge 发送心跳
|
||||||
|
- [ ] 心跳请求正确传递 claw_identifier 和 agent_id
|
||||||
|
- [ ] 正确接收返回的 slot 列表
|
||||||
|
|
||||||
|
### 4.2 唤醒逻辑
|
||||||
|
|
||||||
|
- [ ] Agent Idle 时:唤醒 agent,透传任务上下文,更新 attended/started_at/status
|
||||||
|
- [ ] Agent 非 Idle 时:上报 Deferred
|
||||||
|
- [ ] 多 slot 竞争时正确选择最高 priority
|
||||||
|
|
||||||
|
### 4.3 状态管理
|
||||||
|
|
||||||
|
- [ ] 超过 2 分钟无心跳 → Agent 标记 Offline
|
||||||
|
- [ ] API rate-limit / billing 错误 → Agent 标记 Exhausted
|
||||||
|
- [ ] Exhausted 恢复计时器到期 → Agent 恢复 Idle
|
||||||
|
|
||||||
|
### 4.4 ScheduledGatewayRestart 处理
|
||||||
|
|
||||||
|
- [ ] 收到 ScheduledGatewayRestart 事件后持久化状态
|
||||||
|
- [ ] 发送最终心跳
|
||||||
|
- [ ] 暂停定时任务
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、跨模块集成验收
|
||||||
|
|
||||||
|
- [ ] 完整流程:创建 plan → 心跳触发物化 → Agent 被唤醒执行 → slot 状态更新为 Finished
|
||||||
|
- [ ] 完整流程:schedule 单次日程 → CLI 查看 → 前端查看 → Agent 执行
|
||||||
|
- [ ] Overlap / Warning 全链路:后端检测 → CLI 展示 → 前端展示
|
||||||
|
- [ ] Exhausted 全链路:Agent 报错 → 后端标记 Exhausted → 前端展示 → 恢复后自动 Idle
|
||||||
382
plans/NEXT_WAVE_DEV_DIRECTION.md
Normal file
382
plans/NEXT_WAVE_DEV_DIRECTION.md
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
# HarborForge Calendar System — Design Document
|
||||||
|
|
||||||
|
> Date: 2026-03-22
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
为 HarborForge 新增日程表(Calendar)系统,支持 Agent/人类用户的任务调度、周期性计划、以及通过 OpenClaw 插件心跳自动唤醒 Agent 执行日程。
|
||||||
|
|
||||||
|
同时记录一项项目结构调整:
|
||||||
|
- Propose 改名为 Proposal
|
||||||
|
- Proposal Accept 不再生成单个 Feature Task
|
||||||
|
- 改为在 Proposal 下维护多个 Essential;Accept 时将该 Proposal 下所有 Essential 按类型生成对应的 story task,并落到 Proposal 选择的 Milestone
|
||||||
|
- story 整个大类改为 restricted,只允许通过 Proposal Accept 创建
|
||||||
|
- Essential 拥有独立的 EssentialCode,编码风格参考 ProjectCode / TaskCode 等既有结构
|
||||||
|
|
||||||
|
同时包含一个 bug fix:acc-mgr 用户密码不可修改,前端隐藏修改密码入口。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、数据模型
|
||||||
|
|
||||||
|
### 1.1 TimeSlot(日程槽)
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| slot_id | int (PK) | 已物化 slot 的数据库 ID |
|
||||||
|
| user_id | FK -> users.id | 所属用户 |
|
||||||
|
| date | date | 日期 |
|
||||||
|
| slot_type | Enum(Work, OnCall, Entertainment, System) | 槽类型 |
|
||||||
|
| estimated_duration | int (1-50) | 预估时长(分钟),设计上限 50 分钟,超过需拆分 |
|
||||||
|
| scheduled_at | time (00:00-23:00) | 计划开始时间 |
|
||||||
|
| started_at | time, nullable | 实际开始时间 |
|
||||||
|
| attended | bool, default false | 是否已出席 |
|
||||||
|
| actual_duration | int (0-65535), nullable | 实际时长(分钟),无上限 |
|
||||||
|
| event_type | Enum(Job, Entertainment, SystemEvent), nullable | 事件类型 |
|
||||||
|
| event_data | JSON, nullable | 事件详情(见下方 Event 子类型) |
|
||||||
|
| priority | int (0-99) | 优先级 |
|
||||||
|
| status | Enum(NotStarted, Ongoing, Deferred, Skipped, Paused, Finished, Aborted) | 状态 |
|
||||||
|
| plan_id | FK -> schedule_plans.id, nullable | 来源计划(物化自 plan 时填入,被 edit/cancel 后置 NULL) |
|
||||||
|
| created_at | datetime | 创建时间 |
|
||||||
|
| updated_at | datetime | 更新时间 |
|
||||||
|
|
||||||
|
### 1.2 Event 子类型(存储在 event_data JSON 中)
|
||||||
|
|
||||||
|
**Job:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "Task|Support|Meeting|Essential",
|
||||||
|
"code": "TASK-42",
|
||||||
|
"working_sessions": ["session-id-1", "session-id-2"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**SystemEvent:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"event": "ScheduleToday|SummaryToday|ScheduledGatewayRestart"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `ScheduleToday` — 每日日程规划
|
||||||
|
- `SummaryToday` — 每日总结
|
||||||
|
- `ScheduledGatewayRestart` — OpenClaw 网关计划重启前触发;插件收到后应持久化状态、发送最终心跳、暂停定时任务
|
||||||
|
|
||||||
|
**Entertainment:**
|
||||||
|
```
|
||||||
|
待设计
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 SchedulePlan(周期性计划)
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| id | int (PK) | plan-id |
|
||||||
|
| user_id | FK -> users.id | 所属用户 |
|
||||||
|
| slot_type | Enum(Work, OnCall, Entertainment, System) | 槽类型 |
|
||||||
|
| estimated_duration | int (1-50) | 预估时长 |
|
||||||
|
| event_type | Enum(Job, Entertainment, SystemEvent), nullable | 事件类型 |
|
||||||
|
| event_data | JSON, nullable | 事件详情 |
|
||||||
|
| at_time | time | 每天的计划时间 (--at HH:mm) |
|
||||||
|
| on_day | Enum(Sun, Mon, Tue, Wed, Thu, Fri, Sat), nullable | 星期几 (--on-day) |
|
||||||
|
| on_week | int (1-4), nullable | 第几周 (--on-week) |
|
||||||
|
| on_month | Enum(Jan-Dec), nullable | 月份 (--on-month) |
|
||||||
|
| created_at | datetime | 创建时间 |
|
||||||
|
| updated_at | datetime | 更新时间 |
|
||||||
|
|
||||||
|
**周期参数层级约束:**
|
||||||
|
- 使用 `--on-month` 则 `--on-week` 必须也用
|
||||||
|
- 使用 `--on-week` 则 `--on-day` 必须也用
|
||||||
|
- `--at` 始终必填
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
- `--at 09:00 --on-day Sun --on-week 1 --on-month Jan` → 每年一月第一周周日 09:00
|
||||||
|
- `--at 09:00 --on-day Sun --on-week 1` → 每月第一周周日 09:00
|
||||||
|
- `--at 09:00 --on-day Sun` → 每周日 09:00
|
||||||
|
- `--at 09:00` → 每天 09:00
|
||||||
|
|
||||||
|
### 1.4 Agent 表
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| id | int (PK) | |
|
||||||
|
| user_id | FK -> users.id, UNIQUE | 关联用户 |
|
||||||
|
| agent_id | VARCHAR, UNIQUE | OpenClaw agent name ($AGENT_ID) |
|
||||||
|
| claw_identifier | VARCHAR | OpenClaw 实例 identifier(与 Monitor 碰巧一致,无 FK) |
|
||||||
|
| status | Enum(Idle, OnCall, Busy, Exhausted, Offline), default Idle | Agent 当前状态 |
|
||||||
|
| last_heartbeat | datetime, nullable | 最后心跳时间 |
|
||||||
|
| created_at | datetime | 创建时间 |
|
||||||
|
|
||||||
|
### 1.5 MinimumWorkload(最小工作量配置)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"daily": { "work": 0, "on_call": 0, "entertainment": 0 },
|
||||||
|
"weekly": { "work": 0, "on_call": 0, "entertainment": 0 },
|
||||||
|
"monthly": { "work": 0, "on_call": 0, "entertainment": 0 },
|
||||||
|
"yearly": { "work": 0, "on_call": 0, "entertainment": 0 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
值为分钟数 (0-65535)。存储方式待定(可作为用户级配置存 JSON 字段或独立表)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、Slot ID 策略
|
||||||
|
|
||||||
|
- **已物化的 slot**:使用数据库自增 ID
|
||||||
|
- **Plan 虚拟 slot**(未物化):使用 `plan-{plan_id}-{date}` 格式
|
||||||
|
- 当虚拟 slot 被 `edit` 或 `cancel` 时,物化到数据库,获得真实 ID,同时该日期该 plan 不再生成虚拟 slot
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、存储与缓存策略
|
||||||
|
|
||||||
|
### 3.1 Plan 不预展开
|
||||||
|
|
||||||
|
Plan 只存规则,不为每一天生成数据行。
|
||||||
|
|
||||||
|
### 3.2 物化时机
|
||||||
|
|
||||||
|
以下情况写入 time_slots 表:
|
||||||
|
1. `hf calendar schedule` 手动创建
|
||||||
|
2. Plan 的虚拟 slot 被 `edit` 或 `cancel`(物化后断开 plan 关联)
|
||||||
|
3. 每天预计算:服务器每日将当天所有 plan 匹配的 slot 物化到缓存/数据库
|
||||||
|
|
||||||
|
### 3.3 当日缓存
|
||||||
|
|
||||||
|
- 每天(凌晨或首次心跳时)预计算当天所有 plan → 物化为当日 slot 缓存
|
||||||
|
- 当天新增 `schedule` / `plan-schedule` 影响当天时,同步更新缓存
|
||||||
|
|
||||||
|
### 3.4 不可变性
|
||||||
|
|
||||||
|
- `cancel` / `edit` 不能操作过去的 slot
|
||||||
|
- `plan-cancel` / `plan-edit` 不追溯过去已物化的 slot
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、时区
|
||||||
|
|
||||||
|
统一使用 HarborForge 服务器时区,不做用户级时区。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、验证规则
|
||||||
|
|
||||||
|
`schedule` / `plan-schedule` 提交时验证:
|
||||||
|
1. **Overlap 检测**:与同日已有 slot 时间重叠 → **拒绝,报错**
|
||||||
|
2. **最小工作量检查**:不满足 MinimumWorkload 配置 → **警告,但允许提交**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、Agent 唤醒机制
|
||||||
|
|
||||||
|
### 6.1 心跳流程
|
||||||
|
|
||||||
|
1. 插件每分钟向 HarborForge 服务器发送心跳
|
||||||
|
2. 服务器返回该插件(claw_identifier)对应所有 Agent 当前需要执行的日程
|
||||||
|
- 筛选条件:当天 slot,status 为 NotStarted 或 Deferred,scheduled_at 已过
|
||||||
|
3. 插件检查 Agent 状态
|
||||||
|
|
||||||
|
### 6.2 唤醒逻辑
|
||||||
|
|
||||||
|
**Agent 状态为 Idle:**
|
||||||
|
- 唤醒 Agent,提供提示词开始工作
|
||||||
|
- 向服务器设置 Agent status = Busy 或 OnCall(取决于 slot_type)
|
||||||
|
- 设置 slot: attended = true, started_at = now, status = Ongoing
|
||||||
|
|
||||||
|
**Agent 状态非 Idle:**
|
||||||
|
- 设置 slot status = Deferred
|
||||||
|
|
||||||
|
### 6.3 多 Slot 竞争
|
||||||
|
|
||||||
|
- 选 priority 最高的执行,其余 Deferred 且 priority += 1
|
||||||
|
- 通知 Agent 当前任务完成后重新规划所有 Deferred + NotStarted 的 slot
|
||||||
|
|
||||||
|
### 6.4 状态转移
|
||||||
|
|
||||||
|
| 触发条件 | Agent Status 变化 |
|
||||||
|
|---------|-----------------|
|
||||||
|
| 超过 2 分钟无心跳 | → Offline |
|
||||||
|
| 无待执行日程 | → Idle |
|
||||||
|
| 被 TimeSlot 唤醒 | → Busy / OnCall |
|
||||||
|
| 完成 TimeSlot | → Idle |
|
||||||
|
| API rate-limit 或 billing 错误 | → Exhausted |
|
||||||
|
| Exhausted 恢复计时器到期 | → Idle |
|
||||||
|
|
||||||
|
### 6.5 Exhausted 状态详细规则
|
||||||
|
|
||||||
|
**前提:** 所有 Agent 只使用一个主模型,没有 fallback 模型。
|
||||||
|
|
||||||
|
**进入条件:**
|
||||||
|
- Agent 调用 LLM API 时收到 rate-limit 错误(HTTP 429 等)
|
||||||
|
- Agent 调用 LLM API 时收到 billing 相关错误(额度不足、配额耗尽等)
|
||||||
|
|
||||||
|
**恢复逻辑:**
|
||||||
|
- 解析错误信息,查找类似 `reset in X mins`、`retry after X`、`resets at <timestamp>` 的模式
|
||||||
|
- 如果能解析出时间 → 设置 **X 分钟** 后恢复为 Idle
|
||||||
|
- 如果无法解析 → 默认 **5 小时** 后恢复为 Idle
|
||||||
|
|
||||||
|
**Exhausted 期间行为:**
|
||||||
|
- Agent 视为不可用,不被心跳唤醒
|
||||||
|
- 待执行的 slot 设为 Deferred
|
||||||
|
- 前端/Monitor 显示 Exhausted 状态 + 预计恢复时间
|
||||||
|
|
||||||
|
**Agent 表扩展字段:**
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| exhausted_at | datetime, nullable | 进入 Exhausted 的时间 |
|
||||||
|
| recovery_at | datetime, nullable | 预计恢复时间 |
|
||||||
|
| exhaust_reason | Enum(RateLimit, Billing), nullable | 原因 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、CLI 命令
|
||||||
|
|
||||||
|
### 7.1 日程操作
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建单次日程
|
||||||
|
hf calendar schedule <slot-type> <scheduled-at> <estimated-duration> \
|
||||||
|
[--job <code>] [--date <yyyy-mm-dd>]
|
||||||
|
|
||||||
|
# 查看某天日程
|
||||||
|
hf calendar show [--date <yyyy-mm-dd>]
|
||||||
|
|
||||||
|
# 取消日程(plan 来源的 slot 物化后断开 plan)
|
||||||
|
hf calendar cancel [--date <yyyy-mm-dd>] <slot-id>
|
||||||
|
|
||||||
|
# 编辑日程(plan 来源的 slot 物化后断开 plan)
|
||||||
|
hf calendar edit [--date <yyyy-mm-dd>] <slot-id> \
|
||||||
|
[--slot-type <type>] [--estimated-duration <mins>] \
|
||||||
|
[--job <code>] [--scheduled-at <HH:mm>]
|
||||||
|
|
||||||
|
# 列出所有有已物化日程的未来日期(纯 plan 的不算)
|
||||||
|
hf calendar date-list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 计划操作
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建周期性计划
|
||||||
|
hf calendar plan-schedule <slot-type> <estimated-duration> \
|
||||||
|
--at <HH:mm> [--on-day <day>] [--on-week <1-4>] [--on-month <month>]
|
||||||
|
|
||||||
|
# 列出所有计划
|
||||||
|
hf calendar plan-list
|
||||||
|
|
||||||
|
# 取消计划(不追溯过去)
|
||||||
|
hf calendar plan-cancel <plan-id>
|
||||||
|
|
||||||
|
# 编辑计划(不追溯过去)
|
||||||
|
hf calendar plan-edit <plan-id> \
|
||||||
|
[--at <HH:mm>] [--on-day <day>] [--on-week <1-4>] [--on-month <month>] \
|
||||||
|
[--slot-type <type>] [--estimated-duration <mins>]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 用户创建(Agent 支持)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
hf user create <username> [--agent-id <id>] [--claw-identifier <id>] ...
|
||||||
|
```
|
||||||
|
|
||||||
|
- `--agent-id` + `--claw-identifier` 必须同时出现或同时不出现
|
||||||
|
- pcexec 模式下:
|
||||||
|
- `--agent-id` ← `$AGENT_ID`
|
||||||
|
- `--claw-identifier` ← `openclaw config get plugins.harbor-forge.identifier`
|
||||||
|
- 后端 `POST /users` 扩展:接受 `agent_id` + `claw_identifier`,创建 User 同时写入 agents 表
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、项目结构调整记录(与 Calendar 相关联的设计备注)
|
||||||
|
|
||||||
|
### 8.1 命名调整
|
||||||
|
|
||||||
|
- `Propose` 统一改名为 `Proposal`
|
||||||
|
|
||||||
|
### 8.2 新结构
|
||||||
|
|
||||||
|
```text
|
||||||
|
Project
|
||||||
|
└─ Proposal
|
||||||
|
├─ Essential
|
||||||
|
│ ├─ feature
|
||||||
|
│ ├─ improvement
|
||||||
|
│ └─ refactor
|
||||||
|
└─ accept -> 将该 Proposal 下所有 Essential 生成对应类型的 story task,并创建到 Proposal 选择的 Milestone
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.3 Proposal Accept 语义变更
|
||||||
|
|
||||||
|
旧行为:
|
||||||
|
- Proposal Accept 后生成单个 `story/feature` task
|
||||||
|
|
||||||
|
新行为:
|
||||||
|
- Proposal Accept **不再生成单个 Feature Task**
|
||||||
|
- 每个 Proposal 可维护多个 Essential
|
||||||
|
- Accept 时,遍历该 Proposal 下全部 Essential
|
||||||
|
- 按 Essential 类型映射生成对应的 story task:
|
||||||
|
- `feature` -> `story/feature`
|
||||||
|
- `improvement` -> `story/improvement`
|
||||||
|
- `refactor` -> `story/refactor`
|
||||||
|
- 生成目标 Milestone 由 Proposal 在 Accept 前或 Accept 时明确选择
|
||||||
|
|
||||||
|
### 8.4 Story 创建限制
|
||||||
|
|
||||||
|
- `story` 整个大类视为 **restricted**
|
||||||
|
- 任何 `story/*` task 都不允许通过通用 task create endpoint 直接创建
|
||||||
|
- `story` 仅允许通过 `Proposal Accept` 工作流生成
|
||||||
|
|
||||||
|
### 8.5 Essential
|
||||||
|
|
||||||
|
新增 `Essential` 概念,用于承载 Proposal 下的可落地核心条目。
|
||||||
|
|
||||||
|
建议字段:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| id | int (PK) | |
|
||||||
|
| essential_code | VARCHAR(64), UNIQUE | EssentialCode,风格参考 ProjectCode / TaskCode / MilestoneCode / ProposalCode |
|
||||||
|
| proposal_id | FK -> proposals.id | 所属 Proposal |
|
||||||
|
| type | Enum(feature, improvement, refactor) | Essential 类型 |
|
||||||
|
| title | VARCHAR(255) | 标题 |
|
||||||
|
| description | TEXT, nullable | 描述 |
|
||||||
|
| created_by_id | FK -> users.id, nullable | 创建人 |
|
||||||
|
| created_at | datetime | 创建时间 |
|
||||||
|
| updated_at | datetime | 更新时间 |
|
||||||
|
|
||||||
|
### 8.6 代码生成
|
||||||
|
|
||||||
|
- `Essential` 拥有独立 `EssentialCode`
|
||||||
|
- 编码规则参考现有类似结构,例如:
|
||||||
|
- `ProjectCode`
|
||||||
|
- `MilestoneCode`
|
||||||
|
- `TaskCode`
|
||||||
|
- `ProposalCode`
|
||||||
|
- 具体前缀与编号策略待后续单独定稿
|
||||||
|
|
||||||
|
## 九、前端
|
||||||
|
|
||||||
|
- 每个用户可查看/调整自己的日程表
|
||||||
|
- Admin 可查看/调整所有用户的日程表
|
||||||
|
- 日程表页面展示(具体 UI 待设计)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、Bug Fix
|
||||||
|
|
||||||
|
- acc-mgr 用户:后端禁止修改密码(admin 也不行)
|
||||||
|
- 前端:acc-mgr 用户不显示修改密码入口
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、待定项
|
||||||
|
|
||||||
|
- Entertainment 事件子类型设计
|
||||||
|
- MinimumWorkload 存储方式(JSON 字段 vs 独立表)
|
||||||
|
- 前端日程表 UI 详细设计
|
||||||
|
- Agent 唤醒的提示词模板
|
||||||
|
- Proposal / Essential 的详细数据模型、API、前端页面与 accept 流程实现细节
|
||||||
|
- Story restricted 后,现有 task create / propose accept / milestone flow 的兼容迁移策略
|
||||||
380
plans/TASKLIST.md
Normal file
380
plans/TASKLIST.md
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
# TASKLIST.md
|
||||||
|
|
||||||
|
> 说明:如果某个进行中的 Task 没有完全完成,或者在执行过程中遇到 block,需要在该 Task 下继续拆分若干子 TODO item:本次开发中已经完成的部分标记为已完成,block / pending / 尚未完成的部分标记为未完成。
|
||||||
|
>
|
||||||
|
> 拆分原则:尽量保证 Task 之间相互独立;每个 Task 最好只改动一个子模块(如 `HarborForge.Backend` / `HarborForge.Frontend` / `HarborForge.Cli` / `HarborForge.OpenclawPlugin` / 根目录文档),避免一次任务同时横跨多个子模块。只有在确实无法避免时,才建立跨模块 Task。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# TODOLIST
|
||||||
|
|
||||||
|
## A. Root / Docs(根目录与规划文档)
|
||||||
|
|
||||||
|
- [x] DOC-001:整理本波开发范围说明(root docs only)
|
||||||
|
- [x] 明确 Calendar 属于独立功能线
|
||||||
|
- [x] 明确 Proposal / Essential 属于项目结构调整线
|
||||||
|
- [x] 明确两条线的交叉点仅限 `event_data` / Agent 调度引用层
|
||||||
|
- [x] 将"必须本波完成"和"仅设计保留"区分写清楚
|
||||||
|
|
||||||
|
- [x] DOC-002:整理 Proposal / Essential / Story restricted 的迁移说明(root docs only)
|
||||||
|
- [x] 说明 `Propose -> Proposal` 的命名调整
|
||||||
|
- [x] 说明 `Proposal Accept` 语义变化
|
||||||
|
- [x] 说明 `story/*` 改为 restricted 的影响面
|
||||||
|
- [x] 说明旧数据和旧接口的兼容策略
|
||||||
|
|
||||||
|
- [x] DOC-003:整理 Calendar 验收清单(root docs only)
|
||||||
|
- [x] 列出后端验收项
|
||||||
|
- [x] 列出前端验收项
|
||||||
|
- [x] 列出 CLI 验收项
|
||||||
|
- [x] 列出插件联动验收项
|
||||||
|
|
||||||
|
## B. HarborForge.Backend - Proposal / Essential / Story restricted
|
||||||
|
|
||||||
|
- [x] BE-PR-001:后端统一重命名 `Propose` 概念为 `Proposal`(backend only)
|
||||||
|
- [x] 盘点 `models / schemas / routers / services / tests` 中 `propose` 命名
|
||||||
|
- [x] 明确保留兼容别名还是直接切换 → 保留别名 + legacy API 路由
|
||||||
|
- [x] 输出重命名影响清单 → `docs/BE-PR-001-rename-impact.md`
|
||||||
|
|
||||||
|
- [x] BE-PR-002:新增 Proposal 数据模型调整(backend only)
|
||||||
|
- [x] 调整 Proposal 模型命名与字段注释
|
||||||
|
- [x] 确认 Proposal 与 `project_id / created_by_id / feat_task_id` 的后续关系
|
||||||
|
- [x] 标记 `feat_task_id` 是否废弃或替换
|
||||||
|
|
||||||
|
- [x] BE-PR-003:新增 Essential 模型(backend only)
|
||||||
|
- [x] 新增 `Essential` SQLAlchemy model
|
||||||
|
- [x] 增加 `proposal_id` 外键
|
||||||
|
- [x] 增加 `essential_code`
|
||||||
|
- [x] 增加 `type / title / description / created_by_id / created_at / updated_at`
|
||||||
|
|
||||||
|
- [x] BE-PR-004:实现 EssentialCode 编码规则(backend only)
|
||||||
|
- [x] 参考现有 `ProjectCode / MilestoneCode / TaskCode / ProposeCode` 生成方式
|
||||||
|
- [x] 设计 Essential code 前缀
|
||||||
|
- [x] 实现唯一编号生成逻辑
|
||||||
|
- [x] 明确是否需要独立 counter 表
|
||||||
|
|
||||||
|
- [x] BE-PR-005:新增 Essential 的 schema 定义(backend only)
|
||||||
|
- [x] 新增 create schema
|
||||||
|
- [x] 新增 update schema
|
||||||
|
- [x] 新增 response schema
|
||||||
|
- [x] 新增 Proposal detail 中嵌套 Essential 的返回结构
|
||||||
|
|
||||||
|
- [x] BE-PR-006:新增 Proposal 下 Essential CRUD API(backend only)
|
||||||
|
- [x] 实现创建 Essential
|
||||||
|
- [x] 实现编辑 Essential
|
||||||
|
- [x] 实现删除 Essential
|
||||||
|
- [x] 实现 Proposal 详情返回 Essential 列表
|
||||||
|
|
||||||
|
- [x] BE-PR-007:重构 Proposal Accept 逻辑(backend only)
|
||||||
|
- [x] 移除"accept 后生成单个 `story/feature` task"的旧逻辑
|
||||||
|
- [x] Accept 时要求显式选择目标 Milestone
|
||||||
|
- [x] 遍历 Proposal 下全部 Essential
|
||||||
|
- [x] 按 Essential.type 生成对应 `story/*` task
|
||||||
|
- [x] 保证批量创建在一个事务中完成
|
||||||
|
|
||||||
|
- [x] BE-PR-008:补充 Proposal Accept 追踪字段/关系(backend only)
|
||||||
|
- [x] 明确 Proposal 与生成 tasks 的映射方式
|
||||||
|
- [x] 设计是用反查字段、关联表还是事件记录
|
||||||
|
- [x] 实现最小可用追踪能力
|
||||||
|
|
||||||
|
- [x] BE-PR-009:收紧 Task 类型规则,限制全部 `story/*`(backend only)
|
||||||
|
- [x] 更新 `TASK_SUBTYPE_MAP` 相关约束
|
||||||
|
- [x] 将所有 `story/*` 组合标记为 restricted
|
||||||
|
- [x] 禁止通用 create endpoint 直接创建任何 story
|
||||||
|
- [x] 保留内部受控入口用于 Proposal Accept
|
||||||
|
|
||||||
|
- [x] BE-PR-010:清理旧的 `feat_task_id` 语义(backend only)
|
||||||
|
- [x] 判断字段是否保留但废弃 → 保留 DB 列,标记 DEPRECATED
|
||||||
|
- [x] 如果废弃,给出兼容读取策略 → 旧行仍返回值,新 accept 不写入,客户端迁移到 generated_tasks
|
||||||
|
- [x] 如果替换,落地新的字段或关联方式 → 已由 BE-PR-008 通过 Task.source_proposal_id 替代
|
||||||
|
|
||||||
|
- [x] BE-PR-011:补 Proposal / Essential / Story restricted 的后端测试(backend only)
|
||||||
|
- [x] Essential CRUD 测试
|
||||||
|
- [x] Proposal Accept 批量生成 story task 测试
|
||||||
|
- [x] 非受控入口创建 `story/*` 的失败测试
|
||||||
|
- [x] 兼容旧 proposal 数据的测试
|
||||||
|
|
||||||
|
## C. HarborForge.Backend - Calendar 基础模型与规则
|
||||||
|
|
||||||
|
- [x] BE-CAL-001:新增 Calendar 基础模型 `TimeSlot`(backend only)
|
||||||
|
- [x] 新增表结构
|
||||||
|
- [x] 定义 slot status / slot type / event type 枚举
|
||||||
|
- [x] 定义时间字段与时长字段
|
||||||
|
- [x] 定义 `plan_id` 关联
|
||||||
|
|
||||||
|
- [x] BE-CAL-002:新增 Calendar 基础模型 `SchedulePlan`(backend only)
|
||||||
|
- [x] 新增表结构
|
||||||
|
- [x] 定义 `at_time / on_day / on_week / on_month`
|
||||||
|
- [x] 加入层级参数校验约束
|
||||||
|
- [x] 处理 user 归属关系
|
||||||
|
|
||||||
|
- [x] BE-CAL-003:新增 Agent 扩展字段(backend only)
|
||||||
|
- [x] 为 Agent 增加 `status / last_heartbeat`
|
||||||
|
- [x] 增加 `exhausted_at / recovery_at / exhaust_reason`
|
||||||
|
- [x] 明确与现有 user / monitor 标识的关系
|
||||||
|
|
||||||
|
- [x] BE-CAL-004:实现 MinimumWorkload 存储方案(backend only)
|
||||||
|
- [x] 确定 JSON 字段还是独立表 → 独立表 `minimum_workloads`,config 列为 JSON
|
||||||
|
- [x] 实现用户级配置读写 → GET/PUT/PATCH `/calendar/workload-config` + admin 路由
|
||||||
|
- [x] 提供后续校验调用入口 → `services/minimum_workload.check_workload_warnings()`
|
||||||
|
|
||||||
|
- [x] BE-CAL-005:实现 Plan 虚拟 slot 标识与物化策略(backend only)
|
||||||
|
- [x] 实现 `plan-{plan_id}-{date}` 标识规则
|
||||||
|
- [x] 实现虚拟 slot 转真实 slot 的物化逻辑
|
||||||
|
- [x] 实现 edit / cancel 后断开 plan 关联
|
||||||
|
|
||||||
|
- [x] BE-CAL-006:实现 Calendar overlap 校验(backend only)
|
||||||
|
- [x] 校验同日时间冲突
|
||||||
|
- [x] 返回明确的冲突错误信息
|
||||||
|
- [x] 区分 create 与 edit 两种场景
|
||||||
|
|
||||||
|
- [x] BE-CAL-007:实现 MinimumWorkload warning 规则(backend only)
|
||||||
|
- [x] 计算 daily / weekly / monthly / yearly 工作量
|
||||||
|
- [x] 不阻止提交,仅返回 warning
|
||||||
|
- [x] 统一 warning 数据结构
|
||||||
|
|
||||||
|
- [x] BE-CAL-008:实现不可修改过去 slot 的规则(backend only)
|
||||||
|
- [x] 禁止 edit 过去 slot
|
||||||
|
- [x] 禁止 cancel 过去 slot
|
||||||
|
- [x] 保证 plan-edit / plan-cancel 不追溯过去已物化 slot
|
||||||
|
|
||||||
|
## D. HarborForge.Backend - Calendar API
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-001:实现单次日程创建 API(backend only)
|
||||||
|
- [x] 创建 slot
|
||||||
|
- [x] 支持 job/system/event_data
|
||||||
|
- [x] 接入 overlap 与 workload warning
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-002:实现某日 Calendar 查询 API(backend only)
|
||||||
|
- [x] 返回真实 slot
|
||||||
|
- [x] 合成当日 plan 虚拟 slot
|
||||||
|
- [x] 输出统一排序结构
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-003:实现 Calendar 编辑 API(backend only)
|
||||||
|
- [x] 支持真实 slot 编辑
|
||||||
|
- [x] 支持虚拟 slot 编辑并触发物化
|
||||||
|
- [x] 返回编辑后的真实结果
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-004:实现 Calendar 取消 API(backend only)
|
||||||
|
- [x] 支持真实 slot cancel
|
||||||
|
- [x] 支持虚拟 slot cancel 并触发物化
|
||||||
|
- [x] 处理状态字段更新
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-005:实现 plan-schedule / plan-list API(backend only)
|
||||||
|
- [x] 创建计划
|
||||||
|
- [x] 列出计划
|
||||||
|
- [x] 返回计划规则字段
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-006:实现 plan-edit / plan-cancel API(backend only)
|
||||||
|
- [x] 编辑计划
|
||||||
|
- [x] 取消计划
|
||||||
|
- [x] 不追溯已物化过去数据
|
||||||
|
|
||||||
|
- [x] BE-CAL-API-007:实现 date-list API(backend only)
|
||||||
|
- [x] 仅列出有已物化未来 slot 的日期
|
||||||
|
- [x] 排除纯 plan 未物化日期
|
||||||
|
|
||||||
|
## E. HarborForge.Backend - Agent / Plugin Calendar 协作
|
||||||
|
|
||||||
|
- [x] BE-AGT-001:定义心跳查询待执行 slot 的服务层(backend only)
|
||||||
|
- [x] 筛选当天 `NotStarted / Deferred`
|
||||||
|
- [x] 仅返回 `scheduled_at` 已过的 slot
|
||||||
|
- [x] 按优先级排序
|
||||||
|
|
||||||
|
- [x] BE-AGT-002:实现 Agent 状态流转服务(backend only)
|
||||||
|
- [x] Idle -> Busy / OnCall
|
||||||
|
- [x] Busy / OnCall -> Idle
|
||||||
|
- [x] 超时无心跳 -> Offline
|
||||||
|
- [x] API 配额错误 -> Exhausted
|
||||||
|
|
||||||
|
- [x] BE-AGT-003:实现多 slot 竞争处理(backend only)
|
||||||
|
- [x] 选最高 priority 执行
|
||||||
|
- [x] 其余 slot 标记 Deferred
|
||||||
|
- [x] Deferred slot 自动 priority += 1
|
||||||
|
|
||||||
|
- [x] BE-AGT-004:实现 Exhausted 恢复时间解析(backend only)
|
||||||
|
- [x] 解析 retry-after / reset in / resets at
|
||||||
|
- [x] 解析失败时默认 5 小时
|
||||||
|
- [x] 到期恢复 Idle
|
||||||
|
|
||||||
|
## F. HarborForge.Frontend - Proposal / Essential / Story restricted
|
||||||
|
|
||||||
|
- [x] FE-PR-001:前端统一重命名 Propose -> Proposal(frontend only)
|
||||||
|
- [x] 调整页面标题与菜单文案
|
||||||
|
- [x] 调整类型名与 API 调用命名
|
||||||
|
- [x] 清理旧 propose 文案
|
||||||
|
|
||||||
|
- [x] FE-PR-002:Proposal 详情页增加 Essential 列表区(frontend only)
|
||||||
|
- [x] 展示 Essential 列表
|
||||||
|
- [x] 展示 Essential type / code / title
|
||||||
|
- [x] 处理空状态
|
||||||
|
|
||||||
|
- [x] FE-PR-003:新增 Essential 创建/编辑表单(frontend only)
|
||||||
|
- [x] 创建表单
|
||||||
|
- [x] 编辑表单
|
||||||
|
- [x] type 选择器
|
||||||
|
- [x] 提交后局部刷新
|
||||||
|
|
||||||
|
- [x] FE-PR-004:Proposal Accept 增加目标 Milestone 选择(frontend only)
|
||||||
|
- [x] Accept 前展示 milestone 选择控件
|
||||||
|
- [x] 校验必须选择 milestone
|
||||||
|
- [x] 展示 Accept 成功后的生成结果
|
||||||
|
|
||||||
|
- [x] FE-PR-005:限制前端直接创建 `story/*`(frontend only)
|
||||||
|
- [x] 从 Task 创建入口移除 story
|
||||||
|
- [x] 或将 story 整体设为不可选
|
||||||
|
- [x] 调整相关提示文案
|
||||||
|
|
||||||
|
## G. HarborForge.Frontend - Calendar
|
||||||
|
|
||||||
|
- [x] FE-CAL-001:新增 Calendar 页面基础骨架(frontend only)
|
||||||
|
- [x] 增加路由入口
|
||||||
|
- [x] 增加侧边栏入口
|
||||||
|
- [x] 增加基础页面布局
|
||||||
|
|
||||||
|
- [x] FE-CAL-002:实现某日 slot 列表展示(frontend only)
|
||||||
|
- [x] 展示时间轴或列表
|
||||||
|
- [x] 区分真实 slot 与 plan 虚拟 slot
|
||||||
|
- [x] 展示状态 / 类型 / 时长 / 优先级
|
||||||
|
|
||||||
|
- [x] FE-CAL-003:实现计划列表展示(frontend only)
|
||||||
|
- [x] 展示计划规则
|
||||||
|
- [x] 展示周期参数
|
||||||
|
- [x] 支持跳转编辑
|
||||||
|
|
||||||
|
- [x] FE-CAL-004:实现创建 / 编辑 / 取消日程交互(frontend only)
|
||||||
|
- [x] 新建 slot 表单
|
||||||
|
- [x] 编辑 slot 表单
|
||||||
|
- [x] cancel 操作确认
|
||||||
|
- [x] 展示后端 warning
|
||||||
|
|
||||||
|
- [x] FE-CAL-005:实现 Deferred / Exhausted / overlap 等状态提示(frontend only)
|
||||||
|
- [x] Deferred 提示
|
||||||
|
- [x] overlap 报错展示
|
||||||
|
- [x] workload warning 展示
|
||||||
|
- [x] Exhausted 状态展示
|
||||||
|
|
||||||
|
## H. HarborForge.Cli - Proposal / Essential / Story restricted
|
||||||
|
|
||||||
|
- [x] CLI-PR-001:统一 CLI 文案 `propose -> proposal`(cli only)
|
||||||
|
- [x] 调整命令 help 文案
|
||||||
|
- [x] 调整输出文本
|
||||||
|
- [x] 评估命令名是否兼容保留 `hf propose` → 保留为 alias
|
||||||
|
|
||||||
|
- [x] CLI-PR-002:新增 Essential 相关命令(cli only)
|
||||||
|
- [x] `hf proposal essential list`
|
||||||
|
- [x] `hf proposal essential create`
|
||||||
|
- [x] `hf proposal essential update`
|
||||||
|
- [x] `hf proposal essential delete`
|
||||||
|
|
||||||
|
- [x] CLI-PR-003:更新 Proposal Accept CLI(cli only)
|
||||||
|
- [x] Accept 时支持传入 milestone
|
||||||
|
- [x] 展示批量生成的 task 结果
|
||||||
|
- [x] 更新帮助文案
|
||||||
|
|
||||||
|
- [x] CLI-PR-004:限制 CLI 直接创建 `story/*`(cli only)
|
||||||
|
- [x] 阻止 story 类型直建
|
||||||
|
- [x] 返回明确错误提示
|
||||||
|
- [x] 提示改走 Proposal Accept
|
||||||
|
|
||||||
|
## I. HarborForge.Cli - Calendar
|
||||||
|
|
||||||
|
- [x] CLI-CAL-001:新增 `hf calendar` 命令组骨架(cli only)
|
||||||
|
- [x] 注册命令组
|
||||||
|
- [x] 增加 help surface
|
||||||
|
- [x] 增加 brief help
|
||||||
|
|
||||||
|
- [x] CLI-CAL-002:实现 `hf calendar schedule`(cli only)
|
||||||
|
- [x] 参数解析
|
||||||
|
- [x] 请求构造
|
||||||
|
- [x] 结果输出
|
||||||
|
|
||||||
|
- [x] CLI-CAL-003:实现 `hf calendar show`(cli only)
|
||||||
|
- [x] 日期参数
|
||||||
|
- [x] 列表输出
|
||||||
|
- [x] JSON 输出
|
||||||
|
|
||||||
|
- [x] CLI-CAL-004:实现 `hf calendar edit`(cli only)
|
||||||
|
- [x] 支持 slot-id 与 date
|
||||||
|
- [x] PATCH/POST 适配
|
||||||
|
- [x] 输出 warning / error
|
||||||
|
|
||||||
|
- [x] CLI-CAL-005:实现 `hf calendar cancel`(cli only)
|
||||||
|
- [x] 支持 slot-id 与 date
|
||||||
|
- [x] 输出结果
|
||||||
|
|
||||||
|
- [x] CLI-CAL-006:实现 `hf calendar date-list`(cli only)
|
||||||
|
- [x] 列出未来已物化日期
|
||||||
|
- [x] 适配 JSON 输出
|
||||||
|
|
||||||
|
- [x] CLI-CAL-007:实现 `hf calendar plan-schedule`(cli only)
|
||||||
|
- [x] 参数解析 `--at --on-day --on-week --on-month`
|
||||||
|
- [x] 请求构造
|
||||||
|
- [x] 输出结果
|
||||||
|
|
||||||
|
- [x] CLI-CAL-008:实现 `hf calendar plan-list`(cli only)
|
||||||
|
- [x] 列表输出
|
||||||
|
- [x] JSON 输出
|
||||||
|
|
||||||
|
- [x] CLI-CAL-009:实现 `hf calendar plan-edit`(cli only)
|
||||||
|
- [x] 参数解析
|
||||||
|
- [x] 请求发送
|
||||||
|
- [x] 输出结果
|
||||||
|
|
||||||
|
- [x] CLI-CAL-010:实现 `hf calendar plan-cancel`(cli only)
|
||||||
|
- [x] 参数解析
|
||||||
|
- [x] 请求发送
|
||||||
|
- [x] 输出结果
|
||||||
|
|
||||||
|
## J. HarborForge.OpenclawPlugin / Monitor 联动
|
||||||
|
|
||||||
|
- [x] PLG-CAL-001:插件侧定义 Calendar 心跳请求格式(plugin only)
|
||||||
|
- [x] 明确 claw_identifier 传递方式
|
||||||
|
- [x] 明确 agent_id 传递方式
|
||||||
|
- [x] 明确返回 slot 列表结构
|
||||||
|
|
||||||
|
- [x] PLG-CAL-002:插件侧处理待执行 slot 唤醒(plugin only)
|
||||||
|
- [x] Idle 时唤醒 agent
|
||||||
|
- [x] 透传任务上下文
|
||||||
|
- [x] 执行前更新 attended / started_at / status
|
||||||
|
|
||||||
|
- [x] PLG-CAL-003:插件侧处理非 Idle / Deferred 分支(plugin only)
|
||||||
|
- [x] Agent 非 Idle 时上报 Deferred
|
||||||
|
- [x] 处理多 slot 重排后的重新规划
|
||||||
|
|
||||||
|
- [x] PLG-CAL-004:插件侧处理 ScheduledGatewayRestart(plugin only)
|
||||||
|
- [x] 收到事件后持久化状态
|
||||||
|
- [x] 发送最终心跳
|
||||||
|
- [x] 暂停定时任务
|
||||||
|
|
||||||
|
## K. Tests / Integration(按子模块分别补,不混做)
|
||||||
|
|
||||||
|
- [x] TEST-BE-CAL-001:补 Calendar backend 测试(backend tests only)
|
||||||
|
- [x] 模型测试
|
||||||
|
- [x] API 测试
|
||||||
|
- [x] overlap / warning / materialize 测试
|
||||||
|
- [x] Blocker resolved: `HarborForge.Backend/app/schemas/calendar.py` 的 Python 3.12 + Pydantic 2.5 递归建模问题已通过 schema 类型别名修复,本次已继续补齐 Calendar API / model tests
|
||||||
|
|
||||||
|
- [x] TEST-BE-PR-001:补 Proposal / Essential backend 测试(backend tests only)
|
||||||
|
- [x] Essential CRUD
|
||||||
|
- [x] Accept 生成 story tasks
|
||||||
|
- [x] story restricted
|
||||||
|
|
||||||
|
- [x] TEST-FE-CAL-001:补 Calendar 前端测试(frontend tests only)
|
||||||
|
- [x] 页面渲染
|
||||||
|
- [x] 表单交互
|
||||||
|
- [x] warning / error 展示
|
||||||
|
|
||||||
|
- [x] TEST-FE-PR-001:补 Proposal / Essential 前端测试(frontend tests only)
|
||||||
|
- [x] Essential 列表与表单
|
||||||
|
- [x] Accept milestone 选择
|
||||||
|
- [x] story 创建入口限制
|
||||||
|
|
||||||
|
- [x] TEST-CLI-CAL-001:补 Calendar CLI 测试(cli tests only)
|
||||||
|
- [x] 命令解析
|
||||||
|
- [x] JSON 输出
|
||||||
|
- [x] 错误输出
|
||||||
|
|
||||||
|
- [x] TEST-CLI-PR-001:补 Proposal / Essential CLI 测试(cli tests only)
|
||||||
|
- [x] Essential 子命令
|
||||||
|
- [x] accept milestone 参数
|
||||||
|
- [x] story 限制提示
|
||||||
8
plans/automation/cron/hf-dev-kimi-scheduler-state.json
Normal file
8
plans/automation/cron/hf-dev-kimi-scheduler-state.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"createdAt": "2026-03-29T11:50:00Z",
|
||||||
|
"lastRun": null,
|
||||||
|
"totalRuns": 0,
|
||||||
|
"completedTasks": [],
|
||||||
|
"currentTask": null,
|
||||||
|
"status": "active"
|
||||||
|
}
|
||||||
56
plans/automation/cron/hf-dev-kimi-scheduler.prompt.md
Normal file
56
plans/automation/cron/hf-dev-kimi-scheduler.prompt.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# HarborForge 自动化开发任务 - 定时唤醒
|
||||||
|
# 模型: kimi/k2p5 | Agent: developer
|
||||||
|
# 目标: Discord 1474327736242798612
|
||||||
|
|
||||||
|
## 任务说明
|
||||||
|
|
||||||
|
每次唤醒后执行以下操作:
|
||||||
|
|
||||||
|
### 1. 读取计划文档
|
||||||
|
- 阅读 `/root/.openclaw/workspace/workspace-developer/HarborForge/plans/NEXT_WAVE_DEV_DIRECTION.md`
|
||||||
|
- 理解当前开发方向和架构设计
|
||||||
|
|
||||||
|
### 2. 读取任务列表
|
||||||
|
- 阅读 `/root/.openclaw/workspace/workspace-developer/HarborForge/plans/TASKLIST.md`
|
||||||
|
- 识别未完成的任务项
|
||||||
|
|
||||||
|
### 3. 任务执行策略
|
||||||
|
- 从 TASKLIST.md 中选择一个**未完成的、可独立执行**的任务
|
||||||
|
- 优先选择只涉及单个子模块的任务(Backend/Frontend/CLI/Plugin)
|
||||||
|
- 避免一次任务横跨多个子模块
|
||||||
|
- 如任务过大,拆分为更小的子任务
|
||||||
|
|
||||||
|
### 4. 执行流程
|
||||||
|
1. 创建任务分支(如需要)
|
||||||
|
2. 实现功能代码
|
||||||
|
3. 编写/更新测试
|
||||||
|
4. 本地验证(如可能)
|
||||||
|
5. 提交代码并推送
|
||||||
|
6. 更新 TASKLIST.md,将完成的任务标记为 `[x]`
|
||||||
|
|
||||||
|
### 5. 汇报要求
|
||||||
|
向 Discord channel `1474327736242798612` 发送执行摘要:
|
||||||
|
- 本次处理的任务ID和标题
|
||||||
|
- 完成状态(已完成/部分完成/遇到阻塞)
|
||||||
|
- 关键变更摘要
|
||||||
|
- 下一步计划或遇到的问题
|
||||||
|
|
||||||
|
### 6. 任务完成检测
|
||||||
|
- 检查 TASKLIST.md 中是否还有未完成任务
|
||||||
|
- 如果**所有任务都已完成**:
|
||||||
|
- 在 Discord 汇报最终完成情况
|
||||||
|
- 调用 `openclaw cron delete hf-dev-kimi-scheduler` 删除本定时任务
|
||||||
|
- 说明删除原因
|
||||||
|
|
||||||
|
## 开发原则
|
||||||
|
|
||||||
|
- **单一职责**:每次只处理一个任务
|
||||||
|
- **小步快跑**:任务可拆分则拆分
|
||||||
|
- **及时汇报**:每个任务完成后立即汇报进度
|
||||||
|
- **安全优先**:涉及破坏性变更时先确认
|
||||||
|
|
||||||
|
## 当前上下文
|
||||||
|
|
||||||
|
- 工作目录: `/root/.openclaw/workspace/workspace-developer/HarborForge`
|
||||||
|
- Git 仓库: https://git.hangman-lab.top/zhi/HarborForge
|
||||||
|
- 包含子模块: Backend, Frontend, Cli, Monitor, OpenclawPlugin, Test
|
||||||
Reference in New Issue
Block a user