Skip to content

v0.2.9

Choose a tag to compare

@MichaelShii MichaelShii released this 16 Oct 18:08
· 71 commits to main since this release

TeamFlow v0.2.9

发布日期:2026-10-17。变更清单按 release-npm-package 铁律 1 由 git log v0.2.8..HEAD 生成
(11 提交 / 35 文件 / +1371 −102),不凭会话记忆。⚠️ 本版含破坏性变更(宿主 subagent API)。
逐条论证见各提交信息与 docs/TODO.md。

中文

⬆️ 升级要点

  • 先升宿主,再升插件。本版把 engines.dsh 收窄为 >=0.2.1-alpha.2 <0.3.0——宿主低于该版本会被宿主直接
    跳过本插件(skippedBundles,工作台不可用)
    。这是宿主在 alpha.2 删除旧接口后的必然结果,不是可绕过的。
  • 升级命令见 README;升完重启 dsh --profile web(桌面版重启桌面应用)。
  • 之后的新版本会由插件自己提示(v0.2.8 引入的更新提示),无需再手动查。

① 破坏性:适配宿主 alpha.2 的 subagent API(issue #20)

宿主 dsh-v0.2.1-alpha.2(提交 3d852a1cea)删除了扁平入口 subagents.start(name, request),唯一入口改为
startActivation(spec)。

  • 不做旧版兼容、不写 shim:以 engines.dsh 当门禁。⚠️ 顺带订正两条旧结论——engines.dsh 是宿主强校验
    的(旧 README 写「宿主不校验」是错的);alpha.2 起 one-shot 也占 maxActiveSubagents 池(默认 8)。
  • 计量句柄必须在「启动窗口内」取:宿主对本地子级 idle 即 close,而 activation.result 要等 handle cleanup
    之后才 settle ⇒ 原来的「lazy getter」读 token usage 时句柄早已注销(实锤某个 run 21/21 阶段 usage 全空、
    静默数小时
    ,run 还照报 completed)。现在改为 startActivation 返回那一刻取活 Agent 塞进句柄;再取不到就以
    diag.usageMissing 每 run 一条 warn 显式上报(空值必须可见)。
  • 跳子代理会话的地址 mode 传 'unknown':本插件的阶段子代理在 alpha.2 起一律记 continuable,写死 'one-shot'
    会被宿主判 subagent/unauthorized(实机点「跳转子代理会话」即失败)。'unknown' 是宿主钦定的浏览语义,不是猜。

② 真机暴露后的修复批次

# 症状(真机实锤) 修复要点
1 宿主重启后中文环境整轮产物全英文,且界面中英混排 客户端语言上报改有界重试(成功即停 / 2s 重排 / 上限 8 / 世代判据 / dispose 安静);宿主新增 localeSource() 三态,新 run 语言取自兜底时写可见 warn(原先全静默,正是它长期没被发现的原因)
2 确认单串了上一轮(「汇报层串了模版」):r5 的确认单显示 r4 的目标与 AC state.json 是按项目累积、跨 run 的;确认单改为只读本轮快照 journal.prdSnapshot,缺就诚实显示「没抓到」,不回落旧值冒充本轮
3 模型把参数传错却被判「环境不可用」→ 硬停且不重试 「参数类失败」豁免从「列举 fs 工具三条文案」改为按解析层前缀整体覆盖(含宿主通用前缀 invalid arguments:)——否则任何非 fs 工具的类型错都会硬停
4 QA 复验表里「已修复」的缺陷被计成本轮阻断 → 三轮「未收敛」→ 验收被跳过、run 误降级 needs-human 判据补「状态/结论列」:明确标已闭环的行跳过(残余/待修复/开放 照常计入);新增冻结语料 + 循环级行为门禁
5 「文件即产物」只查「在不在/够不够长」→ 上游越界写下游产物,下游自评 加新鲜度指纹(阶段开始时的 size:mtimeMs):只有指纹变了才认、只填缺失项
6 12 个缺陷卡都显示「待认领」,但两类原因不可区分 卡片/详情面板新增「停留原因」行:P3 观察项(不自动关)/未闭环·来源需求需人工裁定/未闭环·待修复

验证

  • typecheck 0 错;全量测试通过(新增/扩写 confirm-run-snapshot、bug-open-reason、locale、empty-turn、
    orchestration、smoke,以及新增冻结语料 qa-reverify-status-column.md);各修复均配单维度变异证明断言有牙。
  • 真机:alpha.2 适配经两个真实 run(tf-mvaubzdz / tf-mvb3lm0b,共 24 阶段)全程跑通子代理;确认单快照与
    invalid arguments: 豁免均在真机日志中确认生效。
  • 唯一未真机项:第 4 条(QA 复验表)。其输入形态取自真实 QA 报告并已冻结成语料,运行路径由循环级行为门禁
    (orchestration.test.js [10b])覆盖——该项的真实触发很随机(历史样本里触达复验上限只有 1/52),故以门禁替代真机。

English

⬆️ Upgrade notes

  • Upgrade the host first, then this plugin. engines.dsh is now >=0.2.1-alpha.2 <0.3.0. On an older host the
    plugin is skipped by the host (skippedBundles, workbench unavailable). This is forced by the host deleting the
    old subagent entry in alpha.2 — there is no workaround.
  • After upgrading, restart dsh --profile web (restart the desktop app on desktop).
  • Future versions will announce themselves (the update notice introduced in v0.2.8).

① Breaking: adapt to host alpha.2 subagent API (issue #20)

Host dsh-v0.2.1-alpha.2 (commit 3d852a1cea) removed the flat entry subagents.start(name, request); the only
entry point is now startActivation(spec).

  • No backward compatibility, no shim — the engines.dsh range is the gate. Two earlier conclusions were also
    corrected: engines.dsh is host-enforced (the old README claim that it is not was wrong), and since alpha.2
    one-shot agents also occupy the maxActiveSubagents pool (default 8).
  • Metering handles must be taken inside the startup window. The host closes a local child as soon as it goes idle,
    while activation.result settles only after handle cleanup — so the previous lazy getter read token usage after
    the handle was already unregistered (one real run had all 21/21 stages with empty usage, silently, for hours).
    Handles are now captured the instant startActivation returns; missing values raise a per-run diag.usageMissing warn.
  • Subagent-session address mode is now 'unknown'. Stage subagents are recorded as continuable since alpha.2, so
    a hard-coded 'one-shot' is rejected as subagent/unauthorized. 'unknown' is the host's own browsing semantics.

② Fixes found on real machines

# Symptom (observed on a real machine) Fix
1 Whole run produced English artifacts in a Chinese environment Client locale push is now a bounded retry (stop on success / 2s reschedule / max 8 / generation guard / quiet dispose); host adds a three-state localeSource() and warns visibly when a new run falls back
2 Confirm sheet carried the previous run's content state.json accumulates across runs; the confirm sheet now reads a run-level snapshot (journal.prdSnapshot) and honestly says "not captured" instead of showing stale values
3 A wrong tool argument was classified as environment unavailable and hard-stopped The argument-failure exemption now matches the parse-layer prefix class (invalid arguments:), not just three fs-tool messages
4 Fixed defects in a QA re-verification table counted as open blockers → "never converged" → acceptance skipped, run wrongly downgraded to needs-human The status/conclusion column is now honored (rows explicitly marked closed are skipped); frozen corpus + loop-level gate added
5 "File is the artifact" only checked existence/length → upstream could write downstream artifacts Freshness fingerprint (size:mtimeMs captured at stage start)
6 All open defect cards showed "unclaimed" while two very different reasons were indistinguishable Cards/detail pane now show a "why still open" line

Verification

  • typecheck clean; full test suite green (new/extended confirm-run-snapshot, bug-open-reason, locale, empty-turn,
    orchestration, smoke, plus the new frozen corpus qa-reverify-status-column.md); every fix ships with a
    single-dimension mutation proof.
  • Real machine: the alpha.2 adaptation ran through two real pipelines (tf-mvaubzdz / tf-mvb3lm0b, 24 stages total)
    with subagents working end to end; the confirm-sheet snapshot and the invalid arguments: exemption were confirmed in
    real logs.
  • The only item not verified on a real machine is #4; its input shape comes from a real QA report and is frozen as a
    corpus, and its execution path is covered by the loop-level gate (orchestration.test.js [10b]).