@yanglaofish/fishtools 0.1.4 → 0.3.0
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/README.md +79 -25
- package/manual/LICENSE +21 -0
- package/manual/README.md +199 -0
- package/manual/THIRD_PARTY_NOTICES.md +32 -0
- package/manual/docs/examples/action-plugin/LICENSE +21 -0
- package/manual/docs/examples/action-plugin/README.md +38 -0
- package/manual/docs/examples/action-plugin/index.js +18 -0
- package/manual/docs/examples/action-plugin/input.json +1 -0
- package/manual/docs/examples/action-plugin/package.json +9 -0
- package/manual/docs/examples/pipeline-reader/LICENSE +21 -0
- package/manual/docs/examples/pipeline-reader/index.js +14 -0
- package/manual/docs/examples/pipeline-reader/package.json +7 -0
- package/manual/docs/examples/pipeline-writer/LICENSE +21 -0
- package/manual/docs/examples/pipeline-writer/index.js +17 -0
- package/manual/docs/examples/pipeline-writer/package.json +7 -0
- package/manual/docs/plans/2026-10-10-workbench-ui.md +27 -0
- package/{docs → manual/docs}/plugin-development.md +172 -20
- package/{docs → manual/docs}/releases.md +32 -2
- package/manual/docs/research/2026-10-11-plugin-kernel-capabilities.md +167 -0
- package/manual/docs/roadmap.md +90 -0
- package/manual/docs/superpowers/plans/2026-10-09-workflow-mvp.md +115 -0
- package/manual/docs/superpowers/plans/2026-10-10-cordis-services.md +34 -0
- package/manual/docs/superpowers/plans/2026-10-10-fst-terminal.md +33 -0
- package/manual/docs/superpowers/plans/2026-10-10-portable-plugin-contract.md +35 -0
- package/manual/docs/superpowers/plans/2026-10-11-control-observation.md +77 -0
- package/manual/docs/superpowers/plans/2026-10-11-public-plugin-fixes.md +40 -0
- package/manual/docs/superpowers/plans/2026-10-11-terminal-hierarchy.md +40 -0
- package/manual/docs/superpowers/specs/2026-10-09-workflow-cli-design.md +377 -0
- package/manual/docs/superpowers/specs/2026-10-10-cordis-services-design.md +88 -0
- package/manual/docs/superpowers/specs/2026-10-10-portable-plugin-contract.md +31 -0
- package/manual/docs/superpowers/specs/2026-10-10-run-logs.md +28 -0
- package/manual/docs/superpowers/specs/2026-10-11-collapsed-plugin-output.md +23 -0
- package/manual/docs/superpowers/specs/2026-10-11-control-observation.md +37 -0
- package/{docs → manual/docs}/verification.md +97 -1
- package/manual/examples/service-plugins/README.md +20 -0
- package/manual/examples/service-plugins/consumer/LICENSE +21 -0
- package/manual/examples/service-plugins/consumer/index.js +14 -0
- package/manual/examples/service-plugins/consumer/package.json +1 -0
- package/manual/examples/service-plugins/provider/LICENSE +21 -0
- package/manual/examples/service-plugins/provider/index.js +19 -0
- package/manual/examples/service-plugins/provider/package.json +1 -0
- package/manual/packages/core/LICENSE +21 -0
- package/manual/packages/core/src/application.js +211 -0
- package/manual/packages/core/src/engine.js +93 -0
- package/manual/packages/core/src/host.js +124 -0
- package/manual/packages/core/src/runtime.js +135 -0
- package/manual/packages/core/src/terminal/run-feed.js +78 -0
- package/manual/packages/core/src/terminal/session.js +438 -0
- package/manual/packages/core/src/terminal/view.js +283 -0
- package/manual/packages/sdk/LICENSE +21 -0
- package/manual/packages/sdk/index.js +14 -0
- package/manual/packages/sdk/package.json +1 -0
- package/manual/plugins/environment/LICENSE +21 -0
- package/manual/plugins/environment/index.js +92 -0
- package/manual/plugins/environment/package.json +1 -0
- package/manual/plugins/examples/LICENSE +21 -0
- package/manual/plugins/examples/index.js +23 -0
- package/manual/plugins/examples/package.json +1 -0
- package/manual/plugins/examples/scripts/echo.py +5 -0
- package/manual/tests/application.test.js +75 -0
- package/node_modules/@mytools/core/bin/fst.js +12 -4
- package/node_modules/@mytools/core/src/application.js +11 -5
- package/node_modules/@mytools/core/src/cli-run.js +6 -0
- package/node_modules/@mytools/core/src/contracts.js +15 -2
- package/node_modules/@mytools/core/src/control.js +63 -0
- package/node_modules/@mytools/core/src/documentation.js +65 -0
- package/node_modules/@mytools/core/src/engine.js +80 -26
- package/node_modules/@mytools/core/src/host.js +15 -2
- package/node_modules/@mytools/core/src/markdown-log.js +9 -6
- package/node_modules/@mytools/core/src/process.js +49 -15
- package/node_modules/@mytools/core/src/project.js +1 -1
- package/node_modules/@mytools/core/src/run-logs.js +1 -1
- package/node_modules/@mytools/core/src/terminal/conditions.js +32 -0
- package/node_modules/@mytools/core/src/terminal/log-viewer.js +7 -8
- package/node_modules/@mytools/core/src/terminal/model.js +33 -4
- package/node_modules/@mytools/core/src/terminal/navigation.js +17 -0
- package/node_modules/@mytools/core/src/terminal/presentation.js +8 -10
- package/node_modules/@mytools/core/src/terminal/run-feed.js +78 -0
- package/node_modules/@mytools/core/src/terminal/run-presentation.js +60 -0
- package/node_modules/@mytools/core/src/terminal/run-viewer.js +104 -0
- package/node_modules/@mytools/core/src/terminal/session.js +212 -57
- package/node_modules/@mytools/core/src/terminal/theme.js +29 -0
- package/node_modules/@mytools/core/src/terminal/view.js +185 -33
- package/node_modules/@mytools/core/src/terminal/workflow-menu.js +50 -0
- package/node_modules/@mytools/core/src/validation.js +17 -4
- package/node_modules/@mytools/core/src/version.js +1 -1
- package/node_modules/@mytools/core/src/workflows.js +41 -19
- package/node_modules/@mytools/core/templates/control-demo.yaml +47 -0
- package/node_modules/@mytools/environment/index.js +14 -2
- package/node_modules/@mytools/pack/index.js +6 -2
- package/node_modules/@mytools/web/public/THIRD_PARTY_NOTICES.txt +780 -780
- package/node_modules/@mytools/web/public/assets/index-DT2B4tMV.js +70 -0
- package/node_modules/@mytools/web/public/assets/{index-BeV6IqTW.css → index-vuZvrUTT.css} +1 -1
- package/node_modules/@mytools/web/public/index.html +2 -2
- package/package.json +2 -2
- package/node_modules/@mytools/web/public/assets/index-TgsBnZgG.js +0 -70
- /package/{docs → manual/docs}/deployment.md +0 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# 基于 Cordis 的插件式工作流工具首版设计
|
|
2
|
+
|
|
3
|
+
日期:2026-10-09
|
|
4
|
+
|
|
5
|
+
> 历史设计。当前状态见 [路线图](../../roadmap.md),后续决策见 [分层分发设计](2026-10-10-portable-plugin-contract.md)。本文中的 `fish` 默认 Web、Python 仅宿主、默认只读导出等描述已被后续决策替代:当前入口为 `fst` TUI,环境按声明选择,默认导出可编辑完整工具。本文保留初始讨论和验收目标,不能作为全部已实现能力清单。
|
|
6
|
+
|
|
7
|
+
## 1. 状态与约束
|
|
8
|
+
|
|
9
|
+
本文记录当前对话中的需求与设计建议,供用户审阅和后续开发使用。
|
|
10
|
+
|
|
11
|
+
- **已确认**:用户明确提出或接受的要求,见第 2 节。
|
|
12
|
+
- **开发授权**:用户已接受官方 Web 插件方案,并明确要求进入开发;以下建议作为首版实施基线,细节按轻量、跨平台原则处理并记录。
|
|
13
|
+
- **验证门槛**:选型、打包和跨平台能力必须通过实际验证;本文不表示这些能力已经实现或验证。
|
|
14
|
+
|
|
15
|
+
设计开始时没有已有插件或产品代码;当前首版实现与实际验证范围见 `docs/verification.md`。2026-10-10 用户确认产品名 **Fishtools**、CLI 名称 **fish**,并要求支持 Linux 上通过 npm 安装完整工具。默认 `fish` 启动 Web,`fish run` 执行工作流;初始设计中的 `flow` 命令示意以当前 README 为准。内部项目文件和插件标识保持兼容。
|
|
16
|
+
|
|
17
|
+
需求依据是本会话中用户的明确陈述。DeepSeek 共享链接本次访问失败,未据其不可见内容补充需求。
|
|
18
|
+
|
|
19
|
+
## 2. 已确认的目标与范围
|
|
20
|
+
|
|
21
|
+
### 2.1 用户目标
|
|
22
|
+
|
|
23
|
+
构建一个轻量、跨平台、基于 Cordis 的插件式应用。核心是普通编排调用:通过一次启动,按顺序执行多个插件的功能。使用者能够安装第三方插件;其他开发者能够按照公开接口开发插件。
|
|
24
|
+
|
|
25
|
+
首版核心包含以下能力:
|
|
26
|
+
|
|
27
|
+
1. CLI 入口。
|
|
28
|
+
2. 插件安装、加载及公共插件开发接入。
|
|
29
|
+
3. 顺序工作流编排,支持调用插件动作和子工作流。
|
|
30
|
+
4. 插件配置文件与运行入参。
|
|
31
|
+
5. 日志与错误定位。
|
|
32
|
+
6. 按用户选择的入口工作流进行自包含打包。
|
|
33
|
+
|
|
34
|
+
**首款官方插件:环境检查。** 负责目标机器的 Python/pip、NPU、系统内核等检查,作为独立插件交付,不列为第七项核心内置能力。Python 脚本调用是重点接入场景,通过通用进程接口由插件实现。
|
|
35
|
+
|
|
36
|
+
“官方”表示由本项目维护;其注册、安装、调用、版本管理和打包均使用公开插件接口,与第三方插件采用相同机制。只有工作流引用它时才纳入依赖闭包;没有引用时,核心和其他工作流可独立运行。
|
|
37
|
+
|
|
38
|
+
**用户确认的环境边界**:使用目标机器现有的 Python 和业务环境;必需环境缺失或不满足要求属于错误,由环境检查插件诊断并阻止后续任务。首版不打包 Python 解释器或其已安装库,也不自动修复目标环境。
|
|
39
|
+
|
|
40
|
+
工作流必须明确声明调用的插件和子工作流。打包应递归包含需要的子工作流、插件及相关依赖,避免将所有已安装插件无差别打入产物。
|
|
41
|
+
|
|
42
|
+
**用户明确的交互要求**:用户应能看见有哪些插件能力可用、有哪些现成工作流、它们做什么、需要什么输入以及产生什么输出,然后将能力或工作流加入有序步骤列表。依赖声明可以由界面操作自动生成,用户无需手写 YAML、维护依赖清单或配置版本锁。用户接受官方 Web 插件作为主要界面,并要求离线环境能经堡垒机访问。
|
|
43
|
+
|
|
44
|
+
### 2.2 平台与分发
|
|
45
|
+
|
|
46
|
+
- 支持 Windows 原生运行、Linux 原生运行。
|
|
47
|
+
- Linux 分发包能够挂载进兼容的 Linux Docker 容器运行。
|
|
48
|
+
- 首版优先覆盖常见环境;Windows 容器不在首版范围。
|
|
49
|
+
- Linux 首先面向 glibc 环境;Alpine/musl、ARM 等兼容需求后续按实际场景扩展。
|
|
50
|
+
- 不要求用户构建或导入 Docker 镜像,挂载已有分发包即可。
|
|
51
|
+
- 目标机器无需另行安装本工具所需的 Node.js 和插件 npm 生产依赖,启动时无需联网下载依赖。业务脚本使用的 Python、Python 库、驱动等由目标环境提供,其要求随包记录并在运行时检查。
|
|
52
|
+
- “离线可启动”不代表网络类插件自身能够脱离其业务依赖运行。
|
|
53
|
+
|
|
54
|
+
### 2.3 架构方向
|
|
55
|
+
|
|
56
|
+
- 参考 DSH 的插件开发、安装与组合方式,采用显式安装的可信同进程插件模型。
|
|
57
|
+
- 参考 Pi Coding Agent 的扩展开发体验;不把“Pi 也基于 Cordis”作为选型前提。
|
|
58
|
+
- 首版不做 LLM 插件。
|
|
59
|
+
- 多机协调能力可由未来插件提供,例如对接 Kubernetes;首版不建立分布式调度内核。
|
|
60
|
+
- 优先复用合适的开源项目,保持代码简洁、低耦合、高内聚。
|
|
61
|
+
|
|
62
|
+
## 3. 技术路线与轻量化约束(建议)
|
|
63
|
+
|
|
64
|
+
### 3.1 选择
|
|
65
|
+
|
|
66
|
+
| 方案 | 收益 | 代价 | 本设计选择 |
|
|
67
|
+
| --- | --- | --- | --- |
|
|
68
|
+
| TypeScript/JavaScript 插件 + Node.js + Cordis | 与 Cordis 直接集成;纯 JS 插件跨平台发布较简单 | 分发包需要携带 Node.js | 首版默认 |
|
|
69
|
+
| 每个插件独立进程,多语言协议 | 容纳多种语言,可隔离部分故障 | 协议、进程管理及运行时打包成本增加 | 按实际需求扩展 |
|
|
70
|
+
| 将所有内容编译成单个可执行文件 | 单文件交付方便 | 动态插件、资源与原生依赖处理更复杂 | 首版不作为交付要求 |
|
|
71
|
+
|
|
72
|
+
插件接入层使用 TypeScript 或 JavaScript,发布的是可直接加载的 JavaScript 和必要资源。运行端不编译 TypeScript。插件业务逻辑可以由 Python 脚本或外部命令实现,通过子进程调用;这不要求把 Python 代码改写成 JavaScript,也不要求建立独立的多语言插件服务协议。
|
|
73
|
+
|
|
74
|
+
选择实施时仍受官方支持的 Node.js LTS,并锁定准确版本;锁定 Cordis、SDK 和生产依赖版本。不能在分发包中依赖 `latest`。具体版本与最低系统要求必须在兼容性验证后写入构建配置及产物清单。
|
|
75
|
+
|
|
76
|
+
### 3.2 轻量的具体含义
|
|
77
|
+
|
|
78
|
+
- 命令行运行使用单个 Host 进程,插件需要时调用子进程;Web 模式按需启动本地服务并使用系统浏览器,不要求后台常驻守护进程或数据库。
|
|
79
|
+
- 一个仓库组织清晰模块;发布入口、SDK 和必要的官方插件,避免按内部模块拆出大量软件包。
|
|
80
|
+
- 分发包只携带所选工作流需要的生产依赖、运行时和资源,不携带开发工具链。
|
|
81
|
+
- 建议首版提供 Web 的列表编排与运行按钮,同时保留 CLI 的 `run` 命令;不再将用户的“一次点击”仅解释为启动命令。
|
|
82
|
+
- 基础包携带 Node.js;Python 及业务依赖使用目标环境。包内可以携带插件调用的 Python 脚本与资源。容器编排组件按后续插件需要引入。
|
|
83
|
+
- 验证样例记录压缩体积、解压体积、启动耗时和峰值内存。当前没有测量,不能承诺“几 MB”或某个启动速度。
|
|
84
|
+
|
|
85
|
+
## 4. 模块边界(建议)
|
|
86
|
+
|
|
87
|
+
| 模块 | 对外职责 | 依赖约束 |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| 插件 SDK | 动作注册、输入输出契约、日志与资源访问接口 | 不依赖 CLI 或打包器 |
|
|
90
|
+
| 插件 Host | 用 Cordis 管理服务、插件生命周期和动作注册 | 不解析工作流编排规则 |
|
|
91
|
+
| 工作流引擎 | 校验流程、解析引用、顺序执行、生成运行结果 | 依赖动作调用接口,不依赖 Cordis 内部类型 |
|
|
92
|
+
| 插件管理 | 安装、列出、移除、检查 SDK 兼容性,维护项目依赖锁 | 只在开发/组装环境修改插件集合 |
|
|
93
|
+
| 打包器 | 求依赖闭包、组装目标平台运行目录、生成清单与归档 | 使用工作流解析结果,不重复实现解析规则 |
|
|
94
|
+
| 日志 | 统一运行事件、控制台输出、JSONL 文件 | 其他模块依赖稳定事件接口 |
|
|
95
|
+
| 进程执行服务 | 调用可执行文件,管理参数、工作目录、输出、超时和取消 | 不理解 pip、NPU 或具体业务 |
|
|
96
|
+
| 应用服务 | 查询能力与工作流、保存工作流、校验、启动/取消运行、订阅事件、请求打包 | 组合已有模块,对入口提供统一的公开接口,不依赖 HTTP 或页面 |
|
|
97
|
+
| CLI | 参数解析与上述模块的命令组合 | 不内嵌插件业务逻辑 |
|
|
98
|
+
| 官方 Web 插件(建议) | 提供页面、HTTP 接口及运行事件传输 | 只调用公开应用服务,不另写编排器或依赖解析器 |
|
|
99
|
+
|
|
100
|
+
核心稳定接口包括:动作目录查询、动作调用、工作流解析结果、依赖解析结果和运行事件。SDK 不暴露应用内部文件路径、CLI 状态或 Cordis 私有实现。
|
|
101
|
+
|
|
102
|
+
能力目录与工作流存取属于共用应用服务。Web 的路由、页面状态及表单渲染留在插件内;CLI 与 Web 读取和保存同一份工作流定义,调用同一执行服务。所谓公开接口可以是进程内服务,无须为了 CLI 启动 HTTP 服务。
|
|
103
|
+
|
|
104
|
+
首版每个项目只使用一个插件安装集合,每个插件 ID 只加载一个版本。生产包内冻结依赖;升级插件后重新打包。
|
|
105
|
+
|
|
106
|
+
## 5. 插件契约(建议)
|
|
107
|
+
|
|
108
|
+
一个插件是标准 npm 包,并包含本工具专用元数据:
|
|
109
|
+
|
|
110
|
+
- `id`、版本、SDK 兼容范围、JavaScript 入口。
|
|
111
|
+
- 导出的动作名称及各动作的输入/输出 JSON Schema。
|
|
112
|
+
- 供能力目录与表单使用的显示名称、用途说明、输入输出字段说明、默认值及示例。插件作者提供这些信息,普通用户看到说明与表单。
|
|
113
|
+
- 配置 JSON Schema 和允许随包分发的非敏感默认配置。
|
|
114
|
+
- 需要其他宿主插件提供的服务时,显式声明插件依赖及版本范围。
|
|
115
|
+
- 要打包的资源文件路径与支持的目标平台。
|
|
116
|
+
- 外部运行要求:区分随包资源和目标机环境条件;Python 解释器引用必须明确指向目标机器环境。要求按动作声明,插件能够在环境不满足时加载并给出诊断。
|
|
117
|
+
|
|
118
|
+
普通 JavaScript 库依赖沿用 npm 的 `dependencies`;本工具只额外描述宿主插件之间的依赖与动作元数据,不再建立一套 npm 替代品。
|
|
119
|
+
|
|
120
|
+
动作接收已校验的输入、插件配置和运行上下文。上下文提供运行 ID、步骤 ID、日志、取消信号及资源解析函数。动作返回可 JSON 序列化的结果;大文件通过输出文件路径传递,避免放入内存中的步骤结果。
|
|
121
|
+
|
|
122
|
+
插件通过 SDK 注册动作,Host 将注册结果用于执行。打包使用声明式元数据识别依赖,不为了发现依赖执行插件动作。加载时检查实际注册动作与元数据是否一致。
|
|
123
|
+
|
|
124
|
+
实施采用 npm workspaces、package-lock 与 Arborist,支持 npm 包、打包后的本地包和开发目录。选择 npm 是为直接复用同一套安装树、发布文件和依赖解析组件。开发目录在生产打包时转换为文件快照,不能保留指向作者机器的链接。Git 来源、复杂 profile 叠加和热更新不作为首版验收要求。
|
|
125
|
+
|
|
126
|
+
插件属于可信主进程代码,拥有 Host 进程权限。此模型不提供恶意插件隔离;插件调用外部程序也不自动获得沙箱隔离。
|
|
127
|
+
|
|
128
|
+
第三方开发交付物应包括:最小插件模板、接口说明、配置和日志示例,以及无需修改核心仓库的安装运行教程。
|
|
129
|
+
|
|
130
|
+
### 5.1 通用进程接口与 Python 接入示例
|
|
131
|
+
|
|
132
|
+
推荐通过 SDK 的统一进程服务调用:提供可执行文件路径、参数数组、工作目录、环境变量覆盖、超时、输出上限和取消信号;返回退出码、stdout、stderr 与终止原因。默认不经 Shell 拼接命令,避免跨平台引号和路径规则污染业务代码。Windows 启动子进程不弹出额外终端窗口。
|
|
133
|
+
|
|
134
|
+
进程服务需处理输出流和取消后的回收;跨平台子进程树清理作为验证项,不能仅杀掉直接子进程后声称取消完成。该服务是受管理的程序调用,不是安全隔离机制。
|
|
135
|
+
|
|
136
|
+
Python 只使用目标机器已有的解释器,包括已有 venv 或 Conda 环境。配置可明确解释器路径;探测动作可以搜索 PATH 并报告候选项,多环境情况下必须选定具体解释器,不能静默切换或降级到另一个环境。检查通过后,将解析后的绝对解释器路径传给后续 Python 动作,确保检查与执行使用同一个环境。
|
|
137
|
+
|
|
138
|
+
脚本及随附数据可以由插件携带;解释器、pip、Python 第三方库、NPU 驱动与用户态工具链都是目标环境条件。打包清单记录所需版本范围与检查项,不复制开发机 Python 环境,也不在运行时创建环境或执行安装。
|
|
139
|
+
|
|
140
|
+
调用 pip 时使用选定解释器的 `python -m pip`,确保查询的是同一个环境。记录 `sys.executable`、版本、`sys.prefix` 和包信息;`pip inspect` 可用时读取其 JSON,旧 pip 则降级到可用命令并标明信息缺失,不自动升级目标环境。
|
|
141
|
+
|
|
142
|
+
### 5.2 首款官方插件:环境检查
|
|
143
|
+
|
|
144
|
+
建议以独立的 `environment` 插件提供 `check` 动作,按工作流声明的要求调用以下内部探测能力。核心只提供文件、进程和日志基础接口,Python 不存在时也能完成诊断。该插件不获得专用的核心接口或特殊加载待遇:
|
|
145
|
+
|
|
146
|
+
| 检查能力 | 实现依据 | 输出与限制 |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `system.inspect` | Node.js `os` 接口;Linux 读取 `/etc/os-release` | 内核、架构、发行版分别记录;其他系统使用对应适配 |
|
|
149
|
+
| `python.inspect` | 明确路径或发现的解释器执行查询脚本与 `-m pip` | 返回每个被检查环境的路径、版本及包信息;不自动修改或创建环境 |
|
|
150
|
+
| `npu.inspect` | 按厂商适配;昇腾可调用 `npu-smi info` 并读取可访问的版本文件 | 分开报告工具、设备可见性、驱动和用户态工具链;不能因命令不存在就断定无 NPU |
|
|
151
|
+
|
|
152
|
+
NPU 厂商尚未指定,昇腾仅作为设计示例。动作结果应标明可见范围及证据,至少区分 `available`、`not_found`、`permission_denied`、`unsupported`、`error`。`not_found` 表示在本次检查范围内未发现,不等于证明物理机器上不存在。
|
|
153
|
+
|
|
154
|
+
`check` 汇总要求、实际观测、通过状态、证据及修复建议。任一必需项缺失、版本不满足、权限不足而无法验证或检查不受支持时,先写出完整报告,再让检查步骤失败,后续业务步骤不执行。低层探测返回“未发现”是诊断事实;上层检查不能将必需环境缺失当作成功。
|
|
155
|
+
|
|
156
|
+
检查项由实际工作流决定:Python 任务检查指定解释器和所需库;需要 pip 的任务检查该解释器的 pip;NPU 任务检查指定厂商与能力要求。没有声明 NPU 要求的普通任务不因机器没有 NPU 而失败。环境要求可由动作元数据声明,工作流可以添加业务约束;`check` 通过公共只读接口获取解析后的工作流及动作元数据,收集要求并解释检查规则,避免手工复制两份依赖清单。核心仅保留和传递插件扩展元数据,不解释 Python/NPU 版本或检查规则。
|
|
157
|
+
|
|
158
|
+
官方示例工作流应显式将 `environment:check` 放在相关业务步骤之前,后续步骤通过普通输出引用取得已确认的解释器等信息。核心按通用规则校验动作存在性、引用顺序和输入输出,不硬编码必须调用某个环境检查插件。运行期环境检查失败与其他插件动作失败一致,CLI 返回 1;错误对象携带结构化报告路径和失败项,避免错误日志丢失诊断。业务插件本身仍需报告外部命令无法启动等错误,不能假定所有使用者都采用官方检查流程。
|
|
159
|
+
|
|
160
|
+
容器内探测的是当前容器可见的环境:内核与容器内发行版信息分别标注,Python/pip 属于被选中的容器内解释器。访问 NPU 还取决于容器的设备映射、驱动库和工具可见性,仅挂载本工具包不能保证 NPU 可访问。报告不能冒充完整的宿主机资产清单。
|
|
161
|
+
|
|
162
|
+
## 6. 工作流契约与执行(建议)
|
|
163
|
+
|
|
164
|
+
### 6.1 用户操作
|
|
165
|
+
|
|
166
|
+
用户从能力目录或工作流列表开始;每个条目显示名称、用途、输入、输出和当前可用状态。一个插件可以提供多个动作,目录以可执行动作呈现,并注明来自哪个插件。已有工作流也能作为一个步骤加入新工作流。
|
|
167
|
+
|
|
168
|
+
编辑方式是有序列表:添加步骤、上移/下移或拖动排序、删除、展开参数。首版聚焦列表,不增加节点连线画布。运行前可保存为复用工作流,并提供用途说明与运行所需参数。
|
|
169
|
+
|
|
170
|
+
每个参数通过三种方式设置:填固定值、设为启动时填写的工作流输入、选择某个前序步骤的输出字段。第三种方式用“步骤名称 → 输出字段”的选择器表达;用户无需写引用表达式。保存时系统生成稳定步骤 ID 和字段引用,重排不改变 ID;删除来源步骤或把它移到后面时,明确标注受影响参数并阻止无效运行,不能静默改绑。
|
|
171
|
+
|
|
172
|
+
输入表单由元数据生成,先支持字符串、数字、布尔值、枚举、路径和常见结构化字段。目录可查看完整输出结构及说明;运行后在相同步骤显示实际结果。插件缺失、必填参数未填写、明显的字段类型不匹配,直接定位到相关步骤或字段;运行时仍校验真实输入输出。
|
|
173
|
+
|
|
174
|
+
版本和依赖由插件管理与打包器维护。普通用户安装插件、选择能力、点击保存/运行/导出;默认不填写版本范围或依赖列表。不兼容时显示“哪个插件/步骤不可用、原因和可执行的处理方式”,详细版本信息放在详情中。
|
|
175
|
+
|
|
176
|
+
### 6.2 开发者使用的保存格式
|
|
177
|
+
|
|
178
|
+
YAML 仅作为内部可读保存格式的建议,界面自动生成并由核心统一读写。JSON Schema 是开发者声明输入输出的工具,不作为普通用户编辑工作流的前置知识。以下格式用于说明引擎契约,不能据此要求用户手写配置;名称均为示例:
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
schemaVersion: 1
|
|
182
|
+
id: prepare
|
|
183
|
+
inputs:
|
|
184
|
+
type: object
|
|
185
|
+
required: [source]
|
|
186
|
+
properties:
|
|
187
|
+
source: { type: string }
|
|
188
|
+
steps:
|
|
189
|
+
- id: normalize
|
|
190
|
+
action: "@example/text:normalize"
|
|
191
|
+
with:
|
|
192
|
+
source: { $ref: "inputs.source" }
|
|
193
|
+
- id: export
|
|
194
|
+
workflow: "./export.yaml"
|
|
195
|
+
with:
|
|
196
|
+
content: { $ref: "steps.normalize.output.content" }
|
|
197
|
+
outputs:
|
|
198
|
+
result: { $ref: "steps.export.output.result" }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`steps[].action` 和 `steps[].workflow` 本身就是显式调用声明,由“加入步骤”操作生成,不再要求用户手工维护一份内容重复的依赖列表。插件 ID 到准确版本的映射来自系统维护的项目依赖锁。每一步必须且只能声明其中一种调用。
|
|
202
|
+
|
|
203
|
+
- 动作名和子工作流路径必须为静态字符串,不能在运行时计算依赖名称。
|
|
204
|
+
- 子工作流路径相对于声明它的工作流文件,并且必须位于项目工作流根目录内;打包保持该相对关系。
|
|
205
|
+
- 工作流 ID 在项目内唯一,步骤 ID 在所属工作流内唯一。
|
|
206
|
+
- `$ref` 只支持输入和前序步骤输出的字段路径,不执行 JavaScript、Shell 或模板表达式;不存在的引用应明确报错。
|
|
207
|
+
- 子工作流有独立的输入、步骤及输出命名空间,由父流程显式传参。
|
|
208
|
+
- 执行顺序严格按照 `steps` 顺序。首版失败立即停止并向调用方传播错误,不自动重试或回滚。
|
|
209
|
+
- 运行前检查结构、动作存在性、引用顺序和子工作流循环。每一步调用前后校验实际输入输出。
|
|
210
|
+
- 首版不提供并行、条件分支、循环、定时调度和断点续跑。
|
|
211
|
+
|
|
212
|
+
配置分为插件配置和工作流输入,二者分别校验。插件配置优先级为 SDK 默认值 < 项目/包内非敏感配置 < `--config` 指定文件;工作流输入由默认值和 `--input` 文件组成。首版不引入复杂的隐式环境变量覆盖规则。
|
|
213
|
+
|
|
214
|
+
相对资源路径通过 SDK 按插件资源目录解析;插件配置文件中的相对路径按该配置文件目录解析。用户指定的输入和输出路径按启动目录解析,不依赖开发者原机器路径。
|
|
215
|
+
|
|
216
|
+
流程结束返回输出对象和明确的退出码:成功为 0,运行步骤失败为 1,配置/依赖/平台校验失败为 2,用户取消为 130。取消通过信号协作传递;可信同进程插件不能保证单个动作被强制终止且 Host 继续运行,首版不承诺动作级硬超时隔离。
|
|
217
|
+
|
|
218
|
+
## 7. 自包含打包(建议)
|
|
219
|
+
|
|
220
|
+
### 7.1 用户操作
|
|
221
|
+
|
|
222
|
+
Web 操作:勾选要导出的工作流,选择 Windows 或 Linux,选择是否需要运行界面,然后导出。工具自动收集依赖,预览包含的工作流、插件和目标环境要求;用户不逐项填写依赖版本。
|
|
223
|
+
|
|
224
|
+
对应 CLI 示意:`flow pack prepare export --target linux-x64-glibc --out dist`;CLI 参数与页面选项最终调用同一打包服务。
|
|
225
|
+
|
|
226
|
+
用户选择入口工作流和目标平台。Windows 与 Linux 分别生成包含各自运行时的包;“跨平台”指同一套工作流及可移植插件能够为多个目标出包,不要求单个二进制在所有系统运行。
|
|
227
|
+
|
|
228
|
+
### 7.2 依赖闭包规则
|
|
229
|
+
|
|
230
|
+
1. 从用户选择的入口工作流出发,解析所有静态子工作流引用;检测缺失、重复 ID、越界路径与循环。
|
|
231
|
+
2. 收集各工作流引用的插件动作,以及这些插件显式声明的宿主插件依赖。如果导出时选择包含 Web 运行界面,将 Web 插件作为额外入口加入依赖闭包;没有选择则不携带它。业务插件仍只随实际依赖进入产物。
|
|
232
|
+
3. 从锁文件选出准确的插件版本,校验 SDK 兼容范围、动作存在性和平台声明;宿主插件之间的循环依赖首版直接拒绝。
|
|
233
|
+
4. 使用包管理器收集所需生产 npm 依赖,包括适用于目标平台的可选依赖;缺少必要 peer dependency 时打包失败。收集声明的 Python 脚本和资源,目标机 Python 与其他业务环境要求只写入清单。
|
|
234
|
+
5. 同一工作流和宿主插件去重;普通 npm 依赖保留包管理器合法的多版本树,不能仅按包名强行合并。
|
|
235
|
+
6. 加入运行时、CLI、声明的资源、许可信息和非敏感默认配置;移除开发依赖、缓存及包外链接。
|
|
236
|
+
7. 生成清单、文件校验值及目标平台要求,在目标环境通过冒烟验证后发布归档。
|
|
237
|
+
|
|
238
|
+
输入不足时打包失败,并显示依赖链及原因,例如“入口 A → 子流程 B → 插件 C 缺失”。不得静默漏包或在目标机器上临时联网补齐。
|
|
239
|
+
|
|
240
|
+
动态加载而未声明的资源和插件不属于可自动推断的依赖。插件作者应在元数据中声明,测试应验证包脱离源码与开发目录后仍可运行。
|
|
241
|
+
|
|
242
|
+
### 7.3 分发结构
|
|
243
|
+
|
|
244
|
+
```text
|
|
245
|
+
bundle/
|
|
246
|
+
run.cmd 或 run.sh
|
|
247
|
+
runtime/ # 当前目标的 Node.js
|
|
248
|
+
app/ # 编译后的 CLI、Host 与生产依赖
|
|
249
|
+
workflows/ # 选中入口及子工作流
|
|
250
|
+
config/ # 可分发的非敏感默认配置
|
|
251
|
+
manifest.json # 入口、版本、目标要求、文件校验值
|
|
252
|
+
licenses/ # 运行时及依赖的许可文件
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
插件代码及静态资源放在应用的实际依赖树内,清单记录其相对位置。Windows 使用 ZIP;Linux 使用 tar.gz,并保留启动器及运行时的执行权限。
|
|
256
|
+
|
|
257
|
+
运行包在任意目录解压后可启动,支持空格和中文路径。禁止指向开发机或包外缓存的绝对路径/符号链接;包内依赖链接须能在目标平台独立解析。
|
|
258
|
+
|
|
259
|
+
运行日志与业务输出使用可配置的外部目录。启动器必须通过自身位置定位随包 Node.js,不能依赖系统 `node` 命令或当前工作目录。
|
|
260
|
+
|
|
261
|
+
### 7.4 平台与外部依赖边界
|
|
262
|
+
|
|
263
|
+
- 首批目标:`win32-x64`、`linux-x64-glibc`。
|
|
264
|
+
- 插件接入层优先使用纯 JavaScript。原生扩展、外部可执行文件和动态库必须声明随包资源或目标机条件;随包资源未收齐时拒绝出包,目标机必需条件由环境检查插件在业务步骤前检查。构建机器上缺少目标业务环境不妨碍组装包,但不能据此宣称目标环境验证通过。
|
|
265
|
+
- Python 及第三方 Python 库只使用目标环境;首版不在运行时修改机器上的 Python、驱动或系统软件包。
|
|
266
|
+
- 包依赖目标系统内核及所选 Node.js 所需的基础系统库;不把整个操作系统打入归档。
|
|
267
|
+
- 每种目标先使用对应系统构建及验证,不承诺在 Windows 上一键交叉构建所有 Linux 原生依赖。目标 Python 库能否正常导入/使用由相应检查项验证,不能仅依据包版本号判定可用。
|
|
268
|
+
- Linux 容器需满足包的架构和基础库要求。典型用法是把包挂载到 `/opt/flow`,把日志/输出目录挂载到 `/work`,执行包内启动器。
|
|
269
|
+
- 配置文件可在运行时从包外传入;密钥不自动进入归档,也不写入默认日志。
|
|
270
|
+
|
|
271
|
+
## 8. Web、CLI 与日志(建议)
|
|
272
|
+
|
|
273
|
+
### 8.1 Web 的定位与取舍
|
|
274
|
+
|
|
275
|
+
| 方案 | 用户体验与收益 | 代价 |
|
|
276
|
+
| --- | --- | --- |
|
|
277
|
+
| Web 直接写入核心 | 标准入口统一,初期少一层插件边界 | 页面及服务器依赖难以从纯执行包中移除,核心承担更多界面变化 |
|
|
278
|
+
| 官方 Web 插件,标准发行默认提供(推荐) | 用户开箱获得界面;运行包可按需携带;与 CLI 共用能力 | 需要维护明确的应用服务接口 |
|
|
279
|
+
| Web 作为用户另找另装的可选扩展 | 基础发行最小 | 用户仍要先学 CLI/配置,不能直接满足当前交互目标 |
|
|
280
|
+
|
|
281
|
+
建议将 Web 作为产品首版的主要交互入口,以官方插件实现,并在标准发行版默认提供。其服务只在进入 Web 模式时启动;纯 CLI 运行无需加载页面和 HTTP 服务。插件化是实现边界,不应增加普通用户安装和配置界面的步骤。
|
|
282
|
+
|
|
283
|
+
Web 插件携带完整静态资源与轻量 HTTP 服务,使用现有 Host 和随包 Node.js,用户机器无需前端构建工具。浏览器通过它调用应用服务、接收运行状态与日志;字体、脚本、样式均不依赖 CDN。默认监听回环地址,支持堡垒机/SSH 端口转发;可显式配置监听地址。接口采用每次启动生成的访问令牌,防止暴露执行能力给未授权访问者;不建立多用户、账号或权限平台。浏览器请求使用相对 URL,转发端口变化不影响资源与 API。
|
|
284
|
+
|
|
285
|
+
页面首先围绕三个操作区组织:可用能力与已有工作流、当前有序步骤列表、所选步骤的输入输出与运行结果。保存、运行和导出使用同一份定义。已有工作流可以直接填写运行参数后执行,也可以加入另一流程作为步骤。
|
|
286
|
+
|
|
287
|
+
编辑器保留未保存草稿;点击运行时保存并使用确定的执行快照,运行期间的编辑不影响正在执行的步骤。运行和打包复用该校验后的保存定义。错误、日志和步骤结果都在列表的对应位置展示;失败语义与 CLI 一致。
|
|
288
|
+
|
|
289
|
+
工作流编辑保存到项目目录;导出的运行包提供列出入口、填写参数、运行及查看结果的界面,首版不要求在只读包内修改工作流或安装插件。导出 Web 包时包含相应页面资源与服务,实际启动行为按选择的运行模式执行。
|
|
290
|
+
|
|
291
|
+
### 8.2 CLI 与运行日志
|
|
292
|
+
|
|
293
|
+
首版命令面:`plugin add/list/remove`、`workflow list/check`、`run`、`pack`、`doctor`。`workflow check` 验证静态定义和依赖关系;`doctor` 检查编排器本身的平台及包完整性,复用运行/打包校验。Python/NPU 等业务环境由环境检查插件负责,CLI 内不重复实现。
|
|
294
|
+
|
|
295
|
+
若采用官方 Web 方案,增加 `web` 启动入口,并为标准发行版提供可直接启动界面的脚本。CLI 与 Web 共用应用服务,Web 不依赖解析 CLI 文本输出来调用功能。
|
|
296
|
+
|
|
297
|
+
控制台显示当前流程、步骤、结果与错误;每次运行生成独立 JSONL 事件文件,事件包含时间、级别、运行 ID、父子流程调用 ID、步骤 ID、插件动作及耗时。流程和步骤具有开始、成功、失败、取消事件。
|
|
298
|
+
|
|
299
|
+
日志默认记录状态与错误,不转储整个输入、配置或输出。业务插件负责避免主动记录敏感内容。大输出文件保留路径,运行结果保留必要的结构化摘要。
|
|
300
|
+
|
|
301
|
+
流程失败时输出完整调用路径,能够定位到“入口 → 子工作流 → 步骤 → 插件动作”。关闭终端后仍能通过事件文件检查已落盘的记录;首版不提供日志服务器。
|
|
302
|
+
|
|
303
|
+
## 9. 验收标准与需求追踪(建议)
|
|
304
|
+
|
|
305
|
+
A1—A12 验证核心框架,A13—A16 验证首款官方环境检查插件及 Python 示例工作流;A17—A20 是 Web 建议方案的验收项,随方案审阅确定。官方插件应作为公开 SDK 的实际使用者,借此检验第三方开发接口是否足够完整。硬件适配验证缺口记录在插件支持范围中,不等同于通用核心不能交付。
|
|
306
|
+
|
|
307
|
+
| 编号 | 用户需求 | 必须展示的结果 |
|
|
308
|
+
| --- | --- | --- |
|
|
309
|
+
| A1 | 插件顺序编排 | 两个独立示例插件的动作按声明顺序执行,后一动作可使用前一动作输出 |
|
|
310
|
+
| A2 | 子工作流与显式依赖 | 父子流程传参和返回值正确;缺失依赖、非法引用和循环在执行前报错 |
|
|
311
|
+
| A3 | 第三方插件接入 | 在核心仓库外创建并打包插件,按公开文档安装运行,不修改核心代码 |
|
|
312
|
+
| A4 | 选定工作流打包 | 项目包含 A、B、C,选择 A 只收集 A 的传递依赖;不收集无关 C;共享依赖只按合法版本树保留 |
|
|
313
|
+
| A5 | 编排器离线自包含 | 将包复制到无开发源码、无预装 Node.js/包管理器的断网环境,纯 JS 样例成功;未引用官方环境检查插件的包不包含或加载该插件 |
|
|
314
|
+
| A6 | Windows | 在 Windows 11 x64 干净环境验证解压启动,包含空格/中文路径与外部配置 |
|
|
315
|
+
| A7 | Linux | 在 Ubuntu 22.04 x64 glibc 干净环境运行同一套样例的 Linux 产物 |
|
|
316
|
+
| A8 | Docker 挂载 | 在 Debian 12 与 Ubuntu 24.04 的 Linux 容器中挂载同一 Linux 产物,只读挂载应用目录,向独立可写目录写日志和结果 |
|
|
317
|
+
| A9 | 错误与日志 | 构造子流程动作失败,后续步骤不执行,退出码为 1,日志能定位调用路径 |
|
|
318
|
+
| A10 | 配置 | 包外配置覆盖包内默认值,配置不匹配在相关动作执行前明确报错 |
|
|
319
|
+
| A11 | 轻量 | 记录最小样例的归档/解压体积、启动耗时和峰值内存;确认无运行期依赖安装与后台常驻服务 |
|
|
320
|
+
| A12 | 可复现依赖 | 清单记录所有准确版本、平台和文件校验值;依赖被修改或构建缺文件时验证失败 |
|
|
321
|
+
| A13 | Python 与 pip 检查 | 明确选择两个不同解释器分别检查;pip 结果与解释器一致;检查通过的解释器就是后续脚本使用的解释器 |
|
|
322
|
+
| A14 | Python 脚本执行 | JS 插件用目标机解释器调用包内 Python 脚本,参数、JSON 结果、stderr、异常退出与取消可被编排器正确处理 |
|
|
323
|
+
| A15 | 环境缺失阻止执行 | 必需的 Python、pip、库或 NPU 条件缺失/不兼容时,环境检查失败并生成报告,后续业务步骤不执行,不安装或替换目标环境 |
|
|
324
|
+
| A16 | 系统/NPU 探测 | 验证系统信息、工具缺失、权限不足、命令异常;NPU 可用场景必须有对应硬件/容器实测,模拟输出不能代替兼容性声明 |
|
|
325
|
+
| A17 | 无需编写配置即可编排 | 用户从能力目录添加动作和已有工作流,填表、排序、保存、运行,全程不编辑 YAML、JSON Schema 或依赖版本 |
|
|
326
|
+
| A18 | 输入输出可理解 | 通过选择器关联前序输出;删除或重排导致引用无效时定位提示;运行后查看每一步状态、实际输出和失败原因 |
|
|
327
|
+
| A19 | 两种入口行为一致 | Web 保存的工作流可直接由 CLI 运行;相同输入和环境下结果一致;运行时编辑不修改执行快照 |
|
|
328
|
+
| A20 | Web 按需分发 | 标准发行启动即有界面;分别导出带 Web 和纯 CLI 的包,验证两者运行同一工作流,纯 CLI 包不依赖 Web 插件 |
|
|
329
|
+
|
|
330
|
+
上述系统是验收目标,并非当前已验证的支持声明。需在最小运行时验证阶段核对所选 Node.js 的系统支持边界。更多 Windows/Linux 版本只有经过验证后才能列为正式支持。
|
|
331
|
+
|
|
332
|
+
验收以脱离开发目录的完整运行包为准。单元测试覆盖解析、依赖闭包、配置与顺序执行的错误分支;集成测试覆盖外部插件接入和自包含运行。相同锁文件需得到相同逻辑依赖与配置;首版不要求压缩文件字节完全一致。
|
|
333
|
+
|
|
334
|
+
## 10. 实施前的验证顺序与决策记录
|
|
335
|
+
|
|
336
|
+
这部分给出实施优先级,不替代逐任务的实施计划:
|
|
337
|
+
|
|
338
|
+
1. 验证最小 Cordis Host、纯 JS 示例插件、通用进程接口和随包 Node.js 在 Windows/Linux/容器中的运行,记录版本、基础库要求与体积基线。
|
|
339
|
+
2. 固定 SDK、统一工作流模型和应用服务接口,实现顺序执行、配置校验与日志闭环;普通用户的列表操作由接口转换为保存定义。
|
|
340
|
+
3. 打通仓库外插件开发安装流程,验证接口不依赖核心源码。
|
|
341
|
+
4. 实现按工作流求依赖闭包、目标平台出包,完成核心 A1—A12 验收。
|
|
342
|
+
5. 用公开 SDK 开发首款官方环境检查插件及 Python 示例流程,完成 A13—A16 验收;无 NPU 硬件时明确保留 A16 实机验证缺口,不宣称插件已支持该硬件。
|
|
343
|
+
6. 若采纳 Web 方案,用官方 Web 插件打通能力浏览、列表编排、输入输出选择、运行观察和导出,完成 A17—A20;首版产品交付包含这条普通用户操作路径。
|
|
344
|
+
|
|
345
|
+
| 决策 | 状态 | 依据 |
|
|
346
|
+
| --- | --- | --- |
|
|
347
|
+
| Cordis 作为插件运行框架 | 用户确认 | 用户指定参考 Cordis/DSH 的插件化方式 |
|
|
348
|
+
| 首版普通编排,无 LLM | 用户确认 | 用户明确首版范围 |
|
|
349
|
+
| 工作流显式调用插件和子工作流 | 用户确认 | 用户要求依赖可明确识别 |
|
|
350
|
+
| 选定工作流自包含打包 | 用户确认 | 用户明确打包选择及依赖要求 |
|
|
351
|
+
| Linux 包挂载进已有容器 | 用户确认 | 用户纠正镜像导入方案 |
|
|
352
|
+
| 常见平台优先,少数兼容后补 | 用户确认 | 用户要求轻量和覆盖大多数情况 |
|
|
353
|
+
| 可信同进程插件 | 用户接受参考方向 | 用户接受参考 DSH 安装运行模型 |
|
|
354
|
+
| Python 脚本与系统环境探测 | 用户新增重点 | 用户举例 Python/pip、NPU、系统内核 |
|
|
355
|
+
| 环境检查作为首款官方插件交付 | 用户明确定位 | 从核心能力清单移出,与第三方插件使用相同公开接口 |
|
|
356
|
+
| 使用目标机 Python,必需环境缺失即检查失败 | 用户确认 | 用户明确环境检查插件应发现并报告问题;移除携带 Python 的建议 |
|
|
357
|
+
| 能力目录、已有工作流、输入输出、有序步骤列表 | 用户明确交互目标 | 普通用户无需理解文件格式和版本依赖 |
|
|
358
|
+
| 官方 Web 插件作为标准发行默认提供的主要入口 | 用户接受 | 满足界面需求,同时保持核心与纯执行包轻量 |
|
|
359
|
+
| 离线 Web 与堡垒机访问 | 用户新增要求 | 资源随包提供,支持端口转发与显式监听地址 |
|
|
360
|
+
| TypeScript/JavaScript、分平台携带 Node.js | 建议默认值 | 当前无旧插件约束,优先跨平台和实现规模 |
|
|
361
|
+
| 顺序失败即停、无隐式重试 | 建议默认值 | 首版清晰的副作用与失败语义 |
|
|
362
|
+
| 自动保存工作流、自动管理依赖锁 | 建议默认值 | 界面生成显式引用;YAML/JSON Schema 保留为开发者实现细节 |
|
|
363
|
+
|
|
364
|
+
正式产品名称、首批业务插件功能不阻塞基础框架设计。准确依赖版本、最低系统版本和性能数字由验证结果确定,不能用猜测替代。
|
|
365
|
+
|
|
366
|
+
## 11. 开源参考与使用规则
|
|
367
|
+
|
|
368
|
+
- [DSH 插件管理器](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/boot/plugin-manager/README.md):参考显式安装和可信 Host 插件执行方式。
|
|
369
|
+
- [DSH 插件发布](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/publish.md):参考 npm 包、插件组合和安装流程。
|
|
370
|
+
- [Cordis](https://github.com/cordiverse/cordis):使用其插件与服务生命周期能力,具体 API 以锁定版本为准。
|
|
371
|
+
- [Node.js 发布周期](https://nodejs.org/en/about/previous-releases):实施时据此选择受支持的 LTS,再核对该版本的平台要求。
|
|
372
|
+
- [dsh-skill-manager 包定义](https://github.com/yanglaofish/dsh-skill-manager/blob/master/package.json):JavaScript 入口及 DSH 专有服务依赖;语言占比不表示插件能直接移植到任意 Cordis Host。该包使用 `@deepseek-ai/cordis`,实施前须明确本项目采用的 Cordis 发行包及 API,不默认不同发行包可互换。
|
|
373
|
+
- [Node.js 子进程](https://nodejs.org/api/child_process.html)、[系统信息](https://nodejs.org/api/os.html):JavaScript 插件调用外部程序和读取系统信息的基础能力。
|
|
374
|
+
- [pip inspect](https://pip.pypa.io/en/stable/cli/pip_inspect/):查询指定 Python 环境的软件包信息。
|
|
375
|
+
- [昇腾 NPU 管理工具](https://www.hiascend.com/doc_center/source/zh/HDK/2610/A3/A3npu/npusmia3_0003.html)、[昇腾容器说明](https://github.com/Ascend/cann-container-image/blob/main/OVERVIEW.zh.md):厂商工具、驱动和容器可见性的参考;具体适配须按目标硬件及版本验证。
|
|
376
|
+
|
|
377
|
+
上述资料用于参考设计,不意味着需要复制 DSH 的全部应用层。引入代码或依赖前应核对当前许可证、依赖范围和兼容性,保留需要随分发包附带的许可文件。用成熟组件解决包解析、参数解析和数据校验;工作流语义及打包闭包规则由本项目明确维护。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Cordis 服务与生命周期演进设计
|
|
2
|
+
|
|
3
|
+
日期:2026-10-10。状态:已实现并通过本地测试及便携包验证;远端 CI 见 `docs/verification.md`。本文件保留设计依据,公开接口用法以插件开发指南为准。
|
|
4
|
+
|
|
5
|
+
## 1. 用户意图和成功条件
|
|
6
|
+
|
|
7
|
+
Fishtools 将逐渐形成第三方插件生态。简单脚本插件应保持声明动作即可使用;复杂插件可以向其他插件提供连接、后台任务等长期能力。用户在 Windows/Linux 的 TUI、CLI、Web 继续使用同一套工作流和插件,工作流仍按列表顺序执行。
|
|
8
|
+
|
|
9
|
+
成功条件:共享服务不要求修改核心;服务依赖和资源关闭采用 Cordis 的能力;Fishtools 不维护第二套动态服务调度器;旧插件、现有流程、环境声明和分发格式继续可用。
|
|
10
|
+
|
|
11
|
+
## 2. 实施前代码审计(历史基线)
|
|
12
|
+
|
|
13
|
+
- `core/src/host.js` 使用 `Context`、`ctx.plugin()`、`scope.on('dispose')`、`ctx.start/stop()`。动作和服务工厂仍存放在宿主自己的 Map 中。
|
|
14
|
+
- `dependencies` 是插件包身份及版本范围校验,目前不表达某个运行时服务是否已就绪。
|
|
15
|
+
- `services.web` 是启动函数,调用时返回 Web 句柄;它不是一个由 Cordis 管理实例启动/停止的共享服务。
|
|
16
|
+
- CLI 和 TUI 各自关闭 Web 句柄;`application.close()` 只关闭运行及宿主,没有统一承担通过 API 启动的 Web 实例的关闭。
|
|
17
|
+
- 安装或保存配置会构建新宿主,再切换并关闭旧宿主。若直接把 Web 绑定旧宿主销毁,会在 Web 发起安装时中断管理入口;不能机械地添加 dispose 回调就宣称完成生命周期接入。
|
|
18
|
+
- 动作目录、Schema 校验、日志、工作流依赖闭包有明确产品含义,继续由 Fishtools 提供。
|
|
19
|
+
|
|
20
|
+
## 3. 方案比较和选择
|
|
21
|
+
|
|
22
|
+
| 方案 | 收益 | 代价与结论 |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| 保持当前轻量包装 | 改动最少 | 共享服务、资源关系仍需自建,不满足本次演进目标 |
|
|
25
|
+
| 保留声明式插件,增加可选 Cordis 扩展入口 | 普通插件保持简单;服务插件能使用框架生命周期 | 推荐,需要明确兼容、服务元数据及资源归属 |
|
|
26
|
+
| 所有插件立即改为原生 Cordis 插件 | 框架入口统一 | 破坏现有动作声明与开发体验,迁移范围过大;不采用 |
|
|
27
|
+
|
|
28
|
+
## 4. 职责划分
|
|
29
|
+
|
|
30
|
+
| 职责 | 负责方 |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| 运行时服务注册、依赖激活和作用域销毁 | Cordis |
|
|
33
|
+
| 动作/命令目录及其所属插件 | Fishtools,注册撤销绑定对应 Cordis 作用域 |
|
|
34
|
+
| 插件身份、SDK 与包依赖版本 | Fishtools 与 npm |
|
|
35
|
+
| 顺序编排、输入输出、取消、日志 | Fishtools |
|
|
36
|
+
| 平台与环境资源声明、打包闭包 | Fishtools;业务正确性由作者负责 |
|
|
37
|
+
| 共享能力的实现与外部资源关闭方法 | 插件作者;通过约定注册到受管生命周期 |
|
|
38
|
+
| TUI/Web 对服务状态的显示 | 应用服务提供可序列化状态,入口仅呈现 |
|
|
39
|
+
|
|
40
|
+
服务依赖不等于工作流步骤顺序,也不等于 npm 依赖安装。框架能撤销受管注册;作者绕过接口自行创建的进程或连接不会因此自动得到管理。
|
|
41
|
+
|
|
42
|
+
## 5. 接口演进建议
|
|
43
|
+
|
|
44
|
+
保留现有 `actions`、`commands`、`config`、`dependencies`、`environments`。建议增加可选 `runtime` 对象:`provides: string[]` 声明提供的服务名,`inject: string[]` 声明必需服务名,`apply(ctx, config)` 为 Cordis 初始化入口。两种列表缺省为空,`apply` 必须是函数;异步资源使用锁定版本的 ready/dispose 机制。该接口目前仍是设计提案,未进入可用 SDK。
|
|
45
|
+
|
|
46
|
+
- 普通插件不需要提供 `runtime`。
|
|
47
|
+
- 运行时服务的提供者必须能通过已有插件依赖声明纳入打包闭包;不依靠执行初始化函数发现打包依赖。
|
|
48
|
+
- 第一阶段要求每个服务名只有一个提供者;重复、缺失和循环依赖给出插件及服务的定位信息。
|
|
49
|
+
- Cordis 决定依赖激活关系;宿主读取其状态并转成应用可用的错误和状态,避免无限静默等待。
|
|
50
|
+
- 动作调用获得所属激活作用域下的服务访问入口;服务实例不进入 JSON 输入输出、日志或归档清单。
|
|
51
|
+
- 保留现有 `services` 启动函数协议作为兼容入口,不能直接把旧工厂当作已启动单例。
|
|
52
|
+
|
|
53
|
+
插件 ID/版本校验继续存在,它承担安装和分发契约,不能用 Cordis 的服务就绪判断替代。
|
|
54
|
+
|
|
55
|
+
## 6. 生命周期与更新约束
|
|
56
|
+
|
|
57
|
+
分两步实施,以避免资源管理与管理界面互相干扰:
|
|
58
|
+
|
|
59
|
+
1. **应用级实例归属。** 通过应用启动的 Web 句柄由稳定的应用生命周期持有;应用关闭会等待关闭完成,重复 close 安全。兼容 CLI/TUI 已有的显式关闭。业务插件宿主切换不隐式销毁仍在处理管理请求的 Web 实例;移除活动 Web 插件时拒绝并提示先停止 Web。Web 插件的替换在停止后进行。
|
|
60
|
+
2. **插件级运行时。** 插件初始化、依赖激活和动作/命令的注册归入 Cordis 作用域,资源清理可等待。使用锁定版本支持的生命周期机制处理异步初始化和关闭,不能假设 `ctx.effect()` 自动等待任意 Promise。
|
|
61
|
+
|
|
62
|
+
本阶段继续禁止运行期间安装/移除插件。普通声明式插件保留现有宿主切换行为;已激活有状态运行时插件时,涉及重建业务宿主的配置或插件修改先明确拒绝并要求停止后重启,不同时启动新旧连接去冒充事务切换。不中断业务的热替换单独设计。
|
|
63
|
+
|
|
64
|
+
实施补充:TUI `/plugins` 提供维护模式切换,CLI 支持 `--maintenance`。维护模式停止 runtime 插件后允许修改配置及安装;恢复时重新激活服务。每轮初始化与清理独立跟踪,旧调用不能访问后续激活的服务。
|
|
65
|
+
|
|
66
|
+
初始化失败必须让调用方得到错误,并释放本次已取得的受管资源;清理失败要报告,不能写成正常成功。外部副作用不承诺自动回滚。状态至少能区分尚未就绪、可用、失败和已停止,并能定位缺失服务。
|
|
67
|
+
|
|
68
|
+
## 7. 首个验证样例及验收
|
|
69
|
+
|
|
70
|
+
先使用没有外部系统依赖的“连接提供者 + 消费动作”测试插件验证机制;SSH/Kubernetes 不是这一阶段的实现前提。
|
|
71
|
+
|
|
72
|
+
- 旧动作插件、插件命令和现有 Web 调用兼容,原有测试持续通过。
|
|
73
|
+
- 服务提供者后加载时,消费者在服务就绪后才允许调用;调用不受插件列表排序影响。
|
|
74
|
+
- 缺失、重复服务、初始化失败、循环依赖能定位到声明;错误不被框架内部日志吞掉。
|
|
75
|
+
- 两个消费者共享同一受管实例;关闭后实例只清理一次,动作与命令不残留。
|
|
76
|
+
- 异步初始化和关闭的完成/失败可观察;取消后运行记录正常落盘。
|
|
77
|
+
- API 调用 `startWeb` 后只调用 `app.close` 也会释放端口;重复关闭不报无关错误。
|
|
78
|
+
- Web 发起普通插件安装后响应完整,管理入口继续可用;活动 Web 移除和有状态宿主更新按明确约束拒绝。
|
|
79
|
+
- 导出消费者工作流时自动带上已声明的服务提供者;无关插件不入包。
|
|
80
|
+
- 用本地测试、双平台 CI 及 Windows→Linux 便携包验证兼容性。
|
|
81
|
+
|
|
82
|
+
## 8. API 依据和设计边界
|
|
83
|
+
|
|
84
|
+
仓库当前锁定 `cordis@3.18.1`;实施依据为安装包的 `@cordisjs/core/README.md`、类型声明及实现,而非照抄其他 Cordis 分支的用法。已核对到 `Service`、`inject`、`effect`、异步 `ready/dispose` 等声明。
|
|
85
|
+
|
|
86
|
+
上游当前主分支明确提示 API 尚不稳定,且指向新的文档入口,因此本次不顺带升级框架。参考:[上游仓库](https://github.com/cordiverse/cordis)、[核心包说明](https://www.npmjs.com/package/@cordisjs/core)。
|
|
87
|
+
|
|
88
|
+
此次没有实现自动 Python 构建、LLM、远程调度、插件市场、源码监听热更新或多进程隔离。它们按路线图独立立项。
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Fishtools 分层分发与插件接入演进
|
|
2
|
+
|
|
3
|
+
## 已确认的目标
|
|
4
|
+
|
|
5
|
+
Windows/Linux 使用相同的 fst TUI、插件接口和工作流格式。完整便携版携带 Node、内部 npm 和工具生产依赖;工作流导出保留完整工具能力,仅筛选业务工作流及插件。默认支持修改并保存参数,显式 --read-only 保留旧式只读运行包。Python、驱动等业务环境按插件声明处理。
|
|
6
|
+
|
|
7
|
+
核心只验证接入契约、调用输入输出与资源收集是否成功。platforms / architectures 是作者声明,用于展示和打包提示,不能据此禁止加载、调用或导出;不静态判断业务代码跨平台是否正确,也不自动改写平台依赖。
|
|
8
|
+
|
|
9
|
+
## 三层与工作区
|
|
10
|
+
|
|
11
|
+
- runtime:目标平台 Node、内部 npm。复用固定校验的官方 Node 分发,保留许可证。
|
|
12
|
+
- app:同一份核心、打包服务、可选 Web 与所选插件及 npm 依赖。
|
|
13
|
+
- 工作区:工作流、插件配置、用户新增插件和运行结果。
|
|
14
|
+
|
|
15
|
+
新导出包原始内容维持完整性清单;首次启动把初始流程复制到独立可写工作区,以后不覆盖用户修改。默认 ~/.fishtools/workspaces/<包ID>,支持 --workspace / FISHTOOLS_WORKSPACE。只读 Docker 挂载时显式指定可写工作区。程序搬迁后刷新基包位置,配置和流程不丢失。旧格式运行包继续可运行。
|
|
16
|
+
|
|
17
|
+
## 插件契约
|
|
18
|
+
|
|
19
|
+
platforms、architectures 可选字符串数组,旧插件未声明时显示未声明。commands 字典的键是斜杠名称(不含 /),不可与核心命令重名;条目提供 description 及 action 或 run(二选一)。action 指向本插件已有动作;run 支持通过上下文 ui.input/select/show 进行交互。两者均使用宿主运行记录、取消信号和日志,TUI、CLI 共用入口;原子 CLI 调用交互命令时 ui 方法明确报需要 TUI。
|
|
20
|
+
|
|
21
|
+
environments 字典声明依赖:source 为 host / bundled / tool;可写 allowedSources,版本和 packages 为作者元数据,不由核心探测验证。host 的 executable 是目标机命令;tool 首版仅 node;bundled 的 artifacts[target] 指向包内目录及目录内 executable。依赖版本、Python 库和许可证由作者准备在该目录中,核心不下载未知运行时、不运行 pip、不复制开发机虚拟环境来猜兼容性。导出可覆盖作者允许的来源。打包只携带所选目标与来源的环境资源,提供字节数清单,禁止路径越界。动作可用 environments 字典附加自己的要求;每个被携带的插件保留完整能力,因此其全部动作所声明的环境均纳入计划。
|
|
22
|
+
|
|
23
|
+
调用上下文 environments 返回最终来源与可执行路径,插件使用它调用受管进程;宿主环境检查仍由环境检查插件/业务插件实现。插件平台声明不匹配只形成提示。用户显式声明的打包资源缺失是打包错误。
|
|
24
|
+
|
|
25
|
+
## 参数与统一交互
|
|
26
|
+
|
|
27
|
+
TUI 的 /steps 修改固定参数、/run 填本次输入;新增 /config 依照插件配置 schema 编辑并保存配置。不把调用时 --config 的秘密回写或带入导出。/ 插件命令菜单随安装/卸载刷新;冲突在切换插件宿主前报错,旧宿主保持可用。/pack 展示依赖来源、体积并可切换 allowedSources;CLI 提供等价 JSON 覆盖。
|
|
28
|
+
|
|
29
|
+
## 验收
|
|
30
|
+
|
|
31
|
+
自动测试覆盖声明不阻断平台、命令冲突与调用/取消、环境目录与 executable 越界、不同目标资源筛选、可编辑工作区与完整性互不干扰、内部 npm 不依赖 PATH。真实 Windows TUI 和断网 Linux 容器验证加载、运行、改参数保存、安装本地插件、斜杠调用、再次导出。依赖需联网获取时明确失败,离线插件由作者提供完整依赖。
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 运行诊断、可读日志与保留策略
|
|
2
|
+
|
|
3
|
+
## 已确认目标
|
|
4
|
+
|
|
5
|
+
- 日志用于定位插件 bug:明确插件、动作/命令、工作流步骤、原始错误原因和调用栈。
|
|
6
|
+
- 调用不存在的 Python 必须失败并记录;不承担作者吞掉错误后的业务正确性判断。
|
|
7
|
+
- 用户直接阅读 Markdown;TUI 必须内置查看,不能要求另开编辑器或 cat。
|
|
8
|
+
- 保留数量按整个项目合计计算,例如最近 10 次,超过后清理最早结束的记录。
|
|
9
|
+
|
|
10
|
+
## 实现边界
|
|
11
|
+
|
|
12
|
+
- run.md 面向阅读,事件发生时追加;events.jsonl 和 result.json 保留结构化记录。
|
|
13
|
+
- 成功步骤输出写入 Markdown 和结果快照;失败保留错误链,详情序列化失败不能覆盖原始错误。
|
|
14
|
+
- /logs 列出重启前后的历史,复用 Pi TUI Markdown 和 Overlay,方向键/翻页/Home/End,Esc 返回。
|
|
15
|
+
- 日志全文加载到阅读器内存,滚动复用排版缓存;不是大型日志文件的流式检索系统。
|
|
16
|
+
- logs.keepRuns 为正整数或 null,缺省不清理;TUI 设置可写入配置,导出保留设置。
|
|
17
|
+
- 清理只作用于本项目的已结束记录,保护运行中和未完成写入的记录;只删除三个日志文件,保留业务产物,不递归删除或跟随链接。
|
|
18
|
+
- 新记录包含项目目录归属;默认项目日志目录兼容旧记录,自定义共享输出目录不认领无归属旧记录。
|
|
19
|
+
- run.done 返回稳定完成快照,避免并发结束后日志清理影响 CLI/TUI 获取结果。
|
|
20
|
+
|
|
21
|
+
## 验证要点
|
|
22
|
+
|
|
23
|
+
- 缺解释器、Python 非零退出、正常单步输出、错误详情无法序列化。
|
|
24
|
+
- Markdown 执行中可读,正文反引号不会破坏围栏;长中文、窗口缩放与超过 6000 字的末尾可读。
|
|
25
|
+
- 12 次运行保留 10 次,保留业务文件;活动任务、目录链接、其他项目不被清理。
|
|
26
|
+
- 重启历史读取、旧记录 Markdown 回退、并发完成快照、Windows/WSL 真实 TUI。
|
|
27
|
+
|
|
28
|
+
构建、测试和 CI 结果归档于 docs/verification.md。
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 多插件执行摘要与用户输出
|
|
2
|
+
|
|
3
|
+
## 目标
|
|
4
|
+
|
|
5
|
+
同一工作流可以顺序调用不同插件,前一步的结构化输出绑定到后一步输入。默认主面板明确展示每一步的能力、所属插件、调用路径和执行状态,避免用户只能看到最终结果或被技术日志刷屏。
|
|
6
|
+
|
|
7
|
+
## 展示规则
|
|
8
|
+
|
|
9
|
+
- 默认折叠:显示步骤执行中、成功、失败、取消、跳过或停止状态。普通输入输出、作者 log、受管子进程 stdout/stderr 收入详情。
|
|
10
|
+
- 主面板 Ctrl+O 切换本次会话所有运行的摘要/详情,不提交或修改输入框草稿。详情可以翻页;管理菜单不清除运行内容。
|
|
11
|
+
- 执行失败直接展示错误摘要。嵌套失败传播不重复打印父节点与根运行的同一错误;完整错误链仍在详情和持久日志中。
|
|
12
|
+
- 插件 `await print(message,data?)` 表示面向用户的内容,折叠时仍实时展示;`await log(...)` 表示诊断内容。两者均落盘,print 在 log 事件上标记 `audience: user`,沿用现有订阅和日志保留机制。
|
|
13
|
+
- 不读取或生成所谓模型内部思考。未来 LLM 插件可用相同接口提供进度说明与诊断摘要。
|
|
14
|
+
|
|
15
|
+
## 插件契约
|
|
16
|
+
|
|
17
|
+
动作和交互命令获得相同的 print 能力。Python 等子进程默认写诊断日志;作者希望特定输出直接可见时,在 runProcess 的 onOutput 回调中调用 print。print 不直接写终端控制台,也不允许覆盖执行器固定的步骤归属。旧插件无需改动,仍完整记录 log 和返回值。
|
|
18
|
+
|
|
19
|
+
## 本地验收
|
|
20
|
+
|
|
21
|
+
`preview-pipeline` 调用三个不同插件:文本准备示例 → 基础示例转大写 → 报告保存示例。两个新增示例提供可安装目录和 MIT 许可证。文本与演示等待时间可修改,实际写出 report.txt,并通过 print 显示位置。既有试用工作流只在不存在时创建,不覆盖用户修改。
|
|
22
|
+
|
|
23
|
+
验证跨插件结果传递、运行中的状态变化、Ctrl+O 与输入草稿、折叠时错误和 print 的可见性、完整日志落盘,并验证 Windows/WSL 真实终端。仅交付本地试用,不发布。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# 条件控制、并行编排与运行观察
|
|
2
|
+
|
|
3
|
+
## 已确认目标
|
|
4
|
+
|
|
5
|
+
插件负责完成能力并返回符合声明的结果;正常返回表示执行成功,业务结果是否符合要求由工作流判断。提供可编排动作必须声明 input/output(无参数或无输出使用空对象 schema);业务检测返回 passed/ok/count 等结构化字段。判定预设可选,普通大小写转换无需重复声明“执行成功”。
|
|
6
|
+
|
|
7
|
+
用户在 TUI 与 Web 的列表中添加条件分支、并行组、提前结束,也可给步骤设置执行条件。运行中可在步骤总览、输入输出、实时日志间切换,按步骤调用路径区分同一插件的多次调用。支持键盘翻页和鼠标滚轮,离开观察页面不终止任务,停止操作显式取消。
|
|
8
|
+
|
|
9
|
+
## 控制流协议(兼容 schemaVersion: 1 的既有顺序步骤)
|
|
10
|
+
|
|
11
|
+
每个步骤有 id、可选 title、可选 when,以下五种执行目标必须恰有一种:
|
|
12
|
+
|
|
13
|
+
- `{action, with}`:调用插件。
|
|
14
|
+
- `{workflow, with}`:调用子工作流。
|
|
15
|
+
- `{branch: {condition, then: [步骤], else: [步骤]}}`:只执行命中的分支。
|
|
16
|
+
- `{parallel: {steps: [步骤], concurrency: 2}}`:并发执行独立子步骤;concurrency 为 1–32 整数,默认 4。
|
|
17
|
+
- `{stop: {reason: '环境不满足'}}`:正常提前结束整个顶层运行,状态 stopped,保留原因和之前的步骤事件。可以带 when 决定是否触发。
|
|
18
|
+
|
|
19
|
+
条件为 `{left: {$ref: 'steps.check.output.ok'}, op: 'eq', right: true}`;支持 eq/ne/gt/gte/lt/lte/contains/exists,以及 `{all:[条件]}`、`{any:[条件]}`、`{not:条件}`。严格按类型比较,不执行 JS。缺失字段在 exists 中为 false,其他比较也为 false;非法引用在执行前拒绝。when 为 false 记 step.skipped,不调用插件。
|
|
20
|
+
|
|
21
|
+
判定预设:动作上的 `conditions: {passed: {title:'检查通过', path:'ok', op:'eq', value:true}}`,path 相对于本动作输出,界面将其展开为条件节点。核心检查格式与已声明输出字段。检查插件增加独立 report 动作返回 ok:false;保留旧 check 动作失败即抛错以兼容旧工作流。
|
|
22
|
+
|
|
23
|
+
嵌套序列可读取外层已完成步骤及本层前序步骤;并行兄弟之间不可互相引用。节点 id 在同一工作流内唯一。分支/并行组输出为实际执行完成的子步骤 id → 输出对象,外部通过 `steps.group.output.child.field` 引用。跳过/未选中节点无输出;普通绑定读取缺失字段仍明确报错,作者可通过条件/分支避免读取。并行组必须等待所有启动任务清理完成;首个失败或提前结束会停止调度,取消已启动兄弟,保留首个原因。不保证回滚业务副作用。嵌套停止传播到顶层。
|
|
24
|
+
|
|
25
|
+
## 运行事件与界面合同
|
|
26
|
+
|
|
27
|
+
- 保留现有事件,增加 step.skipped、step.stopped、workflow.stopped、run.stopped。
|
|
28
|
+
- step.started 携带解析后的 input、action(如有)、callPath;事件以 callPath 归属步骤。
|
|
29
|
+
- runProcess 输出产生 `{type:'log', stream:'stdout'|'stderr', message, callPath, stepId}` 事件;仍返回 exitCode/stdout/stderr,保留超时、取消、进程树回收和输出上限。UTF-8 分块正确解码。
|
|
30
|
+
- app.getRun/readRun 返回 status、events、output/error、可选 reason;stopped 无 error。CLI stopped 正常退出并打印原因。
|
|
31
|
+
- TUI 新增 /runs,运行后打开可切换视图的观察面板;可关闭面板返回工作台,后台运行继续。/logs 保留已结束日志。滚轮仅在可滚动面板接管,并在关闭后恢复终端鼠标模式。
|
|
32
|
+
- Web 运行面板使用同一事件显示待执行/运行中/已跳过/成功/失败/停止;详情按调用路径过滤日志,滚动离开底部时暂停自动跟随。
|
|
33
|
+
- 所有条件与分组编辑提供表单,不要求手写 JSON/YAML;只读包允许观察和运行,不允许改流程。
|
|
34
|
+
|
|
35
|
+
## 验收与范围
|
|
36
|
+
|
|
37
|
+
覆盖条件分支、正常结束、并发上限、取消清理、嵌套依赖闭包导出、实时 stdout/stderr、鼠标与键盘浏览以及 TUI/Web 编辑保存再运行。Windows/Linux 保持一致。暂停恢复、持久化断点、多机分布式执行、自动回滚不在本次范围。
|