caoqianming
|
80a658eba4
|
core(§7 Phase G G2): task list 页 + /tasks/{id} 占位
- web/app.py 加 list_tasks(limit, status):PG tasks + messages count,
updated_at 降序,返回模板友好 dict。Web 与 cli.py 数据形状不一致
(CLI 用 tuple,Web 用 dict),不预付抽象,等真有 schema 同步成本
再抽。
- / 路由换成 task 列表,支持 ?status=active|completed|abandoned
filter(无效值静默降级 all)。/tasks/{task_id} 占位路由:UUID 解析
失败 → 404,DB 不存在 → 404,有效则渲 task_placeholder.html(G3 来填
消息流)。
- Linux portability:_norm_path() 显示前 replace('\','/') 把 Win
存的 backslash 归一,Win Path.resolve()-str → "D:/..." 显示;Linux
forward-slash 原路通过。Path.as_posix() 在 Linux 读 Win backslash
串时不归一,所以选 replace 而非 as_posix。
- 模板 home.html 表格(id/updated/status/mode/model/msgs/tokens/desc-dir)
+ status badge 配色(active 绿 / completed 蓝 / abandoned 灰) +
filter 表单 + 空态文案。task_placeholder.html 渲染 G3 提示。CSS
tabular-nums 数字对齐 / hover 高亮 / accent-soft note。
Smoke 18 路径全绿(in-process Starlette TestClient):3 task seed
(active/completed/abandoned)+ Win\Linux 双路径形态 → / 渲染对、
status filter 正反向、garbage status 静默 all、UUID 占位、notauuid
404、ghost UUID 404、limit 生效、/healthz 不退化。版本 0.1 → 0.2。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 15:52:11 +08:00 |
caoqianming
|
91202b6172
|
core(§7 Phase G G1): Web UI 脚手架 + cli.py web 子命令
- web/ 新包:app.py FastAPI 工厂(/ + /healthz + /static),Jinja2
base.html / home.html,minimal style.css。HTMX + HTMX-SSE 走 CDN
(无 node 链路,与 §5 Less Scaffolding 一致)。
- cli.py 加 web --host --port --reload 子命令,默认 127.0.0.1:8765,
本地形态 sentinel user 无 auth(Phase D 才上 OIDC)。
- requirements: fastapi / uvicorn[standard] / jinja2 / python-multipart
(multipart 为 G5 文件上传留)。
- Starlette 新签名踩坑:TemplateResponse(request, name, context),
旧式塞 context 里会让 jinja 用 dict 当 cache key 炸 unhashable,记
RUN.md 故障兜底。
- Linux portability:模板 path 显示约定 .as_posix();SSE 头 G4 上时
带 X-Accel-Buffering: no(nginx 反代友好)。`cli.py web` 在
.venv/Scripts/python.exe(Win)/ .venv/bin/python(Linux)走同一路径。
Smoke 四路径(in-process via Starlette TestClient)全绿:/healthz →
"ok" / / → 1063B(title + static + version)/ /static/style.css →
1624B / /nonexistent → 404。`cli.py web --help` 子命令注册 OK。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 13:37:54 +08:00 |
caoqianming
|
e8dbfa57a5
|
core(§7 B Step 6): no-subtask 前缀嵌套校验
- core/storage/utils.py 加 check_no_subtask + NoSubtaskError;PG LIKE
双向(new LIKE existing/% OR existing LIKE new/%),同 task_dir
允许(同项目多对话),空 / whitespace 跳过。
- 分隔符容差:SQL replace(task_dir, '\', '/') 把存的 Windows 反斜杠
与新值统一到 '/' 再比;backslash 通过 bind 参数传,绕开 SQL 转义。
- main.py::build_agent 在 resolve_task_id 后、TaskState 构造前调,
if not resume 单层闸 —— resume 跳过(改名走未来 Folder API cascade).
- cli.py 三处 build_agent 调用现有 try/except 直接接住 NoSubtaskError.
- PROGRESS / RUN 同步:Step 6 完工,故障兜底加一条 NoSubtaskError 处理.
Smoke(9 路径 + e2e 3 分支)全绿。§7 B 完工(Step 5 取消)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 11:59:37 +08:00 |
caoqianming
|
2b3692c8bf
|
core(§7 B Step 4): --task-dir 双形态 + RUN.md 运行手册
- CLI `chat --task-dir <path>` 让用户显式指定项目目录(§7.1 task-primary +
dir 副视图心智模型落地);留空走默认派生 workspace/tasks/<uuid>/。
- main.py::resolve_task_id 加 task_dir_arg;resume 时从 PG tasks.task_dir
读,空则降级默认派生。新增 is_managed_task_dir(td, ws) 判断 task_dir
是否在默认模板下。
- cli.py::_cleanup_if_empty 拿 workspace_dir 作保护开关 —— 用户自指定的
task_dir 绝不 rmtree(可能含用户已有素材);DB 行该删还是删。
- core/export_docx.py::export_chat_to_docx 重构:task_id 升一等参数(从
task_dir.name 提取改入参传入),task_dir 留空时自动从 PG 读;cli /export
与 cli.py export 子命令均改走 _resolve_uuid_or_prefix + task_id 直传。
- 新建 RUN.md(运行手册):env / 初始化 / 日常命令 / 故障兜底 / 关键路径。
- CLAUDE.md 加 RUN.md 维护规则(三文档边界:DESIGN=为什么 / PROGRESS=做到哪
/ RUN=怎么跑),对外行为改动同步更 RUN。
Smoke 4 路径:default-derived(managed=True, cleanup rmtree)/ --task-dir
(managed=False, FS preserved)/ resume reads DB task_dir / export 自动 PG
查路径,全绿。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 11:38:05 +08:00 |
caoqianming
|
aeecc7f0f3
|
core(§7 B Step 3): TaskState ORM + Web UI 设计 (Phase G)
- TaskState dataclass 改 PG-backed:save() → upsert_task (INSERT ON CONFLICT
DO UPDATE,显式刷 updated_at);load(task_id) → SELECT。state.json 全面
废除,task_dir 只承担 skill 产物。
- TaskState 字段去 cwd / 加 task_dir(对齐 §7 SaaS task_dir-as-identity);
cwd 只在 session.meta 内存视图保留(展示用)。
- core/storage/utils.py 新增 upsert_task / update_task;ORM-level UPDATE
自带 onupdate=func.now(),DO UPDATE 需显式 set。
- session.py Session.append 的 ensure 调用补传 mode/description/
reasoning_effort,避免首次 INSERT 后 _list_task_rows 看到空 meta。
- sync_task_tokens 改成 update_task 单字段 UPDATE,避免无谓全字段 UPSERT。
- cli.py _list_task_rows 全字段从 PG 读,status 过滤走 SQL WHERE;
_cleanup_if_empty 去 state.json 特例(任何 FS 文件/子目录都算实质痕迹)。
- core/export_docx.py meta 走 TaskState.load(tid),CWD 字段从 meta 表移除。
- DESIGN.md 追加 Phase G(Web UI 简洁版,FastAPI + Jinja2 + HTMX + SSE),
排在 §7.7 D 后;§7.9 补 server-render 不上 SPA 的取舍 4 条。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 11:25:53 +08:00 |
caoqianming
|
4f87bf14ee
|
core(§7 B Step 2): Session ORM — messages 走 PG, task_id 切 UUID
Session 重写
- messages 落 PG `messages` 表(append-only, idx 严格递增, jsonb payload)
- system prompt 不入库(每次 build_agent 重建到 messages[0],memory 演化即时生效)
- Session.load(task_id, system_prompt=...) 从 DB 读历史
- Session.task_exists / n_user_msgs 工具
Storage utils
- ensure_local_task_row: 首条消息前 INSERT ... ON CONFLICT DO NOTHING
打底 tasks 行(Step 3 后由 TaskState.save 接管字段更新)
task_id 切 UUID
- resolve_task_id(workspace, arg, resume): UUID + 前缀匹配,'last' 从 PG
按 updated_at 取最近
- 显示一律截前 8 位;完整 UUID 在 /id /status 保留
- 旧 workspace 老 task(时间戳格式)**不做兼容**
CLI 适配
- _cleanup_if_empty 双检查:DB messages count + FS 产物
- _list_task_rows: PG tasks ORDER BY updated_at + state.json 兜底字段
- _task_has_messages: /export 检查改 DB
- core/export_docx.py: messages 从 PG 读,state.json 留作 meta
Step 5 (migrate-from-fs) 取消。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 10:55:50 +08:00 |
caoqianming
|
425ea59937
|
core(§7 B Step 1): Storage 基建 — SQLAlchemy ORM + alembic + db CLI
- core/storage/{engine,models}.py: 5 表 ORM(users/tasks/messages/runs/
usage_events)+ session_scope 上下文 + 本地 sentinel user 初始化
- alembic 初版 migration 0001_initial_schema: messages.payload GIN
索引 + tasks (user_id, task_dir) 复合索引 + pgcrypto 扩展兜底
- cli.py: db upgrade/downgrade/current 子命令组;ZCBOT_DB_URL 未设
给 ASCII 报错 + exit 2(避开 Windows GBK 控制台编码问题)
- requirements: +sqlalchemy>=2.0 +psycopg[binary]>=3.1 +alembic>=1.13
- DB URL 来自环境变量 ZCBOT_DB_URL,不引导 docker(用户给测试库地址)
已在远端测试 PG 跑通 db upgrade head + db current。Session/TaskState
ORM 接入留 Step 2-3。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 10:41:44 +08:00 |
caoqianming
|
efe4a91c33
|
design: 精简 DESIGN/PROGRESS (-177 行)
DESIGN 520→351,PROGRESS 88→80。砍 §7 内部重复说理与 SQL 示例,
合并 §6/§7.8 风险表,压缩 §3 字段表与启动顺序;load-bearing 细节
(rename `old/%` 前缀、ModelCapabilities 字段、阶段估时)全部保留。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 08:52:23 +08:00 |
caoqianming
|
b4df60062e
|
design: 更新设计
|
2026-05-14 08:46:53 +08:00 |
caoqianming
|
e4a48fbb53
|
core: Session/TaskState 原子写 + Phase 6 双层记忆
- core.session.atomic_write_text (tmp + fsync + os.replace) 接管 Session/
TaskState 落盘, 中途异常不留 0 字节; _cleanup_if_empty 放过 *.tmp 孤儿
- core/memory.py: workspace/memory/{core.md, extended/} 双层记忆.
core.md 注 system prompt, extended/*.md 索引(标题+绝对路径)注 prompt,
内容靠 read 工具按需拉
- _build_system_prompt 从 build_agent 里提出来, new 和 resume 都走同一段,
resume 时覆盖 messages[0] -> memory 演化即时生效
- PROGRESS/DESIGN 同步: §7 platform track 行 + A 阶段完成 + 双层记忆/原子写
+ 文件清单到 2429 行
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-11 15:13:56 +08:00 |
caoqianming
|
ae93016442
|
cli: REPL /resume 切 task + 懒创建 task_dir + 切走前空清理
- 加 /resume [last|<id>] REPL 命令,无参数列最近 10 个表格让用户挑;
和 /new 对称,都在 REPL 内重建五元组。tasks 命令复用 _list_task_rows
- main.py 新建分支不再 session.save() / task_state.save() 占位 ——
推迟到首条 user 消息触发的 Session.append → save() 才物化 task_dir。
启动 REPL 立刻 /exit 磁盘无痕,跨进程也安全
- _cleanup_if_empty 在 /exit /quit /new /resume + Ctrl-C/EOF 守门:
无 user 消息 + 目录在磁盘上 + 文件集 ⊆ {messages.json} 才删,
state.json 存在(/done /abandon /desc 留下的显式痕迹)就保
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-08 09:55:56 +08:00 |
caoqianming
|
56e414e046
|
proposal: 阶段二两段式 + render_docx 透传 fenced 代码块
- SKILL.md 阶段二改两段式: 先列 3-6 条要点 → 用户确认 → 再起草 → 用户确认。关键章节 (立项依据/研究方案/技术路线/考核指标) 一段一卡。一次性出全文容易把错方向推到底,要点阶段拦得早
- render_docx.py 支持 ```...``` 围栏: 中文新宋体 + 西文 Consolas + 行距 1.0 + 不缩进 + xml:space=preserve。原先 ASCII 流程图被当散文段落合并,框完全错位
- PROGRESS.md backlog 加 mermaid 预渲染 (mmdc → PNG → add_picture),等 ASCII 透传不够用再做
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-08 08:58:18 +08:00 |
caoqianming
|
a32cb049bc
|
ppt+proposal: 素材摄取改用 markitdown, 删自研 source_to_md
ppt/proposal 的"素材 → Markdown"逻辑此前各写一份 (source_to_md.py
内联 pypdf/python-docx/openpyxl), 改用微软 markitdown CLI 统一替换:
表格/标题/列表保留更好, 同时多覆盖 xlsx/url/html/csv 等格式。
- requirements.txt: 加 markitdown[pdf,docx,pptx,xlsx]
- skills/ppt/SKILL.md: 资源行改成 markitdown 说明
- skills/proposal/SKILL.md: 阶段零 32 行 Python 代码 → 4 行 CLI
- skills/ppt/scripts/source_to_md.py: 删除 (157 行)
- PROGRESS.md: scripts 列表同步
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-08 08:03:07 +08:00 |
caoqianming
|
3869089a44
|
DESIGN/PROGRESS: 同步 TUI 打磨 + task_dir 落地
DESIGN: 目录树补全 task_dir 内的 skill 产物;启动顺序 #5 加 task_dir 注入;
3.1 主循环增补 markdown 渲染、spinner 实时耗时/token、每轮成本行。
PROGRESS: 加 2026-05-07 条目;工具基目录决策更新;loop/main 行数刷新。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-07 14:20:59 +08:00 |
caoqianming
|
a25fcbc703
|
精简 DESIGN/PROGRESS:对齐当前实现,去掉落地前的设想
- DESIGN.md 1140 → 212 行:删 v1/v2 比较、Eval Suite 章节、Phase
roadmap、长代码草图、技术栈清单(在 requirements.txt)、超长附录
- PROGRESS.md 185 → 82 行:删超细分的 ppt v3 描述、重复测试列表
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-06 16:26:19 +08:00 |
caoqianming
|
dbb778fe10
|
Phase 4 + 6: capability probe + task 概念 / state.json
- core/probe.py + cli.py probe: basic_chat / parallel_tools /
thinking_mode / long_context 四项实测对账 yaml;不进启动路径
- core/task.py + main.py: workspace/tasks/<id>/{state.json, messages.json},
TaskState 跟 mode/desc/status/tokens/timestamps;build_agent 返 5 元组
- cli.py tasks 子命令 + REPL /status /done /abandon /desc;chat 加
--mode/--desc 选项;移除 legacy workspace/sessions/ 兼容
Phase 5 evals 评估后决定不做:个人工具用 dogfooding 判断模型升级,
probe 已覆盖健康检查;造作 case 没区分度,维护成本不划算。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-06 16:21:17 +08:00 |
caoqianming
|
0971a500e7
|
PPT skill v3: 红色硬约束 + 品牌条 + 强制尾页 + Iconify 图标库
修复上一轮生成的实际问题: 模型擅自把红色换成蓝色 / 内页全裸白 / 缺 Q&A 尾页;
并补齐"个性化图标"能力 (此前只有 MSO_SHAPE + unicode 字形,业务概念图标缺位)。
- SKILL.md: 红色主题改硬约束 + ⛔ BLOCKING 八条对齐 (bundled 推荐, 等用户拍板),
封面/尾页改强制项, 不算在 5-8 页正文预算内
- layouts.md: 加 apply_brand(slide, kind) 4 模式品牌条 (cover/inner/section/end),
9 个版式起手必调, 消灭裸白页
- 图标库: 新增 fetch_icon.py 走 Iconify CDN (tabler/lucide/heroicons 等 150+ 集),
主题色染色, 缓存到 assets/icons/, 配 INDEX.md 推荐清单
- icons.md: 移除 MSO_SHAPE 当业务图标的部分 (PENTAGON/LIGHTNING_BOLT 等视觉陈旧),
三层降级 → 两层 (Iconify / unicode 兜底); MSO_SHAPE 退为 layouts.md helper 内部原语
- canvas_presets.md 并入 design_principles.md §0 (减少零碎文件)
- .gitignore: spec_lock.md 与根目录 *.pptx 不入库 (PPT skill 工作产物)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-06 12:23:06 +08:00 |
caoqianming
|
3a66849953
|
Initial import: zcbot personal task agent
DESIGN.md / PROGRESS.md 落地 Phase 1-3:
- core/: LiteLLM 封装 + ReAct loop + 会话持久化 + Anthropic skill registry
- tools/: read/write/edit/glob/grep/shell/run_python/load_skill (Hybrid 范式)
- skills/coding | proposal: WHY+WHAT 风格 SKILL.md
- skills/ppt: 完整渐进披露 (SKILL + 4 references + 3 scripts)
· 借鉴 hugohe3/ppt-master 的两阶段 + spec lock 思路
· MSO_SHAPE 图标体系 + 安全区 + 越界检测
· 默认商务红主题 (#C00000 / #E15554 / #FFC107)
- config/models/: DeepSeek V4 flash/pro 档案
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-06 11:02:59 +08:00 |