Two new console pages requested directly by the user, beyond 02-V's
original declared non-goal ("不做完整多项目管理 UI(项目列表/切换)"):
- v_project_list: full project list + rename + archive/reactivate.
"Import an existing directory with real code" needs no new code --
project_scaffold.create_project() already only ever adds .graphlemon/
inside the target folder. New: src/project_query.py (list/get/update),
GET/PUT/DELETE /api/projects[/:id]. DELETE archives (status='archived'),
never a physical row delete -- project_id is FK-referenced from task/
artifact/bug_record/etc., and 01-M's own active/archived enum already
models this as soft-delete.
- v_goal_list: extends the existing v_task_board/v_task_detail rather than
duplicating them. Added sort/order to task_query.list_tasks() (column
whitelist, no injection surface) and edit/delete on v_task_detail, both
restricted to status='queued' (task_query.TaskNotEditableError, HTTP 409)
-- editing or deleting a goal after real work has referenced it would
leave that history pointing at something that no longer matches reality.
Implemented directly rather than through graphlemon's own self-hosting
loop -- confirmed with the user first that implement_code() always uses a
hardcoded single-node manifest (no plan_work_graph() call for Coder), so a
multi-page/multi-endpoint feature like this would've been one unreviewable
Coder session with no way to decompose it.
Real bug found on first verification pass (not caught by the existing
_insert_task test helper, which never writes execution_event): a real
task_create.create_task() always writes an execution_event row in the same
transaction (01-M's FK, no ON DELETE CASCADE) -- even a never-touched
queued task already has one, so DELETE FROM task raised
sqlite3.IntegrityError. Fixed by clearing the task's own execution_event
rows first; new regression test goes through the real create_task() path.
474 tests green. Verified end-to-end against a real running server (every
new endpoint exercised via curl) since the Chrome extension is still
unavailable this session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>