Commit Graph

126 Commits

Author SHA1 Message Date
Yaojia Wang
3c87b01379 feat(frontend): 左栏 10 项按写作/资料库/审阅/更多分组(UX P2-1)
navSections(projectId?) 纯函数把平铺项目项归为四组,NavItems 复用「本作」小标题模式逐组渲染;链接/路由/激活键不变,工具箱收进「更多」不丢入口。
2026-07-10 18:14:41 +02:00
Yaojia Wang
e9c5502c2d feat(frontend): 底栏瘦身 + 或让 AI 动作行 + 动词范围提示 + 题材去弹窗(UX P1-1/P1-4/P1-5) 2026-07-10 18:00:42 +02:00
Yaojia Wang
9f6cbb5598 refactor(frontend): 右栏去术语——本章参考/AI 写这章会参考/写完后检查,删重复去审稿(UX P1-3) 2026-07-10 18:00:36 +02:00
Yaojia Wang
59d7c75737 feat(frontend): 统一「采用」动词族——替换整章/加到章末/替换这段,弃「回填」(UX P1-2) 2026-07-10 18:00:28 +02:00
Yaojia Wang
ceae24740a feat(frontend): 正文上方常驻 AI 输入条 + 对话记录正名 + 润色提示 + HITL 微文案
回答用户原话「我怎么和 AI 对话」(docs/design/ux-exploration.md §4 P0-1/2/4/5)。

P0-2 把折叠的「本章写作指令[可选]」原地提升为正文正上方常驻输入条:标题
「告诉 AI 这章想怎么写」、去「可选」徽标、空章默认展开、「AI 写作诉求」→
「你的写作要求」、邀请式 placeholder;发送键即「写本章」(streaming 时切
「停」),复用 composeDirective + 文风/剧情 chips + 流式打字机,不改成聊天气泡。
P0-1 底栏「AI 对话」→「对话记录」(只读日志正名),抽屉标题/aria/空态同改。
P0-4「润色选段」常驻可点,无选区点击弹 toast 提示(去 hover-only title)。
P0-5 输入条旁常驻 HITL 微文案 +「?这是什么」可再发现弹层(非一次性 coach)。
2026-07-10 17:43:59 +02:00
Yaojia Wang
61a6931bb1 refactor(frontend): 删顶部「AI 工具条」,--chrome 归位 4rem(写作台 UX P0-3)
顶栏「AI 工具条」5 项全是重复左栏的导航链接,且让「写本章」同时是导航
Link 与生成动作两种相反含义。删掉后导航只归左栏,同时消灭最严重的三重复
+ 假「AI」标签 + 「写本章」双重含义,并省下 48px(--chrome 7rem→4rem)。
死代码 AiToolbar/AiToolbarMoreMenu/ai-tools 全仓仅 AppShell 引用,一并移除。
2026-07-10 17:43:46 +02:00
Yaojia Wang
1185069572 feat(frontend): 润色/整章重写面板内联对话气泡流(就地可见)
用户反馈:不想每次开「AI 对话」抽屉才看得到对话,要在对话时就地内联可见。
RefinePanel/ChapterRewritePanel 内联渲染 role=log 滚动气泡流(本章 refine/rewrite
+ 其 clarify 往复 ∪ 本轮进行中气泡:流式 token 逐字进气泡、缓冲的 clarify Q&A
亦实时可见),输入框置底像聊天。pending→persisted 无重影(进行中气泡结束即清、
已落库去重);fail-soft(历史加载失败仍显示本轮实时气泡,不阻塞回炉/重写);
气泡「再接受/回填」复用既有 DRAFT-only HITL 回调(drift-safe,正文仍只在验收才变);
clarify gating/abort/停/接受悉数保留。Workbench 改传 conversation + onReaccept。
AiConversationDrawer 保留原样(底栏仍可开,跨章/项目级全量历史浏览)。
2026-07-10 16:32:10 +02:00
Yaojia Wang
5af45f5034 refactor(frontend): 抽出可复用 ConversationThread + inlineConversation 纯助手
把 AiConversationDrawer 内联的气泡渲染(Bubble/readOptions/ACCEPT_LABEL)提取为
共享的 ConversationThread 组件,抽屉改为复用之(外观不变,DRY)。新增纯助手
lib/workbench/inlineConversation.ts:mergeInlineThreads(已落库留痕 ∪ 进行中气泡,
按 id 去重 + 复用 groupByThread 定序)、toPendingView(合成未落库气泡,meta._pending/
_streaming UI 标记)、isPendingView/isStreamingView/readSegment,配 9 单测(RED→GREEN)。
为内联对话视图铺路;抽屉行为完全不变。
2026-07-10 16:31:53 +02:00
Yaojia Wang
33a9b7656c feat(frontend): 五类交互接入 AI 对话留痕 + Workbench 抽屉入口(AC-3)
- RefinePanel/ChapterRewritePanel:结束后 append [author(意见/答复), ai(产出)];
  clarify buffer-until-concluded——澄清 Q&A(原意见→反问→答复)缓冲,随最终产出批
  一起落库同 thread;纯放弃不记。refine ai 行 meta 存 version_no+原选段(每版重锚)。
- ContinuePanel:ai-only(续写无作者输入),每候选一条 ai 气泡 meta{candidate_index}。
- GeneratorRunner:成功后 append [author(字段摘要, meta{tool_key,input_fields}),
  ai(渲染预览, meta{tool_key,output_kind})];空产物不记。lib/toolbox/aiSummary.ts 纯助手+单测。
- InlineToolbox→GeneratorRunner 透传 append+本章号;ToolboxPage 用 silent 直投项目级(chapter_no=null)。
- Workbench:挂 useAiConversation 单实例 + AiConversationDrawer + 底栏「AI 对话」入口(flag 灰度),
  三个 DRAFT-only 再接受回调(替换整章/插入正文/回填选段),成功关抽屉+toast、漂移不盲替换。
2026-07-09 17:27:14 +02:00
Yaojia Wang
59f2f60a7e refactor(frontend): 四生成 hook 结束后额外返回产物(AC-3 留痕前置)
useRefine.refine/recommunicate→RefineVersion|null、useContinue.generate→string|null、
useChapterRewrite.send→RewriteVersion|null、useGenerator.generate→GeneratorArtifact|null。
向后兼容(既有调用忽略返回值不受影响);各 hook 成功用例补返回值断言。
面板据此 if(artifact) 才 append,空候选/错误路径不留痕。
2026-07-09 17:15:49 +02:00
Yaojia Wang
ddf7fa061a feat(frontend): AI 对话核心——视图模型 + 数据/追加 hook + 抽屉(AC-3)
- lib/workbench/aiConversation.ts:纯视图模型(kind 标签/徽标、bubbleSide、
  按 thread 归组 (created_at,seq) 定序、按作用域分区、接受动作映射)+ 单测。
- lib/workbench/useAiConversation.ts:Workbench 级懒加载 + 批量 append(乐观插入 +
  正位对账 / 失败回滚),fail-soft 绝不 throw 进生成/HITL;silent 直投供工具箱页。
  renderHook 测试覆盖懒加载去重、对账、回滚、silent、项目切换复位。
- components/workbench/AiConversationDrawer.tsx:本章对话 + 项目级生成两段的气泡抽屉,
  克隆 ContextDrawer 的 a11y(role=dialog/log、Esc、focus trap、还原焦点);
  ai 气泡挂 DRAFT-only 再接受按钮(替换整章/插入正文/回填选段),不绕开验收事务。
- lib/api/types.ts:re-export AiMessage* 码生成名。
2026-07-09 17:11:09 +02:00
Yaojia Wang
dce882ca91 chore(frontend): pnpm gen:api 纳入 AI 对话端点(AC-3)
POST/GET /projects/{id}/ai-messages + AiMessageAppendRequest/AiMessageInput/
AiMessageView/AiMessageListResponse 由后端 OpenAPI 重生成进 schema.d.ts。
2026-07-09 17:00:14 +02:00
Yaojia Wang
c675a74f1d feat(backend): AI 对话聊天记录 repo + append/list 端点(AC-2)
在 C2 扩(AC-1) `ai_messages` 表上落 AC-2 后端(计划 §3):
- repo `SqlAiMessageRepo`:批 append(seq=批内 0 基位置、同 thread_id、只 flush)
  + `list_for_chapter` newest-first(created_at DESC, seq DESC)、chapter_no 过滤含
  项目级 NULL union、可选 kind、limit/offset。
- schemas `ai_messages.py`:批级 append 信封 + Literal 枚举权威(kind/role)+ content
  200k 上限 + meta 序列化兜底。
- 端点 `POST/GET /projects/{id}/ai-messages`(tag ai-messages,已注册):显式记录写入,
  五个生成端点保持只读不变(守 #3);项目 404、校验 422、POST 端点提交。
- 注入缝 `get_ai_message_repo`。

TDD:repo 真 pg 单测(seq/定序/union/分页/flush-only)9 passed;端点集成测试
(round-trip/union/kind/404/422×5/commit 边界)12 passed。门禁全绿:ruff/format/mypy
238 files/alembic check 无漂移/pytest 992 passed;新模块 cov router+schemas 100% / repo 97%。
2026-07-09 16:54:52 +02:00
Yaojia Wang
c34dbf5d2d chore(devops): 本地/compose 宿主端口 +1000 防冲突(web 4000 / api 9000 / pg 6432)+ 文档登记 2026-07-08 17:33:43 +02:00
Yaojia Wang
a039a1e5d9 chore(devops): 抬高后端依赖下界至 lockfile 主次版本,保可复现(CR-D1) 2026-07-08 13:34:36 +02:00
Yaojia Wang
64145422eb refactor(web): 去冗余 cast(idx.valueOf / dict[error] as string)
stream/sse.ts SseFrameBuffer 去 idx.valueOf()(idx 本就是 number);jobs/job.ts 去 dict["error"] as string(typeof 守卫后 TS 自动收窄)。typecheck 绿。
2026-07-08 13:27:45 +02:00
Yaojia Wang
16f2eae2d3 test(web): parseJsonBody 补非对象/非 JSON 守卫分支测试
server.parseJsonBody 已具边界校验,补两条守卫分支测试(200 返回原始值/非 JSON 体均抛结构化错误)。
2026-07-08 13:27:45 +02:00
Yaojia Wang
9cf4915d49 refactor(web): hasApplicableFix 改类型谓词,消除 applyConflictFix 强转
hasApplicableFix 重写为对象入参类型谓词 patch is ApplicablePatch,谓词命中后 applyConflictFix 里 original/replacement 自动收窄为 string,删两处 as string;补收窄单测。
2026-07-08 13:27:45 +02:00
Yaojia Wang
d80d41a08d refactor(web): ApiErrorEnvelope 改由生成 schema 派生,防契约漂移
手写 ApiErrorEnvelope 改由 components["schemas"]["ErrorEnvelope"] 派生;accept 端点专属 details.missing_conflict_indices 就地收窄。运行时行为不变(既有 useAccept 测试全绿)。
2026-07-08 13:27:32 +02:00
Yaojia Wang
125908ed83 fix(web): ReviewReport flashMark 定时器卸载清理,防泄漏
flashMark 的 setTimeout 句柄入 ref + 卸载 useEffect 清理,重复触发先清旧定时器;提 FLASH_DURATION_MS 常量。闪烁行为不变。
2026-07-08 13:27:32 +02:00
Yaojia Wang
47d5558e4a feat(web): NavDrawer 补 aria-controls + ForeshadowCard 语义化 dl/dt/dd(a11y)
NavDrawer 汉堡按钮补 aria-controls 指向抽屉面板(Drawer 新增可选 id prop,默认 nav-drawer);ForeshadowCard 的 <dl> 裸 <div> 行改真 <dt>/<dd> 结构,可视文案不变,importance 用 sr-only 标签。行为不变。
2026-07-08 13:27:32 +02:00
Yaojia Wang
ec91c8fdf7 refactor(chain): 链 runner 经公开 aget_state.interrupts 判暂停——弃私有 __interrupt__ 键(CR-M3) 2026-07-08 13:04:28 +02:00
Yaojia Wang
832ab7dfa1 refactor(gateway): 适配器暴露 probe_connection 公开探测——provider_deps 弃私有 _client 反手(CR-M1.4) 2026-07-08 13:00:50 +02:00
Yaojia Wang
49e3cb6dc4 docs(backend): SSE 端点在 OpenAPI 如实声明 text/event-stream
draft/rewrite/review 三个流式端点返回 StreamingResponse,OpenAPI 原按默认
application/json 标注 200,schema 不诚实。新增共享 _SSE_RESPONSE 声明 200 的
content 为 text/event-stream 并挂到三个装饰器。export_openapi 通过,schema 现
出现 3 处 text/event-stream。未跑前端 gen:api(按要求)。
2026-07-08 12:46:15 +02:00
Yaojia Wang
bf3dabea82 perf(backend): 角色/世界观入库改批量——create_many 一次 flush 落全部行
角色入库端点与 toolbox world_entities 入库端点原逐卡/逐条 create(每行一次
SELECT/flush/refresh,N+1 round-trip)。新增 create_many:世界观用 add_all,
角色用一次 IN 查已有名 + 一次 flush(保持 (project_id,name) upsert 幂等与批内
重名去重、保序返回)。单条 create 薄封装 create_many,行为不变(既有调用方/E2E
复用)。复活并复用 CharacterWriteFields、新增 WorldEntityFields 作批量入参。
补两端点「多行一次落库」测试;既有幂等/冲突 gate 测试与 m5 真 pg E2E 全绿。
2026-07-08 12:44:07 +02:00
Yaojia Wang
0892ff6cda feat(backend): 无界列表端点加分页——projects/templates 支持 limit/offset
GET /projects 与 GET /templates 原一次返回全部 owner 行,行数随数据线性增长。
新增可复用分页依赖 ww_api.pagination.get_page(limit∈[1,200] 默认 50、offset≥0,
越界 → 422),两端点接入,Repository.list_for_owner 加 keyword-only limit/offset
把 LIMIT/OFFSET 下推 DB。向后兼容:不传参返回第一页。补 projects 分页 + 边界 422 测试。
2026-07-08 12:39:31 +02:00
Yaojia Wang
1392830e57 refactor(backend): jobs 读端点走 JobRepo 而非路由内裸 ORM
GET /jobs/{id} 原在路由里直接 select(Job) 裸 ORM 查询;改为经 get_job_repo
注入 JobRepo 调 .get(job_id),与项目其它端点的 Repository 分层一致,
测试可经 dependency_overrides 注 fake。行为不变(同一 session 同一查询)。
2026-07-08 12:35:09 +02:00
Yaojia Wang
c596a8d342 perf(backend): 大纲卷过滤下推 DB WHERE——list_for_project 加 volume 参数
GET /outline?volume=N 原在端点 Python 侧过滤全部章节;现把 volume 条件下推到
OutlineRepo.list_for_project 的 DB WHERE,只查该卷行(少读多余卷 + 语义正确)。
Protocol/SqlOutlineRepo/各 OutlineRepo fake 同步加 keyword-only volume;补 repo 级
下推断言测试。向后兼容:不传 volume 仍返回全部(默认 None)。
2026-07-08 12:34:06 +02:00
Yaojia Wang
ea9a9d9953 fix(frontend): 澄清反问块加 role=status 向读屏播报(WFW-9 M3,WCAG 4.1.3) 2026-07-08 12:05:54 +02:00
Yaojia Wang
8e29b33a11 feat(frontend): 整章重写接入 AI 反问澄清——useRewriteClarify + ChapterRewritePanel 门控(WFW-9 M2) 2026-07-08 12:00:17 +02:00
Yaojia Wang
4b1088a179 refactor(frontend): clarify toVM/PROCEED 提取到 clarify.ts 共享(WFW-9 M2) 2026-07-08 11:54:05 +02:00
Yaojia Wang
9b32743606 chore(frontend): gen:api 纳入 rewrite/clarify 端点(WFW-9 M2) 2026-07-08 11:52:11 +02:00
Yaojia Wang
6fd637596b feat(backend): 整章重写 AI 反问澄清预检端点 rewrite/clarify(WFW-9 M2)
新增 POST /projects/{id}/chapters/{no}/rewrite/clarify(非流式 JSON)→ ClarifyDecision,
镜像 refine 侧 clarify:404 缺项目 → _build_rewrite_clarify_input(章级意见 + prior_draft
有界摘录 3000 字,不整章入 LLM)→ run_clarify(clarify_rewrite_spec, analyst 档) → 末尾
commit 落 usage_ledger → 返回决策。只读不写业务表(不变量 #3);日志只记 feedback_len(脱敏);
畸形 parsed 经 run_clarify 韧性回退 need_clarification=false(非 500)。新增 RewriteClarifyRequest
(feedback 必给、prior_draft 可选)。6 端点用例覆盖含糊/明确/404/fail-open/422/摘录有界不泄漏。
2026-07-08 11:46:24 +02:00
Yaojia Wang
d6b53d08b2 fix(backend): 补 directive/instruction 文本上界——LLM 入参防超长(CR-H9 收尾) 2026-07-08 11:29:27 +02:00
Yaojia Wang
6e2b478ca9 fix(frontend): Drawer 焦点还原提取 useRestoreFocus + 回归测试 + DRY(CR-H11) 2026-07-08 11:10:23 +02:00
Yaojia Wang
5c02792e5f fix(frontend): RefineView 取消在途 refine——AbortController 防段切换竞态(CR-H12) 2026-07-08 11:08:21 +02:00
Yaojia Wang
5665cc9a16 fix(frontend): errorCode 统一自 generation/cards 去重复定义(CR-H10) 2026-07-08 11:06:30 +02:00
Yaojia Wang
f4c2c4e8ec fix(frontend): 升级 Next→15.5.20 + React 19.2.7 修 RCE/补丁 + 版本下界守卫(CR-C1)
- next/eslint-config-next 15.1.3→15.5.20(backport 安全维护线),react/react-dom 19.0.0→19.2.7
- @types/react(-dom) →^19.2.0;pnpm audit --prod 无 next/react/react-dom 高危/严重告警
- 新增 lib/security/dependencyFloors 守卫 + 回归测试锁定安全下界
- 连带修 useDraftStream.test noUncheckedIndexedAccess(重锁失效增量缓存后暴露,对齐 useReviewStream 既有 ! 约定)
2026-07-08 11:04:55 +02:00
Yaojia Wang
e1a24a2c2c fix(backend): API 文本输入加 max_length + 请求体大小中间件(CR-H9) 2026-07-08 10:53:44 +02:00
Yaojia Wang
5dd336b011 fix(backend): Kimi OAuth 请求级 httpx 客户端改生成器依赖修泄漏(CR-H2) 2026-07-08 10:40:14 +02:00
Yaojia Wang
ca8fbc89a1 fix(backend): Kimi OAuth 轮询移出 DB 会话——只在最终持久化开短会话(CR-H1) 2026-07-08 10:37:42 +02:00
Yaojia Wang
ed0a679322 fix(backend): 多章链设显式 recursion_limit 防御硬化(CR-C2) 2026-07-08 10:32:37 +02:00
Yaojia Wang
e30c933c76 feat(frontend): 润色再沟通接入 AI 反问澄清——选项芯片 + 折答案回炉(WFW-9 M1)
RefinePanel「再沟通」升级为对话式:意见含糊/极短(门控 <10 字,或点「帮我理清方向」)时先调
clarify 预检端点让 AI 反问,渲染 ChoiceChips 选项芯片(+自由输入兜底);作者选/答后
foldClarifications 把答案折进 instruction,再走既有 refine 回炉(零迁移)。清晰意见直接回炉、
不交往返税;预检失败=放行(useClarify 视 error/异常为 needClarification=false,不阻塞润色)。
新增:lib/workbench/clarify.ts(VM 类型+foldClarifications+needsClarifyGate 纯逻辑) +
useClarify(SSE 外调映射 snake→VM) + ChoiceChips.tsx;gen:api 重生成客户端。
门禁绿:tsc/lint/vitest 654(+clarify/useClarify 18 例)/build/coverage 95.36%。
2026-07-08 08:47:28 +02:00
Yaojia Wang
1652ad9d20 feat(backend): AI 反问澄清预检端点——refine 侧结构化 clarify(WFW-9 M1,路线A 两阶段)
润色「再沟通」意见含糊时先反问给选项(路线A:问题走独立非流式 JSON 预检端点,正文仍走
既有 refine 一字不改)。新增:
- ClarifyDecision/ClarifyQuestion/ClarifyOption 结构化 schema(既有 output-schema 处,供
  producer 与端点共用);clarify_refine.md 教条(含糊→need_clarification+≤1问+2–4锚定选项+
  自由输入;明确→verification 放行;防循环);注册 clarify_refine_spec(analyst 档,#24)+
  SCHEMA_CATALOG + 重生成金标准。
- clarify_node:build_clarify_request 纯函数(缓存前缀不含易变) + run_clarify(gateway.run
  结构化,判别/校验失败确定性回退 need_clarification=false,只读不写库)。
- POST /projects/{id}/chapters/{no}/refine/clarify → ClarifyDecision(analyst 网关,404/503,
  末尾 commit 记账)。**既有 refine 端点/RefineRequest/Response 完全未改**。
门禁绿:ruff/mypy 227/pytest 900(+test_clarify_spec/_node/style clarify)/alembic 无漂移。
2026-07-08 08:47:13 +02:00
Yaojia Wang
542c2abac9 feat(frontend): 整章「再沟通/重写」面板——给意见流式重写整章,版本栈迭代,接受替换正文
WFW-8 整章级再沟通(前端)。底栏新增「整章重写」→ ChapterRewritePanel:
- 作者给意见 → useChapterRewrite 消费 POST .../rewrite 的 SSE 流(复用 lib/stream/sse
  帧解析),流式 live 展示新一版;
- 每轮完成压入版本栈,「再改一版」以最新版为 prior_draft + 新意见迭代(多轮对话式);
- 接受某版才「替换整章正文」落草稿(HITL,AI 绝不静默覆盖);停/错误/网络异常均归一处理。
四张 AI 结果卡(润色/续写/工具箱/整章重写)互斥。gen:api 重生成 TS 客户端。
门禁绿:tsc/lint/vitest 636(+7 useChapterRewrite)/build/coverage 95.36%。
2026-07-08 07:12:04 +02:00
Yaojia Wang
6ed9c89430 feat(backend): 整章再沟通/重写 SSE 端点——喂当前草稿+意见+完整记忆注入流式重写一版
WFW-8 整章级再沟通(后端)。新增 POST /projects/{id}/chapters/{no}/rewrite(SSE):
- rewrite.md 教条(品类无关内核,非 SPEC,仿 write_craft 经 load_prompt 读盘);
- rewrite_node:build_rewrite_request 纯函数(system=[rewrite教条,stable_core] cache 前缀;
  input=近况+当前草稿+作者意见,断点后不入缓存前缀——守不变量 #9)+ stream_chapter_rewrite;
- RewriteStreamRequest{feedback,prior_draft}(带 max_length 上界);端点复用 assemble 记忆注入
  + normalize_deltas SSE,只读不写库(HITL,新版停前端接受才落,不变量 #3),是工具非写节点
  (不破坏 章=f(outline,state) 纯函数,不变量 #7),项目不存在触网关前 404。

门禁绿:ruff / mypy 224 files / pytest(新增 test_rewrite_node 5 例 + 更新 doctrine 一一对应)/
alembic 无漂移。OpenAPI 含新路径 + schema(前端待 gen:api)。
2026-07-08 07:04:42 +02:00
Yaojia Wang
3dd7d2861f feat(frontend): 写作工作台补齐三项——内容感知书名 / 上下文速查抽屉 / genre采集
写作工作台重构剩余 3 项(多 agent 并行构建各自新文件,主线统一集成):

- WFW-5 内容感知书名(#6):buildManuscriptExcerpt 取正文首尾摘录(硬上界控 token);
  GeneratorRunner 加 manuscriptText,有 brief 字段时出现「用当前正文」按钮把摘录填入
  brief,让 book-title 等据正文反推。纯前端零后端;HITL——只填表单,生成仍需作者触发。
- WFW-6 上下文速查抽屉(#7):ContextDrawer 视口无关右侧 slide-over,设定库/大纲完整
  只读速查 + 伏笔/规则/文风摘要跳链;底栏「速查」按钮触发。加法式、CONTEXT_DRAWER_ENABLED
  一键回滚、旧侧栏/全宽页路由全保留。
- WFW-7 genre 采集 + 无大纲降级:项目无题材时首次写章前弹 GenrePicker 采集(临时并入
  本次 directive 不落库);chapters 为空时编辑器显式提示「尚无大纲,将按设定自由生成」。

各项 TDD:manuscriptExcerpt/useGenreGate/contextDrawer/useContextDrawer 共 32 新单测。
门禁全绿:vitest 629 / tsc / lint / build / coverage 95.43%。
2026-07-07 20:44:09 +02:00
Yaojia Wang
44b0b8a7f0 feat(frontend): AI写作三槽——文风 / 剧情需求 / 自定义要求,写章前按需组合
Phase 2(写作工作台重构):把写章指令升级为三槽——文风预设 + 新增剧情需求预设
(打脸反转/章末钩子/高潮/转折/扮猪吃虎,源自 plan §4.2 分类法,tianyayu6/oh-story MIT)
+ 自定义自由文本。三者经 composeDirective 合并为单条 directive→volatile(MVP 纯前端、
零契约、不动 write_craft.md 字节,金标准零回归)。DirectivePanel 拆成文风/剧情两组 chips。
2026-07-07 19:51:19 +02:00
Yaojia Wang
04f4785292 feat(frontend): 编辑器内联工具箱——就地调生成器(含金手指),结果一键插入正文
Phase 1(写作工作台重构):编辑器「工具箱」按钮打开内联面板,不离开写作界面即可调用
全部生成器(含金手指——后端 golden-finger 早已齐全,此处首次露出)。复用 GeneratorRunner,
为其加可选 onInsertText:文本类产物(开篇/简介/续写/扩写等)点「插入正文」直接追加到章末,
可入库类仍走既有 ingest。useToolboxTools 客户端拉描述符(已单测)。润色/续写/工具箱三卡互斥。
2026-07-07 19:48:13 +02:00
Yaojia Wang
9195cf36f3 feat(frontend): 编辑器内「续写」——读本章前文生成多候选,点选插入正文
Phase 1(写作工作台重构):编辑器「续写」按钮复用 continue 生成器(with_prior_chapter
自动读该章已写正文承接),每次产出一条候选并累加成多候选(useContinue,已单测),
「再来一个」可多生成几版;作者点某条「插入正文」才追加到章末(HITL,不静默写入)。
续写前 flush 自动保存,确保读到最新草稿。润色/续写结果卡互斥不并占。
2026-07-07 19:41:57 +02:00