Commit Graph

78 Commits

Author SHA1 Message Date
Yaojia Wang
c6651b74b9 fix(web): stale-closure + focus trap + 去边界强转 + a11y/性能打磨 + 类型化客户端
P1-6 useStyleLearn/useKimiOauth 修 stale-closure 依赖。
P1-7 CommandPalette/Drawer 加 focus trap(新 lib/a11y/focusTrap)。
P1-8 SSE 解析与 server.ts 去 as 强转改类型守卫/运行时校验。
P2 删冗余强转、开 noUncheckedIndexedAccess、Toast 清理+稳定 key、列表 key 稳定化、
  rel=noopener、useMemo 大文本、ConflictCard role=group、useInjection 加锁、
  client.test 真断言。
codegen 重生成 schema.d.ts + 消费 DimensionEntry/ReviewConflictView 强类型。
2026-06-21 19:32:49 +02:00
Yaojia Wang
016509c5c6 fix(gateway): 熔断计入持续 4xx + 去 assert + Protocol/transient 去重
P1-2 非可重试错误(持续 401/403)也 record_failure,坏 key 可触发熔断。
P1-9 _complete_structured 的 assert 改显式 raise ValueError(-O 安全)。
P2 GatewayRun 抽到 orchestrator/_protocols.py 单点(去 4 处重复);
  _is_transient 抽到 adapters/base.py is_transient_by_name(去 3 处重复);
  Gemini Protocol 改 async def;gateway._retrying 去无用 async。
2026-06-21 19:32:49 +02:00
Yaojia Wang
f7004e8d74 fix(db): 时间列 TIMESTAMPTZ + 热路径索引 + 状态 CHECK 约束
P1-1 base.py 时间列改 timezone=True;迁移把 16 表 created_at/updated_at
  ALTER 为 TIMESTAMPTZ(手写 USING ... AT TIME ZONE 'UTC')。
P1-3 新增 8 个索引(chapter_reviews/chapter_digests 复合、owner_id、
  usage_ledger、rules + jobs/rules 部分索引)。
P2 chapters/foreshadow status CHECK 约束。
迁移链 ad2c4c663daf → b1a2c3d4e5f6 → c2b3d4e5f6a7,upgrade/downgrade 往返无漂移。
2026-06-21 19:32:49 +02:00
Yaojia Wang
345cc73965 fix(txn+security): 仓储改 flush + 启动校验/兜底 + job.error 脱敏 + SSE 异常硬化
P0-1 SqlCredentialStore/save_draft 由自提交改 flush,端点/服务统一 commit
  (新增 CredentialStore.commit() 统一提交点;token 刷新落库显式提交);
  补多凭据一请求中途失败整体回滚集成测试。
P0-2 启动校验 _fernet(enc_key) 快速失败 + catch-all Exception → ErrorEnvelope;
  credential_enc_key 改 SecretStr。
P0-3 run_job 异常分类:AppError 存 code+message,其余存通用文案不泄 str(exc)。
P0-4 评审/正文 SSE 失败先发 error 事件,尾部 commit 包 try/except。
P1-4 max_version 加 FOR UPDATE 行锁消除 TOCTOU。
P1-5 scan_overdue 谓词下推 + 批量 UPDATE RETURNING。
P1-10 移除 OAuth user_code 日志。
P2 provider_deps 改调网关 build_adapter;accept_service Committable Protocol;
  CORS 白名单收窄;request_id 安全字符集白名单;stdlib 日志接管;读端点 404 校验;
  httpx timeout;测试用合法 Fernet key;类型化响应模型(JobResponse/DimensionEntry/
  ReviewConflictView/selling_points)+路由 ErrorEnvelope responses(供 codegen)。
2026-06-21 19:32:24 +02:00
Yaojia Wang
2282d4fd24 merge: UX 清晰化修复 — 水合告警/正文滚动/草稿已保存/推理动画/裁决保存提示
- fix: html/body suppressHydrationWarning(浏览器扩展注入,非应用 bug)
- fix: 正文编辑器自适应高度,消除嵌套滚动条、铺满写作区
- fix(Q6): useAutosave 种入已存草稿 → 初始显示「已保存」
- feat(A): ThinkingIndicator 三点波动接入 审稿/验收/回炉 推理等待
- feat(B): 审稿裁决保存模型提示(暂存本地、验收落库)
门禁绿: typecheck/lint/vitest 213/build。实景验证: 已保存/正文滚动/审稿动画。
2026-06-21 18:18:55 +02:00
Yaojia Wang
5515e1069f feat(ux): 审稿裁决保存模型提示(B) — 裁决暂存本地、验收时落库 2026-06-21 18:16:32 +02:00
Yaojia Wang
c51623836f fix+feat(ux): 已存草稿显示已保存(Q6) + AI 推理动画指示器(A)
- Q6 bug: useAutosave 加 initialSavedText,进页种入已存草稿时初始即「已保存」,修「加载已存草稿却显示尚未保存」的误导。
- A: 新 ThinkingIndicator(三点波动,motion-safe 尊重 reduced-motion)接入审稿进行中/验收中/回炉中三处静态文案,长等待看得见在工作。
2026-06-21 18:05:55 +02:00
Yaojia Wang
10c0d4bead fix(ux): 修水合告警(扩展注入) + 正文编辑器嵌套滚动条/不铺满
- layout: html/body 加 suppressHydrationWarning(浏览器扩展水合前注入 class/attr,非本应用 bug)
- Editor: textarea 高度自适应内容 + overflow-hidden,消除内部嵌套滚动条、正文随内容铺满写作区,外层单一滚动条统管
2026-06-21 17:57:53 +02:00
Yaojia Wang
95b662d85d merge: UX 审稿人体学(R1/R2/R3) + Tier4 全局 AI 工具条 + 本章指令直通
R1/R2/R3: 冲突卡内联片段 + 分组/排序/跳下一条/主次按钮 + 验收前清单。
T4-a: 全局 AI 工具条(AppShell 顶栏下,--chrome CSS 变量适配固定高度页)。
T4-b: draft 端点接收本章指令 directive 直通 assemble(volatile, 守缓存前缀),前端指令框+风格预设。
门禁绿: 后端 pytest 479 / 前端 vitest 213 / build。
2026-06-20 18:33:01 +02:00
Yaojia Wang
cc0aabdd9a feat(ux): T4-b 前端 — 本章指令框 + 风格快捷预设传入 draft 生成
新 lib/workbench/directive.ts (STYLE_PRESETS + composeDirective 纯函数+测);useDraftStream.start 加 directive 参数(非空时 POST JSON body);Workbench 加「本章指令」textarea + 风格预设 chips,写本章时 composeDirective 传入。TDD: directive 测。前端门禁绿。docs(progress): 记 Tier4 完成。
2026-06-20 18:27:47 +02:00
Yaojia Wang
2155193cdc feat(ux): T4-b 后端 — draft 端点接收本章指令 directive 直通 assemble(volatile)
assemble/_build_volatile 加 directive 参数(仅入 volatile,守缓存前缀不变量 #9);stream_draft 加可选 body {directive} 透传;不持久化、无迁移;directive 长度入 log 不记原文。新 DraftStreamRequest schema + 重生成 TS 客户端。后端门禁绿: ruff/mypy/pytest。契约记 memory/contracts.md。
2026-06-20 18:25:00 +02:00
Yaojia Wang
8779530806 feat(ux): T4-a 全局 AI 工具条 — 项目页顶部常驻写本章/审稿/大纲/设定库/工具箱
新 lib/nav/ai-tools.ts (aiToolItems) + components/AiToolbar.tsx 服务端组件;AppShell 顶栏下渲染(仅项目页),用 --chrome CSS 变量统一 chrome 高度,6 个固定高度页改用 calc(100vh-var(--chrome,4rem)) 适配。TDD: ai-tools 测。前端门禁绿: lint/tsc/vitest/build。
2026-06-20 18:19:46 +02:00
Yaojia Wang
6e5d0e88f6 feat(ux): R3 验收前清单 — AcceptPanel「本次将更新」预览
新 lib/review/accept-preview.ts (buildAcceptPreview):据现有 client state 列验收前预期项——晋升版次/提炼摘要/写回裁决/伏笔到期扫描/伏笔建议待登记。仅列后端 accept 事务确实做的事(核对 projects.py accept 端点),不声称改人物 latest_state,带「以验收回执为准」免责。
AcceptPanel 加 foreshadowCount prop + 未阻断时渲染清单;ReviewReport 传 foreshadow.length。
TDD: 4 测。前端门禁绿: lint/tsc/vitest 205/build。
2026-06-20 16:00:51 +02:00
Yaojia Wang
d81583d5d1 feat(ux): R1+R2 审稿裁决人体学 — 冲突卡内联片段 + 分组/排序/跳下一条/主次按钮
R1: 新 lib/review/snippet.ts 从 where 解析段号取终稿命中段预览,ConflictCard 渲染引用块。
R2: 新 lib/review/grouping.ts 按 type 分组+严重度排序(仅改显示顺序,保留原始 index 守 conflict_index 不变量),组计数徽标、跳到下一条未裁决(环回)、采纳改法主按钮/忽略手改次级。
TDD: snippet 8 测 + grouping 10 测。前端门禁绿: lint/tsc/vitest 201/build。
2026-06-20 15:53:45 +02:00
Yaojia Wang
6f419b35ed merge: B0 注入透明可控版 + F1 控件(pin/排除/recent_n override) 2026-06-20 15:45:28 +02:00
Yaojia Wang
7a1a498683 docs(progress): 记 B0 可控版 + F1 控件完成(注入透明 override)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 12:03:11 +02:00
Yaojia Wang
6449c3103a feat(ux): F1 注入面板可控版 — 📌置顶/✕排除/近N章步进器 + 已排除恢复
- injection.ts 加 override 纯函数(currentOverride/withPinToggled/withExcluded/withRestored/withRecentN/isPinned,钳 1..20)+ author_pin 徽标
- useInjection 加 saving 态 + togglePin/exclude/restore/setRecentN,PUT 后以服务端确定结果为准(不变量 #6);写失败可读文案、不改本地态(天然回滚)
- ChapterAssistant:每实体置顶/排除按钮 + 「近 N 章」步进器 + 「已排除」恢复区
- 13 新 vitest(override 纯函数);前端门禁绿(lint/tsc/vitest 183/build)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 12:01:09 +02:00
Yaojia Wang
0d473e726e feat(b0): 注入透明可控版后端 — PUT override(pin/排除/recent_n) + 选择函数加参 + draft 同读
- selection.select_relevant_entities 加 pinned/excluded frozenset 入参;新理由 author_pin(末位)
- assemble 加 override 关键字参(recent_n 覆盖回看章数 + pin/排除);GET/PUT/draft 同读同一覆盖(不变量 #6 作者兜底)
- 新 domain/injection_repo.py(InjectionOverride/EntityRef/SqlInjectionOverrideRepo,upsert 只 flush)
- 新表 chapter_injection(迁移 ad2c4c663daf,唯一 project_id+chapter_no;复用 outline 行已否决)
- PUT/GET injection 端点 + InjectionOverrideRequest/回显 pinned/excluded;recent_n 1..20 校验 422
- 单测:selection pin/排除/exclude>pin + assemble override + 端点 PUT/404/422;regen TS 客户端
- 门禁绿:ruff/format · mypy 163 · alembic 无漂移 · pytest 476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 11:56:54 +02:00
Yaojia Wang
e8cccf7389 feat: T6.1 创作工具箱通用生成器框架地基 — 脑洞生成器 + run_generator
- schemas: Idea/IdeaListResult(脑洞生成器结构化产出,纯预览不入库)
- specs: brainstorm_spec(light 档,reads=[projects] writes=[])
- orchestrator: build_brief_context(brief_only 策略)+ 通用 run_generator
  (据 spec.output_schema 校验 parsed,不绑定具体类型,任一声明式生成器共用)
- 新增 13 测;两包 ruff/format/mypy 干净、252 passed 无回归

P1 第一波(@llm):证实「加生成器=加一份声明」。@backend T6.2/T6.3 待续。
2026-06-20 11:31:59 +02:00
Yaojia Wang
9b893a6c61 feat(ux): M1/M2 移动端可用 — 导航汉堡抽屉 + 写作工具条不溢出
M1 左导航响应式抽屉:抽出 lib/nav/items.ts(条目数据+激活判定,纯逻辑+vitest)
共用于桌面静态侧栏(hidden lg:block)与移动汉堡抽屉。新增通用 Drawer(遮罩/
Esc 关闭/打开聚焦,复用 CommandPalette a11y 模式)+ NavDrawer + NavItems;
LeftNav 改 <lg 隐藏,AppShell 顶栏加汉堡(aria-label 打开导航)。

M2 写作工具条不溢出 + 移动端可达章节/助手:Toolbar 改 flex-wrap,390px 不再
横切「尚未保存」;ChapterList/ChapterAssistant 抽出 *Content,Workbench 经
左/右 Drawer 在 <lg 触达目录/助手。

实景 390px 复验(browse):汉堡显示/静态导航隐藏/抽屉开合聚焦+Esc、工具条
两行不溢出、助手抽屉真注入面板。门禁:lint/typecheck 干净 · vitest 177 · build OK。
2026-06-20 11:26:14 +02:00
Yaojia Wang
b18310bcb7 feat(ux): F3 流式进度感 + F4 友好错误文案(纯前端)
F4:新 lib/errors/messages.ts —— friendlyError(code, fallback) 把错误码映射为
中文文案 + 可选「去设置提供商」动作;覆盖后端 ErrorCode + 前端 NETWORK/
STREAM_FAILED;未知码回退原 message。写作页与审稿页错误块改用之,不再暴露
raw error code。+4 vitest。

F3:写作页工具条字数计数器流式时显示「生成中… N 字」+ 朱砂脉冲
(motion-safe:animate-pulse,尊重 prefers-reduced-motion),停后回「字数 N」。
纯 text.length,无后端改动。

前端门禁绿:lint/typecheck/vitest 171/build。无契约变更。
2026-06-20 11:02:27 +02:00
Yaojia Wang
8058cfb11a feat(ux): B0 注入透明读端点 + F1 写作页右栏真面板
兑现「看到的=写章用的」信任牌(不变量 #6),替换写作页右栏过时假占位
(「M1 暂未接 / M2 开放」)。

后端:
- GET /projects/{id}/chapters/{no}/injection → InjectionResponse(selected
  实体 + 入选理由 + recent_n);调既有 assemble() 回放确定性 SelectionTrace,
  无 LLM / 无 commit / 无 DDL;项目不存在→404,无大纲→selected:[]。
- 新 schemas/injection.py;tests/test_injection.py(3 测)。

前端:
- gen:api 纳入端点;纯逻辑 lib/workbench/injection.ts(理由/类型→中文徽标
  + 4 vitest)+ useInjection 读 hook。
- ChapterAssistant 改 client 组件:列出选中实体 + 理由徽标 + 空/载/错三态,
  四审段指向审稿页;Workbench 传 projectId/chapterNo。

门禁:后端 ruff/format/mypy 159/alembic 无漂移/pytest 454;
前端 lint/typecheck/vitest 167/build。

B0 可控版(PUT override pin/排除/recent_n + selection 加参 + draft 同读
override + 持久化)+ F1 可控控件待后续。
2026-06-20 10:57:03 +02:00
Yaojia Wang
7e63534366 fix(web): 审稿页右栏去掉冲突列表 flex-1,四审聚合消除约 400px 死白 2026-06-20 10:44:37 +02:00
Yaojia Wang
765dbdfbd4 feat: M4 文风 + M5 生成/多provider/Skill + Kimi Code 订阅接入 + 本地联调修复
M4(文风): style-auditor 双轨(提取指纹/漂移第四审)+ jobs 长任务框架(zombie reaper) + 回炉 refine + GET /style read-back。
M5(生成+扩展): worldbuilder/character-gen(入库 continuity 409 gate + partition_writes 白名单 + schema→JSONB 形变);
  网关多 provider 回退链/熔断/能力降级(Anthropic/Gemini 适配器);Skill registry + 表权限沙箱 + 规则;
  前端 角色生成器/世界观/Codex/规则页/技能库/⌘K 命令面板。
K1(Kimi Code 订阅接入): OAuth device-flow(kimi-code)+ 静态 Console key(kimi-code-key)两路径;
  coding 端点 KimiCLI 伪造头(实测 UA allow-list 门禁,缺则 403)+ JSON 模式结构化(thinking ⊥ tool_choice)。
本地联调修复: CORS 中间件;assemble 注入 premise+「写第N章」指令(修空 prompt 400);
  GET /outline·/draft read-back + 大纲/工作台/审稿页重载;写页 client/server 常量边界 + notFound 健壮化;
  字数 toLocaleString locale 水合;审稿页终稿从已存草稿 seed(修 accept 422)。
门禁: backend ruff/mypy(157)/alembic 无漂移/pytest 451 · frontend lint/tsc/vitest/build。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 10:39:58 +02:00
Yaojia Wang
5fb7bfb1de feat: M3 — 伏笔账本 + 节奏引擎 + 大纲(含并发记账 bugfix)
- 伏笔账本:纯函数状态机(OPEN/PARTIAL/CLOSED/OVERDUE) + ForeshadowLedger repo;验收后到期扫描(BackgroundTask 自建 session 置 OVERDUE);登记/状态变更端点
- 节奏 + 三审齐:foreshadow-analyst + pace-checker 并入 LangGraph 并行审(REVIEW_SPECS),collect 分列落 chapter_reviews(conflicts/foreshadow_sug/pace),review SSE 加 foreshadow/pace 事件
- 大纲:outliner Agent 产 OutlineResult(含 foreshadow_windows),POST /outline 逐章 upsert outline 表;GET /foreshadow?status= 看板
- 前端:伏笔四泳道看板(OVERDUE 琥珀) + 大纲编辑器(窗口徽标) + 节奏节拍图(▁▃▅) + 审稿页消费 foreshadow/pace SSE
- bugfix(T3.8):并行三审共用请求 session 记账触发 'Session is already flushing' → foreshadow/pace 静默丢失;SqlAlchemyLedgerSink.record 改 add-only(靠端点/事务 commit),加并发回归测试
- M3 E2E:真实 DB + mock 网关零 token 走通 埋设→进展→验收后扫描 OVERDUE→看板 + 大纲含窗口 + 三审齐 SSE/留痕;E2E 暴露并钉住上述 bug
- 门禁绿:mypy 111 / pytest 228(0 xfailed) / alembic 无漂移;前端 gen:api/lint/tsc/vitest 69/build
2026-06-18 14:21:17 +02:00
Yaojia Wang
68f194a043 feat: M2 — 写→审(一致性)→裁决→验收(事务);未决冲突禁验收
- 续审 Agent 声明(AgentSpec) + 结构化输出契约(ContinuityReview/Conflict 五类)
- LangGraph 并行审子图(可扩四审) + collect 落 chapter_reviews 留痕 + review SSE(section/conflict)
- 验收-side Repository:章节 accepted 版本晋升 + digest append-only + 审稿留痕/裁决
- API:review(SSE) + reviews 历史 + accept(单原子事务:晋升 version + 终稿 digest + 裁决留痕)
- 冲突 gate:未决裁决拦截(CONFLICT_UNRESOLVED);digest 从终稿提炼(不变量#4)
- 前端:审稿报告页 + 冲突就地标注 + 裁决(采纳/忽略/手改) + 未决禁验收 + 「本次将更新」清单
- M2 E2E:真实 DB + 多档位 mock 网关零 token 走通 写→审→裁决→验收→摘要入库
- 多 agent 协同台账(PROGRESS.md) + 共享记忆(memory/contracts·decisions·gotchas)
2026-06-18 11:38:28 +02:00
Yaojia Wang
b523b4fd21 feat: M1 — 立项→写章草稿(SSE)→自动保存;连一家 provider
- 薄自建 LLM 网关:OpenAI 兼容适配器(DeepSeek) + instructor 结构化输出 + usage_ledger 记账 + 档位路由
- 记忆服务 assemble:确定性选择(显式+主角+近况) + 渲染卡 + 缓存断点(中性文本)
- LangGraph 写章节点 + Postgres checkpointer + SSE 归一(token/done/error)
- API:立项 + 写章 draft(SSE) + PUT 自动保存 + 提供商凭据(Fernet 加密/测试连接)
- 前端:AppShell + 作品库 + 5 步立项向导 + 写作工作台(流式打字机+自动保存) + 设置页
- M1 E2E:真实 DB + mock 网关零 token 走通闭环
2026-06-18 11:38:28 +02:00
Yaojia Wang
d3dc620a71 feat: Phase 0 — monorepo 骨架 + 全表迁移 + FastAPI/Next 骨架 + CI
- uv(workspace) + pnpm monorepo;docker-compose(pg+api+web)
- SQLAlchemy 16 MVP 表 + Alembic 初版迁移(无漂移,users stub)
- FastAPI 骨架:统一错误信封(带 request_id) + structlog + /jobs/:id + OpenAPI
- Next.js 骨架:纸感主题 token + OpenAPI→TS 客户端代码生成(gen:api)
- CI(ruff/mypy/pytest + pg service + alembic 漂移校验)
- 四份设计规格(PRODUCT/UX/ARCHITECTURE/DEV_PLAN) + CLAUDE.md
2026-06-18 11:38:28 +02:00