@nestos/kanban 0.0.0-stage → 0.5.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/LICENSE +674 -0
- package/README.md +165 -2
- package/dist/activity-BbC4sgKL.d.cts +258 -0
- package/dist/activity-Czlan5xW.d.ts +258 -0
- package/dist/activity-module-DaO1Rry0.d.cts +22 -0
- package/dist/activity-module-T22wliZu.d.ts +22 -0
- package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
- package/dist/activity-ports-cxfrelaL.d.ts +12 -0
- package/dist/activity.cjs +16 -0
- package/dist/activity.cjs.map +1 -0
- package/dist/activity.d.cts +12 -0
- package/dist/activity.d.ts +12 -0
- package/dist/activity.js +16 -0
- package/dist/activity.js.map +1 -0
- package/dist/chunk-3JYLJPE5.js +95 -0
- package/dist/chunk-3JYLJPE5.js.map +1 -0
- package/dist/chunk-3LEIHB7Y.js +221 -0
- package/dist/chunk-3LEIHB7Y.js.map +1 -0
- package/dist/chunk-4XF6LQSU.cjs +9 -0
- package/dist/chunk-4XF6LQSU.cjs.map +1 -0
- package/dist/chunk-5Q7WB63A.cjs +282 -0
- package/dist/chunk-5Q7WB63A.cjs.map +1 -0
- package/dist/chunk-7KDOTBRX.cjs +58 -0
- package/dist/chunk-7KDOTBRX.cjs.map +1 -0
- package/dist/chunk-AHHEGTUA.js +148 -0
- package/dist/chunk-AHHEGTUA.js.map +1 -0
- package/dist/chunk-AOHQCX7K.cjs +95 -0
- package/dist/chunk-AOHQCX7K.cjs.map +1 -0
- package/dist/chunk-DINLR6E6.cjs +443 -0
- package/dist/chunk-DINLR6E6.cjs.map +1 -0
- package/dist/chunk-EYTVC2H5.cjs +1612 -0
- package/dist/chunk-EYTVC2H5.cjs.map +1 -0
- package/dist/chunk-FEE2YBZ7.js +1972 -0
- package/dist/chunk-FEE2YBZ7.js.map +1 -0
- package/dist/chunk-FNO5K3A7.js +282 -0
- package/dist/chunk-FNO5K3A7.js.map +1 -0
- package/dist/chunk-IHHDXZPZ.js +382 -0
- package/dist/chunk-IHHDXZPZ.js.map +1 -0
- package/dist/chunk-J3EAIVA3.js +280 -0
- package/dist/chunk-J3EAIVA3.js.map +1 -0
- package/dist/chunk-KH3WF3K4.js +443 -0
- package/dist/chunk-KH3WF3K4.js.map +1 -0
- package/dist/chunk-M35X5PHO.js +196 -0
- package/dist/chunk-M35X5PHO.js.map +1 -0
- package/dist/chunk-QRGZD2JU.cjs +1972 -0
- package/dist/chunk-QRGZD2JU.cjs.map +1 -0
- package/dist/chunk-RBOER6EW.cjs +221 -0
- package/dist/chunk-RBOER6EW.cjs.map +1 -0
- package/dist/chunk-RQP77ZTY.js +9 -0
- package/dist/chunk-RQP77ZTY.js.map +1 -0
- package/dist/chunk-RSH6QSEC.cjs +196 -0
- package/dist/chunk-RSH6QSEC.cjs.map +1 -0
- package/dist/chunk-VMRDXOLX.cjs +148 -0
- package/dist/chunk-VMRDXOLX.cjs.map +1 -0
- package/dist/chunk-X4UHZX6F.js +58 -0
- package/dist/chunk-X4UHZX6F.js.map +1 -0
- package/dist/chunk-XBSGUVCY.cjs +382 -0
- package/dist/chunk-XBSGUVCY.cjs.map +1 -0
- package/dist/chunk-XKDZHAUE.js +1612 -0
- package/dist/chunk-XKDZHAUE.js.map +1 -0
- package/dist/chunk-ZUZGAO6G.cjs +280 -0
- package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
- package/dist/content-C5aJZFlw.d.cts +35 -0
- package/dist/content-hLH5BNud.d.ts +35 -0
- package/dist/contracts/index.cjs +31 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +5 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +31 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/discovery-9E-LfwIw.d.cts +61 -0
- package/dist/discovery-D60yrjej.d.ts +61 -0
- package/dist/discovery.cjs +377 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +22 -0
- package/dist/discovery.d.ts +22 -0
- package/dist/discovery.js +377 -0
- package/dist/discovery.js.map +1 -0
- package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
- package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
- package/dist/execution.cjs +18 -0
- package/dist/execution.cjs.map +1 -0
- package/dist/execution.d.cts +42 -0
- package/dist/execution.d.ts +42 -0
- package/dist/execution.js +18 -0
- package/dist/execution.js.map +1 -0
- package/dist/index.cjs +74 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/module-CYfE7YhM.d.ts +11 -0
- package/dist/module-Ca9L3qCn.d.cts +11 -0
- package/dist/planning-CHrOqQ6b.d.cts +879 -0
- package/dist/planning-CHrOqQ6b.d.ts +879 -0
- package/dist/ports-B0McVg7B.d.ts +143 -0
- package/dist/ports-BeGO1VRI.d.cts +49 -0
- package/dist/ports-GQy0x-RI.d.cts +143 -0
- package/dist/ports-ykGiNUSx.d.ts +49 -0
- package/dist/runtime/index.cjs +205 -0
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.cts +75 -0
- package/dist/runtime/index.d.ts +75 -0
- package/dist/runtime/index.js +205 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/integration.cjs +423 -0
- package/dist/runtime/integration.cjs.map +1 -0
- package/dist/runtime/integration.d.cts +658 -0
- package/dist/runtime/integration.d.ts +658 -0
- package/dist/runtime/integration.js +423 -0
- package/dist/runtime/integration.js.map +1 -0
- package/dist/storage.cjs +21 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +71 -0
- package/dist/storage.d.ts +71 -0
- package/dist/storage.js +21 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-DPwHzGiz.d.cts +28 -0
- package/dist/store-DgdrPCV9.d.ts +28 -0
- package/dist/task-projection-CSorlMws.d.ts +11 -0
- package/dist/task-projection-DKKB_ueb.d.cts +11 -0
- package/examples/standalone.ts +22 -0
- package/package.json +143 -4
package/README.md
CHANGED
|
@@ -1,3 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nestos/kanban
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 独立安装与开发
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @nestos/kanban @nestos/vfs-core
|
|
7
|
+
# 在本仓库开发
|
|
8
|
+
pnpm install --frozen-lockfile
|
|
9
|
+
pnpm typecheck
|
|
10
|
+
pnpm test
|
|
11
|
+
pnpm build
|
|
12
|
+
pnpm pack
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
本包提供领域服务与运行时,不包含 DOM 界面、CSS 或 UI 依赖。`/contracts` 为前台与远程调用提供无 I/O 的契约和纯函数。
|
|
16
|
+
|
|
17
|
+
基于 VFS 的通用看板与工作协调库,存储与运行时通过可选 peer `@nestos/vfs-core` 接入 VFS;使用这些入口时显式安装该依赖。提供唯一责任人、估算与在制额度、依赖、验收、归档、日志和决策,以及持久派发意图。库不调用模型、不创建 Session/Task、不安装后台调度器。执行、来源与资源活动通过可选端口接入。
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import {SeqKanbanStore, createKanbanModule} from '@nestos/kanban';
|
|
21
|
+
|
|
22
|
+
const service = createKanbanModule({
|
|
23
|
+
store: await SeqKanbanStore.open(authorizedFS, '/work'),
|
|
24
|
+
actor: authenticatedPrincipal,
|
|
25
|
+
authorize: authorizeOperation,
|
|
26
|
+
verifyOutputs: verifyImmutableArtifacts,
|
|
27
|
+
onCommitted: async (boardId, source) => publishPersistedEvents(boardId, source),
|
|
28
|
+
log: logMetadata,
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`actor`、授权及产物核验均来自可信宿主,不能从命令 JSON 中采信。`create` 传入 scope、members、职责和 policy;`execute` 传入稳定 operationId、expectedRevision 和强类型 command。并发冲突由调用方重新读取后决定,不能换 ID 盲目重试外部执行。
|
|
33
|
+
|
|
34
|
+
## 公共入口
|
|
35
|
+
|
|
36
|
+
| 入口 | 内容 |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| 根入口 | `createKanban` 分组 API;`createKanbanModule` 服务工厂与 `SeqKanbanStore` |
|
|
39
|
+
| `/contracts` | 无副作用 DTO、命令、事件与默认配置 |
|
|
40
|
+
| `/storage` | `SeqKanbanStore`、`ConditionalKanbanStore`、内容安装与传输端口 |
|
|
41
|
+
| `/execution` | `createKanbanExecutionBridge`;宿主提供 prepare/start/inspect |
|
|
42
|
+
| `/discovery` | `createKanbanDiscovery`;宿主提供来源、分析和授权 |
|
|
43
|
+
| `/runtime` | `createKanbanRuntime`;单一工厂、执行意图/句柄/回执及完整协调 |
|
|
44
|
+
| `/integration` | 自定义宿主的装配、业务协调与语义状态接口 |
|
|
45
|
+
| `/activity` | `createKanbanActivityModule`;注入来源和外部引用 namespace |
|
|
46
|
+
|
|
47
|
+
`createKanban(options)` 提供 `boards.create/get/list/overview`、`items.get/query`、`records.get/query`、`planning.get`、`references.resolve/suggest`、`execute`、`events`、`tick` 和 `quiesce/dispose`。execute 返回 `{boardId, operationId, revision}`;幂等重放时 revision 是当前返回快照的版本。需要 KanbanService(例如 UI、执行桥)时直接使用 `createKanbanModule`,二者共享同一实现与命令协议。
|
|
48
|
+
|
|
49
|
+
主体 ID、Session/Task/Message ID 及历史持久格式保留。独立 Agent 可以只提供自己的 ID;若提供执行身份,所有权继续按该身份隔离。NestOS 在适配边界继续要求真实 Session/Task,宿主始终负责实际权限核验。
|
|
50
|
+
|
|
51
|
+
## 前台界面
|
|
52
|
+
|
|
53
|
+
界面由独立包 `@nestos/kanban-ui` 提供,样式入口为 `@nestos/kanban-ui/style.css`。前台仅通过本库 `/contracts` 中的 KanbanClient 接入本地或远程服务,不依赖后台存储、执行或恢复实现。
|
|
54
|
+
|
|
55
|
+
## 版本化内容安装
|
|
56
|
+
|
|
57
|
+
`/contracts` 自包含定义 `KanbanContent`、`KanbanClient` 及领域 DTO。`/storage` 的 `installKanbanContent({store, actor, authorize, log, content, operationId})` 安装宿主提供的内容;显式授权 action=install-content,在同一事务保存工作项、记录、修改建议、归档、事件、回执与安装版本。安装内容不授予执行或审核权限。库不携带 NestOS 示例、文案或模板。
|
|
58
|
+
|
|
59
|
+
默认只补充新版本新增的身份,保留用户修改和删除。显式 fillMissing 可以恢复缺失项,已存在或已归档身份不会重新创建。missingReferences=detach 是明确选择的引用修复策略,默认仍按领域约束拒绝无效关系。inspectKanbanContent 返回安装版本与完整性,不向宿主泄露 reducer 状态。
|
|
60
|
+
|
|
61
|
+
## 验证
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm --filter @nestos/kanban typecheck
|
|
65
|
+
pnpm --filter @nestos/kanban test
|
|
66
|
+
pnpm --filter @nestos/kanban build
|
|
67
|
+
pnpm --filter @nestos/kanban example
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
[独立示例](examples/standalone.ts) 只使用 VFS 与假执行器,完成两节点依赖计划,显式自动验收后关闭;没有 NestOS Runtime、模型或网络调用。内存后端用于演示,生产需提供持久后端和实际授权。
|
|
71
|
+
|
|
72
|
+
## 计划与执行
|
|
73
|
+
|
|
74
|
+
管理主体以 `publish-plan` 发布 `kanban.plan/1`:每项指定 assignee、dependsOn、验收条件及输入/输出名称。决策可保存 `coordination.manager/executor`,关联计划只允许该管理主体发布;成员和宿主权限仍需独立检查。计划校验循环、悬空依赖及版本冲突后,原子创建工作项。
|
|
75
|
+
|
|
76
|
+
执行主体提交 `prepare-dispatch`,同一事务完成认领、估算、依赖产物固定和派发意图持久化。可选 execution 入口负责冻结请求和提交前日志,再通过宿主端口调用既有执行器。`observe-execution` 只接收原 dispatchId/fence 的真实观察;`unknown` 保留责任,禁止自动重派。成功首先进入 review;默认需要独立主体 `accept-execution`。显式 review=assignee 时可信成功可自动验收。只有依赖已验收且输出存在,后续任务才能进入 ready。
|
|
77
|
+
|
|
78
|
+
`workflow(boardId)` 返回计划、派发和 ready 摘要。核心只解锁已发布 DAG;动态分解和业务决策仍由管理主体提交下一版计划。修改任务定义需要新任务 ID,未结算执行阻止替换计划或转交责任。`completedPlans` 仅说明已封闭计划中的事项完成,不能替代业务目标验收。
|
|
79
|
+
|
|
80
|
+
## 文件协议
|
|
81
|
+
|
|
82
|
+
默认存储 `/kanban/boards.seq`,可注入目录或完全替换 KanbanStore。SeqFile 必须支持 transaction。键中身份使用 encodeURIComponent:
|
|
83
|
+
|
|
84
|
+
| 键 | 内容 |
|
|
85
|
+
| --- | --- |
|
|
86
|
+
| `index` | 看板 ID 列表 |
|
|
87
|
+
| `board/<boardId>` | layout=2 清单:板元数据、摘要索引、workflow、序列及状态 |
|
|
88
|
+
| `item/<boardId>/<itemId>` | 工作项正文或内容寻址引用 |
|
|
89
|
+
| `record/<boardId>/<recordId>` | 日志/决策正文或引用 |
|
|
90
|
+
| `archive/<boardId>/<itemId>` | 已关闭归档项与关闭事实 |
|
|
91
|
+
| `event/<boardId>/<16位序号>` | 不可变事件/outbox |
|
|
92
|
+
| `receipt/<boardId>/<operationId>` | 请求指纹,防止重复或异义提交 |
|
|
93
|
+
|
|
94
|
+
看板编号使用同文件的计数器与反向索引。计划及派发目前在 board 清单的 state.workflow 中,不另建伪数据库键。一个命令的所有控制记录在同一事务提交;回滚不发布其中任一变化。
|
|
95
|
+
|
|
96
|
+
正文超过 8 KiB 时先保存为同 SeqFile 的 `<sha256>.json` 资产并核验摘要/长度,再提交引用。失败可留下未引用资产,不会发布半个正文;自动垃圾回收和历史裁剪尚未启用。产物引用 `{name,ref,sha256,bytes}` 的权限与实际内容由宿主核验,引用字符串本身不授予文件访问。
|
|
97
|
+
|
|
98
|
+
VFS `seq:committed` 可用于唤醒宿主,但持久状态与定期补扫才是恢复依据。`content:finished` 在读取关闭时也会发出,不能当成任务完成。禁止直接改内部 JSON 或用普通文件复制覆盖活动数据库;外部 Agent 应调用授权命令接口。
|
|
99
|
+
|
|
100
|
+
## 生命周期与宿主边界
|
|
101
|
+
|
|
102
|
+
关闭顺序:停止事件/定时准入 → service.quiesce(拒新操作、等待已准入事务)→ 排空执行适配器 → 最后关闭 VFS。宿主重启后扫描持久派发、检查原执行身份并补投 outbox。SeqFile 不能与模型调用、远程服务或另一数据库组成单一事务,执行桥必须保留提交前日志和 unknown 状态。
|
|
103
|
+
|
|
104
|
+
NestOS 的默认目录、远程 HttpSeqClient、Session 来源读取、发布 Agent/Flow、Kernel 回执、系统 notify 与调度接线均位于 `backend/app-core/src/kanban/`。扫描状态机、批量提交、远程事务编码与执行恢复归独立库;UI 的 NestOS 包装位于 `ui/app-shell/src/kanban/`。应用入口只导出实际 NestOS 绑定,不代转出库 API,核心没有这些运行依赖。完整规范见 [Kanban 协调设计](https://github.com/nest-agentos/NestOS/blob/main/doc/design/kanban-coordination.md)。
|
|
105
|
+
|
|
106
|
+
会话活动入口 `executionSession(boardId, itemId)` 只读取当前执行摘要。显式传入 `{includeRelated: true}` 时,通过可选 `KanbanSessionSource.related` 合并宿主关联与已有执行绑定、参与者;返回的 `sessions` 按不透明 Session ID 去重,各自包含用途和 `executions` 执行记录。续办在同一 Session 下保留不同尝试,`current` 仅由正式执行绑定决定。UI 在展开「相关会话」时加载,支持刷新和宿主注入的原始资源链接;普通活动轮询不读取历史。资源属性由宿主提供,库不识别工作区、Git 或原生会话协议。
|
|
107
|
+
|
|
108
|
+
## Optional automation integration
|
|
109
|
+
|
|
110
|
+
Boards may store automation settings with opaque planner/executor references and trusted coordinator/worker principals. `configure-automation` changes configuration only; the host owns model calls and scheduling. Existing unassigned work may join a sealed plan with `expectedRevision`; adoption preserves its identity and manual dependencies. `edit-item` updates unplanned work while published definitions remain immutable. Execution bridges accept a dynamic `autoDispatch` predicate so pausing prevents new claims while existing admissions are still inspected. Optional client `automationCatalog` and `analysisStatus` ports supply the generic configuration UI and analysis details.
|
|
111
|
+
|
|
112
|
+
宿主已有工作区导航时,可直接构造 `KanbanWorkbench` 并省略 `sidebar`,通过 `createBoard()` 接入导航动作,通过 `committed` 刷新目录;`mountKanban` 的独立默认侧栏保持可用。父项详情提供子事项分页与新建入口,子项通过 `planning.parentId` 关联父项,执行依赖仍单独保存在 `planning.dependencies`。
|
|
113
|
+
|
|
114
|
+
Task 的持久 startAt、编辑租约、单一状态投影与文件协议见 [执行规范](https://github.com/nest-agentos/NestOS/blob/main/doc/design/kanban-task-execution.md)。`item().task` 和 query 的 `task` 为相同宿主事实的投影,`phase` 过滤在服务端执行。
|
|
115
|
+
|
|
116
|
+
事项支持 `request-control action=cancel` 的持久取消中状态及宿主停止回执;父项取消原子登记后代取消意图。`delete-item`、`delete-record` 保存逻辑删除墓碑,默认查询隐藏,`includeDeleted` 显式包含,原 ID 和审计保留。决策取消分为 `request-record-cancellation` 与结算后的 `cancel-record`。可选宿主端口 `controlRecord`、`taskFixes`、`cancelFix` 提供关联执行控制及修复澄清放弃;库不自行控制 Session。资源 `ownership` 独立于 `state`,归属未知或其他事项的资源必须保留,不得从归属未知推断执行已停止。
|
|
117
|
+
|
|
118
|
+
看板 `lifecycle` 支持整体取消与等待删除屏障:`request-board-stop` 冻结新任务/计划/准入/派发/续办,`observe-board-stop` 保存收尾阶段。宿主可提供 `cancelBoard`、`requestBoardDeletion`;后者保存跨重启删除请求,默认 drain 等待原执行结束,或显式 cancel 后再删除。独立库不自装调度器,宿主扫描负责最终预检和自动删除,UI 显示请求已接纳与具体阻塞项。
|
|
119
|
+
|
|
120
|
+
## 完整运行时
|
|
121
|
+
|
|
122
|
+
普通接入使用一个工厂,直接获得可查询、提交命令、扫描和关停的看板实例:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import {createKanbanRuntime} from '@nestos/kanban/runtime';
|
|
126
|
+
|
|
127
|
+
const kanban = await createKanbanRuntime({
|
|
128
|
+
fs: authorizedFS,
|
|
129
|
+
actor: authenticatedPrincipal,
|
|
130
|
+
authorize: authorizeOperation,
|
|
131
|
+
execution: executionAdapter, // Optional for boards without automated execution.
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await kanban.scan();
|
|
135
|
+
await kanban.dispose();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
默认目录为 `/kanban`,可通过 `directory` 设置。`resources` 注入资源目录与权限校验,`activity` 注入执行活动来源,`onCommitted` 接入已有事件通道,`log` 接入诊断。库不自动创建定时器。返回值只包含看板语义操作,不暴露 store、journal、serviceFor 或原始 VFS。
|
|
139
|
+
|
|
140
|
+
执行适配器只实现以下协议:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const executionAdapter = {
|
|
144
|
+
catalog: () => authorizedTargets(),
|
|
145
|
+
prepare: intent => prepareExternalRequest(intent),
|
|
146
|
+
submit: handle => submitExternalRequest(handle),
|
|
147
|
+
inspect: handle => inspectExternalReceipt(handle),
|
|
148
|
+
control: (handle, command) => controlExternalExecution(handle, command),
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- `ExecutionIntent` 包含稳定身份、作用域、目标与结构化上下文;`purpose` 区分规划和工作。规划返回 `ready/dependencies/reason` 及可选 estimate/subtasks,不引入宿主 Session/Flow DTO。
|
|
153
|
+
- `ExecutionHandle` 是可持久化的 `{id,data?}`,由适配器解释。prepare 不能启动外部执行;运行时先保存句柄再 submit,恢复时使用原句柄 inspect。
|
|
154
|
+
- 回执返回 `outcome`、可选 `result/executionId/code/controlCapabilities`。运行时保存并校验结果,通过 `kanban.results(boardId, dispatchId)` 读取授权产物。成功但结果未到达时保持 unknown;无正文结果显式返回 `result: null`。
|
|
155
|
+
- 控制统一接收句柄与 `{operationId,action}`。不提供 control 时返回明确的 `TASK_CONTROL_UNSUPPORTED`,不能把取消意图当作取消完成。
|
|
156
|
+
- 当前事项正文只放在 context.task 一处;决策只携带身份与修订,规划的 related 为摘要。执行依赖只传直接依赖的已验收产物。适配器按需通过授权查询读取额外内容。
|
|
157
|
+
|
|
158
|
+
运行时负责幂等认领、回执丢失恢复、日志投影、产物归属、取消协调和删除屏障。宿主无需了解持久键,也无需自行编写这些状态机。完整接入、重启恢复、失败处理和取消验收见 `tests/public-runtime.test.ts`。
|
|
159
|
+
|
|
160
|
+
## 自定义宿主集成
|
|
161
|
+
|
|
162
|
+
`/integration` 面向需要自定义预设、交互确认或底层装配的受信任宿主,显式导出 `assembleKanbanRuntime`、协调组件与语义状态接口。它与普通 `/runtime` 入口分开;远程 HTTP/MCP 服务应只暴露经过授权的看板语义操作,不能透传 integration 对象。
|
|
163
|
+
|
|
164
|
+
`KanbanCollaboration` 提供修复准备、冻结确认、接纳与决策快照,`collaborationRelations` 提供关联执行投影;适配器无需读取 fix、record-runs 或 task-reply 的内部持久键。宿主仍负责确认文案、通道交互和系统事件投影。
|
|
165
|
+
|
|
166
|
+
`KanbanOperationRecord` 与 `coordinateOperation` 提供自定义业务操作的统一持久协调;执行请求和结果保持不透明,业务插件负责结果约束。只有正式“未启动”回执允许重试提交,连接中断只核对原身份。
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { u as KanbanExternalReference, y as KanbanItemQuery, x as KanbanItemPage, z as KanbanItemSummary, r as KanbanDispatch, T as KanbanService, v as KanbanFixSession, f as KanbanAutomationCatalog, b as KanbanAnalysisStatus } from './planning-CHrOqQ6b.cjs';
|
|
2
|
+
|
|
3
|
+
/** Hosts resolve opaque resources and execute records; the library owns no project policy. */
|
|
4
|
+
interface KanbanRecordResource {
|
|
5
|
+
reference: KanbanExternalReference;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
interface KanbanItemResourceCatalog {
|
|
9
|
+
resources: KanbanRecordResource[];
|
|
10
|
+
selected?: KanbanExternalReference;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
readonly?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface KanbanRecordExecution {
|
|
15
|
+
id: string;
|
|
16
|
+
recordId: string;
|
|
17
|
+
recordRevision: number;
|
|
18
|
+
boardId: string;
|
|
19
|
+
rootItemId?: string;
|
|
20
|
+
itemIds?: string[];
|
|
21
|
+
state: 'preparing' | 'running' | 'blocked' | 'review' | 'completed' | 'failed' | 'cancelling' | 'cancelled' | 'pausing' | 'paused' | 'resuming' | 'unknown';
|
|
22
|
+
createdAt: number;
|
|
23
|
+
updatedAt: number;
|
|
24
|
+
code?: string;
|
|
25
|
+
}
|
|
26
|
+
interface KanbanRecordRunRequest {
|
|
27
|
+
operationId: string;
|
|
28
|
+
recordId: string;
|
|
29
|
+
expectedRevision: number;
|
|
30
|
+
placement?: 'current-board' | 'new-board';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Host-owned execution resources; the coordination library does not interpret their backend. */
|
|
34
|
+
interface KanbanWorkResource {
|
|
35
|
+
id: string;
|
|
36
|
+
kind: string;
|
|
37
|
+
title: string;
|
|
38
|
+
location: string;
|
|
39
|
+
version: string;
|
|
40
|
+
ownership?: 'current' | 'other' | 'unknown';
|
|
41
|
+
state: 'associated' | 'in-use' | 'retained' | 'cleanup-ready' | 'cleaned' | 'unknown';
|
|
42
|
+
reasons: string[];
|
|
43
|
+
properties: Array<{
|
|
44
|
+
label: string;
|
|
45
|
+
value: string;
|
|
46
|
+
}>;
|
|
47
|
+
canCleanup: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface KanbanWorkResourceQuery {
|
|
50
|
+
inspect?: boolean;
|
|
51
|
+
}
|
|
52
|
+
interface KanbanWorkResourceCleanup {
|
|
53
|
+
operationId: string;
|
|
54
|
+
itemId: string;
|
|
55
|
+
resourceId: string;
|
|
56
|
+
version: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface KanbanOperationChoice {
|
|
60
|
+
id: string;
|
|
61
|
+
label: string;
|
|
62
|
+
detail?: string;
|
|
63
|
+
}
|
|
64
|
+
interface KanbanOperationField {
|
|
65
|
+
id: string;
|
|
66
|
+
label: string;
|
|
67
|
+
choices: KanbanOperationChoice[];
|
|
68
|
+
selected?: string;
|
|
69
|
+
}
|
|
70
|
+
/** Host-owned operations; the portable view does not interpret deployment or Git policy. */
|
|
71
|
+
interface KanbanItemOperation {
|
|
72
|
+
id: string;
|
|
73
|
+
label: string;
|
|
74
|
+
state: 'unavailable' | 'ready' | 'running' | 'unknown' | 'succeeded' | 'failed' | 'waiting-confirmation';
|
|
75
|
+
enabled: boolean;
|
|
76
|
+
code?: string;
|
|
77
|
+
reason?: string;
|
|
78
|
+
runId?: string;
|
|
79
|
+
sessionId?: string;
|
|
80
|
+
summary?: string;
|
|
81
|
+
fields?: KanbanOperationField[];
|
|
82
|
+
confirmation?: string;
|
|
83
|
+
configurable?: boolean;
|
|
84
|
+
binding?: KanbanExternalReference;
|
|
85
|
+
openSessionOnRun?: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface KanbanItemOperations {
|
|
88
|
+
revision: string;
|
|
89
|
+
operations: KanbanItemOperation[];
|
|
90
|
+
targets?: Array<{
|
|
91
|
+
label: string;
|
|
92
|
+
reference: KanbanExternalReference;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
interface KanbanItemOperationRequest {
|
|
96
|
+
operationId: string;
|
|
97
|
+
itemId: string;
|
|
98
|
+
action: string;
|
|
99
|
+
expectedRevision: string;
|
|
100
|
+
selections?: Record<string, string>;
|
|
101
|
+
confirmed?: boolean;
|
|
102
|
+
}
|
|
103
|
+
interface KanbanItemOperationBinding {
|
|
104
|
+
operationId: string;
|
|
105
|
+
itemId: string;
|
|
106
|
+
action: string;
|
|
107
|
+
expectedRevision: string;
|
|
108
|
+
target: KanbanExternalReference;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
interface KanbanDeletionPreview {
|
|
112
|
+
boardId: string;
|
|
113
|
+
title: string;
|
|
114
|
+
revision: number;
|
|
115
|
+
version: string;
|
|
116
|
+
blockers: Array<{
|
|
117
|
+
code: string;
|
|
118
|
+
itemId?: string;
|
|
119
|
+
sessionId?: string;
|
|
120
|
+
}>;
|
|
121
|
+
pendingItems: number;
|
|
122
|
+
pendingDeletion?: {
|
|
123
|
+
operationId: string;
|
|
124
|
+
mode: 'drain' | 'cancel';
|
|
125
|
+
phase: 'waiting' | 'ready' | 'blocked';
|
|
126
|
+
code?: string;
|
|
127
|
+
};
|
|
128
|
+
/** Display labels for items referenced by blockers and resources. */
|
|
129
|
+
itemTitles?: Record<string, string>;
|
|
130
|
+
resources: Array<{
|
|
131
|
+
itemId: string;
|
|
132
|
+
resource: KanbanWorkResource;
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
interface KanbanDeletionRequest {
|
|
136
|
+
operationId: string;
|
|
137
|
+
version: string;
|
|
138
|
+
expectedRevision: number;
|
|
139
|
+
cleanup: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
type KanbanSessionPhase = 'running' | 'queued' | 'waiting' | 'waiting-input' | 'waiting-approval' | 'paused' | 'idle' | 'completed' | 'failed' | 'cancelled' | 'unknown';
|
|
143
|
+
interface KanbanExecutionSession {
|
|
144
|
+
sessionId: string;
|
|
145
|
+
resourceId?: string;
|
|
146
|
+
title?: string;
|
|
147
|
+
state: KanbanSessionPhase;
|
|
148
|
+
createdAt?: number;
|
|
149
|
+
lastActivityAt?: number;
|
|
150
|
+
observedAt?: number;
|
|
151
|
+
stale: boolean;
|
|
152
|
+
recent: boolean;
|
|
153
|
+
code?: string;
|
|
154
|
+
}
|
|
155
|
+
interface KanbanSessionActivityQuery extends KanbanItemQuery {
|
|
156
|
+
execution?: 'all' | 'running' | 'recent' | 'active';
|
|
157
|
+
}
|
|
158
|
+
interface KanbanSessionItemSummary extends KanbanItemSummary {
|
|
159
|
+
execution?: KanbanExecutionSession;
|
|
160
|
+
}
|
|
161
|
+
interface KanbanSessionItemPage extends Omit<KanbanItemPage, 'items'> {
|
|
162
|
+
items: KanbanSessionItemSummary[];
|
|
163
|
+
}
|
|
164
|
+
type KanbanSessionPurpose = 'execution' | 'planning' | 'fix' | 'finalization' | 'discussion';
|
|
165
|
+
/** A run belongs to a Session; continuing it does not create another Session. */
|
|
166
|
+
interface KanbanSessionExecution {
|
|
167
|
+
id: string;
|
|
168
|
+
purpose: KanbanSessionPurpose;
|
|
169
|
+
dispatchId?: string;
|
|
170
|
+
attempt?: number;
|
|
171
|
+
previousDispatchId?: string;
|
|
172
|
+
roundId?: string;
|
|
173
|
+
turnId?: string;
|
|
174
|
+
state?: KanbanSessionPhase;
|
|
175
|
+
outcome?: KanbanDispatch['outcome'];
|
|
176
|
+
createdAt?: number;
|
|
177
|
+
completedAt?: number;
|
|
178
|
+
code?: string;
|
|
179
|
+
resources?: Array<{
|
|
180
|
+
label: string;
|
|
181
|
+
value: string;
|
|
182
|
+
}>;
|
|
183
|
+
}
|
|
184
|
+
interface KanbanSessionAssociation {
|
|
185
|
+
sessionId: string;
|
|
186
|
+
purpose: KanbanSessionPurpose;
|
|
187
|
+
execution?: KanbanSessionExecution;
|
|
188
|
+
}
|
|
189
|
+
interface KanbanRelatedSession extends KanbanExecutionSession {
|
|
190
|
+
current: boolean;
|
|
191
|
+
purposes: KanbanSessionPurpose[];
|
|
192
|
+
executions: KanbanSessionExecution[];
|
|
193
|
+
}
|
|
194
|
+
interface KanbanSessionDetailQuery {
|
|
195
|
+
includeRelated?: boolean;
|
|
196
|
+
}
|
|
197
|
+
interface KanbanExecutionSessionDetail {
|
|
198
|
+
continuation?: {
|
|
199
|
+
previousDispatchId: string;
|
|
200
|
+
};
|
|
201
|
+
current?: KanbanExecutionSession;
|
|
202
|
+
history: Array<{
|
|
203
|
+
sessionId: string;
|
|
204
|
+
bindingId?: string;
|
|
205
|
+
current: boolean;
|
|
206
|
+
}>;
|
|
207
|
+
/** Loaded explicitly so activity polling never enumerates historical Sessions. */
|
|
208
|
+
sessions?: KanbanRelatedSession[];
|
|
209
|
+
sessionsCode?: string;
|
|
210
|
+
}
|
|
211
|
+
/** Transport-facing service with optional authorized resource activity. */
|
|
212
|
+
interface KanbanClient extends KanbanService {
|
|
213
|
+
cancelBoard?(boardId: string, request: {
|
|
214
|
+
operationId: string;
|
|
215
|
+
expectedRevision: number;
|
|
216
|
+
}): Promise<void>;
|
|
217
|
+
requestBoardDeletion?(boardId: string, request: KanbanDeletionRequest & {
|
|
218
|
+
mode: 'drain' | 'cancel';
|
|
219
|
+
}): Promise<void>;
|
|
220
|
+
previewDeletion?(boardId: string): Promise<KanbanDeletionPreview>;
|
|
221
|
+
deleteBoard?(boardId: string, request: KanbanDeletionRequest): Promise<void>;
|
|
222
|
+
itemOperations?(boardId: string, itemId: string): Promise<KanbanItemOperations>;
|
|
223
|
+
runItemOperation?(boardId: string, request: KanbanItemOperationRequest): Promise<KanbanItemOperations>;
|
|
224
|
+
bindItemOperation?(boardId: string, request: KanbanItemOperationBinding): Promise<KanbanItemOperations>;
|
|
225
|
+
workResources?(boardId: string, itemId: string, query?: KanbanWorkResourceQuery): Promise<KanbanWorkResource[]>;
|
|
226
|
+
cleanupWorkResource?(boardId: string, request: KanbanWorkResourceCleanup): Promise<KanbanWorkResource>;
|
|
227
|
+
replyTask?(boardId: string, request: {
|
|
228
|
+
itemId: string;
|
|
229
|
+
attemptId: string;
|
|
230
|
+
replyTo: string;
|
|
231
|
+
operationId: string;
|
|
232
|
+
content: string;
|
|
233
|
+
}): Promise<void>;
|
|
234
|
+
taskFixes?(boardId: string, itemId: string): Promise<KanbanFixSession[]>;
|
|
235
|
+
cancelFix?(boardId: string, request: {
|
|
236
|
+
fixId: string;
|
|
237
|
+
operationId: string;
|
|
238
|
+
}): Promise<KanbanFixSession>;
|
|
239
|
+
controlRecord?(boardId: string, request: {
|
|
240
|
+
recordId: string;
|
|
241
|
+
operationId: string;
|
|
242
|
+
action: 'pause' | 'resume' | 'cancel';
|
|
243
|
+
}): Promise<void>;
|
|
244
|
+
fixTask?(boardId: string, request: {
|
|
245
|
+
itemId: string;
|
|
246
|
+
operationId: string;
|
|
247
|
+
}): Promise<KanbanFixSession>;
|
|
248
|
+
itemResources?(boardId: string, parentId?: string): Promise<KanbanItemResourceCatalog>;
|
|
249
|
+
recordResources?(): Promise<KanbanRecordResource[]>;
|
|
250
|
+
runRecord?(boardId: string, request: KanbanRecordRunRequest): Promise<KanbanRecordExecution>;
|
|
251
|
+
recordExecutions?(boardId: string, recordId: string): Promise<KanbanRecordExecution[]>;
|
|
252
|
+
automationCatalog?(): Promise<KanbanAutomationCatalog>;
|
|
253
|
+
analysisStatus?(boardId: string, itemId: string): Promise<KanbanAnalysisStatus | null>;
|
|
254
|
+
queryActivity?(boardId: string, query?: KanbanSessionActivityQuery): Promise<KanbanSessionItemPage>;
|
|
255
|
+
executionSession?(boardId: string, itemId: string, query?: KanbanSessionDetailQuery): Promise<KanbanExecutionSessionDetail>;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export type { KanbanClient as K, KanbanDeletionPreview as a, KanbanDeletionRequest as b, KanbanExecutionSession as c, KanbanExecutionSessionDetail as d, KanbanItemOperation as e, KanbanItemOperationBinding as f, KanbanItemOperationRequest as g, KanbanItemOperations as h, KanbanItemResourceCatalog as i, KanbanOperationChoice as j, KanbanOperationField as k, KanbanRecordExecution as l, KanbanRecordResource as m, KanbanRecordRunRequest as n, KanbanRelatedSession as o, KanbanSessionActivityQuery as p, KanbanSessionAssociation as q, KanbanSessionDetailQuery as r, KanbanSessionExecution as s, KanbanSessionItemPage as t, KanbanSessionItemSummary as u, KanbanSessionPhase as v, KanbanSessionPurpose as w, KanbanWorkResource as x, KanbanWorkResourceCleanup as y, KanbanWorkResourceQuery as z };
|