dsh-plugin-teamflow 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ > 本插件首次公开发布版本为 **v0.1.0**;发布前的内部迭代(v0.3~v0.13)记录于 `AGENTS.md` §5,对外统一归到 v0.1.0。
4
+
5
+ ## [0.1.2] - 2026-08-26
6
+
7
+ ### 变更
8
+ - 提示词指令层英文化(方案 A):指令英文 + 输出契约中文(PRD 头部声明 / QA 缺陷表 / 验收结论等解析器锚点不变);工具描述英文化
9
+ - backlog 卡片 / 详情抽屉跳转指定 run 的流水线视图(host `backlog` 附带 `runId` 映射)
10
+ - 详情抽屉长文本折叠(概览 / 需求原文默认预览几行,可展开收起)
11
+ - 断点重跑语义修正:阶段全 done 的 failed/cancelled 不再显示续跑按钮(host 硬拒绝兜底);按钮/pill/chip 补 runId 全名可溯
12
+ - 架构蓝图提取回退任务夹 `TECHNICAL.md`(模型把蓝图写进文档而非回复输出时 M2 拆卡不再退化为整体开发)
13
+ - `meta.json` 改为静态标识卡(废弃终态回写,status/endedAt 权威在 journal)
14
+ - 开源发布元数据:keywords / homepage / bugs;`react` 移入 peerDependencies;README.en.md 与 CHANGELOG.md 显式进包
15
+
16
+ ## [0.1.1] - 2026-08-26
17
+
18
+ ### 修复
19
+ - npm 发布包 `files` 白名单收窄为 `lib` / `cordis.patch.yml` / `README.md`,不再携带 `AGENTS.md` 与 `docs/adr`(开发者文档仅保留在 GitHub 仓库)
20
+
21
+ ## [0.1.0] - 2026-08-26
22
+
23
+ ### 初始公开发布
24
+ - 一句话需求 → 多 Agent 研发流水线(PRD / 设计 / 架构 / 技术方案 / 并行开发 / QA / 验收)
25
+ - backlog 持久化 + 断点续跑(自研 journal,不依赖 LangGraph)
26
+ - 防假交付:实质校验 + token 熔断 + 产品级并发锁 + 内存裁剪
27
+ - 完成汇总自动汇报主线程(空闲唤醒 / 忙碌注入)
28
+ - token 官方口径计量(输入未命中 / 命中 / 写缓存 / 输出 + 调用数 + 缓存命中率)
29
+ - lite / tech / patch 模式 + 模型驱动需求分诊(`teamflow_triage`)
30
+ - 🏭 团队工作台 Web tab:阶段泳道 / 拖拽看板 / 成本中心 / 人工介入中心
31
+ - QA 打回修复有界闭环(ADR-0007,超限转 needs-human)
32
+ - 任务夹文档制(ADR-0008):每需求自包含任务夹,消除双归档 / memory 堆积
package/README.en.md ADDED
@@ -0,0 +1,162 @@
1
+ # dsh-plugin-teamflow
2
+
3
+ [![npm version](https://img.shields.io/npm/v/dsh-plugin-teamflow)](https://www.npmjs.com/package/dsh-plugin-teamflow) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
4
+
5
+ [中文](./README.md) | English
6
+
7
+ TeamFlow team R&D pipeline — a distributable DeepSeek Harness plugin (install via `dsh plugin --profile web add`).
8
+
9
+ Turns "one-line user requirement → real R&D team multi-agent pipeline" into a host-level capability:
10
+
11
+ ```
12
+ requirement → PRD (based on existing patterns / product memory, archived to prevent bloat)
13
+ → (UI redesign) UI/UX design
14
+ → (new project) architect plans and scaffolds + AGENTS.md
15
+ → senior full-stack engineer tech spec (aligned with dispatched tasks)
16
+ → parallel dev when tasks are splittable
17
+ → QA functional testing (structured defects → register bugs)
18
+ → product acceptance (update product memory)
19
+ ```
20
+
21
+ ## Core Features
22
+
23
+ - **Anti-fake-delivery**: ① Substantive validation — outputs containing rejection phrases ("I cannot complete", etc.) or below the per-stage length floor are treated as undelivered and routed to retry / human intervention; ② Token circuit breaker — a single stage accumulating 60k budget stops retries; ③ Context-exhaustion failures are not retried (retrying the same prompt likely reproduces); ④ Product-level concurrency lock — only one active pipeline per product at a time, preventing requirement state from stepping on itself; ⑤ Full stage outputs are retained (memory + disk) for the detail drawer and checkpoint resume.
24
+ - **Auto completion report to main thread**: when a pipeline ends (success / failure / cancel / interrupt), it automatically delivers a summary (status / stage stats / total token / backlog / next-step guidance) to the initiating session's Agent — wakes on idle (followup), injects next-step context when busy (inject), using the same mechanism as DSH's background-task notifications (tool-jobs mode, but independently implemented and not dependent on the web-disabled tool-jobs). The user need not watch the panel; the model relays the result or continues per guidance (claim defects / transition / resume from checkpoint).
25
+ - **Resume from checkpoint**: every stage checkpoint persists to `$DSH_HOME/teamflow/runs/<runId>.json` (LangGraph checkpointer semantics); after a process crash / restart it is auto-marked `interrupted`, and `teamflow_resume` / the panel's "↻ resume from checkpoint" continues from the first unfinished stage (skipping completed stages, reusing full stage outputs).
26
+ - **Backlog persistence (workspace-isolated since v0.1.0)** under `$DSH_HOME/teamflow/<workspace>/backlog/` as `requirements.json` / `tasks.json` / `bugs.json`, surviving restarts; backlog is isolated per "workspace (project)" — one workspace is one product line, and different workspaces each see their own Team Workspace.
27
+ - **Single-task model **: one requirement = one rotating task card (no longer split by role); the task card records `devAssign` / `qaAssign` / acceptor, with state rotation: todo → developing → to-test → testing → to-accept → accepted | bounced | needs-human; the delivered frontend page also shows each role's **real token usage** spent on that task.
28
+ - **Artifact consolidation **: pipeline docs (PRD / design / architecture / tech spec / QA / memory / history) all consolidate into `docs/teamflow/`, command run logs into `logs/teamflow/<runId>/`, so the host `docs/<role>/` and project root are no longer polluted by TeamFlow; the host-side run log likewise lands in `<workspace>/logs/teamflow/<runId>.log`.
29
+ - **State machine + event log**: requirement (initiated → in-progress → to-accept → accepted), task (todo → developing → to-test → testing → to-accept → done | bounced | needs-human), defect (to-claim → in-progress → fixed-to-verify → closed).
30
+ - **Bounce-back threshold**: 2 consecutive Agent failures in a single stage auto-retry; still failing → `needs-human`, requiring human intervention.
31
+ - **Concurrency pool**: dev tasks run in parallel by `maxConcurrency` (default 3, max 8).
32
+ - **QA defect registration**: the QA report outputs in a fixed table → auto-parsed into bugs entering the backlog.
33
+ - **Token metering (official semantics)**: each stage records `usage` = **cache-miss input / cache-hit input / write-cache / output + call count** (accumulated per event by the sub-agent session) + **cache hit rate** (cacheRead / (input + cacheRead)). Workspace cards / task cards / completion reports all display in this basis — model-agnostic and consistent with the official bill.
34
+ - **lite mode **: lightweight micro-features — `teamflow_start(lite:true)` skips the standalone tech-spec doc stage (PRD is the contract) and goes straight **PRD → dev → QA → acceptance**; with `needDesign:true` it **keeps the UI/UX design stage**. Measured ~64% time / ~88% token savings vs the full 7-stage run.
35
+ - **Token circuit breaker**: when a stage's official total consumption (input + cacheRead + cacheWrite + output accumulated) exceeds `STAGE_TOKEN_BUDGET` (default 60k), retries stop and human intervention is required.
36
+ - **🏭 Team Workspace (Web tab)**: a session-header tab alongside chat / trace, containing:
37
+ - Pipeline graph (stage swimlanes + node cards: status / duration / token / sub-agent session, 2s live refresh)
38
+ - **Backlog drag-drop kanban** (requirement / task / defect three status swimlanes, cards dragged to transition, native HTML5 DnD zero-dep)
39
+ - Cost center (per-stage token + total + runtime)
40
+ - Human-intervention center (needs-human items aggregated + one-click terminal state)
41
+ - History run switching + product switching
42
+
43
+ ## AGENTS.md minimal-invasion principle (important)
44
+
45
+ AGENTS.md is unconditionally injected into every session by the harness; it is **team assets**. TeamFlow follows separation of concerns:
46
+
47
+ - **AGENTS.md holds only the stable consensus layer**: team role flows, engineering conventions, doc index, and the `<!-- teamflow:begin/end -->` managed region (pointers only).
48
+ - **Product memory / todos go in a separate live doc** `docs/teamflow/memory.md` (read on demand, not injected every session → saves token).
49
+ - **Onboarding existing projects**: if AGENTS.md already exists → never rewrite / reorder / overwrite; only append a managed block at the end (if none); the team's original conventions are left untouched line by line.
50
+ - **Clean exit**: after a team stops using TeamFlow, deleting the managed block and `docs/teamflow/` fully restores it, with no ledger left in AGENTS.md.
51
+
52
+ ## Architecture (stage 3)
53
+
54
+ ```
55
+ web profile host composition
56
+ ├── teamflow-host (dsh-plugin-teamflow/host) Cordis service `teamflow`
57
+ │ └── TeamflowService extends TypertRemoteService
58
+ │ ├── ctx.typert.register(strict descriptors) ← 17 Remote methods
59
+ │ ├── ctx.tools.register(teamflow_*) ← 11 model tools
60
+ │ └── node:fs → $DSH_HOME/teamflow/...
61
+ └── teamflow-client (dsh-plugin-teamflow/client, auto-scanned) ← package.json declares dsh.client,
62
+ └── ctx.remote.$mount(TEAMFLOW_REMOTE_CONTRIBUTION) no patch line needed, clientModules auto-registers
63
+ └── conversation.view tab "🏭 Team Workspace"
64
+ ```
65
+
66
+ **Why not the @Remote decorator**: host plugins are distributed as plain JS to avoid decorator syntax / TS compilation requirements; `ctx.typert.register` registers strict descriptors (`descriptors.js` pure data, shared by host/client, keeping endpoint and wire parameters consistent).
67
+
68
+ **Why a host-level plugin (not a dynamic plugin)**: dynamic (in-session) plugins run in a restricted sandbox whose `fs` is hard-limited to the runtime root and cannot write to `$DSH_HOME` or the session workspace (observed `file access denied under workspace-write mode`). Only a formal plugin inside the host composition has real Node `fs`, able to land backlog in `$DSH_HOME`, and the client can register an independent tab.
69
+
70
+ ## Directory structure
71
+
72
+ ```
73
+ dsh-plugin-teamflow/
74
+ package.json # dsh.bundle.patch + dsh.client declarations; exports point to lib/ build output
75
+ cordis.patch.yml # insert block; entry name uses package root (so clientModules can scan dsh.client)
76
+ tsdown.config.ts # client build (ModuleLoader bundle → lib/client.js)
77
+ tsdown.host.config.ts # host/store/descriptors build (ESM → lib/*.mjs)
78
+ descriptors.ts # Remote descriptors (pure data, shared by host/client)
79
+ store.ts # persistence layer: atomic write / backup / corruption self-heal + journal serialize / load (independently testable)
80
+ host/index.ts # TeamflowService (TS; built to lib/host.mjs for the host to load)
81
+ client/index.tsx # Team Workspace (TSX; built to lib/client.js)
82
+ test/smoke.js # dependency-free smoke test (descriptors / structure / security hardening)
83
+ test/journal.test.js # journal behavior test (runs store.ts source directly)
84
+ ```
85
+
86
+ **TypeScript note**: the whole repo is TS/TSX. The host **must be built** (cannot rely on Node strip-types to run directly) — Node 22's type stripping does not apply to files under `node_modules` ("unsupported for files under node_modules"), while the host composition loads plugins from `profile/node_modules`. Consistent with the DSH ecosystem (the `@deepseek-ai/dsh-*` host packages' exports all point to lib/*.js). After changing source, run `pnpm bundle` to rebuild and sync the profile copy's `lib/`.
87
+
88
+ ## Requirements
89
+
90
+ - DeepSeek Harness (dsh) host, **web profile** (the plugin ships a browser-side workspace; the client targets the web platform);
91
+ - Node.js ≥ 22.18;
92
+ - Relies on host-provided `@deepseek-ai/dsh-*` and `react` (peerDependencies, injected by the host — no separate install needed).
93
+
94
+ ## Install (for users)
95
+
96
+ ```bash
97
+ # Install from npm (after publish)
98
+ dsh plugin --profile web add dsh-plugin-teamflow
99
+
100
+ # Or local directory install (during development)
101
+ dsh plugin --profile web add file:./plugins/dsh-plugin-teamflow
102
+ ```
103
+
104
+ After install, **restart** `dsh --profile web` for the host `teamflow-host` to take effect:
105
+ - The model side gains 11 `teamflow_*` tools: `start / triage / status / backlog / claim / update / assign / cancel / resume / pause / resume_session`;
106
+ - The browser session header shows the "🏭 Team Workspace" tab;
107
+ - Backlog is written to `$DSH_HOME/teamflow/<product>/backlog/*.json`.
108
+
109
+ > Note: `@deepseek-ai/*` are host-private packages; running requires the DeepSeek Harness (dsh) host environment; this package is neither published standalone nor runnable alone.
110
+
111
+ ## Quick start
112
+
113
+ 1. **Pick a team**: click the 🏭 button next to the input box and choose a team (or "no team" = chat directly, no pipeline);
114
+ 2. **Say the requirement**: just describe it — the model calls `teamflow_start` automatically (auto-triage: patch / lite / tech / medium / full); or force a mode, e.g. "run this in medium mode";
115
+ 3. **Watch progress**: switch to the 🏭 Team Workspace tab in the session header — the pipeline graph live-refreshes (per-stage token / duration / sub-agent session), and the backlog kanban supports drag transitions and card detail drawers;
116
+ 4. **Get the result**: the pipeline reports back to the session automatically when done (status / stage stats / token / next steps); interrupted/failed runs can "↻ resume from checkpoint".
117
+
118
+ > Note: after `teamflow_start`, the **main thread should not modify code or run verifications itself** — implementation, QA, and reporting are done by pipeline sub-agents (avoid fighting the pipeline over the workspace).
119
+
120
+ ## Uninstall (for users)
121
+
122
+ ```bash
123
+ dsh plugin --profile web remove dsh-plugin-teamflow
124
+ ```
125
+
126
+ After restarting `dsh --profile web`, the plugin is fully removed (the model-side `teamflow_*` tools and the 🏭 Team Workspace tab disappear).
127
+
128
+ Optional cleanup (NOT done automatically; run as needed):
129
+ - **Runtime data**: delete `$DSH_HOME/teamflow/` (backlog / run records — confirm you no longer need them first).
130
+ - **Project traces**: if a team used TeamFlow in a project, delete the `<!-- teamflow:begin/end -->` managed block in that project's `AGENTS.md` and the `docs/teamflow/` directory to fully restore it (the "clean exit" rule of the AGENTS.md minimal-invasion principle).
131
+
132
+ ## Development & verification
133
+
134
+ ```bash
135
+ npm test # smoke (descriptors / structure / security) + journal (resume behavior)
136
+ npm run typecheck # tsc --noEmit type check (same as VSCode, no drift)
137
+ node --check lib/host.mjs lib/client.js lib/store.mjs lib/descriptors.mjs
138
+ npm run bundle # build client (tsdown → lib/client.js, __ModuleLoader__.load registers)
139
+ ```
140
+
141
+ **For plugin developers** (the local dev loop of THIS plugin): see [`AGENTS.md`](./AGENTS.md) and [`docs/adr/`](./docs/adr) in the repo — deployment sync (`node deploy.mjs` → restart `dsh --profile web`), the "running web loads the host from the profile deployment copy, building source alone does not take effect" caveat, design decision records (ADR-0001~0008) and benchmarks (`docs/benchmarks/`). All repo source is TS/TSX and must be built first (`pnpm bundle`) to run (`strip-types` does not apply under `node_modules`).
142
+
143
+ Note: `lib/` is excluded by `.gitignore` but must ship with the package (`files` whitelist includes `lib/`; `exports["./client"]` points to `./lib/client.js`).
144
+
145
+ ## Contract quick reference
146
+
147
+ | Tool / Remote | Purpose |
148
+ |---|---|
149
+ | `teamflow_start` / `teamflow.start(sessionId, requirement, options)` | Start the pipeline |
150
+ | `teamflow_status` / `teamflow.list()` + `teamflow.snapshot(runId)` | Query run progress (stage / status / token / log / needs-human?) |
151
+ | `teamflow_backlog` / `teamflow.backlog(product)` | View backlog (+ persistence path) |
152
+ | `teamflow_claim` | Claim a task or defect |
153
+ | `teamflow_update` / `teamflow.backlogUpdate(kind, id, to, product, reason)` | Manually transition state (handle needs-human) |
154
+ | `teamflow_cancel` / `teamflow.cancel(runId)` | Cancel a run |
155
+ | `teamflow_resume` / `teamflow.resume(runId, sessionId)` | Resume from checkpoint (rerun from first unfinished stage) |
156
+ | `teamflow_triage` | Requirement triage preview (start auto-triages by default; use only to pre-assess / force a mode) |
157
+ | `teamflow_assign` | Assign owner of a task / defect (separate from claim: claim only changes state) |
158
+ | `teamflow_pause` / `teamflow_resume_session` | Pause / resume teamflow triggering for the current session (session-level, auto-reset on new session) |
159
+
160
+ ## License
161
+
162
+ MIT — see [LICENSE](./LICENSE).
package/README.md CHANGED
@@ -1,169 +1,168 @@
1
- # dsh-plugin-teamflow
2
-
3
- TeamFlow 团队研发流水线 —— DeepSeek Harness 可分发插件(`dsh plugin --profile web add` 安装)。
4
-
5
- 把「用户一句话需求 真实研发团队多 Agent 流水线」做成宿主级能力:
6
-
7
- ```
8
- 需求 → PRD(基于既有模式/产品记忆,文档归档防臃肿)
9
- (UI 改造时)UI/UX 设计
10
- → (新项目时)架构师规划并落地脚手架 + AGENTS.md
11
- → 高级全栈工程师技术方案(与派发任务对齐)
12
- 可拆分任务时按并发并行开发
13
- QA 功能测试(结构化缺陷 → 登记 Bug)
14
- 产品验收(更新产品记忆)
15
- ```
16
-
17
- ## 核心特性
18
-
19
- - **防假交付(v0.1.0)**:① 实质校验——拒绝措辞("我无法完成"等)或低于阶段长度下限的输出视为未交付,走重试/需人工;② token 熔断——单阶段累计 60k 预算,超限停止重试;③ 上下文耗尽类失败不重试(重试同一 prompt 大概率复现);④ 产品级并发锁——同一产品同时只允许一条活跃流水线,防需求状态互踩;⑤ 内存裁剪——timeline 摘要化 + 阶段产物内存删除(磁盘保留,resume 时从磁盘加载全文)。
20
- - **完成汇总自动汇报主线程(v0.1.0)**:流水线结束(成功/失败/取消/中断)后自动把汇总(状态/阶段统计/token 总计/backlog/后续操作指引)投递给发起会话的 Agent——空闲时唤醒(followup),忙碌时注入下一步上下文(inject),与 DSH 后台任务通知同款机制(tool-jobs 模式,但独立实现,不依赖 web 面被禁用的 tool-jobs)。用户无需盯面板,模型会转述结果或按指引继续(认领缺陷/流转/断点重跑)。
21
- - **断点续跑(v0.1.0)**:每阶段 checkpoint 落盘 `$DSH_HOME/teamflow/runs/<runId>.json`(LangGraph checkpointer 语义);进程崩溃/重启后自动标记 `interrupted`,可用 `teamflow_resume` / 面板「↻ 从断点重跑」从第一个未完成阶段继续(跳过已完成阶段,复用阶段产物全文)。
22
- - **backlog 持久化(v0.1.0 起按工作区隔离)到 `$DSH_HOME/teamflow/<workspace>/backlog/`**
23
- `requirements.json` / `tasks.json` / `bugs.json`,跨重启不丢;backlog 按「工作区(项目)」隔离——一个工作区就是一条项目线,不同工作区各看各的团队工作台。
24
- - **单任务模型(v0.1.0)**:一个需求 = 一张轮转任务卡(不再按角色拆任务),任务卡记录 `devAssign` / `qaAssign` / 验收人,状态轮转:待办→开发中→待测试→测试中→待验收→已验收|打回|需人工;交付前端页面同时展示每个角色花在该任务上的**真实 token usage**。
25
- - **产物收口(v0.1.0)**:流水线文档(PRD/设计/架构/技术方案/QA/记忆/历史)全部收口到 `docs/teamflow/`,命令运行日志收口到 `logs/teamflow/<runId>/`,宿主 `docs/<职责>/` 与项目根不再被 TeamFlow 污染;host run 日志同样落 `<工作区>/logs/teamflow/<runId>.log`。
26
- - **状态机 + 事件日志**:需求(立项→进行中→待验收→已验收)、任务(待办→开发中→待测试→测试中→待验收→完成|打回|需人工)、缺陷(待认领→处理中→已修复待验→已关闭)。
27
- - **打回阈值**:单阶段连续 2 Agent 失败自动重试,仍失败 → `needs-human`,需人工介入。
28
- - **并发池**:开发任务按 `maxConcurrency`(默认 3,最大 8)并行执行。
29
- - **QA 缺陷登记**:QA 报告按固定表格输出 自动解析成 Bug 进入 backlog。
30
- - **token 计量(官方口径)**:每阶段记录 `usage` = **输入(缓存未命中)/输入(缓存命中)/写缓存/输出 + 调用数**(由子代理会话逐事件累计)+ **缓存命中率**(cacheRead/(input+cacheRead))。工作台卡片/任务卡/完成汇报均按此口径展示,模型无关、与官方账单一致。
31
- - **lite 模式(v0.1.0)**:微功能轻量——`teamflow_start(lite:true)` 跳过独立技术方案文档阶段(PRD 即契约),直接 **PRD开发 → QA → 验收**;配套 `needDesign:true` 时**保留 UI/UX 设计阶段**。实测较完整 7 段省 ~64% 时间、~88% token。
32
- - **token 熔断**:单阶段官方总消耗(input+cacheRead+cacheWrite+output 累计)超 `STAGE_TOKEN_BUDGET`(默认 60k)时停止重试、需人工介入。
33
- - **🏭 团队工作台(Web tab)**:与 chat / 轨迹并列的会话头部 tab,含:
34
- - 流水线图形工作流(阶段泳道 + 节点卡片:状态/耗时/token/子代理会话,2s 实时刷新)
35
- - **Backlog 拖拽看板**(需求/任务/缺陷三组状态泳道,卡片拖拽流转,原生 HTML5 DnD 零依赖)
36
- - 成本中心(每阶段 token + 总计 + 运行时长)
37
- - 人工介入中心(needs-human 项聚合 + 一键终态)
38
- - 历史 run 切换 + 产品切换
39
-
40
- ## AGENTS.md 最小侵入原则(重要)
41
-
42
- AGENTS.md 会被 harness 无条件注入每个会话,是**团队资产**。TeamFlow 遵循职责分离:
43
-
44
- - **AGENTS.md 只放稳定共识层**:团队角色流程、工程约定、文档索引、`<!-- teamflow:begin/end -->` 托管区(仅指针)。
45
- - **产品记忆/待办放独立活文档** `docs/teamflow/memory.md`(按需读取,不注入每次会话 → 省 token)。
46
- - **已有项目接入**:检测到 AGENTS.md 已存在 绝不重写/重排/覆盖,仅在文末追加托管块(若没有);团队原有约定一行不动。
47
- - **退出干净**:团队停用 TeamFlow 后,删除托管块与 `docs/teamflow/` 即完全复原,AGENTS.md 无残留账本。
48
-
49
- ## 架构决策记录(ADR)
50
-
51
- 关键设计决策独立存档于 `docs/adr/`,README 只留索引:
52
-
53
- - [ADR-0001 断点续跑自研 journal,不引入 LangGraph](docs/adr/0001-self-hosted-journal-vs-langgraph.md)
54
- - [ADR-0002 AGENTS.md 最小侵入(共识层/运营数据分离)](docs/adr/0002-agents-md-minimal-invasion.md)
55
- - [ADR-0003 部署生效契约 + token 计量口径(真实累计/当量/观测线)](docs/adr/0003-release-deploy-and-token-metering.md)
56
- - [ADR-0004 需求分诊路由 + 共享状态分层(full/lite/tech + context bundle)](docs/adr/0004-triage-and-shared-state.md)
57
-
58
- 新增决策时:`docs/adr/NNNN-<kebab-name>.md`(背景/决策/理由/影响/触发信号),并在本索引追加一行。
59
-
60
- ## 架构(阶段 3)
61
-
62
- ```
63
- web profile 宿主组合
64
- ├── teamflow-host (dsh-plugin-teamflow/host) Cordis service `teamflow`
65
- │ └── TeamflowService extends TypertRemoteService
66
- │ ├── ctx.typert.register(strict descriptors) ← 7 个 Remote 方法
67
- │ ├── ctx.tools.register(teamflow_*) ← 6 个模型工具
68
- │ └── node:fs $DSH_HOME/teamflow/...
69
- └── teamflow-client (dsh-plugin-teamflow/client,自动扫描) ← package.json 声明 dsh.client,
70
- └── ctx.remote.$mount(TEAMFLOW_REMOTE_CONTRIBUTION) 无需 patch 行,clientModules 自动注册
71
- └── conversation.view tab「🏭 团队工作台」
72
- ```
73
-
74
- **为什么不用 @Remote 装饰器**:宿主插件以纯 JS 分发,避免装饰器语法/TS 编译要求;
75
- 用 `ctx.typert.register` 注册 strict 描述符(`descriptors.js` 纯数据,host/client 共用一份,
76
- 保证 endpoint 与 wire 参数一致)。
77
-
78
- **为什么是宿主级插件(而不是动态插件)**:动态(会话内)插件宿主运行在受限沙箱,
79
- 其 `fs` 被硬限制在运行时根,无法写入 `$DSH_HOME` 或会话工作区(实测
80
- `file access denied under workspace-write mode`)。只有宿主组合里的正式插件拥有真实
81
- Node `fs`,能把 backlog 落到 `$DSH_HOME`,且 client 能注册独立 tab。
82
-
83
- ## 目录结构
84
-
85
- ```
86
- dsh-plugin-teamflow/
87
- package.json # dsh.bundle.patch + dsh.client 声明;exports 指向 lib/ 构建产物
88
- cordis.patch.yml # insert 块;entry 名用包根(clientModules 才能扫到 dsh.client)
89
- tsdown.config.ts # client 构建(ModuleLoader bundle → lib/client.js)
90
- tsdown.host.config.ts # host/store/descriptors 构建(ESM → lib/*.mjs)
91
- descriptors.ts # Remote 描述符(纯数据,host/client 共用)
92
- store.ts # 持久化层:原子写/备份/损坏自愈 + journal 序列化/加载(可独立测试)
93
- host/index.ts # TeamflowService(TS;构建为 lib/host.mjs 供宿主加载)
94
- client/index.tsx # 团队工作台(TSX;构建为 lib/client.js)
95
- docs/adr/ # 架构决策记录(ADR-0001/0002…)
96
- test/smoke.js # 无依赖 smoke 测试(描述符/模块结构/安全加固)
97
- test/journal.test.js # journal 行为测试(直跑 store.ts 源码)
98
- ```
99
-
100
- **TypeScript 说明**:全仓 TS/TSX。host 之所以**必须构建**(不能靠 Node strip-types 直跑)——Node 22 的 type stripping 对 `node_modules` 下的文件不生效("unsupported for files under node_modules"),而宿主组合从 profile/node_modules 加载插件。与 DSH 生态一致(`@deepseek-ai/dsh-*` 宿主包 exports 均指向 lib/*.js)。改动源码后需 `pnpm bundle` 重建并同步 profile 副本的 `lib/`。
101
-
102
- ## 安装(对使用者)
103
-
104
- ```bash
105
- # 从 npm 安装(发布后)
106
- dsh plugin --profile web add dsh-plugin-teamflow
107
-
108
- # 或本地目录安装(开发时)
109
- dsh plugin --profile web add file:./plugins/dsh-plugin-teamflow
110
- ```
111
-
112
- 安装后**重启** `dsh --profile web`,宿主行 `teamflow-host` 生效:
113
- - 模型侧出现 11 个 `teamflow_*` 工具:`start / triage / status / backlog / claim / update / assign / cancel / resume / pause / resume_session`;
114
- - 浏览器侧会话头部出现「🏭 团队工作台」tab;
115
- - backlog 写入 `$DSH_HOME/teamflow/<product>/backlog/*.json`。
116
-
117
- ## 开发与验证
118
-
119
- ```bash
120
- npm test # smoke(描述符/结构/安全)+ journal(断点续跑行为)
121
- npm run typecheck # tsc --noEmit 类型检查(VSCode 同源,不飘红)
122
- node --check lib/host.mjs lib/client.js lib/store.mjs lib/descriptors.mjs
123
- npm run bundle # 构建 client(tsdown → lib/client.js,__ModuleLoader__.load 注册)
124
- ```
125
-
126
- **类型解析说明**:`@deepseek-ai/dsh-*` 是宿主私有包(不在公共 registry,运行时由 dsh profile
127
- 注入),类型取自本机已安装的宿主副本 `~/.dsh/profiles/node_modules/@deepseek-ai/*`——
128
- `tsconfig.json` 的 `paths` 已映射(跨机器时把路径中的用户名改成自己的即可)。
129
- 构建(tsdown)不依赖此映射:host 构建对 `@deepseek-ai/*` 保持 external,client 不引用宿主包。
130
-
131
- 改完代码的生效链路(推荐):`node deploy.mjs`(构建 + 测试 + 同步 profile 副本 + 检测运行中 web 并提示重启)→ 重启 `dsh --profile web`。
132
- 改完代码的生效链路(备用):`npm run bundle` profile 副本更新(`pnpm update dsh-plugin-teamflow`,在 `~/.dsh/profiles/web/` 下,若 Already up to date 先删 `node_modules/dsh-plugin-teamflow` update)→ 重启 `dsh --profile web`。
133
-
134
- **⚠ 生效前提(易踩坑,详见 ADR-0003)**:运行中的 web **从 profile 部署副本**(`~/.dsh/profiles/web/node_modules/dsh-plugin-teamflow/lib/`)加载 host,不是源码 `plugins/.../lib/`。只构建源码不在 profile 生效;必须 deploy 同步 + 重启进程,否则跑旧逻辑(如 lite 参数被静默忽略)。
135
-
136
- 注意:`lib/` `.gitignore` 排除,但 `.npmignore` 不排除——`file:` 安装与 npm 发布
137
- 都必须带上构建产物(`exports["./client"]` 指向 `./lib/client.js`)。
138
-
139
- ## 发布
140
-
141
- ```bash
142
- # 1) 升版本号(package.json version,遵循 semver)
143
- # 2) 构建产物(lib/ 已被 .gitignore 排除,但靠 package.json 的 files 白名单随包发布)
144
- pnpm bundle # npx tsdown && npx tsdown -c tsdown.host.config.ts
145
- # 3) 跑测试 + 发布(prepublishOnly 会自动 build + test,可跳过手动 build)
146
- npm login
147
- npm publish # 仅发布 files 白名单内的 lib / cordis.patch.yml / README.md / AGENTS.md / docs/adr
148
- ```
149
-
150
- > 注意:`@deepseek-ai/*` 为宿主私有包,运行需 DeepSeek Harness(dsh)宿主环境;本包不发布也无法独立运行。
151
-
152
- ## 契约速览
153
-
154
- | 工具 / Remote | 作用 |
155
- |---|---|
156
- | `teamflow_start` / `teamflow.start(sessionId, requirement, options)` | 启动流水线 |
157
- | `teamflow_status` / `teamflow.list()` + `teamflow.snapshot(runId)` | 查询运行进度(阶段/状态/token/日志/是否需人工) |
158
- | `teamflow_backlog` / `teamflow.backlog(product)` | 查看 backlog(+ persistence 落盘路径) |
159
- | `teamflow_claim` | 认领任务或缺陷 |
160
- | `teamflow_update` / `teamflow.backlogUpdate(kind, id, to, product, reason)` | 人工流转状态(处理 needs-human) |
161
- | `teamflow_cancel` / `teamflow.cancel(runId)` | 取消运行 |
162
- | `teamflow_resume` / `teamflow.resume(runId, sessionId)` | 断点续跑(从第一个未完成阶段重跑) |
163
- | `teamflow_triage` | 需求分诊预览(默认 start 自动分诊,仅在想预评估/强制 mode 时使用) |
164
- | `teamflow_assign` | 指定任务/缺陷的负责人(与 claim 分离:claim 只改状态) |
165
- | `teamflow_pause` / `teamflow_resume_session` | 当前会话暂停/恢复 teamflow 触发(会话级,新会话自动重置) |
166
-
167
- ## License
168
-
169
- MIT —— 详见 [LICENSE](./LICENSE)。
1
+ # dsh-plugin-teamflow
2
+
3
+ [![npm version](https://img.shields.io/npm/v/dsh-plugin-teamflow)](https://www.npmjs.com/package/dsh-plugin-teamflow) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
4
+
5
+ 中文 | [English](./README.en.md)
6
+
7
+ TeamFlow 团队研发流水线 —— DeepSeek Harness 可分发插件(`dsh plugin --profile web add` 安装)。
8
+
9
+ 把「用户一句话需求 真实研发团队多 Agent 流水线」做成宿主级能力:
10
+
11
+ ```
12
+ 需求 PRD(基于既有模式/产品记忆,文档归档防臃肿)
13
+ (UI 改造时)UI/UX 设计
14
+ (新项目时)架构师规划并落地脚手架 + AGENTS.md
15
+ → 高级全栈工程师技术方案(与派发任务对齐)
16
+ → 可拆分任务时按并发并行开发
17
+ QA 功能测试(结构化缺陷 → 登记 Bug)
18
+ → 产品验收(更新产品记忆)
19
+ ```
20
+
21
+ ## 核心特性
22
+
23
+ - **防假交付**:① 实质校验——拒绝措辞("我无法完成"等)或低于阶段长度下限的输出视为未交付,走重试/需人工;② token 熔断——单阶段累计 60k 预算,超限停止重试;③ 上下文耗尽类失败不重试(重试同一 prompt 大概率复现);④ 产品级并发锁——同一产品同时只允许一条活跃流水线,防需求状态互踩;⑤ 阶段产物全文保留(内存 + 磁盘,供详情抽屉与断点续跑读取)。
24
+ - **完成汇总自动汇报主线程**:流水线结束(成功/失败/取消/中断)后自动把汇总(状态/阶段统计/token 总计/backlog/后续操作指引)投递给发起会话的 Agent——空闲时唤醒(followup),忙碌时注入下一步上下文(inject),与 DSH 后台任务通知同款机制(tool-jobs 模式,但独立实现,不依赖 web 面被禁用的 tool-jobs)。用户无需盯面板,模型会转述结果或按指引继续(认领缺陷/流转/断点重跑)。
25
+ - **断点续跑**:每阶段 checkpoint 落盘 `$DSH_HOME/teamflow/runs/<runId>.json`(LangGraph checkpointer 语义);进程崩溃/重启后自动标记 `interrupted`,可用 `teamflow_resume` / 面板「↻ 从断点重跑」从第一个未完成阶段继续(跳过已完成阶段,复用阶段产物全文)。
26
+ - **backlog 持久化(v0.1.0 起按工作区隔离)到 `$DSH_HOME/teamflow/<workspace>/backlog/`**
27
+ `requirements.json` / `tasks.json` / `bugs.json`,跨重启不丢;backlog 按「工作区(项目)」隔离——一个工作区就是一条项目线,不同工作区各看各的团队工作台。
28
+ - **单任务模型**:一个需求 = 一张轮转任务卡(不再按角色拆任务),任务卡记录 `devAssign` / `qaAssign` / 验收人,状态轮转:待办→开发中→待测试→测试中→待验收→已验收|打回|需人工;交付前端页面同时展示每个角色花在该任务上的**真实 token usage**。
29
+ - **产物收口**:流水线文档(PRD/设计/架构/技术方案/QA/记忆/历史)全部收口到 `docs/teamflow/`,命令运行日志收口到 `logs/teamflow/<runId>/`,宿主 `docs/<职责>/` 与项目根不再被 TeamFlow 污染;host 端 run 日志同样落 `<工作区>/logs/teamflow/<runId>.log`。
30
+ - **状态机 + 事件日志**:需求(立项→进行中→待验收→已验收)、任务(待办→开发中→待测试→测试中→待验收→完成|打回|需人工)、缺陷(待认领→处理中→已修复待验→已关闭)。
31
+ - **打回阈值**:单阶段连续 2 Agent 失败自动重试,仍失败 → `needs-human`,需人工介入。
32
+ - **并发池**:开发任务按 `maxConcurrency`(默认 3,最大 8)并行执行。
33
+ - **QA 缺陷登记**:QA 报告按固定表格输出 自动解析成 Bug 进入 backlog。
34
+ - **token 计量(官方口径)**:每阶段记录 `usage` = **输入(缓存未命中)/输入(缓存命中)/写缓存/输出 + 调用数**(由子代理会话逐事件累计)+ **缓存命中率**(cacheRead/(input+cacheRead))。工作台卡片/任务卡/完成汇报均按此口径展示,模型无关、与官方账单一致。
35
+ - **lite 模式**:微功能轻量——`teamflow_start(lite:true)` 跳过独立技术方案文档阶段(PRD 即契约),直接 **PRD → 开发 → QA → 验收**;配套 `needDesign:true` 时**保留 UI/UX 设计阶段**。实测较完整 7 段省 ~64% 时间、~88% token。
36
+ - **token 熔断**:单阶段官方总消耗(input+cacheRead+cacheWrite+output 累计)超 `STAGE_TOKEN_BUDGET`(默认 60k)时停止重试、需人工介入。
37
+ - **🏭 团队工作台(Web tab)**:与 chat / 轨迹并列的会话头部 tab,含:
38
+ - 流水线图形工作流(阶段泳道 + 节点卡片:状态/耗时/token/子代理会话,2s 实时刷新)
39
+ - **Backlog 拖拽看板**(需求/任务/缺陷三组状态泳道,卡片拖拽流转,原生 HTML5 DnD 零依赖)
40
+ - 成本中心(每阶段 token + 总计 + 运行时长)
41
+ - 人工介入中心(needs-human 项聚合 + 一键终态)
42
+ - 历史 run 切换 + 产品切换
43
+
44
+ ## AGENTS.md 最小侵入原则(重要)
45
+
46
+ AGENTS.md 会被 harness 无条件注入每个会话,是**团队资产**。TeamFlow 遵循职责分离:
47
+
48
+ - **AGENTS.md 只放稳定共识层**:团队角色流程、工程约定、文档索引、`<!-- teamflow:begin/end -->` 托管区(仅指针)。
49
+ - **产品记忆/待办放独立活文档** `docs/teamflow/memory.md`(按需读取,不注入每次会话 → 省 token)。
50
+ - **已有项目接入**:检测到 AGENTS.md 已存在 → 绝不重写/重排/覆盖,仅在文末追加托管块(若没有);团队原有约定一行不动。
51
+ - **退出干净**:团队停用 TeamFlow 后,删除托管块与 `docs/teamflow/` 即完全复原,AGENTS.md 无残留账本。
52
+
53
+ ## 架构(阶段 3)
54
+
55
+ ```
56
+ web profile 宿主组合
57
+ ├── teamflow-host (dsh-plugin-teamflow/host) Cordis service `teamflow`
58
+ │ └── TeamflowService extends TypertRemoteService
59
+ │ ├── ctx.typert.register(strict descriptors) ← 17 个 Remote 方法
60
+ │ ├── ctx.tools.register(teamflow_*) ← 11 个模型工具
61
+ │ └── node:fs → $DSH_HOME/teamflow/...
62
+ └── teamflow-client (dsh-plugin-teamflow/client,自动扫描) ← package.json 声明 dsh.client,
63
+ └── ctx.remote.$mount(TEAMFLOW_REMOTE_CONTRIBUTION) 无需 patch 行,clientModules 自动注册
64
+ └── conversation.view tab「🏭 团队工作台」
65
+ ```
66
+
67
+ **为什么不用 @Remote 装饰器**:宿主插件以纯 JS 分发,避免装饰器语法/TS 编译要求;
68
+ `ctx.typert.register` 注册 strict 描述符(`descriptors.js` 纯数据,host/client 共用一份,
69
+ 保证 endpoint wire 参数一致)。
70
+
71
+ **为什么是宿主级插件(而不是动态插件)**:动态(会话内)插件宿主运行在受限沙箱,
72
+ 其 `fs` 被硬限制在运行时根,无法写入 `$DSH_HOME` 或会话工作区(实测
73
+ `file access denied under workspace-write mode`)。只有宿主组合里的正式插件拥有真实
74
+ Node `fs`,能把 backlog 落到 `$DSH_HOME`,且 client 能注册独立 tab。
75
+
76
+ ## 目录结构
77
+
78
+ ```
79
+ dsh-plugin-teamflow/
80
+ package.json # dsh.bundle.patch + dsh.client 声明;exports 指向 lib/ 构建产物
81
+ cordis.patch.yml # insert 块;entry 名用包根(clientModules 才能扫到 dsh.client
82
+ tsdown.config.ts # client 构建(ModuleLoader bundle → lib/client.js)
83
+ tsdown.host.config.ts # host/store/descriptors 构建(ESM → lib/*.mjs)
84
+ descriptors.ts # Remote 描述符(纯数据,host/client 共用)
85
+ store.ts # 持久化层:原子写/备份/损坏自愈 + journal 序列化/加载(可独立测试)
86
+ host/index.ts # TeamflowService(TS;构建为 lib/host.mjs 供宿主加载)
87
+ client/index.tsx # 团队工作台(TSX;构建为 lib/client.js)
88
+ test/smoke.js # 无依赖 smoke 测试(描述符/模块结构/安全加固)
89
+ test/journal.test.js # journal 行为测试(直跑 store.ts 源码)
90
+ ```
91
+
92
+ **TypeScript 说明**:全仓 TS/TSX。host 之所以**必须构建**(不能靠 Node strip-types 直跑)——Node 22 的 type stripping 对 `node_modules` 下的文件不生效("unsupported for files under node_modules"),而宿主组合从 profile/node_modules 加载插件。与 DSH 生态一致(`@deepseek-ai/dsh-*` 宿主包 exports 均指向 lib/*.js)。改动源码后需 `pnpm bundle` 重建并同步 profile 副本的 `lib/`。
93
+
94
+ ## 环境要求
95
+
96
+ - DeepSeek Harness(dsh)宿主,**web profile**(插件含浏览器端工作台,client 面向 web 平台);
97
+ - Node.js 22.18;
98
+ - 依赖宿主提供的 `@deepseek-ai/dsh-*` 与 `react`(peerDependencies,宿主注入,无需单独安装)。
99
+
100
+ ## 安装(对使用者)
101
+
102
+ ```bash
103
+ # 从 npm 安装(发布后)
104
+ dsh plugin --profile web add dsh-plugin-teamflow
105
+
106
+ # 或本地目录安装(开发时)
107
+ dsh plugin --profile web add file:./plugins/dsh-plugin-teamflow
108
+ ```
109
+
110
+ 安装后**重启** `dsh --profile web`,宿主行 `teamflow-host` 生效:
111
+ - 模型侧出现 11 个 `teamflow_*` 工具:`start / triage / status / backlog / claim / update / assign / cancel / resume / pause / resume_session`;
112
+ - 浏览器侧会话头部出现「🏭 团队工作台」tab;
113
+ - backlog 写入 `$DSH_HOME/teamflow/<product>/backlog/*.json`。
114
+
115
+ > 注意:`@deepseek-ai/*` 为宿主私有包,运行需 DeepSeek Harness(dsh)宿主环境;本包不发布也无法独立运行。
116
+
117
+ ## 快速上手
118
+
119
+ 1. **选团队**:会话输入框旁点「🏭」按钮,选择团队(或选「无团队」= 不走流水线,直接对话);
120
+ 2. **发需求**:直接说需求,模型会自动调用 `teamflow_start`(自动分诊模式:patch / lite / tech / medium / full)——也可以用「直接跑 medium 模式做这个」等指定档位;
121
+ 3. **看进展**:会话头部切到「🏭 团队工作台」tab——流水线图实时刷新(每阶段 token / 耗时 / 子代理会话),Backlog 看板可拖拽流转、点卡片看详情;
122
+ 4. **收结果**:流水线完成后自动向当前会话汇报(状态 / 阶段统计 / token / 后续指引);中断/失败的运行可「↻ 从断点重跑」。
123
+
124
+ > 使用规则提醒:`teamflow_start` 调用后**主线程不要自行改代码或跑验证**——实现、QA、汇报由流水线各阶段子代理完成(避免与流水线抢活)。
125
+
126
+ ## 卸载(对使用者)
127
+
128
+ ```bash
129
+ dsh plugin --profile web remove dsh-plugin-teamflow
130
+ ```
131
+
132
+ 重启 `dsh --profile web` 后插件完全移除(模型侧 `teamflow_*` 工具与「🏭 团队工作台」tab 消失)。
133
+
134
+ 可选清理(卸载**不会**自动清,按需执行):
135
+ - **运行数据**:删除 `$DSH_HOME/teamflow/`(backlog / 运行记录,删除前确认不再需要)。
136
+ - **项目痕迹**:若某项目用过 TeamFlow,删除该项目 `AGENTS.md` 中的 `<!-- teamflow:begin/end -->` 托管块与 `docs/teamflow/` 目录,即可完全复原(AGENTS.md 最小侵入原则的"退出干净")。
137
+
138
+ ## 开发与验证
139
+
140
+ ```bash
141
+ npm test # smoke(描述符/结构/安全)+ journal(断点续跑行为)
142
+ npm run typecheck # tsc --noEmit 类型检查(需本机 dsh profile 提供 @deepseek-ai/* 类型)
143
+ node --check lib/host.mjs lib/client.js lib/store.mjs lib/descriptors.mjs
144
+ npm run bundle # 构建 client(tsdown lib/client.js,__ModuleLoader__.load 注册)
145
+ ```
146
+
147
+ **插件开发者**(本插件的本地开发链路)见仓库内 [`AGENTS.md`](./AGENTS.md) [`docs/adr/`](./docs/adr)——含部署同步(`node deploy.mjs` 重启 `dsh --profile web`)、生效前提(运行中 web profile 部署副本加载 host,只构建源码不生效)、设计决策记录(ADR-0001~0008)与基准对比(`docs/benchmarks/`)。本仓库其余源码均为 TS/TSX,需先 `pnpm bundle` 构建后再运行(`node_modules` 下 strip-types 不生效)。
148
+
149
+ 注意:`lib/` 被 `.gitignore` 排除,但发布必须带上构建产物(`files` 白名单已含 `lib/`;`exports["./client"]` 指向 `./lib/client.js`)。
150
+
151
+ ## 契约速览
152
+
153
+ | 工具 / Remote | 作用 |
154
+ |---|---|
155
+ | `teamflow_start` / `teamflow.start(sessionId, requirement, options)` | 启动流水线 |
156
+ | `teamflow_status` / `teamflow.list()` + `teamflow.snapshot(runId)` | 查询运行进度(阶段/状态/token/日志/是否需人工) |
157
+ | `teamflow_backlog` / `teamflow.backlog(product)` | 查看 backlog(+ persistence 落盘路径) |
158
+ | `teamflow_claim` | 认领任务或缺陷 |
159
+ | `teamflow_update` / `teamflow.backlogUpdate(kind, id, to, product, reason)` | 人工流转状态(处理 needs-human) |
160
+ | `teamflow_cancel` / `teamflow.cancel(runId)` | 取消运行 |
161
+ | `teamflow_resume` / `teamflow.resume(runId, sessionId)` | 断点续跑(从第一个未完成阶段重跑) |
162
+ | `teamflow_triage` | 需求分诊预览(默认 start 自动分诊,仅在想预评估/强制 mode 时使用) |
163
+ | `teamflow_assign` | 指定任务/缺陷的负责人(与 claim 分离:claim 只改状态) |
164
+ | `teamflow_pause` / `teamflow_resume_session` | 当前会话暂停/恢复 teamflow 触发(会话级,新会话自动重置) |
165
+
166
+ ## License
167
+
168
+ MIT —— 详见 [LICENSE](./LICENSE)。
package/lib/client.js CHANGED
@@ -2408,5 +2408,3 @@ window.__ModuleLoader__.load({
2408
2408
  return module.exports;
2409
2409
  }
2410
2410
  });
2411
-
2412
- //# sourceMappingURL=client.js.map
@@ -197,5 +197,3 @@ const TEAMFLOW_REMOTE_CONTRIBUTION = Object.freeze({
197
197
  });
198
198
  //#endregion
199
199
  export { TEAMFLOW_DESCRIPTORS, TEAMFLOW_REMOTE_CONTRIBUTION };
200
-
201
- //# sourceMappingURL=descriptors.mjs.map