Compare commits

..

30 Commits

Author SHA1 Message Date
zhi
77d8f6098f BE-CAL-API-001: Update submodule ref + mark task complete 2026-03-31 05:46:03 +00:00
zhi
18e50156df BE-CAL-API-001: Implement single slot creation API
- Add TimeSlotCreate, TimeSlotResponse, TimeSlotCreateResponse schemas
- Add SlotConflictItem, SlotTypeEnum, EventTypeEnum, SlotStatusEnum to schemas
- Add POST /calendar/slots endpoint with:
  - Overlap detection (409 on conflict)
  - Workload warning computation (advisory, returned in response)
  - Support for event_type + event_data (job/system/entertainment)
  - Default date to today if not provided
- Add _slot_to_response helper for ORM -> schema conversion
2026-03-31 05:45:51 +00:00
zhi
bc1a427f22 BE-CAL-007 + BE-CAL-008: mark completed, update Backend submodule 2026-03-31 04:16:58 +00:00
zhi
5b9d2618ad BE-CAL-006: mark overlap detection task complete in TASKLIST 2026-03-31 01:18:01 +00:00
zhi
eece0773cb Update Backend submodule: BE-CAL-005 plan virtual-slot materialization 2026-03-30 23:47:15 +00:00
zhi
3e1fe5cc79 BE-CAL-005: Implement plan virtual-slot identification and materialization
- Virtual slot ID: plan-{plan_id}-{YYYY-MM-DD} format with parse/make helpers
- Plan-date matching: on_month/on_week/on_day hierarchy with week_of_month calc
- Materialization: convert virtual slot to real TimeSlot row, copy plan template
- Detach: clear plan_id after edit/cancel to break plan association
- Bulk materialization: materialize_all_for_date for daily pre-compute
- 23 tests covering all paths (matching, virtual gen, materialize, detach, bulk)
2026-03-30 23:46:51 +00:00
zhi
d12a46b2a3 BE-CAL-004: update submodule pointer + mark task complete in TASKLIST 2026-03-30 22:27:15 +00:00
zhi
c01881ade0 BE-CAL-003: Agent model with status/heartbeat/exhausted fields (backend submodule) 2026-03-30 20:47:56 +00:00
zhi
35045a9490 Mark BE-CAL-002 complete in TASKLIST.md 2026-03-30 19:16:33 +00:00
zhi
ea9f12b9b1 BE-CAL-001: Mark TimeSlot model task complete, update Backend submodule 2026-03-30 17:45:22 +00:00
zhi
2d5e055fc8 BE-PR-011: Mark Proposal/Essential/Story restricted tests complete
- Updated HarborForge.Backend submodule (test infra fix + 29 passing tests)
- Marked BE-PR-011 complete in TASKLIST.md
2026-03-30 16:17:16 +00:00
zhi
52530486d1 BE-PR-010: clean up feat_task_id semantics — deprecate with read-only compat
Decision: retain DB column, mark DEPRECATED. Existing rows still return
feat_task_id via API. New accept flow (BE-PR-007) does not write it.
Clients should migrate to generated_tasks / Task.source_proposal_id.

- Backend: model/schema/router deprecation comments updated
- Backend: added docs/BE-PR-010-feat-task-id-deprecation.md
- Tests: updated to work with Essential-based accept flow
- Tests: all 21 proposal tests pass
- TASKLIST: BE-PR-010 marked complete
2026-03-30 12:50:14 +00:00
zhi
f61b5ee17f BE-PR-009: restrict all story/* task types + fix test conftest imports 2026-03-30 11:46:28 +00:00
zhi
93fe52750c Mark BE-PR-008 complete in TASKLIST.md 2026-03-30 10:46:38 +00:00
zhi
051183bbe7 Update Backend submodule: BE-PR-008 tracking fields 2026-03-30 10:46:28 +00:00
zhi
988cfcec4d BE-PR-007: mark task complete, update Backend submodule ref 2026-03-30 07:46:28 +00:00
zhi
6493e72d80 Update Backend submodule ref for BE-PR-006 2026-03-30 07:16:34 +00:00
zhi
23052db117 BE-PR-006: Add Essential CRUD API under Proposals
- New router: /projects/{project_id}/proposals/{proposal_id}/essentials
  - GET    (list)   - list all essentials under a proposal
  - POST   (create) - create essential with auto-generated EssentialCode
  - GET    /{id}    - get single essential by id or essential_code
  - PATCH  /{id}    - update essential (title, type, description)
  - DELETE /{id}    - delete essential
- All mutations restricted to open proposals only
- Permission: creator, project owner, or global admin
- Registered essentials router in main.py
- Updated GET /proposals/{id} to return ProposalDetailResponse with
  embedded essentials list
- Activity logging on all CRUD operations
2026-03-30 07:16:21 +00:00
zhi
5be0f11aac Update Backend submodule ref for BE-PR-005 2026-03-30 06:45:30 +00:00
zhi
5d20df11e9 BE-PR-005: Add Essential schema definitions (create/update/response) and ProposalDetailResponse with nested essentials 2026-03-30 06:45:06 +00:00
zhi
b688ebd35d BE-PR-004: implement EssentialCode encoding rules (submodule update) 2026-03-30 06:16:05 +00:00
zhi
1cdd05d554 BE-PR-003: Update Backend submodule ref + mark task complete 2026-03-29 16:33:10 +00:00
zhi
5ee79e5c5e BE-PR-003: Add Essential SQLAlchemy model
- New app/models/essential.py with Essential model and EssentialType enum
  (feature, improvement, refactor)
- Fields: id, essential_code (unique), proposal_id (FK to proposes),
  type, title, description, created_by_id (FK to users), created_at, updated_at
- Added essentials relationship to Proposal model (cascade delete-orphan)
- Added essentials table auto-migration in main.py _migrate_schema()
- Registered essential module import in startup()
2026-03-29 16:32:40 +00:00
zhi
598900650d chore: update Backend submodule pointer (BE-PR-002) 2026-03-29 16:02:22 +00:00
zhi
ac585b09b1 BE-PR-002: Proposal model naming & field adjustments
- Add comprehensive docstring to Proposal model documenting all relationships
- Add column comments for all fields (title, description, status, project_id, etc.)
- Mark feat_task_id as DEPRECATED (will be replaced by Essential→task mapping in BE-PR-008)
- Add proposal_code hybrid property as preferred alias for DB column propose_code
- Update ProposalResponse schema to include proposal_code alongside propose_code
- Update serializer to emit both proposal_code and propose_code for backward compat
- No DB migration needed — only Python-level changes
2026-03-29 16:02:07 +00:00
zhi
55ac776462 BE-PR-001: Rename Propose -> Proposal across backend
- Backend: new canonical Proposal model + /proposals router
- Backward-compat shims for old Propose imports and /proposes API
- Tests updated to use /proposals, legacy compat tests added
- Impact checklist: docs/BE-PR-001-rename-impact.md
- TASKLIST.md: BE-PR-001 marked complete

All 21 proposal tests pass.
2026-03-29 15:35:59 +00:00
zhi
339f9aa126 DOC-003: 整理 Calendar 验收清单
- 后端验收项: 数据模型、Slot ID 策略与物化、验证规则、不可变性、Calendar API、Agent/心跳协作
- 前端验收项: 页面骨架、日程展示、计划展示、操作交互、状态提示、权限
- CLI 验收项: 命令组、日程/计划操作命令、输出格式、用户创建扩展
- 插件联动验收项: 心跳请求、唤醒逻辑、状态管理、ScheduledGatewayRestart
- 跨模块集成验收项
2026-03-29 15:01:35 +00:00
zhi
c2b11248d7 DOC-002: Proposal/Essential/Story restricted migration guide
- Document Propose → Proposal naming changes across all layers
- Document Proposal Accept semantic change (single task → Essential-based batch)
- Document story/* restricted expansion and impact analysis
- Document feat_task_id deprecation and backward compatibility strategy
- Document migration execution order and rollback plan
2026-03-29 14:32:23 +00:00
zhi
d6ed523731 DOC-001: 整理本波开发范围说明
- 明确 Calendar 为独立功能线,Proposal/Essential 为项目结构调整线
- 明确两条线交叉点仅限 event_data / Agent 调度引用层
- 区分必须本波完成 vs 仅设计保留内容
- 新增 docs/wave-2026-03-scope.md
2026-03-29 14:01:10 +00:00
d7029a1cc7 Merge pull request 'chore/archive-plans-and-next-wave-doc' (#6) from chore/archive-plans-and-next-wave-doc into main
Reviewed-on: #6
2026-03-29 11:45:01 +00:00
11 changed files with 240 additions and 292 deletions

3
.gitmodules vendored
View File

@@ -24,6 +24,3 @@
path = HarborForge.Cli path = HarborForge.Cli
url = https://git.hangman-lab.top/zhi/HarborForge.Cli.git url = https://git.hangman-lab.top/zhi/HarborForge.Cli.git
branch = main branch = main
[submodule "HarborForge.PlexumPlugin"]
path = HarborForge.PlexumPlugin
url = https://git.hangman-lab.top/zhi/HarborForge.PlexumPlugin.git

159
README.md
View File

@@ -1,148 +1,101 @@
# HarborForge # HarborForge
Agent / human collaborative task-management platform — manages the full Agent/人类协同任务管理平台
proposal → milestone → task lifecycle with strict state machines, plus a
CLI, monitoring, and OpenClaw integration.
## Repository layout ## 项目结构
This is the umbrella repository; every component is a git submodule:
``` ```
HarborForge/ HarborForge/
├── AbstractWizard/ # Go, secure first-time setup service (SSH tunnel, port 8080) ├── HarborForge.Backend/ # 后端 (FastAPI + MySQL)
├── HarborForge.Backend/ # Python/FastAPI, core REST API + RBAC (port 8000) ├── HarborForge.Frontend/ # 前端 (React + Vite)
├── HarborForge.Frontend/ # React + TypeScript + Vite single-page app (port 3000) ├── docker-compose.yml # Docker 部署配置
├── HarborForge.Cli/ # Go command-line client `hf` ├── nginx-host.conf.example # 宿主机 nginx 配置示例
── HarborForge.Monitor/ # Go host telemetry client (optional local bridge 9100) ── .env.example # 环境变量模板
├── HarborForge.OpenclawPlugin/ # Node OpenClaw plugin `harbor-forge`
├── HarborForge.Test/ # Integration tests (backend pytest / frontend Playwright)
├── docker-compose.yml # Docker orchestration
├── nginx-host.conf.example # Host nginx config example
└── .env.example # Environment variable template
``` ```
## Quick start ## 快速开始
```bash ```bash
# Clone and initialize all submodules # 克隆并初始化子模块
git clone --recurse-submodules https://git.hangman-lab.top/zhi/HarborForge.git git clone https://git.hangman-lab.top/zhi/HarborForge.git
cd HarborForge cd HarborForge
# If already cloned without submodules:
git submodule update --init --recursive git submodule update --init --recursive
# Configure environment (do NOT use the defaults — see "Security") # 启动服务
cp .env.example .env
# Edit .env: set at minimum a strong random SECRET_KEY and DB passwords
# Start the services
docker compose up -d docker compose up -d
``` ```
## First deployment — setup wizard ## 首次部署 — 初始化向导
HarborForge uses [AbstractWizard](./AbstractWizard) for secure HarborForge 使用 [AbstractWizard](https://git.hangman-lab.top/hzhang/AbstractWizard) 进行安全初始化。
initialization. The wizard listens on `127.0.0.1` only and must be Wizard 仅监听 `127.0.0.1`,必须通过 SSH 隧道访问。
reached over an SSH tunnel.
```bash ```bash
# 1. SSH tunnel: forward the wizard port to your machine # 1. SSH 隧道映射 wizard 端口到本地
ssh -L 18080:127.0.0.1:18080 user@your-server ssh -L 18080:127.0.0.1:18080 user@your-server
# 2. Open the frontend in a browser (or via the host nginx). # 2. 浏览器访问前端(或通过宿主机 nginx
# If the backend is not initialized, it redirects to the setup wizard. # 前端检测到后端未就绪 → 自动跳转初始化向导
# 3. In the wizard, configure: database connection, admin account, # 3. 在向导中配置:
# default project (optional). # - 数据库连接信息
# - 管理员账号
# - 默认项目(可选)
# 4. Once saved, the backend detects the config and starts; refresh # 4. 配置保存后,后端自动检测到配置并启动
# the page → login screen. # 刷新页面 → 进入登录界面
``` ```
### Startup flow ### 启动流程
``` ```
docker compose up docker compose up
├── mysql → database starts ├── mysql → 数据库启动
├── wizard → AbstractWizard starts (127.0.0.1, SSH-tunnel access) ├── wizard → AbstractWizard 启动 (127.0.0.1:18080)
├── backend → blocks waiting for the config file (polls /config/harborforge.json) ├── backend → 等待配置文件... (轮询 /config/harborforge.json)
└── frontend → checks backend state └── frontend → 检测后端状态
├── backend not ready → shows the setup wizard (SSH tunnel to wizard) ├── 后端未就绪 → 显示初始化向导 (SSH 隧道连 wizard)
└── backend ready → normal login screen └── 后端就绪 → 正常登录界面
``` ```
### Security model ### 安全模型
- The wizard port binds to `127.0.0.1` and is never exposed to the - Wizard 端口绑定 `127.0.0.1`,不暴露到外部网络
external network; initialization must be done over an SSH tunnel. - 初始化必须通过 SSH 隧道完成(与 AbstractWizard 安全模型一致)
- Config is shared with the backend via a Docker volume (never over the - 配置完成后 Wizard 自动切换为只读模式
network); the backend mounts it read-only. - 配置通过 Docker volume 共享给后端(不走网络)
## Deployment architecture ## 部署架构
``` ```
Host nginx (80/443) 宿主机 nginx (80/443)
├── / → frontend (Docker, port 3000) ├── / → frontend (Docker, port 3000)
└── /api/ → backend (Docker, port 8000) └── /api/ → backend (Docker, port 8000)
Internal to Docker (not exposed): Docker 内部 (不暴露):
wizard (127.0.0.1) → config management, SSH-tunnel access wizard (127.0.0.1:18080) → 配置管理SSH 隧道访问
wizard_config vol → written by wizard, read-only for the backend wizard_config volume → wizard 写入,backend 读取
mysql (127.0.0.1) → data persistence
``` ```
## Submodules ## 子模块
| Submodule | Stack | Role | - [HarborForge.Backend](https://git.hangman-lab.top/zhi/HarborForge.Backend) - FastAPI 后端 API
|-----------|-------|------| - [HarborForge.Frontend](https://git.hangman-lab.top/zhi/HarborForge.Frontend) - React 前端
| [AbstractWizard](./AbstractWizard) | Go | First-time setup wizard; atomic config writes + backups; init/readonly modes |
| [HarborForge.Backend](./HarborForge.Backend) | Python / FastAPI / SQLAlchemy / MySQL | Core API: users, projects, tasks, milestones, proposals, RBAC, webhooks, worklogs, notifications |
| [HarborForge.Frontend](./HarborForge.Frontend) | React 18 / TS / Vite | SPA, ~20 pages; auto-detects an uninitialized backend → setup wizard |
| [HarborForge.Cli](./HarborForge.Cli) | Go | Permission-aware command-line client `hf` |
| [HarborForge.Monitor](./HarborForge.Monitor) | Go | Standalone host telemetry client, heartbeat reporting |
| [HarborForge.OpenclawPlugin](./HarborForge.OpenclawPlugin) | Node / TS | OpenClaw plugin; bridges telemetry; can install the `hf` skills and calendar scheduling |
| [HarborForge.Test](./HarborForge.Test) | pytest / Playwright | Backend and frontend integration tests |
## Core domain model ## 端口
- **Milestone**: `open → freeze → undergoing → completed` (freeze | 服务 | 默认端口 | 绑定 | 环境变量 |
requires exactly one release task) |------|----------|------|----------|
- **Task** (issue / story / test / maintenance / research / review / | Frontend | 3000 | 0.0.0.0 | `FRONTEND_PORT` |
resolution): `pending → open → undergoing → completed`; completion | Backend | 8000 | 0.0.0.0 | `BACKEND_PORT` |
requires a comment
- **Proposal**: a user proposes → a manager accepts → a feature-story
task is auto-created in a milestone; rejected proposals can reopen
- **RBAC**: fine-grained permissions + a project role hierarchy
(guest < viewer < member < dev < mgr < admin)
## Ports
| Service | Container port | Bind | Env var |
|---------|----------------|------|---------|
| Frontend | 3000 | see compose | `FRONTEND_PORT` |
| Backend | 8000 | see compose | `BACKEND_PORT` |
| MySQL | 3306 | 127.0.0.1 | `MYSQL_PORT` | | MySQL | 3306 | 127.0.0.1 | `MYSQL_PORT` |
| Wizard | 8080 | 127.0.0.1 | `WIZARD_PORT` | | Wizard | 18080 | 127.0.0.1 | `WIZARD_PORT` |
> The SSH-tunnel example uses local port `18080` forwarding to the ## 前端页面
> server-side wizard.
## Security - 🔧 初始化向导 — 首次部署配置SSH 隧道)
- 📊 仪表盘 — 统计概览
Before deploying, you must: - 📋 Issues — 创建、列表、详情、状态变更、评论
- 📁 项目 — 项目管理、成员、关联 issue
- **Set a strong random `SECRET_KEY`** (e.g. `openssl rand -hex 32`). - 🏁 里程碑 — 进度追踪、完成百分比
The backend refuses to start on a weak/default/short key. - 🔔 通知 — 实时通知中心、未读计数
- Not use the placeholder passwords from `.env.example`; set a strong
MySQL password.
- Never commit a `.env` containing real secrets.
The backend's auth / RBAC / SSRF hardening is documented in the
"Security" section of the
[HarborForge.Backend README](./HarborForge.Backend).
## Frontend
The frontend uses a centralized custom design system (the industrial
"Foundry Deck" theme); see the
[HarborForge.Frontend README](./HarborForge.Frontend) for details.

View File

@@ -144,237 +144,236 @@
- [x] 支持 job/system/event_data - [x] 支持 job/system/event_data
- [x] 接入 overlap 与 workload warning - [x] 接入 overlap 与 workload warning
- [x] BE-CAL-API-002:实现某日 Calendar 查询 APIbackend only - [ ] BE-CAL-API-002:实现某日 Calendar 查询 API(backend only)
- [x] 返回真实 slot - [ ] 返回真实 slot
- [x] 合成当日 plan 虚拟 slot - [ ] 合成当日 plan 虚拟 slot
- [x] 输出统一排序结构 - [ ] 输出统一排序结构
- [x] BE-CAL-API-003:实现 Calendar 编辑 APIbackend only - [ ] BE-CAL-API-003:实现 Calendar 编辑 API(backend only)
- [x] 支持真实 slot 编辑 - [ ] 支持真实 slot 编辑
- [x] 支持虚拟 slot 编辑并触发物化 - [ ] 支持虚拟 slot 编辑并触发物化
- [x] 返回编辑后的真实结果 - [ ] 返回编辑后的真实结果
- [x] BE-CAL-API-004:实现 Calendar 取消 API(backend only) - [ ] BE-CAL-API-004:实现 Calendar 取消 API(backend only)
- [x] 支持真实 slot cancel - [ ] 支持真实 slot cancel
- [x] 支持虚拟 slot cancel 并触发物化 - [ ] 支持虚拟 slot cancel 并触发物化
- [x] 处理状态字段更新 - [ ] 处理状态字段更新
- [x] BE-CAL-API-005:实现 plan-schedule / plan-list API(backend only) - [ ] BE-CAL-API-005:实现 plan-schedule / plan-list API(backend only)
- [x] 创建计划 - [ ] 创建计划
- [x] 列出计划 - [ ] 列出计划
- [x] 返回计划规则字段 - [ ] 返回计划规则字段
- [x] BE-CAL-API-006:实现 plan-edit / plan-cancel APIbackend only - [ ] BE-CAL-API-006:实现 plan-edit / plan-cancel API(backend only)
- [x] 编辑计划 - [ ] 编辑计划
- [x] 取消计划 - [ ] 取消计划
- [x] 不追溯已物化过去数据 - [ ] 不追溯已物化过去数据
- [x] BE-CAL-API-007:实现 date-list API(backend only) - [ ] BE-CAL-API-007:实现 date-list API(backend only)
- [x] 仅列出有已物化未来 slot 的日期 - [ ] 仅列出有已物化未来 slot 的日期
- [x] 排除纯 plan 未物化日期 - [ ] 排除纯 plan 未物化日期
## E. HarborForge.Backend - Agent / Plugin Calendar 协作 ## E. HarborForge.Backend - Agent / Plugin Calendar 协作
- [x] BE-AGT-001:定义心跳查询待执行 slot 的服务层(backend only) - [ ] BE-AGT-001:定义心跳查询待执行 slot 的服务层(backend only)
- [x] 筛选当天 `NotStarted / Deferred` - [ ] 筛选当天 `NotStarted / Deferred`
- [x] 仅返回 `scheduled_at` 已过的 slot - [ ] 仅返回 `scheduled_at` 已过的 slot
- [x] 按优先级排序 - [ ] 按优先级排序
- [x] BE-AGT-002:实现 Agent 状态流转服务(backend only) - [ ] BE-AGT-002:实现 Agent 状态流转服务(backend only)
- [x] Idle -> Busy / OnCall - [ ] Idle -> Busy / OnCall
- [x] Busy / OnCall -> Idle - [ ] Busy / OnCall -> Idle
- [x] 超时无心跳 -> Offline - [ ] 超时无心跳 -> Offline
- [x] API 配额错误 -> Exhausted - [ ] API 配额错误 -> Exhausted
- [x] BE-AGT-003:实现多 slot 竞争处理(backend only) - [ ] BE-AGT-003:实现多 slot 竞争处理(backend only)
- [x] 选最高 priority 执行 - [ ] 选最高 priority 执行
- [x] 其余 slot 标记 Deferred - [ ] 其余 slot 标记 Deferred
- [x] Deferred slot 自动 priority += 1 - [ ] Deferred slot 自动 priority += 1
- [x] BE-AGT-004:实现 Exhausted 恢复时间解析(backend only) - [ ] BE-AGT-004:实现 Exhausted 恢复时间解析(backend only)
- [x] 解析 retry-after / reset in / resets at - [ ] 解析 retry-after / reset in / resets at
- [x] 解析失败时默认 5 小时 - [ ] 解析失败时默认 5 小时
- [x] 到期恢复 Idle - [ ] 到期恢复 Idle
## F. HarborForge.Frontend - Proposal / Essential / Story restricted ## F. HarborForge.Frontend - Proposal / Essential / Story restricted
- [x] FE-PR-001:前端统一重命名 Propose -> Proposal(frontend only) - [ ] FE-PR-001:前端统一重命名 Propose -> Proposal(frontend only)
- [x] 调整页面标题与菜单文案 - [ ] 调整页面标题与菜单文案
- [x] 调整类型名与 API 调用命名 - [ ] 调整类型名与 API 调用命名
- [x] 清理旧 propose 文案 - [ ] 清理旧 propose 文案
- [x] FE-PR-002:Proposal 详情页增加 Essential 列表区(frontend only) - [ ] FE-PR-002:Proposal 详情页增加 Essential 列表区(frontend only)
- [x] 展示 Essential 列表 - [ ] 展示 Essential 列表
- [x] 展示 Essential type / code / title - [ ] 展示 Essential type / code / title
- [x] 处理空状态 - [ ] 处理空状态
- [x] FE-PR-003:新增 Essential 创建/编辑表单(frontend only) - [ ] FE-PR-003:新增 Essential 创建/编辑表单(frontend only)
- [x] 创建表单 - [ ] 创建表单
- [x] 编辑表单 - [ ] 编辑表单
- [x] type 选择器 - [ ] type 选择器
- [x] 提交后局部刷新 - [ ] 提交后局部刷新
- [x] FE-PR-004:Proposal Accept 增加目标 Milestone 选择(frontend only) - [ ] FE-PR-004:Proposal Accept 增加目标 Milestone 选择(frontend only)
- [x] Accept 前展示 milestone 选择控件 - [ ] Accept 前展示 milestone 选择控件
- [x] 校验必须选择 milestone - [ ] 校验必须选择 milestone
- [x] 展示 Accept 成功后的生成结果 - [ ] 展示 Accept 成功后的生成结果
- [x] FE-PR-005:限制前端直接创建 `story/*`(frontend only) - [ ] FE-PR-005:限制前端直接创建 `story/*`(frontend only)
- [x] 从 Task 创建入口移除 story - [ ] 从 Task 创建入口移除 story
- [x] 或将 story 整体设为不可选 - [ ] 或将 story 整体设为不可选
- [x] 调整相关提示文案 - [ ] 调整相关提示文案
## G. HarborForge.Frontend - Calendar ## G. HarborForge.Frontend - Calendar
- [x] FE-CAL-001:新增 Calendar 页面基础骨架(frontend only) - [ ] FE-CAL-001:新增 Calendar 页面基础骨架(frontend only)
- [x] 增加路由入口 - [ ] 增加路由入口
- [x] 增加侧边栏入口 - [ ] 增加侧边栏入口
- [x] 增加基础页面布局 - [ ] 增加基础页面布局
- [x] FE-CAL-002:实现某日 slot 列表展示(frontend only) - [ ] FE-CAL-002:实现某日 slot 列表展示(frontend only)
- [x] 展示时间轴或列表 - [ ] 展示时间轴或列表
- [x] 区分真实 slot 与 plan 虚拟 slot - [ ] 区分真实 slot 与 plan 虚拟 slot
- [x] 展示状态 / 类型 / 时长 / 优先级 - [ ] 展示状态 / 类型 / 时长 / 优先级
- [x] FE-CAL-003:实现计划列表展示(frontend only) - [ ] FE-CAL-003:实现计划列表展示(frontend only)
- [x] 展示计划规则 - [ ] 展示计划规则
- [x] 展示周期参数 - [ ] 展示周期参数
- [x] 支持跳转编辑 - [ ] 支持跳转编辑
- [x] FE-CAL-004:实现创建 / 编辑 / 取消日程交互(frontend only) - [ ] FE-CAL-004:实现创建 / 编辑 / 取消日程交互(frontend only)
- [x] 新建 slot 表单 - [ ] 新建 slot 表单
- [x] 编辑 slot 表单 - [ ] 编辑 slot 表单
- [x] cancel 操作确认 - [ ] cancel 操作确认
- [x] 展示后端 warning - [ ] 展示后端 warning
- [x] FE-CAL-005:实现 Deferred / Exhausted / overlap 等状态提示(frontend only) - [ ] FE-CAL-005:实现 Deferred / Exhausted / overlap 等状态提示(frontend only)
- [x] Deferred 提示 - [ ] Deferred 提示
- [x] overlap 报错展示 - [ ] overlap 报错展示
- [x] workload warning 展示 - [ ] workload warning 展示
- [x] Exhausted 状态展示 - [ ] Exhausted 状态展示
## H. HarborForge.Cli - Proposal / Essential / Story restricted ## H. HarborForge.Cli - Proposal / Essential / Story restricted
- [x] CLI-PR-001:统一 CLI 文案 `propose -> proposal`(cli only) - [ ] CLI-PR-001:统一 CLI 文案 `propose -> proposal`(cli only)
- [x] 调整命令 help 文案 - [ ] 调整命令 help 文案
- [x] 调整输出文本 - [ ] 调整输出文本
- [x] 评估命令名是否兼容保留 `hf propose` → 保留为 alias - [ ] 评估命令名是否兼容保留 `hf propose`
- [x] CLI-PR-002:新增 Essential 相关命令(cli only) - [ ] CLI-PR-002:新增 Essential 相关命令(cli only)
- [x] `hf proposal essential list` - [ ] `hf proposal essential list`
- [x] `hf proposal essential create` - [ ] `hf proposal essential create`
- [x] `hf proposal essential update` - [ ] `hf proposal essential update`
- [x] `hf proposal essential delete` - [ ] `hf proposal essential delete`
- [x] CLI-PR-003:更新 Proposal Accept CLI(cli only) - [ ] CLI-PR-003:更新 Proposal Accept CLI(cli only)
- [x] Accept 时支持传入 milestone - [ ] Accept 时支持传入 milestone
- [x] 展示批量生成的 task 结果 - [ ] 展示批量生成的 task 结果
- [x] 更新帮助文案 - [ ] 更新帮助文案
- [x] CLI-PR-004:限制 CLI 直接创建 `story/*`(cli only) - [ ] CLI-PR-004:限制 CLI 直接创建 `story/*`(cli only)
- [x] 阻止 story 类型直建 - [ ] 阻止 story 类型直建
- [x] 返回明确错误提示 - [ ] 返回明确错误提示
- [x] 提示改走 Proposal Accept - [ ] 提示改走 Proposal Accept
## I. HarborForge.Cli - Calendar ## I. HarborForge.Cli - Calendar
- [x] CLI-CAL-001:新增 `hf calendar` 命令组骨架(cli only) - [ ] CLI-CAL-001:新增 `hf calendar` 命令组骨架(cli only)
- [x] 注册命令组 - [ ] 注册命令组
- [x] 增加 help surface - [ ] 增加 help surface
- [x] 增加 brief help - [ ] 增加 brief help
- [x] CLI-CAL-002:实现 `hf calendar schedule`(cli only) - [ ] CLI-CAL-002:实现 `hf calendar schedule`(cli only)
- [x] 参数解析 - [ ] 参数解析
- [x] 请求构造 - [ ] 请求构造
- [x] 结果输出 - [ ] 结果输出
- [x] CLI-CAL-003:实现 `hf calendar show`(cli only) - [ ] CLI-CAL-003:实现 `hf calendar show`(cli only)
- [x] 日期参数 - [ ] 日期参数
- [x] 列表输出 - [ ] 列表输出
- [x] JSON 输出 - [ ] JSON 输出
- [x] CLI-CAL-004:实现 `hf calendar edit`(cli only) - [ ] CLI-CAL-004:实现 `hf calendar edit`(cli only)
- [x] 支持 slot-id 与 date - [ ] 支持 slot-id 与 date
- [x] PATCH/POST 适配 - [ ] PATCH/POST 适配
- [x] 输出 warning / error - [ ] 输出 warning / error
- [x] CLI-CAL-005:实现 `hf calendar cancel`(cli only) - [ ] CLI-CAL-005:实现 `hf calendar cancel`(cli only)
- [x] 支持 slot-id 与 date - [ ] 支持 slot-id 与 date
- [x] 输出结果 - [ ] 输出结果
- [x] CLI-CAL-006:实现 `hf calendar date-list`(cli only) - [ ] CLI-CAL-006:实现 `hf calendar date-list`(cli only)
- [x] 列出未来已物化日期 - [ ] 列出未来已物化日期
- [x] 适配 JSON 输出 - [ ] 适配 JSON 输出
- [x] CLI-CAL-007:实现 `hf calendar plan-schedule`(cli only) - [ ] CLI-CAL-007:实现 `hf calendar plan-schedule`(cli only)
- [x] 参数解析 `--at --on-day --on-week --on-month` - [ ] 参数解析 `--at --on-day --on-week --on-month`
- [x] 请求构造 - [ ] 请求构造
- [x] 输出结果 - [ ] 输出结果
- [x] CLI-CAL-008:实现 `hf calendar plan-list`(cli only) - [ ] CLI-CAL-008:实现 `hf calendar plan-list`(cli only)
- [x] 列表输出 - [ ] 列表输出
- [x] JSON 输出 - [ ] JSON 输出
- [x] CLI-CAL-009:实现 `hf calendar plan-edit`(cli only) - [ ] CLI-CAL-009:实现 `hf calendar plan-edit`(cli only)
- [x] 参数解析 - [ ] 参数解析
- [x] 请求发送 - [ ] 请求发送
- [x] 输出结果 - [ ] 输出结果
- [x] CLI-CAL-010:实现 `hf calendar plan-cancel`(cli only) - [ ] CLI-CAL-010:实现 `hf calendar plan-cancel`(cli only)
- [x] 参数解析 - [ ] 参数解析
- [x] 请求发送 - [ ] 请求发送
- [x] 输出结果 - [ ] 输出结果
## J. HarborForge.OpenclawPlugin / Monitor 联动 ## J. HarborForge.OpenclawPlugin / Monitor 联动
- [x] PLG-CAL-001:插件侧定义 Calendar 心跳请求格式(plugin only) - [ ] PLG-CAL-001:插件侧定义 Calendar 心跳请求格式(plugin only)
- [x] 明确 claw_identifier 传递方式 - [ ] 明确 claw_identifier 传递方式
- [x] 明确 agent_id 传递方式 - [ ] 明确 agent_id 传递方式
- [x] 明确返回 slot 列表结构 - [ ] 明确返回 slot 列表结构
- [x] PLG-CAL-002:插件侧处理待执行 slot 唤醒(plugin only) - [ ] PLG-CAL-002:插件侧处理待执行 slot 唤醒(plugin only)
- [x] Idle 时唤醒 agent - [ ] Idle 时唤醒 agent
- [x] 透传任务上下文 - [ ] 透传任务上下文
- [x] 执行前更新 attended / started_at / status - [ ] 执行前更新 attended / started_at / status
- [x] PLG-CAL-003:插件侧处理非 Idle / Deferred 分支(plugin only) - [ ] PLG-CAL-003:插件侧处理非 Idle / Deferred 分支(plugin only)
- [x] Agent 非 Idle 时上报 Deferred - [ ] Agent 非 Idle 时上报 Deferred
- [x] 处理多 slot 重排后的重新规划 - [ ] 处理多 slot 重排后的重新规划
- [x] PLG-CAL-004:插件侧处理 ScheduledGatewayRestart(plugin only) - [ ] PLG-CAL-004:插件侧处理 ScheduledGatewayRestart(plugin only)
- [x] 收到事件后持久化状态 - [ ] 收到事件后持久化状态
- [x] 发送最终心跳 - [ ] 发送最终心跳
- [x] 暂停定时任务 - [ ] 暂停定时任务
## K. Tests / Integration(按子模块分别补,不混做) ## K. Tests / Integration(按子模块分别补,不混做)
- [x] TEST-BE-CAL-001:补 Calendar backend 测试(backend tests only) - [ ] TEST-BE-CAL-001:补 Calendar backend 测试(backend tests only)
- [x] 模型测试 - [ ] 模型测试
- [x] API 测试 - [ ] API 测试
- [x] overlap / warning / materialize 测试 - [ ] 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) - [ ] TEST-BE-PR-001:补 Proposal / Essential backend 测试(backend tests only)
- [x] Essential CRUD - [ ] Essential CRUD
- [x] Accept 生成 story tasks - [ ] Accept 生成 story tasks
- [x] story restricted - [ ] story restricted
- [x] TEST-FE-CAL-001:补 Calendar 前端测试(frontend tests only) - [ ] TEST-FE-CAL-001:补 Calendar 前端测试(frontend tests only)
- [x] 页面渲染 - [ ] 页面渲染
- [x] 表单交互 - [ ] 表单交互
- [x] warning / error 展示 - [ ] warning / error 展示
- [x] TEST-FE-PR-001:补 Proposal / Essential 前端测试(frontend tests only) - [ ] TEST-FE-PR-001:补 Proposal / Essential 前端测试(frontend tests only)
- [x] Essential 列表与表单 - [ ] Essential 列表与表单
- [x] Accept milestone 选择 - [ ] Accept milestone 选择
- [x] story 创建入口限制 - [ ] story 创建入口限制
- [x] TEST-CLI-CAL-001:补 Calendar CLI 测试(cli tests only) - [ ] TEST-CLI-CAL-001:补 Calendar CLI 测试(cli tests only)
- [x] 命令解析 - [ ] 命令解析
- [x] JSON 输出 - [ ] JSON 输出
- [x] 错误输出 - [ ] 错误输出
- [x] TEST-CLI-PR-001:补 Proposal / Essential CLI 测试(cli tests only) - [ ] TEST-CLI-PR-001:补 Proposal / Essential CLI 测试(cli tests only)
- [x] Essential 子命令 - [ ] Essential 子命令
- [x] accept milestone 参数 - [ ] accept milestone 参数
- [x] story 限制提示 - [ ] story 限制提示