Commit Graph
6 Commits
Author SHA1 Message Date
ChaiHaoandClaude Opus 5 545103af1b A6 三个去向改选择组,「恰选一口」全链打通 —— 整条流第一次真正跑完
G4 是整条流最后的断点:三个去向写成了必交口里的 outcome 字段 + selective: [],
而引擎只在选择组恰发一口时才注入 outcome —— 结构上永远没有判据。

## 四层贯通

① 契约:验收工单加 `portChoice`(组名 + 可选出口)。draft 是 Omit 透传,human-tool 零改动。
② A6 声明:outcome 移出必交口,三个去向成选择组(won/revise/lost 各一口带人读说明)。
   契约 0.2.0、包版 0.7.0。G4 三条边一行没改 —— outcome 由放行选口注入落地事实。
③ 引擎:验收发卡时从活动契约现读选择组上卡(组是契约的事实,不在步的卡面里声明)。
④ 前端 AcceptForm:选择组渲染为必选单选,不选「通过」不亮;选中的口随放行回传。

## 「恰选一口」拦在收单,不拦在落地 —— 拦错位置实测翻过车

第一版把 validateSelection 放进 release.land:回传是**同步收单**(200 = 收到裁决),
落地在推进器里**异步**跑 —— 拦晚了就是「工单已答完、任务卡死、推进器循环报错」(实测)。
改到 checkWorkOrderReply(与「驳回必附意见」同族的收单规矩):工单投影自带 portChoice,
放行回传缺口/口不在组内 → 400 同步拒收,工单还活着,人补选就是。
land 里的 validateSelection 留作兜底 —— 这条从 contracts 导出以来从未被执行的不变量,
现在两个岗位都有了。

## 实测四连

  不选口通过 → 400「放行前先选『议价结果』」,工单未被吃掉
  选 won    → end_won released,流 completed —— **整条流第一次真正跑完**
  选 revise → A4#2 重开新实例(A4#1 留痕不动)
  选 lost   → A7 情报归档 → end_arch released,流 completed
  全程 route-dead-end 事件 0 条

typecheck ✓ lint ✓ depcruise ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 16:37:59 +08:00
ChaiHaoandClaude Opus 5 9802550ae8 审批 / 消息 / 纪要 / 汇报补上助理栏 —— 那不是空态,是整栏没渲染
`.workspace` 是**三列**网格(侧栏 · 工作区 · 助理栏 440px)。这四个模块只渲染了
两栏,右边就空出一条 **234px 的白带** —— 里面什么都没有,不是「空态没写好」,
是这一栏根本没画。实测四面皆然。

那一栏该摆什么,按 OS 4.1 定:「对话流 / 视图区」是**工作台-任务**的交互结构、
是回环输入的唯一入口。这四个要素各有自己的形态 —— 审批是通过/驳回附依据、
消息是就地答(MessageDesk 自己那条 NoteBand 早写着「不开放任务对话流」)、
纪要靠人记、汇报是确认即提交 —— 都不经对话流。

所以**不摆能打字的输入框**:那是在许诺聊得起来。只如实说这一栏是什么、
这一面该怎么用、想说话该去哪儿。共用件 `AssistantAside`,色调 `muted`
(通路不在这儿,灰着就不许诺),章也不打彩色渐变 —— 亮着像在待命。
四句文案各说各的事,不是同一句复制四遍:

  审批 拍板不用先商量 —— 看依据就够了,想先问一句就去那一单的任务里说
  消息 这儿不用聊     —— 就地答完即可,作答只及卡面,不用跑进别人的任务
  纪要 会得你自己开   —— 你写下来最准,写完登记起单责任才落到人
  汇报 不用你写一个字 —— 按任务日志自动聚合,要数字好看得回任务里干活

顺带治了题头被截:一行摆四件(章 · 任务助理 · Agent · 说明句),对话区压到
212px 时说明句只剩 29px,被省略号截成「汇…」,一个字都读不出来。改为按**本栏宽度**
容器查询,挤了就让说明句换到第二行拿整行说完。任务面的「盯着这单推进 · 有事随时说」
以前也是截的,这下一并读全了。容器上下文落在 `.jc-tch` 不是 `.session-chat` ——
后者带拖拽调宽的负偏移柄,不给它加 containment。

补 3 个缺失图标(gavel / pencil-line / chart-column)—— 不补就是空 SVG,这坑踩过。

typecheck ✓ lint ✓ depcruise 374 模块 ✓ api:check ✓ 490 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 11:27:52 +08:00
ChaiHaoandClaude Opus 5 f7b6a3a107 空态分出第三种空 —— 「没接通」不许诺,别让人白等
上一版补占位时漏了一件:占位分**两种**空,我只做了一种。

「沟通记录」的注释写着「明说没接,不伪装成暂无数据」,正文却写「与客户、供应商的
邮件和消息都会归到这里」—— 注释和文案自相矛盾。按单归档的投影根本没做,`outbound_mail`
至今只有 channel 建表和 reset-runs 碰过,**任何界面都读不到**。所以在那一屏等下去
永远不会有内容,而文案在请人等。

改成如实说:「往来记录还没接通」。并给 EmptyState 加第三色调,让三种空长得不一样:

  ok     办完了、清空了 —— 这是好事(待批清空、无未读)
  brand  还没发生,但通路是通的 —— 等着就会有(还没有任务、还没有成果)
  muted  通路还没接 —— 等下去也不会有。灰环灰图标,视觉上就不许诺

`muted` 是新加的真色调(不是我编的类名 —— union 与 CSS 一并落地)。
文案也不把人指去「消息」面:那里同样读不到外部邮件,指过去是第二个谎。

顺手把十处空态过了一遍:其余 brand 都名副其实(起单、聚合、纪要、成果的装配都通),
只有沟通记录这一处在许诺。债务簿该条对账。

tsc ✓ eslint ✓ depcruise ✓ 481 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 10:32:23 +08:00
ChaiHaoandClaude Opus 5 c59e73754b 工作台空占位补齐 —— 有内容渲染内容,没内容才落空态
任务面原来缺两处占位:中栏是一行裸文字,对话区在没选中任务时**整栏不渲染**。
补齐后三栏恒在:中栏落设计空态「手上没有任务」,对话区给全壳(题头 +
空态 + 禁用输入条),空着也看得出这是干什么的地方。

但真起一单之后暴露了更重的问题:占位在**说谎**。待处理角标写着 1,正文却
说「手上没有待办」—— 因为 ChatStream(643 行)与 WorkOrderReport(449 行)
早就写好、也从 @features/desk-task 导出了,却没有一处在用。占位不是缺内容,
是内容没接上。三处接回真渲染:

  待处理  → WorkOrderReport(工单正文、编号、派发时间、数据与分析)
  工作日志 → .jc-log 行,按归侧四类各一色(机器/人类/裁决/等世界)
  工作成果 → .jc-file 行,点开进 FileViewer;打开时右槽换「返回」
  对话区  → ChatStream,三个回传(说一句 / 答卡 / 答工单)在这里收口

顺带治了窄对话区的抗压:工作区优先保「五按钮 + 翻页」,对话区在 1280 下被
压到 212px,卡头标题 `flex:1` 没设 `min-width:0`,一挤就逐字折断成竖排单字。
降级顺序改成「状态芯片换行下沉、标题始终整词可读」—— 截断能让布局不崩,
但读的人不知道这是什么卡。不改任何一栏尺寸。

五闸:tsc ✓ eslint ✓ depcruise 373 模块 ✓ api:check 公开契约无变化 ✓ 481 测试 ✓
走查后清了运行数据(仓库自带 reset-runs,配置原样留着),换业务化主题重起一单。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-28 10:25:19 +08:00
ChaiHaoandClaude Fable 5 ac85ecf2ea 基线:鉴权会话+工作组+工作台三区修复+编排工作区+产品设计文档
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 20:43:35 +08:00
JCAI Main AgentandClaude Opus 5 3cfaa04098 M6(1/n): 工作台任务要素 —— 原型 1:1 平移的第一屏
样式整文件搬(README 平移规则 1):app.css 2767 行 + proto.vendor.css +
theme.css + console.css 原样搬,设计令牌与全部 jc-* / g-* 类名不动。

前端(按 §9 重排,渲染输出 1:1):
- shared/:Ico / ScrollArea / useChatWidth 自原型搬,去掉 "use client" 等 Next 专有件;
  失效的 react-hooks disable 指令按 §17 清掉(不改渲染)
- shared/typed-fetch.ts:服务端交互唯一通道,路由契约来自 @contracts/api;
  不引 Hono RPC 客户端(那要求前端 import 后端类型,违反 §5.1)
- app/query.ts:TanStack Query;缓存失效由订阅层驱动,组件不轮询
- features/desk-task:任务列表(一条 = 一个活动的一次运行,不是一整条工作流)/
  标题区 + 工作区四页签 / 对话区(气泡二元制 + 卡族 + **composer 锁**)
- @ui:ViewContainer 用**沙箱 iframe(sandbox 不含 allow-scripts)** —— 结构上无脚本执行权,
  不依赖净化算法的完备性;ViewBlocks 渲染十一种视图块
  feature 不得自行 dangerouslySetInnerHTML,eslint 有规则守着

后端:工作台路由 /api/desk/*(任务清单 / 任务详情 / 工单回传 / 自由输入 / 消息);
回传与后端校验**同 schema**;任务详情是服务端投影 —— 前端零过程状态,刷新即重建

已验证(真机):任务卡「A1 RFQ需求分析 · 序位 1/7 · awaiting-event」、
预算 2/40 步、1 张工单(LLM 步失败后转人兜底那张)、7 行带归侧标签的任务日志

358 个测试通过,门禁五道全绿;web 构建通过

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
2026-07-27 02:45:42 +08:00