Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
54d07dc
feat(agents): 工作流工程化——产出实双闸 + 契约引用打法 + 合并冲突 LLM 解 + 认领前适任判断(决策 14)
dommaker Sep 15, 2026
558932f
feat(skills): 度量地基票A——loadSkill cache 命中路径补发射 skill_used(level=info)
dommaker Sep 15, 2026
2a1292f
feat(skills): 度量地基票B——transcript 后验使用扫描(usage 主口径)
dommaker Sep 15, 2026
4e40582
feat(skills): 度量地基票C——skill_used 提级 signal(level=info,归档保留不 7 天滚)
dommaker Sep 15, 2026
14c7b30
feat(skills): 度量地基票D——聚合口径重定义:successRate 使用归因 + exposures 曝光分离
dommaker Sep 15, 2026
15af29b
docs(skills): 度量地基票收尾——CONTEXT.md 同步(使用/曝光口径、skill-usage-scan、level 提级)
dommaker Sep 15, 2026
388e9df
docs(adr): 架构评审 grilling 定案——C1 写路径单口(#538) + B1 web 闸门写模块(#545)
dommaker Sep 15, 2026
2ca76cf
refactor(workunit): 删除 types.ts 死 DTO 副本 + 复活 workunit-api CI 测试 + 删占…
dommaker Sep 15, 2026
f46aeb9
feat(workunit): service.delete 加 reason + 发 workunit:removed(墓碑单点构造)(…
dommaker Sep 15, 2026
1e3f7b2
feat(workunit): workunit:removed SSE 转发 + web 两 store 删行分支 (#538)
dommaker Sep 15, 2026
b47ca76
refactor(agents): monitor TTL / ops GC 删除循环改调 service.delete (#538)
dommaker Sep 15, 2026
d730168
feat(triggers): UPDATE 动作禁改 status + 白名单/metadata 合并写 (#538)
dommaker Sep 15, 2026
81fe723
refactor(discord): 按钮回调与 /studio stop 收口到 service 语义方法 (#538)
dommaker Sep 15, 2026
938d0e5
docs(context): #538 写单口收口落地同步六处 CONTEXT.md (#538)
dommaker Sep 15, 2026
045e4b9
fix(agents): monitor TTL 加终态守卫——仅删 done/closed,不再强删进行中长周期单 (#540)
dommaker Sep 15, 2026
bd18c8d
refactor(agents): 拆除 agent-loop re-export 门面,测试 import 迁真属主 (#544)
dommaker Sep 15, 2026
fe5a325
refactor(agents): agentStep 入口守卫链抽出 step-guards(对称 completion-gates)(…
dommaker Sep 15, 2026
d6e866d
docs(context): agents/CONTEXT.md 补 step-guards 条目 (#541)
dommaker Sep 15, 2026
dd56cd8
refactor(agent-loop): per-WU-type COMPLETE 收割改注册表 (#542)
dommaker Sep 15, 2026
7606280
refactor(agent-loop): 两段孪生重试骨架收编为步执行重试策略 (#543)
dommaker Sep 15, 2026
35ee290
refactor(web): 闸门写路径五处重抄收口为单一写模块 gateWriter (#545)
dommaker Sep 15, 2026
76d1564
refactor(web): per-channel need-input 投影收口 needInputViewOf 单源选择器 (#546)
dommaker Sep 15, 2026
2a04c94
refactor(web): ChannelMessageItem 公开 Props 收口——横切值经 ChannelMessageEnv…
dommaker Sep 15, 2026
88713ab
refactor(web): 频道 messages 收编 channelMessageStore 数据面 store (#548)
dommaker Sep 15, 2026
5584ffb
refactor(web): WU 域 SSE 被动写收口 + fresh 机制合一 + AuditLogsPage 对齐 useAsyn…
dommaker Sep 15, 2026
672ee8a
refactor(api): workunit 关闭单口 close() + 迁移类写路径统一落库尾部 (#550)
dommaker Sep 15, 2026
816378b
docs(discord): CONTEXT.md 同步 wu-closure 删除与 close() 单口 (#550)
dommaker Sep 15, 2026
df3b249
refactor(api): workunit routes 错误契约收口 + verify 业务下沉 service (#551)
dommaker Sep 15, 2026
fa3dd97
fix(api): step-retry-policy 日志恢复 traceId 透传 (#552)
dommaker Sep 16, 2026
887c97d
fix(api): monitor 2.5h 强杀豁免 decision/spec 单,消除每轮重复 critical 告警 (#553)
dommaker Sep 16, 2026
7fc2d8a
refactor(api): updateMetadata 补 service 语义口,收口 discord/trigger 两处 Fil…
dommaker Sep 16, 2026
e6f8dbf
docs(api): discord/triggers CONTEXT.md 同步 #554 updateMetadata 语义口 (#554)
dommaker Sep 16, 2026
bb4f296
fix(api): discord abandon 区分 not found 与状态机拒绝/落库失败,后者回真实原因 (#555)
dommaker Sep 16, 2026
35e5fda
docs(plans): #547 plan L3 指向修正——Agent Brief 空挂改为决策摘要+commit 正文 (#556)
dommaker Sep 16, 2026
d6eb502
fix(web): workUnitEnsureFresh 改用 listOnScreen 真实在屏信号,空列表不再丢重连对齐 (#557)
dommaker Sep 16, 2026
68961fe
docs(web): 样式规范批次 I-1——class 分层归属等 6 条文 + 规范入库
dommaker Sep 16, 2026
223740b
refactor(web): 批次 I-2 手写弹窗收编 ui/Modal
dommaker Sep 16, 2026
05fb7a4
fix(web): 批次 I-3 焦点可见性兜底 + 断点/卡片覆盖修正
dommaker Sep 16, 2026
5d68162
chore(web): 批次 I-4 死 CSS 清理 + u-* 迁址 utilities.css + 间距 token 化
dommaker Sep 16, 2026
647bcae
refactor(web): 批次 I-5a z-index/阴影 token 化 + 裸 transition 收窄 + import …
dommaker Sep 16, 2026
5028315
refactor(web): 批次 I-5b 原生 button 归队 .btn/.icon-btn 体系(components)
dommaker Sep 16, 2026
443fa1d
refactor(web): 批次 I-5b 原生 button 归队 .btn/.icon-btn 体系(pages + 沉淀)
dommaker Sep 16, 2026
a6c3600
refactor(web): 批次 I-6 任务一 ✓/✕/⚠ 字形扫尾 → ui/icons SVG
dommaker Sep 16, 2026
a73b499
refactor(web): 批次 I-6 任务二 3 处 Tailwind 自拼结构行归队
dommaker Sep 16, 2026
0909f25
refactor(web): 批次 I-6 任务三 responsive.css 删死规则 .form-group
dommaker Sep 16, 2026
7f088d6
docs(web): 批次 I-6 条目沉淀(字形扫尾/结构行归队/死规则验证)
dommaker Sep 16, 2026
8aa505a
fix(web): surface sub-fetch failures as inline error rows with retry
dommaker Sep 16, 2026
4604e81
feat(web): live-refresh KnowledgePage via knowledge.entry_changed SSE…
dommaker Sep 16, 2026
f739400
refactor(web): extract ApproveDialogShell from four isomorphic approv…
dommaker Sep 16, 2026
539d74b
refactor(web): replace css import-order contract with explicit specif…
dommaker Sep 16, 2026
20a4d75
fix(web): channel 消息流视觉层次改造——角色辨识/信息层级/折叠提示/线程成组/代码块/工作条
dommaker Sep 16, 2026
9ea0d89
feat(deps): 采纳 @dommaker/harness 1.8.0 并完成 breaking 随动改造
dommaker Sep 16, 2026
5a86e02
fix(harness): 管线外直调 hook 恢复 enabled/errorStrategy 判定闸——1.8.0 随动把 runH…
dommaker Sep 16, 2026
f5fa645
docs(harness): 消音三处「判定只住管线」不实表述,挂上 harness#167 票号
dommaker Sep 16, 2026
ce8f988
fix(web): channel 线程归属与折叠组模块感——锚点摘要头/作者标注/模块盒
dommaker Sep 16, 2026
9c45d29
fix(web): 折叠组与紧随同作者消息合成角色消息链模块(.mc-reply-chain)
dommaker Sep 16, 2026
7b38180
fix(agents): 唤醒只放行不裁决——复活/首睡窗口不再白等 30s
dommaker Sep 16, 2026
eb6bc83
fix(web): channel 消息角色分框 + 线程重复引用抑制——agent/人类盒子化、anchor quote 收口归属头
dommaker Sep 16, 2026
02bcf27
fix(agent): WU worktree 工具产物 exclude 补 CLAUDE.md
dommaker Sep 16, 2026
bc28831
fix(web): 折叠组/回复链内同作者相邻消息合并——一个头像多条消息
dommaker Sep 16, 2026
6b6668a
test(e2e): fake-cli COMPLETE 路径真实 git commit,同步收口守卫契约
dommaker Sep 16, 2026
629ac88
fix(web): 线程回复区去左缩进——与主流 agent 消息左边对齐
dommaker Sep 16, 2026
77e003f
fix(channel): members 端点校验 profile id + dev 启动脚本显式环境变量优先
dommaker Sep 16, 2026
714ec4d
perf(web): 频道消息流派生降本——deriveStreamView Set 化/升序不变量免全量 sort/日期串缓存,appl…
dommaker Sep 16, 2026
5072ec0
perf(web): needInput 投影等值复用,切断 stateItems 全局穿透(F2)
dommaker Sep 16, 2026
a4dab84
perf(web): 频道侧栏渲染降本——step 事件等值守卫 + 频道行 memo/per-channel unread select…
dommaker Sep 16, 2026
f07cc7e
docs(web): CONTEXT.md 同步 F3/F4 渲染边界(step 等值守卫 + 频道行 memo/per-channel …
dommaker Sep 16, 2026
35b7424
docs(plans): 本地形态/CLI探测/MCP安装器/方向锁定/skill流动 五份设计方案 + README写法备忘
dommaker Sep 16, 2026
022401c
docs(plans): 五份方案开放问题人审决策回写(2026-09-16)
dommaker Sep 16, 2026
17caf70
perf(file-store): 频道消息热层倒扫快径——before 锚点翻页到锚即停 + 带过滤 queryMessages 谓词倒扫早停
dommaker Sep 16, 2026
419f400
docs(shared): src/CONTEXT.md 同步 file-store 热层倒扫快径(B4/B5)
dommaker Sep 16, 2026
8d21af4
docs(plans): Q10 决策修订——命令面只要 web 动词 studio run web,不单设 start
dommaker Sep 16, 2026
3ee6480
docs(research): npm 本地形态摸底事实报告(#563)
dommaker Sep 16, 2026
b50aa38
perf(channels,events): channel 性能审计 B6-B8——SSE 广播每事件序列化一次、词表派生链并行+短 T…
dommaker Sep 16, 2026
f834186
docs(plans): Q10 决策终稿——studio run web 一体起服务,旧 studio run 删除让位
dommaker Sep 16, 2026
ab79718
test(channels): 缓存失效用例补建 profile 夹具,适配 members id 存在性校验
dommaker Sep 16, 2026
5279c74
fix(shared): eventBus 监听器上限抬到 64——workunit.status_changed 模块级订阅方常态 11…
dommaker Sep 16, 2026
9a3575c
feat(agents): STUDIO_AUTO_REVIEW=false 关停自动评审——闸 in_review 事件链与对账重派两条…
dommaker Sep 16, 2026
cc96093
feat(knowledge): STUDIO_KNOWLEDGE_EXTRACTION=false 跳过会话知识提取——无凭证/fake…
dommaker Sep 16, 2026
3f4eec1
test(e2e): mvp-loop (d) 断言认领前后两态(claim 会把 assigneeId 改写为实例 id,与本轮 GET…
dommaker Sep 16, 2026
e2bb505
fix(shared): stream-json 按 parent_tool_use_id 过滤子 agent 事件——子 error r…
dommaker Sep 16, 2026
691044b
chore(cli): 移除 legacy studio run 命令——@Analyst 角色已退役 (#569)
dommaker Sep 16, 2026
5b07566
docs(#570): 数据目录契约成文 + 迁移/首启/端口设计冻结
dommaker Sep 16, 2026
e2e9c3a
docs(#570): studio-shared/src/CONTEXT.md 数据根条目挂契约指针
dommaker Sep 16, 2026
6366389
feat(npm): npm 单包打包与 bin 改造 + studio run web 一体起服务 (#571)
dommaker Sep 16, 2026
9c5884c
feat(#572): 数据区 schema 版本标记 + 启动时迁移框架(契约 §5 方案 A 骨架)
dommaker Sep 16, 2026
8ed8c44
feat(#573): 首启/端口双口径收口 + checkPrerequisites 对齐 provider 注册表
dommaker Sep 16, 2026
6378549
feat(#565): CLI 能力探测 + auth 三态诊断 + 失败分类器
dommaker Sep 16, 2026
cda34c4
feat(mcp): 对外只读 MCP 入口 + studio mcp install 一键安装器 (#566)
dommaker Sep 16, 2026
7b05809
feat(agents): plan 流程方向锁定卡——候选方向 + 人锁定后再拆单 (#567)
dommaker Sep 16, 2026
0e85e13
feat(cli): studio skill validate — 布局/frontmatter 离线校验 + CLI 分流骨架 (#5…
dommaker Sep 16, 2026
b9fac06
feat(cli): studio skill export/install — 目录拷贝 + PROVENANCE 边车 + seed …
dommaker Sep 16, 2026
267e91d
docs(cli): skill 三件套 CONTEXT 沉淀 + 回馈内置库流程 (#568 P3)
dommaker Sep 16, 2026
8c24459
feat(providers): provider 动态模型发现 listModels — 探测命令+解析器声明,失败回退静态 fallb…
dommaker Sep 17, 2026
96a2011
docs: 脱敏公开仓文档中的本机绝对路径(批次 564 复审 Standards 轴 major 修复)
dommaker Sep 17, 2026
a1969cf
style(agents): agent-loop consecutiveStuck 改 const——只读变量清 prefer-cons…
dommaker Sep 17, 2026
7cd3324
fix(agents): monitor-agent-resilience 套件 import 崩溃——wholesale mock 补 …
dommaker Sep 17, 2026
00ae3b2
docs(agents): CONTEXT.md 沉淀 wholesale mock import 期崩坑(#575 排查结论)
dommaker Sep 17, 2026
3b00bc1
chore: upgrade @dommaker/harness 1.8.0 → 1.8.1
dommaker Sep 17, 2026
f0c0e60
perf(channels): WU 讨论串端点 limit 下推命中 file-store 倒扫快径 (#576)
dommaker Sep 17, 2026
70d6e5a
fix(agents): system-executor execSh 恒开 killProcessGroup(#581)
dommaker Sep 17, 2026
8d8f03e
test(cli): server.test.ts mock scanAllProviders 隔离真机全量扫描 (#577)
dommaker Sep 17, 2026
1739056
docs(cli): CONTEXT.md 沉淀 checkPrerequisites 测试 mock 口径 (#577)
dommaker Sep 17, 2026
379a592
feat(agents): STUDIO_CLAIM_FITNESS=false 豁免认领前适任判断的真实 CLI 调用——fake/无凭…
dommaker Sep 17, 2026
5324a29
test(e2e): pmo-full-chain boot env 补 PMO_GIT_REPO_ROOTS——三条腿仓库建在 tmpR…
dommaker Sep 17, 2026
ad80baa
test(agents): review-gate.test 随动 harness 删除 GateContext.projectId (#…
dommaker Sep 17, 2026
49ae7a1
docs(adr): hooks 层收缩与约束分拣标准(#562 裁决)
dommaker Sep 17, 2026
dc1ecae
refactor(hooks): 删除 hooks 管线层与 session loop 死路径(#562 裁决落地)
dommaker Sep 17, 2026
7f8f11c
docs(hooks): #562 评审随动——清掉指向已删路径的注释与申报新孤儿
dommaker Sep 17, 2026
c0b968e
docs(hooks): #562 评审随动第二批——补齐上一条声称却未落地的修正
dommaker Sep 17, 2026
d974c01
docs(shared): CONTEXT.md 墓碑收紧——按 exploration-sediment「不留已删符号残影」重写 hoo…
dommaker Sep 17, 2026
d1e2b07
docs(adr): 决策审计归并——events:audit 链下线 + 审计数据补齐走 audit-logs 轨(#588)
dommaker Sep 17, 2026
fc47d1c
refactor(runner): 清 #562 遗留孤儿 helper 与 sessionFlags 死通道(#587)
dommaker Sep 17, 2026
6cee8d0
docs(shared): CONTEXT.md 记 #587 后的 RKB 消费方收敛与新孤儿 formatRkbHint(申报待另票)
dommaker Sep 17, 2026
7d7054e
docs(shared): #587 评审随动——申报第二个新孤儿 spawn.addDirFlag + 计划文档入库补 AC#4 凭据
dommaker Sep 17, 2026
1ecc0b3
docs(shared): 沉淀——约束 prompt 正本只剩 harness 一处,别在 studio 重建 role→trigger…
dommaker Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
run: pnpm install

- name: Build
run: pnpm build
run: pnpm build && pnpm build:npm

- name: Test
run: pnpm test
Expand Down
13 changes: 10 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ node_modules/
# Build output
dist/
build/
dist-npm/

# API 前端构建产物落盘(apps/api/frontend/dist 由 prod/deploy.sh 同步,
# 历史手工拷贝的 stale 副本以 dist.stale-* 隔离;整个目录不入库)
Expand Down Expand Up @@ -62,6 +63,12 @@ docs/*
!docs/adr/
# docs/visual-reports/ 豁免——#390 决议:截图 diff 报告入 git 作改版验收凭据(#391)
!docs/visual-reports/
# docs/specs/ui/style-guide.md 豁免——样式规范是唯一权威来源,须入 git 评审/回溯(批次 I-1 治理人闸当场过,2026-09-16);其余 spec 源文件维持忽略
!docs/specs/
docs/specs/*
!docs/specs/ui/
docs/specs/ui/*
!docs/specs/ui/style-guide.md

# Scratch workspace (ignored)
.scratch/
Expand All @@ -88,9 +95,9 @@ e2e/.auth.json
CLAUDE.md
.claude/

# Runner worktree artifacts (regenerated per worktree at runtime;
# committing them breaks per-worktree regeneration — runner-execution only
# writes CACHE_PREFIX.md when absent, and worktrees inherit tracked files)
# Runner worktree artifacts (regenerated per worktree at runtime; committing them
# breaks per-worktree regeneration, and worktrees inherit tracked files).
# 两条写方随 #562 删除,保留规则只为兜住历史 worktree 里的残留产物。
CACHE_PREFIX.md
.prompt.md

Expand Down
2 changes: 1 addition & 1 deletion .harness/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
preset: standard
harness:
version: 1.7.0
version: 1.8.0
10 changes: 7 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
| `.harness/` | harness 配置与运行时状态 |
| `apps/` | monorepo 应用:api、web |
| `bin/` | 可执行入口/脚本 |
| `dist-npm/` | — |
| `docs/` | 项目文档 |
| `node-compile-cache/` | — |
| `packages/` | monorepo 共享包:studio-agent、studio-audit、studio-capability、studio-notification、studio-shared、studio-skill、studio-spec |
Expand Down Expand Up @@ -46,9 +47,11 @@ pnpm start # 启动生产服务

> 本段手写,增删改走段末「治理变更流程」。依据:docs/adr/2026-08-21-agent-docs-three-kinds.md(内容三分)+ 2026-08-21-agent-docs-placement-model.md(落点模型),2026-08-21 自 CLAUDE.md 迁入(#300/#303)。

- 数据目录契约:`docs/architecture/data-directory-contract.md` 是 `~/.studio` 数据区布局/可改纪律/变更纪律/版本迁移的唯一正本;布局变更须先修订契约(出处:#570 / docs/plans/2026-09-npm-local-form.md §7.4,治理人闸 2026-09-16 当场通过)。

## Governance Rules
<!-- HARNESS_CONSTRAINTS_START -->
<!-- version: 1.7.0 -->
<!-- version: 1.8.0 -->
### Iron Laws (违反将阻断)
- **no_completion_without_verification**: 在声明任务完成前,必须重新运行新鲜的验证命令——受改动影响的测试(vitest run --changed origin/master)+ type check,使用新鲜的输出作为完成证据,不得复用旧结果。全量测试由 CI / 发布流程兜底。
- **incremental_progress**: 一次只处理一个任务。改动涉及多个模块、超过 100 行、或影响多个文件时,必须拆分为小步骤分步执行,每步有独立 checkpoint 可回滚。不要试图一次性完成所有改动。
Expand Down Expand Up @@ -168,6 +171,7 @@ pnpm start # 启动生产服务
| `apps/api/src/modules/mcp` | MCP(Model Context Protocol)模块 — 将 Studio 系统能力暴露为 MCP tools,供 Agent 和 UI 共享调用。 |
| `apps/api/src/modules/monitoring` | 负责聚合 Agent Network 的监控指标,包括 Agent 摘要、统计信息、飞轮指标(M1)和封装开销(M2),通过 HTTP 路由对外暴露。 |
| `apps/api/src/modules/notifications` | 提供通知相关的 API 路由,包括获取通知列表、查询未读数量、标记单条已读和标记全部已读,作为后台消息通知模块的 HTTP 接口层。 |
| `apps/api/src/modules/notify-channels` | 通知渠道配置(#525 P2-6,决策 #516 项⑦⑧):服务端配置存储 + 读写 API + ClawBot(iLink 协议)内嵌轻量直连。/settings「通知渠道」配置区的服务端支撑——#434 死配置的「复活成真功能」版... |
| `apps/api/src/modules/outbound-notify` | 本模块提供基于 Discord 的通知发送服务,支持多种任务与会议相关通知类型。内部封装了对 discordNotifier 的调用,并通过 eventBus 将通知事件发布到消息总线。还暴露 HTTP 路由供内部模块通过 POST... |
| `apps/api/src/modules/pmo` | 项目管理办公室(PMO):OKR 管理 + 项目 CRUD + 交付守卫。PMO 是链条脊椎:id = 分支名、需求文档挂载点、状态 = WU 汇总 + 证据台账、交付策略挂在项目上。统一编号 PMO-<n>。 |
| `apps/api/src/modules/projects` | Project Discovery(AC-D1 + AC-D3):发现已注册的工程(repo)信息并对外提供查询 API,供频道默认工程、WorkUnit 工程绑定等流程使用。 |
Expand All @@ -176,12 +180,12 @@ pnpm start # 启动生产服务
| `apps/api/src/modules/role-memory` | 角色记忆存储服务:per-role 目录落数据区(经 studioPath()),三件套--MEMORY.md 索引 + topics/*.md topic 正文 + draft.jsonl append-only 草稿区。role-... |
| `apps/api/src/modules/skills` | skills 模块负责技能(Skill)的完整生命周期管理,包括基于文件的技能元数据存储(SkillStore)、技能目录扫描与加载(manifest-loader)、基于描述的技能匹配(skill-selector)、从 WorkU... |
| `apps/api/src/modules/specs` | 提供 Specs 模块的 HTTP API 路由,包括变更分析、变更历史查询和门禁验证(待实现)。遵循 SP-002 变更分级流程,通过调用外部 SDK 中的服务处理 Spec 变更相关的业务逻辑。 |
| `apps/api/src/modules/transcripts` | transcript 归档器(#97,#88 子票):把会话原文落盘到数据区(经 studioDir()/studioPath()),供三个消费方共用——#99 WU 收尾批量提取(要全文)、handoff 摘要(要对话)、#85 执... |
| `apps/api/src/modules/transcripts` | transcript 归档器(#97,#88 子票):把会话原文落盘到数据区(经 studioDir()/studioPath()),供四个消费方共用——#99 WU 收尾批量提取(要全文)、handoff 摘要(要对话)、#85 执... |
| `apps/api/src/modules/triage` | 实现错误的分类(triage)与严重度评估,提供策略路由(auto_retry / manual_fix / escalate / ignore),支持开发者错误和系统级事件的分类。 |
| `apps/api/src/modules/triggers` | Trigger 子系统(AS-026,3.28c-4):SCHEDULE(cron)+ EVENT(EventBus)两类条件的触发器调度与持久化,动作包括 CREATE WorkUnit / UPDATE / EXECUTE。系统默... |
| `apps/api/src/modules/workspaces` | 本机 Workspace 记录的自动注册与查询(只读 list/get + 删除)、CLI 运行时清单扫描。Token 管理已随 #481 退役删除。 |
| `apps/api/src/modules/workunit` | WorkUnit 核心域: 任务单元 CRUD、认领与状态机; F5 双向沟通的 NEED_INPUT 挂起/恢复与超时提醒。 |
| `packages/studio-agent` | Sub-agent 的完整生命周期管理:创建隔离 worktree → spawn Claude Codesession loop 监控 → 完成判定。 |
| `packages/studio-agent` | Sub-agent 的完整生命周期管理:创建隔离 worktree → 传播 harness 配置spawn provider CLI(单 session)→ stream-json 解析与事件发射。完成判定/状态机不在本包,由... |
| `packages/studio-audit` | 提供审计日志的记录、查询、统计与导出功能。通过 AuditService 进行持久化日志操作(JSONL 存储)。 |
| `packages/studio-capability` | 本目录负责能力管理(CapabilityService)。CapabilityService 提供能力的 CRUD、同步、统计,并基于 FileStore JSON 文件存储实现(替代 Prisma)。 |
| `packages/studio-notification` | 本目录提供 studio-notification 包的核心代码,包含通知的创建、查询、标记,服务层基于 FileStore 实现持久化通知管理。 |
Expand Down
7 changes: 5 additions & 2 deletions CAPABILITIES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CAPABILITIES.md

> 最后更新: 2026-09-15
> 最后更新: 2026-09-17

---

Expand All @@ -16,7 +16,7 @@

| src | packages/studio-shared/src/ | Studio Event Bus — 替代 Redis pub/sub(2026-05-08) |
| auditor-types | packages/studio-shared/src/harness/auditor/auditor-types.ts | Auditor ↔ 其他角色协议定义(BP-013 + BP-014) |
| hooks | packages/studio-shared/src/harness/hooks/ | Agent Execution Phase Hooks |

| harness | packages/studio-shared/src/harness/ | Constraint Prompt Injection — 将 harness 约束的前置声明注入 Agent prompt |
| runtime | packages/studio-shared/src/harness/runtime/ | Harness Runtime Bootstrap — Phase 2 迁移 |

Expand Down Expand Up @@ -275,4 +275,7 @@
| NotifyChannelsSection | apps/web/src/components/settings/NotifyChannelsSection.tsx | 通知渠道 section(#525 P2-6):企业微信群机器人 webhook + ClawBot(个人微信)扫码绑定 + 浏览器通知总开关。 |
| wecom-client | apps/api/src/modules/notify-channels/wecom-client.ts | 企业微信群机器人 markdown 发送唯一出口(#525 review 收口): |
| ChannelStreamBody | apps/web/src/components/channel/ChannelStreamBody.tsx | 频道消息流结构组件(#531,架构评审 2026-09-14 候选 3):消费 useChannelStream 产物, |
| ChannelMessageEnv | apps/web/src/components/channel/ChannelMessageEnv.tsx | 频道消息环境(#547,架构评审 2026-09-15 候选 B3,grilling 已决): |
| ApproveDialogShell | apps/web/src/components/ui/ApproveDialogShell.tsx | ApproveDialogShell — 审批弹窗公共壳(docs/plans/2026-09-web-ux-optional-fixes.md Step 3, |
| PlanDirectionCard | apps/web/src/components/channel/PlanDirectionCard.tsx | PlanDirectionCard — #567:方向锁定接力卡(plan 一脉会话内方向人闸,裁决轮前置环节) |
| mockMatchMedia | apps/web/src/test/mockMatchMedia.ts | #395:jsdom 无 window.matchMedia 实现——按给定视口宽度求值 (min|max)-width 媒体查询, |
20 changes: 10 additions & 10 deletions apps/api/bench/claim-latency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
* 特征词触发 B2 守卫——认领后立即关闭,不起 LLM 会话、不烧 token):
* B1 拾取延迟:建 unassigned WU(指名本 role)→ 轮询 index 拿 claimedAt,N 轮随机相位;
* 同时记录 getIndex 调用时刻,验证 workunit.created EVENT 触发的 observe 是否带来认领。
* B2 事件唤醒延迟:blocked WU(assignee=实例)进入 lastActiveWuIds 后发人类消息,
* B2 事件唤醒延迟:blocked WU(assignee=实例)就绪且 loop 进入 idleSleep 后发人类消息,
* 测量 message_sent publish → 下一次 observe(getIndex) 的时延。
* (2026-09-16 唤醒放宽:不再等 lastActiveWuIds,该派生缓存机制已删——唤醒只放行不裁决)
*/
import fs from 'node:fs';
import path from 'node:path';
Expand Down Expand Up @@ -187,7 +188,8 @@ async function main(): Promise<void> {

// B2:channel.message_sent 唤醒延迟
console.log('\n── B2: 人类消息 → 唤醒 idle sleep → 下一次 observe ──');
// 建 blocked WU 挂本实例,等它进入 lastActiveWuIds(observe 每 ≤15s 刷一次)。
// 建 blocked WU 挂本实例。2026-09-16 唤醒放宽后不再等 lastActiveWuIds(机制已删,
// 唤醒只放行不裁决)——只需等 loop 进入 idleSleep。
// scope 必须带 test 特征词:唤醒后 loop 会真的拾取该 WU 起会话——B2 守卫拦在
// prompt 组装前直接关闭,防误烧 token(2026-09-12 首跑教训:无 test 词的 scope
// 被唤醒的 loop 当真任务 spawn 了真实 CLI 会话)。
Expand All @@ -197,17 +199,14 @@ async function main(): Promise<void> {
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const seam = loop as any;
const regDeadline = Date.now() + 20_000;
while (!seam.lastActiveWuIds?.has(blockedWu.id) && Date.now() < regDeadline) {
await new Promise(res => setTimeout(res, 100));
}
if (!seam.lastActiveWuIds?.has(blockedWu.id)) {
console.log('B2 SKIP: blocked WU 20s 未进入 lastActiveWuIds');
} else {
console.log('[bench] blocked WU 已进入 lastActiveWuIds,loop 处于 idleSleep');
{
// 等 loop 确实进入 idleSleep(wakeIdle 挂起)
const idleDeadline = Date.now() + 20_000;
while (!seam.wakeIdle && Date.now() < idleDeadline) await new Promise(res => setTimeout(res, 50));
if (!seam.wakeIdle) {
console.log('B2 SKIP: loop 20s 未进入 idleSleep');
} else {
console.log('[bench] loop 处于 idleSleep');
const wakeLat: number[] = [];
for (let i = 0; i < 3; i++) {
// 等回 idleSleep
Expand All @@ -233,6 +232,7 @@ async function main(): Promise<void> {
await new Promise(res => setTimeout(res, 3_000));
}
if (wakeLat.length > 0) console.log(`B2 唤醒延迟: ${summary(wakeLat)}`);
}
}

loop.stop();
Expand Down
5 changes: 1 addition & 4 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
"name": "@dommaker/studio-api",
"version": "0.1.0",
"private": true,
"bin": {
"studio": "src/cli/studio-cli.ts"
},
"scripts": {
"dev": "STUDIO_HOME=${STUDIO_HOME:-$HOME/.studio-dev} tsx watch src/index.ts",
"build": "tsc",
Expand All @@ -13,7 +10,7 @@
"test:watch": "vitest"
},
"dependencies": {
"@dommaker/harness": "^1.7.0",
"@dommaker/harness": "^1.8.1",
"@dommaker/studio-agent": "workspace:*",
"@dommaker/studio-audit": "workspace:*",
"@dommaker/studio-capability": "workspace:*",
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export async function registerRoutes(): Promise<void> {
'/mcp/health', // MCP health check
'/mcp/sse', // MCP SSE transport endpoint
'/mcp/messages', // MCP SSE message endpoint
'/mcp/external/sse', // #566: 外部只读 SSE 入口(钉死 external 角色)
'/mcp/external/messages', // #566: 外部只读 SSE 消息端点
]);
const optAuth = optionalAuth();
app.use('/api/v1', async (req: any, res: any, next: any) => {
Expand Down
28 changes: 28 additions & 0 deletions apps/api/src/cli/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# apps/api/src/cli — Studio CLI 入口与命令域

## 职责

`studio` 命令的入口/分发(studio-cli.ts)与各命令域实现。两类服务启动路径:

- `studio run web`(run-web.ts,#571):npm 本地形态一体起服务总入口——API + 托管已构建 web dist + 首启检测块 + 端口动态顺延,前台进程 Ctrl-C 即停。
- `studio up`(server.ts):服务器形态启动(systemd 托管场景),原样保留。

## 核心导出

- `studio-cli.ts`:入口/分发/帮助文本;`run web [--port <n>]` 动词。
- `run-web.ts`:`studioRunWeb()`——启动链:ensureDataDirs/ensureDaemonSecrets → 端口解析 → 首启面板 → preflight(存储探针 + frontend dist)→ ensureDefaults → `await import('../index.js')`。数据区迁移钩子接入点(#572)在其 preflight 之前。
- `bootstrap.ts`:ensureDataDirs / ensureDaemonSecrets(env > .daemon/ 文件 > 生成落盘)/ probeStorageWritable;run web 与 up 共用。
- `port-probe.ts`:probePortFree(net 模块探测,跨平台不走 lsof)/ resolvePort(默认 3001 起顺延上限 +100;显式 --port/PORT 占用即拒启)/ parsePortFlag / explicitPortFromEnv。
- `first-run-panel.ts`:buildFirstRunPanel()——Node 版本对 engines>=20、cli-scanner 全 provider 探测结果、数据根、实际监听地址;零 provider 只提示不阻断。
- `mcp-install.ts`(#566 P3):`studio mcp install <agent> [--url] [--print] [--uninstall]`——把对外只读 MCP 入口(/api/v1/mcp/external/sse)幂等合入 agent 用户级配置(claude `~/.claude.json` / kimi `~/.kimi-code/mcp.json` / opencode `~/.config/opencode/opencode.json`,均只动 `studio` key、写前 .bak 备份、JSON 损坏拒写);URL 缺省探测 3001 /mcp/health,不通报错提示 --url;codex 不支持 SSE 报错(Q2 不架 mcp-remote 桥)。
- `skill.ts` + `skill-validate.ts`(#568):`studio skill validate/export/install` 流动三件套——纯本地文件操作(daemon 离线可用,与走 HTTP 的 `studio skill list` 分流于 studio-cli.ts `case 'skill'`);validate 规则 = 布局 + frontmatter(name≠目录名为 error,description/triggers 缺为 warning);export = 目录拷贝 + `PROVENANCE.json` 边车(contentHash 复用 `hashSkillDir`,脱敏不写绝对路径);install 与内置正本同名硬拒绝(保护 seed hash 升级通道),冲突/no-op/--force 三态,不碰 `.builtin-hashes.json` 与 `skills-index.json`。

## 注意事项

- **npm 单包形态 = esbuild bundle**(`scripts/build-npm.mjs` → `dist-npm/`,根 package.json files 白名单 `bin/studio` + `dist-npm`):workspace 包代码全部内嵌,npm 依赖保持 external(= 根 dependencies,metafile 校验内嵌零 node_modules)。`bin/studio` 薄入口:bundle 存在则 import,否则 monorepo fallback 到 tsx 跑源。
- **两个 bundle 相对路径约定**:frontend dist = `<bundle>/../frontend/dist`(与 app.ts:133 同表达式);内置 skill 正本 = `<bundle>/../skills`(seed.ts defaultSourceDir 上溯一级约定)。改 dist-npm 布局三处要一起动。
- **坑(esbuild 提升)**:index.ts 顶部的 `import 'dotenv/config'` 被 esbuild 提升到 bundle 顶层 → 任何 CLI 动词都会加载 **cwd 的 .env**;其中 PORT 对 `run web` 是显式语义(占用即拒启)。在含 PORT 的仓库目录下跑 `studio run web` 不带 --port 会被 .env 的 PORT 卡住。
- **apps/api 的 tsc dist 不能被 node 直跑**(tsconfig module ESNext 而包无 `type: module`,产物含 ESM import + 裸 require/__dirname)——npm 形态不走 tsc dist,`pnpm start`/`dev` 走 tsx;不要再给 tsc dist 加 bin 指向(apps/api bin 已于 #571 移除)。
- CJS 遗迹:部分模块仍有 `require(...)` 惰性调用——bundle 靠 banner 的 createRequire 兜底,dev 靠 tsx;改 ESM 化时逐文件处理,别指望 tsc 产物直接跑。
- **checkPrerequisites 测试口径(#577)**:scanAllProviders 真机全量扫描成本随 provider 探测增长(#573 注册表扫描、#574 模型探测后复审环境实测 43-55s),`__tests__/server.test.ts` 已用 importOriginal 部分 mock 隔离——该文件任何用例不得再打真扫描/留集成级超时窗口;要真扫描覆盖请放 e2e。
- `studio up` 语义不动,但端口口径已随 #573 收口:启动前经 port-probe 解析(PORT 显式占用即拒启,缺省 3001 动态顺延上限 +100),ops preflight 的 lsof abort 与 index.ts 的 EADDRINUSE 3s 无限重试均已删除(后者归 utils/listen-error.ts,listen 竞态撞占用 = 拒启)。checkPrerequisites 的 agent CLI 检查同票对齐 provider 注册表扫描(不再硬编码 claude),缺失只警告不阻断。
Loading
Loading