@yanglaofish/fishtools 0.2.0 → 0.4.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 +43 -17
- package/manual/README.md +43 -17
- 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/examples/script-plugin/LICENSE +21 -0
- package/manual/docs/examples/script-plugin/README.md +64 -0
- package/manual/docs/examples/script-plugin/index.js +39 -0
- package/manual/docs/examples/script-plugin/package.json +9 -0
- package/manual/docs/examples/script-plugin/scripts/benchmark.py +23 -0
- package/manual/docs/plugin-development.md +75 -14
- package/manual/docs/releases.md +30 -1
- package/manual/docs/research/2026-10-11-plugin-kernel-capabilities.md +167 -0
- package/manual/docs/roadmap.md +8 -1
- package/manual/docs/superpowers/plans/2026-10-11-control-observation.md +1 -1
- 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/plans/2026-10-12-plugin-developer-experience.md +50 -0
- package/manual/docs/superpowers/reviews/2026-10-12-plugin-release-review.md +20 -0
- package/manual/docs/superpowers/specs/2026-10-11-collapsed-plugin-output.md +23 -0
- package/manual/docs/superpowers/specs/2026-10-12-plugin-developer-experience.md +22 -0
- package/manual/docs/verification.md +100 -0
- package/manual/packages/core/src/application.js +235 -0
- package/manual/packages/core/src/engine.js +93 -0
- package/manual/packages/core/src/host.js +22 -5
- 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/tests/application.test.js +30 -0
- package/node_modules/@mytools/core/bin/fst.js +27 -5
- package/node_modules/@mytools/core/package.json +2 -0
- package/node_modules/@mytools/core/src/application.js +46 -21
- package/node_modules/@mytools/core/src/contracts.js +27 -9
- package/node_modules/@mytools/core/src/documentation.js +1 -1
- package/node_modules/@mytools/core/src/engine.js +1 -1
- package/node_modules/@mytools/core/src/environments.js +39 -1
- package/node_modules/@mytools/core/src/host.js +22 -5
- package/node_modules/@mytools/core/src/markdown-log.js +1 -1
- package/node_modules/@mytools/core/src/plugin-installations.js +84 -0
- package/node_modules/@mytools/core/src/plugin-tools.js +133 -0
- package/node_modules/@mytools/core/src/plugins.js +16 -6
- package/node_modules/@mytools/core/src/process.js +30 -8
- package/node_modules/@mytools/core/src/schema-path.js +31 -0
- package/node_modules/@mytools/core/src/terminal/model.js +1 -1
- package/node_modules/@mytools/core/src/terminal/navigation.js +17 -0
- package/node_modules/@mytools/core/src/terminal/presentation.js +3 -3
- 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 +30 -12
- package/node_modules/@mytools/core/src/terminal/session.js +118 -50
- package/node_modules/@mytools/core/src/terminal/theme.js +1 -0
- package/node_modules/@mytools/core/src/terminal/view.js +125 -28
- package/node_modules/@mytools/core/src/terminal/workflow-menu.js +50 -0
- package/node_modules/@mytools/core/src/validation.js +24 -9
- package/node_modules/@mytools/core/src/version.js +1 -1
- package/node_modules/@mytools/core/src/workflows.js +13 -15
- package/node_modules/@mytools/pack/dependencies.js +8 -1
- package/node_modules/@mytools/pack/index.js +4 -2
- package/node_modules/@mytools/web/public/THIRD_PARTY_NOTICES.txt +871 -870
- package/node_modules/{tar → minipass-flush/node_modules/minipass}/node_modules/yallist/README.md +7 -8
- package/node_modules/minipass-flush/node_modules/minipass/node_modules/yallist/package.json +29 -0
- package/node_modules/yallist/README.md +8 -7
- package/node_modules/yallist/package.json +51 -12
- package/package.json +15 -15
- package/node_modules/tar/node_modules/yallist/package.json +0 -68
- /package/node_modules/{yallist → minipass-flush/node_modules/minipass/node_modules/yallist}/LICENSE +0 -0
- /package/node_modules/{yallist → minipass-flush/node_modules/minipass/node_modules/yallist}/iterator.js +0 -0
- /package/node_modules/{yallist → minipass-flush/node_modules/minipass/node_modules/yallist}/yallist.js +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/LICENSE.md +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/index.js +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/index.js.map +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/commonjs/package.json +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/index.d.ts +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/index.js +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/index.js.map +0 -0
- /package/node_modules/{tar/node_modules/yallist → yallist}/dist/esm/package.json +0 -0
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
本文是 Fishtools 的公共插件接入规范,面向第三方开发者。普通动作插件与官方环境检查插件使用同一套契约;不要求依赖 Web 前端,也不要求开发者直接操作 Cordis。
|
|
4
4
|
|
|
5
|
+
`print()` 用户输出接口、主面板默认折叠和 Ctrl+O 展开从 0.3.0 起纳入发行包;0.2.0 不包含这些能力。
|
|
6
|
+
|
|
7
|
+
从 0.4.0 起包含下文的 `plugin create/validate/link/gc`、编码选项、插件状态目录和环境候选能力;0.3.0 不包含这些新增接口。源码试用时将 `fst` 替换为 `npm run fst --`。0.4.0 的输出校验停止补默认值,迁移说明见下文。发布结果见[版本记录](releases.md)。
|
|
8
|
+
|
|
5
9
|
## 从已安装的工具查阅规范
|
|
6
10
|
|
|
7
11
|
完整 npm 与便携发行包随附离线资料,包含本文、控制流规范、服务示例和可安装的[零依赖动作插件](examples/action-plugin/README.md)。无需克隆源码仓库:
|
|
@@ -16,7 +20,7 @@ fst docs --export ./fishtools-manual
|
|
|
16
20
|
|
|
17
21
|
`fst docs <主题>` 输出正文,`--path` 输出本地路径;`--export` 导出全部资料到新目录,已有目标会拒绝覆盖。资料按当前安装版本定位,不依赖当前工作目录,不启动插件或服务。TUI 中通过 `/docs` 选择主题,在内置阅读器查看。
|
|
18
22
|
|
|
19
|
-
导出目录保留相对链接,可离线浏览规范与示例。`plugins/`、`packages/`、`tests/` 中附带的源码仅供阅读,保留其 LICENSE;它们不是另一份可执行宿主或完整源码工作区。实际可安装示例位于 `docs/examples/action-plugin` 和 `examples/service-plugins`。内部 SDK 不承诺已作为独立公共 npm 包发布,首次开发可直接使用零依赖示例。
|
|
23
|
+
导出目录保留相对链接,可离线浏览规范与示例。`plugins/`、`packages/`、`tests/` 中附带的源码仅供阅读,保留其 LICENSE;它们不是另一份可执行宿主或完整源码工作区。实际可安装示例位于 `docs/examples/action-plugin`、`docs/examples/script-plugin` 和 `examples/service-plugins`。内部 SDK 不承诺已作为独立公共 npm 包发布,首次开发可直接使用零依赖示例。
|
|
20
24
|
|
|
21
25
|
## 0.2.0:条件控制与运行观察
|
|
22
26
|
|
|
@@ -35,7 +39,7 @@ fst docs --export ./fishtools-manual
|
|
|
35
39
|
|
|
36
40
|
| 约束 | 开发者要求 | 当前宿主检查 |
|
|
37
41
|
| --- | --- | --- |
|
|
38
|
-
| 标识与版本 | `id` 必须等于 npm 包名,`version` 必须等于包版本并使用 semver;升级时保持已有动作标识稳定 |
|
|
42
|
+
| 标识与版本 | `id` 必须等于 npm 包名,`version` 必须等于包版本并使用 semver;升级时保持已有动作标识稳定 | 宿主检查 ID 非空、重复和 SDK/依赖兼容性;`plugin validate` 比对包名/版本,开发引用也要求身份一致 |
|
|
39
43
|
| 能力元数据 | 每个公开动作必须提供清楚的 `title`、`description`、`input`、`output`、`run` | 检查 `run` 是函数;编排前检查 input/output schema;标题和描述的质量由作者负责 |
|
|
40
44
|
| 输入输出 | 显式提供有效的 JSON Schema,推荐对象形式声明类型、必填项、默认值和字段说明;无参数或无输出也要声明空对象 schema | 编排前校验 schema 声明,调用时用 Ajv 验证实际输入输出;返回值经过 JSON 序列化边界 |
|
|
41
45
|
| 判定预设 | `conditions` 提供标题、相对输出路径、比较符和值;不提供可执行判定函数 | 加载时检查格式、比较符、危险路径及已声明的输出字段 |
|
|
@@ -49,6 +53,10 @@ fst docs --export ./fishtools-manual
|
|
|
49
53
|
|
|
50
54
|
JSON 序列化可能丢弃对象中的 `undefined`、函数或 Symbol,并将非有限数字转为 `null`;不能把“能够序列化”当作完整的类型保证。请给输出写明确的 schema,不返回循环引用、BigInt、函数或依赖隐式转换的对象。
|
|
51
55
|
|
|
56
|
+
每份 schema 独立编译并缓存,`$id` 不会在不同插件或安装批次之间共享注册。插件升级可以保留相同 `$id` 并调整约束;定义内部的 `$ref` 正常解析,不支持隐式引用另一个插件曾注册的 schema。
|
|
57
|
+
|
|
58
|
+
输入与配置校验继续应用 `default`;动作和交互命令的输出校验只验证实际返回值,不补默认值。旧插件若依靠输出 schema 自动生成 `ok` 等字段,必须在 `run` 返回值中明确赋值。诊断消息和 `details[].jsonPointer` 提供完整 JSON 指针(如 `/benchmark_config/model_name`),`schemaPath` 标明约束位置;`required` 放在顶层时只能报告顶层缺失,不会猜测作者原本想放在哪个子对象。
|
|
59
|
+
|
|
52
60
|
无参数或无输出时,分别使用 `{type:'object', properties:{}, additionalProperties:false}`,动作返回 `{}`。JSON Schema 的布尔形式也受支持:`true` 接受任意值,`false` 拒绝所有值;为了生成字段表单与输出选择器,推荐明确声明对象和字段。缺省、`null`、数组、字符串和数值都不能代替 schema 声明。原有动作/子工作流的 `schemaVersion: 1` 格式保留;旧插件若要参与编排,需要补齐有效的 input/output 声明。正常返回且输出校验通过即执行成功,不要求返回额外的 `success:true`。
|
|
53
61
|
|
|
54
62
|
## 插件定义字段
|
|
@@ -121,10 +129,38 @@ fst plugin remove my-flow-plugin
|
|
|
121
129
|
|
|
122
130
|
也支持 npm 包标识或本地 `.tgz`;Web“插件管理”提供相同入口。本地路径以服务器所在机器为准。
|
|
123
131
|
|
|
132
|
+
`plugin add <本地目录>` 是复制安装,源文件修改不会自动反映到已安装副本;重复 `add` 即可更新,无需先 `remove`。开发时使用下述引用模式。安装、移除、开发引用和 CLI 配置命令自动在管理模式下运行,不启动 runtime 服务;常驻 TUI/Web 保持维护模式保护。
|
|
133
|
+
|
|
124
134
|
插件安装在 `.flow/installations/<随机安装批次ID>` 新目录,验证加载成功才切换状态,失败保留原配置。安装禁用 npm 生命周期脚本;TS 发布前编译,原生库及其目标平台资源由作者准备。核心不审核平台兼容性,也不自动重建原生库。工作流运行期间不能变更插件。
|
|
125
135
|
|
|
126
136
|
业务 npm 库写入 `package.json.dependencies`,开发库写入 `devDependencies`。插件间依赖另外写在定义的 `dependencies: {'other-plugin': '^1.0.0'}`,用于宿主版本检查和打包闭包;被依赖插件也需安装并注册。
|
|
127
137
|
|
|
138
|
+
### 创建、校验与开发引用
|
|
139
|
+
|
|
140
|
+
```sh
|
|
141
|
+
fst plugin create my-plugin ./my-plugin
|
|
142
|
+
fst plugin validate ./my-plugin
|
|
143
|
+
fst plugin validate ./my-plugin --json
|
|
144
|
+
fst --project ./test-project plugin link ./my-plugin
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
脚手架生成 ESM 包、嵌套输入动作、业务判定、`node:test`、README 和 MIT LICENSE,不依赖内部 SDK,拒绝覆盖已有目录。按实际支持范围调整平台和架构声明。
|
|
148
|
+
|
|
149
|
+
`validate` 检查包身份、SDK 范围、schema、动作/命令、条件和环境等声明,不安装依赖、不执行动作或 `runtime.apply`。它会导入模块,因此模块顶层代码会执行,只校验可信插件。错误返回退出码 1;警告不改变成功退出码。未声明平台/架构、当前平台不匹配、同层未声明的 required 字段给出警告。JSON Schema 允许开放字段,因此 required 的位置提示不自动判定 schema 无效。校验无法代替硬件和业务环境测试。
|
|
150
|
+
|
|
151
|
+
`link` 将源码绝对路径保存到当前工作区,不复制源码,不安装源码目录的 npm 依赖;需要依赖时先在插件目录自行安装。源码修改后退出并重新启动 fst,TUI/Web 随新宿主读取修改;当前进程的模块缓存不会热更新。工作区迁移后需要重新 link。正常 `add` 同名包可替换开发引用,`remove` 解除引用,不删除源码。分发收集源码的发布文件和生产依赖快照,不把开发路径链接带给最终用户。
|
|
152
|
+
|
|
153
|
+
### 安装批次清理与恢复
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
fst plugin gc
|
|
157
|
+
fst plugin gc --apply
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
默认只预览。执行清理会重新核对状态,并在 `.flow/installation-backups/` 创建每个候选批次的 `.tgz` 备份后删除该批次。当前批次、上一批次及活动宿主的租约批次保留;未知目录和链接不清理。`.flow/plugins.previous.json` 保存上一次成功切换前的状态。备份也占用空间,应在确认不再需要恢复后自行删除。
|
|
161
|
+
|
|
162
|
+
恢复时先退出该工作区所有 fst 进程,将对应备份解压回 `.flow/installations/`(归档自带批次子目录);需要退回上次插件列表时先另存当前 `plugins.json`,再用 `plugins.previous.json` 替换它。源码引用不包含源码副本,恢复前还需确保源码路径可访问。旧版 0.3.0 不登记租约,清理前必须退出旧版宿主。异常退出遗留 `.flow/plugin-mutation.lock` 时,确认没有活动修改进程再手工移除该空锁目录。
|
|
163
|
+
|
|
128
164
|
## 动作上下文
|
|
129
165
|
|
|
130
166
|
服务插件的 `runtime` 初始化和生命周期见本文末尾;普通动作插件无需添加此字段。
|
|
@@ -136,15 +172,30 @@ fst plugin remove my-flow-plugin
|
|
|
136
172
|
| `runId`、`stepId`、`callPath` | 运行和嵌套步骤定位 |
|
|
137
173
|
| `outputDir` | 本次运行的可写结果目录 |
|
|
138
174
|
| `resourceDir` | 插件包目录,用于定位脚本 |
|
|
175
|
+
| `projectDir` | 当前工作区根目录;可编辑便携包使用其包外工作区 |
|
|
176
|
+
| `stateDir` | 当前插件跨运行持久目录,与 outputDir 无关;只读项目或无应用的独立宿主为 undefined |
|
|
139
177
|
| `getService(name)` | 获取本插件 runtime.inject/provides 声明的已就绪服务;未声明或不可用时抛错 |
|
|
140
178
|
| `environments` | 按声明和来源选择解析的环境;包含解释器路径,随包环境另有资源根目录 |
|
|
141
179
|
| `runProcess(file,args,options)` | 通用进程调用,自动关联当前日志与取消信号 |
|
|
142
180
|
| `log(message,data,meta?)` | 写结构化日志并返回落盘 Promise;常规调用保持 `log(message,data)` |
|
|
181
|
+
| `print(message,data?)` | 面向用户输出,默认主面板直接显示;同样返回落盘 Promise |
|
|
143
182
|
|
|
144
183
|
返回值必须可 JSON 序列化,输入输出经 Ajv 校验。插件在宿主进程中执行,属于可信代码;同步阻塞代码不能被取消信号抢占。
|
|
145
184
|
|
|
185
|
+
可写应用在调用前创建 `.flow/plugin-state/<插件ID的SHA-256十六进制摘要>/`。固定长度目录避免 scoped 包名、Windows 大小写和长文件名问题;卸载不自动删除此目录,分发也不自动携带其中数据。插件自行处理原子写入、并发和数据版本。跨插件交换业务结果使用工作流输出或公开服务,不依赖其他插件的私有目录。只读精简包不创建持久状态,需要状态的插件应提示使用可编辑工作区。
|
|
186
|
+
|
|
187
|
+
`runProcess` 新增 `encoding`,默认 `utf8`,也可用 `utf16le`、`gbk` 等当前 Node TextDecoder 支持的编码;实时日志和返回文本采用同一编码,并正确处理跨块字符。示例:`runProcess('wsl',['-l','-v'],{encoding:'utf16le'})`,具体编码应以目标命令版本为准。Windows PowerShell 的编码和 CLIXML 是不同问题,宿主不自动猜编码或解析 CLIXML。输出上限仍按每个流的原始字节计量,默认 4 MiB;超限回收进程树并抛 `OUTPUT_LIMIT`,不返回伪装完整的截断结果。
|
|
188
|
+
|
|
189
|
+
主面板默认展示步骤状态,Ctrl+O 展开或收起各步输入输出和技术日志。普通 `log` 与子进程 stdout/stderr 默认折叠;失败摘要始终直接显示。希望用户直接看到的进度或结果,显式使用 `await print('报告已保存', {file})`。`print` 沿用日志通道,以 `type: 'log', audience: 'user'` 持久化,工作流中自动带上步骤归属。动作和交互命令都支持,不应直接用 `console.log` 向 TUI 打印。
|
|
190
|
+
|
|
191
|
+
若 Python 程序的部分输出需要直接展示,可使用 `runProcess(file, args, {onOutput: ({stream,message}) => stream === 'stdout' ? print(message) : undefined})`。回调按数据块触发;作者可先缓存成完整行再选择性 print。完整进程输出仍自动保存在诊断日志,print 的用户提示另外保留。写入 stderr 本身不等同执行失败,动作仍须按退出码决定抛错。
|
|
192
|
+
|
|
193
|
+
跨插件示例源码:[文本准备插件](examples/pipeline-reader/index.js)、[报告保存插件](examples/pipeline-writer/index.js)。它们与基础示例的转大写动作组成 `preview-pipeline`,通过前一步输出绑定下一步输入;每个目录都是独立插件包,可参考现有安装方法接入。
|
|
194
|
+
|
|
146
195
|
`runProcess` 默认无 Shell,参数用数组。支持 `cwd`、`env`、`signal`、`timeout`(默认 30 秒)、`maxBuffer`(stdout/stderr 各默认 4 MiB)和可选的 `onOutput({stream,message})`。普通非零退出返回 `{exitCode,stdout,stderr}`,动作应自行决定是否抛出业务错误;缺失程序、超时、取消、输出超限抛错,并等待进程树回收。不要把密码或令牌写入日志。
|
|
147
196
|
|
|
197
|
+
相对程序路径及 `PATH` 中的相对目录以传入的 `cwd` 为基准;未传 `cwd` 时使用宿主当前目录。例如 `runProcess('./tools/check', [], {cwd: resourceDir})` 调用插件资源目录内的工具,不改变其他并发动作的工作目录。
|
|
198
|
+
|
|
148
199
|
通过动作上下文调用时,stdout/stderr 在子进程执行期间自动产生 `type:'log'` 事件,`stream` 为 `stdout` 或 `stderr`,工作流事件保留 `stepId` 和 `callPath`。例如同一动作分别位于 `main/group/left`、`main/group/right`,日志按各自调用归属显示。写入 stderr 本身不会把运行改成失败。
|
|
149
200
|
|
|
150
201
|
输出按 UTF-8 解码,跨数据块的中文和 emoji 不会被拆坏;回调消息是流数据块,不保证一条消息就是一整行。可选 `onOutput` 在自动日志落盘后执行,不需要再手动 `log` 同一份输出。回调可以返回 Promise,`runProcess` 会等待;回调抛错或拒绝会终止受管进程并向调用方报告错误。完整 stdout/stderr 返回缓冲仍受输出上限约束。不要启动未等待的回调后台任务。
|
|
@@ -155,8 +206,8 @@ fst plugin remove my-flow-plugin
|
|
|
155
206
|
|
|
156
207
|
每次通过应用运行工作流或插件命令,都在 `.flow/runs/<runId>/` 写入 `run.md`、`events.jsonl` 与 `result.json`(指定 `--output` 时使用该目录;便携版写入可写工作区)。
|
|
157
208
|
|
|
158
|
-
- **运行中直接观察**:TUI
|
|
159
|
-
- **历史日志直接阅读**:TUI `/logs`
|
|
209
|
+
- **运行中直接观察**:TUI 主面板逐步更新状态,Ctrl+O 展开输入输出和诊断日志;`/logs` 可选择某次运行进入详细面板。Web 使用“查看运行”。按调用路径区分同一动作的不同调用。
|
|
210
|
+
- **历史日志直接阅读**:TUI `/logs` 选择记录后切换总览、输入输出和日志;方向键或鼠标滚轮滚动,PageUp/PageDown 翻页,Home/End 跳转,Esc 或 q 返回,Enter 查看步骤。重启后读取磁盘历史;run.md 也可用外部 Markdown 阅读器打开。
|
|
160
211
|
- **导出阅读内容**:`run.md` 按时间顺序展示步骤、作者日志、stdout/stderr、执行结果、失败原因、错误详情和调用栈,结束后附最终状态。它在执行过程中逐条追加,也可使用外部 Markdown 阅读器查看。调用栈保留原始换行。
|
|
161
212
|
|
|
162
213
|
- `events.jsonl` 按顺序记录启动、步骤成功/失败/跳过/停止、作者日志、进程流输出和运行结束。`step.started` 含解析后的 input;失败事件包含插件 ID、动作或命令、错误码、message,以及 `error` 中的 stack 和 cause 链。工作流还有 stepId、callPath、耗时。
|
|
@@ -259,7 +310,7 @@ outputs:
|
|
|
259
310
|
|
|
260
311
|
TUI `/add` 选择动作、子工作流、条件分支、并行组或提前结束;`/steps` 可进入分支/并行组编辑内部步骤,设置执行条件、并发数和结束原因。条件表单支持选择字段或预设,也支持且、或、取反。`/save` 保存后,Web 可继续编辑同一份工作流。
|
|
261
312
|
|
|
262
|
-
TUI `/run`
|
|
313
|
+
TUI `/run 工作流ID` 支持 ID 和中文标题补全,执行过程、步骤输入输出与最终结果留在主面板。运行期间可继续输入命令或配置工具;多次执行分别记录,PgUp/PgDn 或鼠标滚轮回看。F4 或 `/runs` 打开详细观察面板,`/logs` 直接查看某次运行的日志;包括跨重启保留下来的记录。
|
|
263
314
|
|
|
264
315
|
| 面板键位 | 行为 |
|
|
265
316
|
| --- | --- |
|
|
@@ -268,10 +319,12 @@ TUI `/run` 启动工作流后打开观察面板,`/runs` 可重新选择当前
|
|
|
268
319
|
| `a` | 切换本步骤日志与全部日志 |
|
|
269
320
|
| ↑↓、鼠标滚轮、PageUp/PageDown、Home | 滚动或跳到开头;手动滚动暂停日志跟随 |
|
|
270
321
|
| End / `f` | End 跳至尾部并恢复跟随;f 切换跟随状态 |
|
|
271
|
-
|
|
|
322
|
+
| Enter | 在总览查看所选步骤详情 |
|
|
323
|
+
| `j` | 切换可读字段与原始 JSON / 完整诊断 |
|
|
324
|
+
| Esc、q、Ctrl+C | 返回上一级,运行中任务继续 |
|
|
272
325
|
| `x`,再按 `y` | 确认取消整个运行;确认提示中其他键返回 |
|
|
273
326
|
|
|
274
|
-
关闭观察面板不等于退出应用。主提示符 `/exit` 或 Ctrl+C 遇到后台运行时,会提示退出将取消这些任务,默认不退出。普通参数输入和插件命令忙碌页仍使用原有 Ctrl+C
|
|
327
|
+
关闭观察面板不等于退出应用。主提示符 `/exit` 或 Ctrl+C 遇到后台运行时,会提示退出将取消这些任务,默认不退出。普通参数输入和插件命令忙碌页仍使用原有 Ctrl+C 取消行为。鼠标滚轮用于主面板和详细阅读面板;参数输入或菜单按各自的键盘提示操作,退出应用时恢复终端鼠标模式。
|
|
275
328
|
|
|
276
329
|
Web 通过“添加步骤 → 流程控制”添加分支、并行组或提前结束,点击节点填写条件、并发数、原因及内部步骤;普通步骤也可设置执行条件。保存后点击“运行工作流”,运行面板提供“步骤总览 / 输入输出 / 实时日志”和调用路径筛选。向上滚动日志会暂停跟随,可以点击“恢复自动跟随”继续查看尾部。关闭观察窗口后任务继续,顶部“查看运行”可重新打开;“停止运行”发送取消请求。只读运行包允许运行和观察,不允许修改流程。
|
|
277
330
|
|
|
@@ -302,16 +355,20 @@ async function run({executable, text}, {resourceDir, runProcess, signal}) {
|
|
|
302
355
|
{"my-flow-plugin":{"endpoint":"http://127.0.0.1:9000"}}
|
|
303
356
|
```
|
|
304
357
|
|
|
305
|
-
私有配置不默认入包,`defaultConfig` 只放公开默认值。TUI `/
|
|
358
|
+
私有配置不默认入包,`defaultConfig` 只放公开默认值。TUI `/plugin` → 选择插件 → 设置插件配置,根据 schema 编辑并保存;`/config` 专用于 Fishtools 自身设置。CLI `fst configure 插件ID 配置.json` 继续配置插件。调用时 `--config` 优先于工作区配置,不自动回写或导出。
|
|
306
359
|
|
|
307
360
|
## 平台声明与责任边界
|
|
308
361
|
|
|
309
|
-
插件可声明 `platforms: ['win32', 'linux']` 和 `architectures: ['x64', 'arm64']
|
|
362
|
+
插件可声明 `platforms: ['win32', 'linux']` 和 `architectures: ['x64', 'arm64']`;未声明的旧插件继续可用。声明由作者负责,核心不据此拒绝加载、调用或导出;CLI 启动、运行日志及导出计划都会提示对应的平台不匹配。核心检查接口、依赖收集与运行错误,不静态分析路径、系统 API,也不替开发者测试业务兼容性。
|
|
310
363
|
|
|
311
364
|
## 注册斜杠命令
|
|
312
365
|
|
|
313
366
|
`commands` 的键不含 `/`,推荐使用 `插件短名.操作名`;不得与核心入口或其他插件命令重名。安装/移除后 TUI `/` 菜单立即更新,失败的安装不会替换旧宿主。
|
|
314
367
|
|
|
368
|
+
TUI 顶层按插件归组:例如 ID `@mytools/examples` 对应 `/examples`,进入后选择具体能力,列表标明 `[插件]`、插件名称及 ID。入口取插件 ID 的末段;同名插件使用完整 ID 转为连字符名称,遇到保留名或已有命令则加 `plugin-` 前缀。以当前补全列表中的实际入口为准,不要在插件间依赖这个 UI 别名。只有注册了 `commands` 的插件才产生能力入口,纯服务/纯动作插件仍可在 `/plugin` 管理或参与工作流。原始命令名和 CLI `fst command` 协议不变,旧插件无需迁移定义。新保留入口包括 `plugin`、`tools`,作者应继续使用带插件前缀的命令名。
|
|
369
|
+
|
|
370
|
+
TUI 负责展示当前工作区、操作入口、菜单标题以及提交命令和操作结果。返回时只更新当前位置,不追加通用返回消息。插件使用 `ui.input/select/show/confirm`,不要自行清屏或打印终端控制序列,以免破坏主面板中的运行过程。导航记录仅保留在本次会话,持久诊断请使用动作上下文的日志接口。`/run` 执行已保存的工作流;工作流草稿只在编辑菜单明确选择“保存并运行”后才写入,不由插件命令隐式保存。
|
|
371
|
+
|
|
315
372
|
```js
|
|
316
373
|
commands: {
|
|
317
374
|
'demo.greet': { description: '生成问候', action: 'greet' },
|
|
@@ -340,7 +397,7 @@ environments: {
|
|
|
340
397
|
python: {
|
|
341
398
|
source: 'host',
|
|
342
399
|
allowedSources: ['host', 'bundled'],
|
|
343
|
-
executable: 'python3',
|
|
400
|
+
executable: ['python3', 'python'],
|
|
344
401
|
version: '>=3.11',
|
|
345
402
|
packages: { numpy: '2.x' },
|
|
346
403
|
artifacts: {
|
|
@@ -358,12 +415,14 @@ environments: {
|
|
|
358
415
|
```
|
|
359
416
|
|
|
360
417
|
- `host`:目标机器或容器内部提供;不携带 artifacts,也不自动检查/安装依赖。插件负责检查版本、库、设备和错误提示。
|
|
361
|
-
- `bundled`:作者提供完整、可迁移的目标环境目录(包括所需库与许可证),工具按目标收集;目录和 executable 均为使用 `/`
|
|
418
|
+
- `bundled`:作者提供完整、可迁移的目标环境目录(包括所需库与许可证),工具按目标收集;目录和 executable 均为使用 `/` 分隔的相对路径。默认采用 bundled 时必须声明非空 `artifacts`;静态校验检查各目标项的字段和包内路径,但不要求包含开发机平台。实际导出缺少所选资源或遇到目录循环时仍会报错。核心不自动下载 Python 或运行 pip。
|
|
362
419
|
- `tool`:首版只允许环境名 `node`,使用 Fishtools 自带的 Node。
|
|
363
420
|
- `version`、`packages` 为作者元数据;宿主不将它们当作已验证的事实。`allowedSources` 决定导出时可以切换哪些来源,缺省只能使用 source。
|
|
364
421
|
|
|
365
422
|
动作使用上下文 `environments.python.executable` 获得最终解释器路径,随包环境另有 `root`。继续通过 `runProcess(executable, args, {signal})` 调用。声明不会替换插件代码里自行写死的命令。
|
|
366
423
|
|
|
424
|
+
host 来源可声明有序候选数组,调用前按当前工作区和 PATH 选择第一个存在的程序,返回其绝对路径;不承诺该程序版本满足业务要求。单字符串声明继续透传。用户可在 `flow.project.json` 设置 `environments: {"插件ID": {"python": {"executable": "F:/miniconda/envs/example/python.exe"}}}`;显式覆盖只用于 host,找不到就报错,不回退到其他 Python。`source` 覆盖仍可单独使用。候选在目标机调用时解析,打包不会固化本机候选解析结果。
|
|
425
|
+
|
|
367
426
|
完整插件的所有动作和命令随插件保留,所以其动作声明的环境均参与计划。不同动作的同名环境可以有不同资源,但导出时同一个插件/环境名的来源覆盖统一生效;允许来源取交集。相同资源路径只复制一次,不自动合并不同 Python 环境或推断版本兼容性。
|
|
368
427
|
|
|
369
428
|
TUI `/pack` 选择来源并展示资源字节数;CLI 支持 `--plan` 和 `--environments 来源.json`:
|
|
@@ -386,7 +445,7 @@ TUI `/pack` 选择来源并展示资源字节数;CLI 支持 `--plan` 和 `--en
|
|
|
386
445
|
6. **部署检查**:导出包含该动作的工作流,在包外目录运行;验证路径中有空格和中文、包目录只读且结果目录可写的情况。声明支持 Windows 和 Linux 时,应分别实测;依赖设备或驱动的能力注明所需环境和未验证项。
|
|
387
446
|
7. **文档检查**:插件 README 写清支持平台、环境前提、配置示例、输入输出、错误行为、副作用、许可证与兼容范围。改变既有输入输出或行为时说明迁移方式并合理升级版本。
|
|
388
447
|
|
|
389
|
-
|
|
448
|
+
发布前先运行 `fst plugin validate <目录>`,再按平台声明逐项实际测试。仅适用 Linux 的 NPU 插件应明确声明 Linux;宿主对声明不匹配给出告警并记录到运行日志,继续允许执行。没有声明的旧插件继续兼容;不会根据描述中的 NPU、驱动等关键词猜测兼容性,也没有 `reject/allow/warn` 配置门禁。
|
|
390
449
|
|
|
391
450
|
## 参考实现与当前边界
|
|
392
451
|
|
|
@@ -395,8 +454,9 @@ TUI `/pack` 选择来源并展示资源字节数;CLI 支持 `--plan` 和 `--en
|
|
|
395
454
|
- [SDK](../packages/sdk/index.js):`definePlugin`、`FlowError` 与 SDK 版本。
|
|
396
455
|
- [宿主校验](../packages/core/src/host.js):加载、依赖、配置、动作输入输出和服务名检查。
|
|
397
456
|
- [外部插件接入测试](../tests/application.test.js):仓库外插件安装、运行与移除。
|
|
457
|
+
- [完整 Python 脚本插件](examples/script-plugin/README.md):嵌套输入、解释器候选、业务不通过、异常和条件预设。
|
|
398
458
|
|
|
399
|
-
|
|
459
|
+
当前源码提供 `plugin create`、`plugin validate`、开发引用和批次回收;没有单独的 `plugin lint`、运行中热重载、插件市场审核流程。SDK 尚未独立发布到公共 npm;独立插件使用普通 ESM 默认导出即可。
|
|
400
460
|
|
|
401
461
|
## Cordis 共享服务与生命周期
|
|
402
462
|
|
|
@@ -438,9 +498,10 @@ Fishtools 等待 `ctx.on('dispose', async () => ...)` 的清理完成并报告
|
|
|
438
498
|
### 维护与 Web 资源
|
|
439
499
|
|
|
440
500
|
- 有 runtime 插件时,安装、移除或修改插件配置会要求先进入维护模式,避免同时打开两套连接。
|
|
441
|
-
- TUI `/plugins` 可进入维护模式并恢复服务;CLI
|
|
501
|
+
- TUI `/plugins` 可进入维护模式并恢复服务;CLI 的 add/remove/link/configure 自动使用管理模式,也兼容显式 `--maintenance`。维护模式不持久化,默认重启恢复服务。
|
|
442
502
|
- 维护模式停止 runtime 插件的动作和命令,普通插件仍可使用;声明校验仍执行,不能借维护模式加载无效插件定义。
|
|
443
503
|
- 现有 `services.web` 仍为兼容的启动工厂;应用持有其返回的 close 句柄。`app.close()` 先关闭这些句柄,再关闭业务宿主,重复关闭安全。
|
|
504
|
+
- 打包选择包含 Web 时,按 `services.web` 声明选取实际提供者,连同其传递插件依赖一起导出,不要求官方包名。完整便携包关闭 Web 选项时,仅省略非必需的 Web 提供者;工作流或其他插件确实依赖它时仍保留。
|
|
444
505
|
- 活动 Web 提供者不能移除、替换或修改配置;TUI 插件管理可先停止 Web。普通插件更新不会关闭标准发行版中的 Web 管理入口。外部安装的 Web 提供者若被 npm 重新生成到新目录,也需先停止。
|
|
445
506
|
- 没有实现运行中无缝热替换。服务撤销后消费者动作/命令被撤销;恢复后按 Cordis 生命周期重新激活。
|
|
446
507
|
|
package/manual/docs/releases.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
产品名称 Fishtools,公共 npm 包名 `@yanglaofish/fishtools`,启动命令 `fst`。`0.x` 定位为早期可用版本。内部 `@mytools/*` 包随主包捆绑,不单独发布;内部插件 API 版本独立维护。
|
|
4
4
|
|
|
5
|
+
## 0.4.0 第三方插件开发体验
|
|
6
|
+
|
|
7
|
+
- 增加 `fst plugin create/validate/link/gc`:生成零依赖插件、离线检查声明、引用开发源码、预览并备份清理旧安装批次。源码修改后需重启宿主。
|
|
8
|
+
- schema 路径校验统一支持带类型的动态字段;错误给出完整 JSON 指针和约束位置。动作及命令输出只验证,不再填充默认值;输入和配置保留默认值。
|
|
9
|
+
- `runProcess` 支持显式编码并统一实时日志与返回文本。`host` 环境支持有序解释器候选及显式路径覆盖;显式路径不存在时不回退。
|
|
10
|
+
- 插件获得按工作区及 ID 隔离的 `stateDir`,平台不匹配给告警;独立 CLI 管理命令自动使用维护模式。新增可安装的 Python 脚本插件和中文开发说明。
|
|
11
|
+
|
|
12
|
+
升级时退出旧版宿主,再使用批次清理;旧版 0.3.0 不登记活动安装租约。若插件依赖输出 schema 的 `default`,请在动作返回值中明确填写对应字段。工作流格式和内部 SDK 版本不变;没有加入运行中热重载或平台强制拒绝策略。
|
|
13
|
+
|
|
14
|
+
用户已于 2026-10-12 授权审查、验证后推送和发布;是否发布完成以本版本 GitHub Release 与验收记录为准。
|
|
15
|
+
|
|
16
|
+
## 0.3.0 终端交互与插件输出
|
|
17
|
+
|
|
18
|
+
- 终端顶层按工作流、插件、工具和配置组织;命令历史保留未提交草稿,工作流编辑与执行互不覆盖。
|
|
19
|
+
- 主面板按步骤展示跨插件执行摘要;`Ctrl+O` 展开输入输出和诊断。插件可用 `print()` 发送用户可见内容,展开详情包含完整错误链。
|
|
20
|
+
- `/logs` 统一回看实时和历史运行;修复第三方插件进程调用、Web 依赖打包和 JSON Schema 升级。
|
|
21
|
+
- 离线手册补齐新增研究文档引用的源码,长日志刷新合并处理。
|
|
22
|
+
|
|
23
|
+
本版本沿用 0.2.0 的工作流格式与插件 API 版本;第三方插件可按需使用新增 `print()`。发布验收结果记录在下方及[验收记录](verification.md)。
|
|
24
|
+
|
|
5
25
|
## 0.2.0 控制流与运行观察
|
|
6
26
|
|
|
7
27
|
- 增加执行条件、条件分支、并行组、提前结束;TUI/Web 均可通过表单编辑嵌套步骤与参数引用。
|
|
@@ -16,6 +36,10 @@
|
|
|
16
36
|
|
|
17
37
|
## 发布入口
|
|
18
38
|
|
|
39
|
+
**发布前先完成本地试用并取得用户确认。** 自动化测试通过只代表具备试用条件,不代替用户对交互体验的验收。交付本地启动入口、说明改动及测试结果后,等待用户明确确认本轮可以发布,才创建版本 tag、发布 npm 或 GitHub Release。普通修复提交不触发发包。
|
|
40
|
+
|
|
41
|
+
`npm run preview` / 根目录 `fst-preview.cmd` 继续提供独立源码预览工作区;其运行不会修改全局安装或默认工作区。0.3.0 的对象菜单、主面板运行及公共插件修复已列入本次发布范围。
|
|
42
|
+
|
|
19
43
|
普通 push / PR 只验证代码。推送 `v版本号` tag 触发 `.github/workflows/release.yml`:
|
|
20
44
|
|
|
21
45
|
1. 检查 tag、根 package.json 和 CLI 版本一致。
|
|
@@ -51,7 +75,8 @@ git push origin v0.1.4
|
|
|
51
75
|
- Secret `NPM` 仅传入最后的发布步骤。需要有创建/发布 `@yanglaofish/fishtools` 的权限,以及 npm 自动发布要求的 Bypass 2FA 配置。缺失或权限不足时保留失败状态,修正 Secret 后重跑失败任务。
|
|
52
76
|
- npm 与 GitHub 不能进行同一个原子事务。若 npm 已成功、GitHub 暂时失败,使用 Actions 的 **Re-run failed jobs**;同版本归档 SHA-512 一致才跳过 npm 并继续 GitHub 发布。不同内容必须增加版本,不能覆盖。
|
|
53
77
|
- npm 首次发布可能先返回成功并提示正在处理,而注册表暂时仍返回 404。发布后会等待最多约 5 分钟再核对 SHA-512;若仍未可见,等待 `npm view @yanglaofish/fishtools@版本号` 能查询到后,再重跑失败任务,避免在处理阶段重复提交。
|
|
54
|
-
- GitHub Release
|
|
78
|
+
- GitHub Release 先创建草稿,附件齐备且 npm 可见后公开;重试可补齐草稿。已公开 Release 不自动覆盖附件。
|
|
79
|
+
- 若 npm 处理持续较久,可手动运行 `查询 npm 版本状态`(`npm-status.yml`)并填写版本。此工作流使用现有 Secret 只读查询官方生命周期接口,只记录状态字段,不输出凭据、不上传包。`validating` 表示仍在校验,需等注册表可见后再重跑发布。
|
|
55
80
|
- 也可使用 `gh workflow run release.yml --ref v0.1.3` 针对现有 tag 重新触发。由于完整重建可能产生不同归档,优先重跑失败任务,以复用原始已验证产物。
|
|
56
81
|
- 仓库当前为 private,Release 也沿用仓库访问权限;npm 包公开发布。未启用要求公开源码仓库的 npm provenance,不改变仓库可见性。
|
|
57
82
|
|
|
@@ -74,3 +99,7 @@ git push origin v0.1.4
|
|
|
74
99
|
`v0.1.3` 的 Windows/Linux 全量测试、自包含包执行和 Docker 验收全部通过。npm 于 2026-10-10 23:18(北京时间)接受 `@yanglaofish/fishtools@0.1.3`,首次发布后的处理延迟曾导致注册表返回 404。待注册表可见后重跑原发布任务,核对相同归档并跳过重复上传,于 23:24 完成 [GitHub Release](https://github.com/yanglaofish/Fishtools/releases/tag/v0.1.3),包含 npm、Windows、Linux 三个归档及 SHA256SUMS。[发布流程](https://github.com/yanglaofish/Fishtools/actions/runs/38062508265) 全部成功;后续发布脚本已增加有上限的注册表可见性等待。
|
|
75
100
|
|
|
76
101
|
首次发布时第三方 npm 镜像可能尚未同步归档。若遇到镜像 404,可指定官方源安装:`npm install -g @yanglaofish/fishtools --registry=https://registry.npmjs.org`。
|
|
102
|
+
|
|
103
|
+
## 0.2.0 发布结果
|
|
104
|
+
|
|
105
|
+
2026-10-11:双平台各 143 项测试、自包含归档与断网 Docker 验收通过。npm 接受上传后,生命周期状态为 `validating`,超过首次五分钟等待上限;注册表可见后核对相同 SHA-512,重跑原任务的失败步骤完成同步。当前官方注册表 `latest` 为 0.2.0,[发布流程](https://github.com/yanglaofish/Fishtools/actions/runs/38076094907)成功,[Release](https://github.com/yanglaofish/Fishtools/releases/tag/v0.2.0) 已包含全部三个归档和校验文件。
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# 插件内核公共能力研究:会话、执行、Hook 与授权
|
|
2
|
+
|
|
3
|
+
日期:2026-10-11。状态:研究与设计建议,**不是已实现的接口规范或发布承诺**。
|
|
4
|
+
|
|
5
|
+
Fishtools 核对基线:`838d572f0eff85f759b3c1118abb9dda616a4113`。
|
|
6
|
+
|
|
7
|
+
## 1. 来源与研究边界
|
|
8
|
+
|
|
9
|
+
- 用户提供的 [pengchengneo/Claude-Code](https://github.com/pengchengneo/Claude-Code) 自述为 npm source map 还原的非官方源码,README 声明源码版权归 Anthropic。查询时 GitHub 未识别到许可证;不能按 MIT 组件直接融合。
|
|
10
|
+
- 本次固定读取快照 `b78dd22a091b717c8938ab98c736bc04825a8ee8`。Git 克隆连接失败后,改用 GitHub API 读取关键文件;没有运行该仓库的脚本、依赖或二进制,没有把其代码复制进产品。
|
|
11
|
+
- 官方公开文档用于核对受支持的扩展机制;官方当前文档与还原快照不是同一版本,不能互相证明所有实现细节。
|
|
12
|
+
- 下文“建议”均为 Fishtools 的设计判断;具体 API 名称仍需设计确认。当前可用接口以 [插件开发规范](../plugin-development.md) 为准。
|
|
13
|
+
|
|
14
|
+
## 2. 值得借鉴的机制
|
|
15
|
+
|
|
16
|
+
| 观察到的机制 | 源码或官方证据 | 对 Fishtools 的意义 |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| 工具契约涵盖执行、输入输出、进度、权限与展示 | [Tool.ts](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/Tool.ts) | 插件动作除了能调用,还应能被统一展示、取消和审核;不把模型提示词、React 节点放进我们的通用动作契约 |
|
|
19
|
+
| 调用管线串起校验、前置 Hook、权限、执行及后置 Hook | [toolExecution.ts](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/services/tools/toolExecution.ts) | 工作流、斜杠命令与未来 Agent 调用同一能力时,应经过同一条受管调用路径 |
|
|
20
|
+
| 会话文件在首条用户/助手消息时才创建,之前缓存元数据 | [sessionStorage.ts](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/utils/sessionStorage.ts#L973) | 支持用户提出的空会话不落盘;Fishtools 的触发点应改为首次实质操作,不能照搬聊天消息标准 |
|
|
21
|
+
| 执行任务和观察界面有独立状态 | [task/framework.ts](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/utils/task/framework.ts) | 返回菜单不结束运行;日志、主面板及运行详情查看同一执行记录 |
|
|
22
|
+
| 权限有独立决策对象和交互组件 | [permissions.ts](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/utils/permissions/permissions.ts)、[PermissionRequest.tsx](https://github.com/pengchengneo/Claude-Code/blob/b78dd22a091b717c8938ab98c736bc04825a8ee8/src/components/permissions/PermissionRequest.tsx) | 判断结果不能只是一行文本;应有带请求 ID、操作范围、理由和有效期的决定,再由界面收集用户选择 |
|
|
23
|
+
| 官方 Mods 提供同进程 JavaScript/TypeScript 扩展 | [Mods overview](https://code.claude.com/docs/en/plugins/mods/overview) | 公开接口也能覆盖命令、界面和执行拦截;同进程扩展仍可直接访问宿主,不构成沙箱 |
|
|
24
|
+
| 官方事件接口区分观察、改写和接管,允许等待用户输入 | [React to events](https://code.claude.com/docs/en/plugins/mods/events) | 借鉴事件契约与异步交互;首版不必开放任意替换执行结果、自动重试或完整接管调用的能力 |
|
|
25
|
+
| 官方 API 将命令、工具和受管资源集中提供;界面文档区分多种状态生命周期 | [Mods API](https://code.claude.com/docs/en/plugins/mods/api)、[UI 与状态](https://code.claude.com/docs/en/plugins/mods/interface) | 分开运行临时数据、会话扩展状态和持久插件数据;由宿主管理交互焦点,避免插件互相抢占终端 |
|
|
26
|
+
|
|
27
|
+
该快照的权限界面仍有按内置工具对象选择组件的分支。Fishtools 应提供通用展示协议和默认渲染器,避免为第三方插件增加内核分支。源码中出现的隐藏特性不作为我们的产品目标。
|
|
28
|
+
|
|
29
|
+
## 3. 先明确四个对象
|
|
30
|
+
|
|
31
|
+
| 对象 | 定义 | 生命周期 |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| 工作区 Workspace | 工作流、插件配置、会话记录和结果的归属位置 | 跨启动保留;不是权限沙箱 |
|
|
34
|
+
| 会话 Session | 用户这一次连续工作的记录,可含多个工作流和直接插件调用 | 启动产生临时会话;有实际操作才保存;可从历史重新打开 |
|
|
35
|
+
| 执行 Run | 一次工作流或一次独立插件能力调用 | 有独立 ID、状态、输出和日志;固定归属启动它的会话 |
|
|
36
|
+
| 调用 Invocation | Run 内某一步插件调用或嵌套子调用 | 有调用路径、父调用、输入输出、进度及取消信号 |
|
|
37
|
+
|
|
38
|
+
由此确定入口分工:
|
|
39
|
+
|
|
40
|
+
- `/history`:查找、打开会话;恢复该会话主面板、执行记录和阅读位置。
|
|
41
|
+
- `/logs`:浏览当前会话内的执行,进一步查看某一步诊断。它是同一批记录的另一种视图。
|
|
42
|
+
- 主面板:按会话连续展示操作与执行摘要;配置菜单只是临时界面,不销毁运行过程。
|
|
43
|
+
- ↑↓:输入命令回溯,和会话历史是不同功能。
|
|
44
|
+
|
|
45
|
+
恢复历史不等于重跑工作流,也不等于恢复已经退出的 Python/Node 进程。LLM 插件可以恢复自己的对话状态;恢复何种模型上下文由该插件决定。
|
|
46
|
+
|
|
47
|
+
这也符合官方会话文档对“恢复记录”和“重新运行中断调用”的区分;具体保留策略仍由 Fishtools 自己定义。参见 [恢复会话的范围](https://code.claude.com/docs/en/sessions#what-a-resumed-session-restores)。
|
|
48
|
+
|
|
49
|
+
## 4. 公共能力清单与当前差距
|
|
50
|
+
|
|
51
|
+
“部分已有”只表示具备基础实现,不表示新接口已可调用。
|
|
52
|
+
|
|
53
|
+
| 公共能力 | 当前状态及证据 | 建议补齐的契约 |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| 插件加载、依赖、生命周期和共享服务 | 已有:[host.js](../../packages/core/src/host.js)、[runtime.js](../../packages/core/src/runtime.js) | 继续使用 Cordis;新增订阅、Hook、面板注册也跟随插件作用域注销 |
|
|
56
|
+
| 动作发现、调用与结果校验 | 已有 catalog、invoke、commands、input/output:[host.js](../../packages/core/src/host.js) | 稳定的第三方调用门面;身份和调用归属由内核赋值,统一经过 Hook/授权/日志 |
|
|
57
|
+
| 顺序、分支、并行、条件停止 | 已有:[engine.js](../../packages/core/src/engine.js) | 沿用现有控制节点和状态,不为 LLM 另造一套编排协议 |
|
|
58
|
+
| 会话与插件状态存储 | 尚无持久会话;[terminal/view.js](../../packages/core/src/terminal/view.js) 的命令历史在内存中 | 延迟落盘、会话索引、恢复、按插件命名空间存储数据和版本;工作区状态与会话状态分开 |
|
|
59
|
+
| 执行记录、日志和用户输出 | 已有 run、events、run.md、log/print:[application.js](../../packages/core/src/application.js)、[run-feed.js](../../packages/core/src/terminal/run-feed.js) | 统一事件版本与顺序号;进度更新、结果摘要、产物引用;历史与实时使用相同渲染输入 |
|
|
60
|
+
| 公共交互与界面扩展 | 插件交互命令已有 input/select/show/confirm:[terminal/session.js](../../packages/core/src/terminal/session.js) | 能力查询、结构化确认/表单/详情;由内核仲裁并发提问和焦点;动作与 Hook 可通过统一请求通道交互 |
|
|
61
|
+
| 执行 Hook | 仅有生命周期回调和运行事件订阅 | 注册前置决策与后置通知;过滤范围、超时、取消、顺序、异常归属和注销契约 |
|
|
62
|
+
| 授权请求、模式和审计 | 尚无统一机制 | 操作与资源范围声明、允许/拒绝/询问/无意见、用户规则与可选决策插件、真实 TUI 请求 |
|
|
63
|
+
| 受管进程与后台工作 | 已有 runProcess、取消/超时、stdout/stderr;运行可在主面板持续显示 | 给受管操作接入权限与调用归属;长期后台任务句柄随后按实际需要增加,不立刻建设新调度系统 |
|
|
64
|
+
| 分发和第三方开发支持 | 已有按工作流依赖打包、平台/环境声明、随包手册与示例 | 每项新契约同步类型、离线说明、仓库外插件示例和接入验收;不能只让内置插件使用 |
|
|
65
|
+
|
|
66
|
+
当前 [SDK](../../packages/sdk/index.js) 很小,且未作为独立公共 npm SDK 发布。不能把内部存在某个函数等同于第三方已经拥有稳定 API。
|
|
67
|
+
|
|
68
|
+
## 5. 会话、日志和持久化
|
|
69
|
+
|
|
70
|
+
以下是把已讨论方向落实为契约的建议:
|
|
71
|
+
|
|
72
|
+
1. `fst` 启动只产生内存中的临时会话。浏览帮助、插件列表、历史不会制造空记录;直接打开旧会话丢弃这个临时对象。
|
|
73
|
+
2. 第一次请求实际执行时,在可能发生副作用之前保存会话与请求。失败、取消和权限拒绝也有诊断意义。工作流保存/配置修改算作实质操作并记录摘要,是本次建议,仍需确认。
|
|
74
|
+
3. 每个运行在创建时固定 sessionId。用户之后切换历史页面,后台事件仍写回原会话,不能读一个可变的“当前会话”决定归属。
|
|
75
|
+
4. 会话记录引用其全部 Run;事件原始数据只保存一份,主面板、执行详情、Markdown 导出从中构建视图。保留 run.md 方便离线阅读,TUI 不直接展示原始 Markdown 标记。
|
|
76
|
+
5. 建议以整会话为日志保留单位,替代“整个项目最近 10 个 Run”。保留的会话不能被独立 Run 清理掏空;活动会话/执行不参加清理,业务产物仍不随日志自动删除。
|
|
77
|
+
6. 旧记录先兼容读取并标注“旧版执行记录”。迁移先备份、可回退,不在首次启动时直接删除旧文件;保留数量也不静默把 10 次解释成 10 个会话。
|
|
78
|
+
7. 序列化和追加写入是内部持久化方法,用户仍看可读内容。增量写入、崩溃后的末尾损坏处理、多个 fst 同时写入的锁/版本策略都需要明确。
|
|
79
|
+
8. 重启后未正常结束的本地执行显示“中断”,不伪装仍在执行。没有插件明确支持的恢复协议,就只恢复记录。
|
|
80
|
+
|
|
81
|
+
LLM 插件可以在自身会话命名空间保存消息、模型配置引用、压缩状态。内核只管理归属、读写、版本和清理,不解释 token 或提示词。敏感配置不应随日志和分发包无意传播;日志字段需提供显式隐藏/脱敏声明,不能宣称能识别所有任意文本中的秘密。
|
|
82
|
+
|
|
83
|
+
## 6. Hook 与权限需要分开
|
|
84
|
+
|
|
85
|
+
### 6.1 Hook 是执行扩展点
|
|
86
|
+
|
|
87
|
+
建议先有少量事件族:会话开始/恢复/结束;Run 开始/结束;动作执行前/成功/失败/取消;权限请求/决定。
|
|
88
|
+
|
|
89
|
+
- 通知 Hook 用于观察、统计、保存插件状态。异常需要记录,不能把已经成功的动作改成“没有执行”。
|
|
90
|
+
- 前置决策 Hook 可阻止或请求确认。声明为必要的决策 Hook 超时/失败时,该操作不能继续冒充已审核。
|
|
91
|
+
- 插件只能注册自己作用域内的 Hook,卸载自动注销;顺序固定并可诊断,不能依赖竞速最先返回的结果。
|
|
92
|
+
- 首版建议不开放任意输入改写/结果替换/自动重试。后续若支持改写,必须重新校验最终输入、重新评估权限并记录差异;后置 Hook 无法撤销已发生的副作用。
|
|
93
|
+
- 事件订阅只是观察通道;不能把目前 `application.subscribe` 更名成 Hook 就算完成执行拦截。
|
|
94
|
+
|
|
95
|
+
官方存在设置型 Hook 与同进程 Mods 两种机制;Fishtools 先做一种公共 JS 注册契约即可。运行脚本、HTTP 或 LLM 审核可通过插件实现,不必都进入内核。参见 [官方 Hooks](https://code.claude.com/docs/en/hooks) 与 [Mods 事件](https://code.claude.com/docs/en/plugins/mods/events)。
|
|
96
|
+
|
|
97
|
+
### 6.2 权限是受管操作的决策
|
|
98
|
+
|
|
99
|
+
建议的受管调用顺序:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
工作流 / 插件命令 / 第三方调用门面
|
|
103
|
+
→ 创建调用身份并记录请求
|
|
104
|
+
→ 校验输入
|
|
105
|
+
→ 执行前决策 Hook
|
|
106
|
+
→ 收集操作范围并进行权限决策
|
|
107
|
+
→ 需要时排队显示交互确认
|
|
108
|
+
→ 执行动作(受管子进程仍检查其具体操作)
|
|
109
|
+
→ 校验输出并记录成功/失败/取消
|
|
110
|
+
→ 后置通知
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
若前置 Hook 拒绝,也记录拒绝及来源,并走统一收尾。避免一个嵌套调用对相同、已授权范围重复弹窗,但新增路径/参数/目的地必须重新判断。
|
|
114
|
+
|
|
115
|
+
操作类别从文件读取、写入、删除、进程启动、网络访问等小集合起步;请求包含插件、动作、实际目标、参数、cwd 和目的。插件声明描述自己的操作,**不能据此给自己授予权限**。`rm -f` 只是某种命令表达,不能用几个字符串匹配代替所有删除请求。
|
|
116
|
+
|
|
117
|
+
规则裁决建议:用户明确拒绝优先;用户明确要求询问的操作不能被普通自动模式绕过;匹配允许范围后执行;其他请求按模式处理。可选审核插件必须由用户选择启用作为决策提供者,不能因安装了一个业务插件就让它审批其他插件。
|
|
118
|
+
|
|
119
|
+
| 建议模式 | 未命中明确规则时 | 无交互终端时 |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| 确认 | 展示 TUI 确认 | 返回需要授权的结构化结果,不等待 stdin |
|
|
122
|
+
| 自动 | 本地规则/用户启用的审核插件给出决定;无结论则询问 | 无法完成审批则拒绝此次操作并说明原因 |
|
|
123
|
+
| 宽松 | 自动允许普通受管请求;仍保留明确拒绝和必须询问规则 | 按用户明确选择的同一策略处理 |
|
|
124
|
+
|
|
125
|
+
这是 Fishtools 的候选语义,**不等同 Claude 的同名模式**。[官方权限模式](https://code.claude.com/docs/en/permission-modes) 用于比较,不逐项照搬。预览执行计划单独提供:显示已知步骤、条件、依赖和权限,未知运行值标记未知;不靠真实执行插件来“预览”。
|
|
126
|
+
|
|
127
|
+
确认界面应显示操作和范围,提供“允许本次 / 本会话允许此范围 / 拒绝”,以拒绝为安全默认;↑↓、Enter、Esc 可操作。会话授权不会无提示变为永久授权。每条请求有 ID;多步骤并行时由界面依次展示,后台输出继续记录。请求取消或用户切换权限模式后,旧审核结果不得批准已经失效的请求。恢复旧会话不静默恢复过去的宽松授权。
|
|
128
|
+
|
|
129
|
+
无沙箱的边界保持明确:以上约束公共调用路径。插件直接使用 Node fs、网络或 child_process 可以绕开受管接口。我们不因此限制用户安装谁的插件,也不声称能强制隔离任意插件代码。官方同进程 Mods 文档同样明确了宿主权限访问边界;这是架构条件,不是官方审核要求。
|
|
130
|
+
|
|
131
|
+
## 7. 展示与交互也必须是公共能力
|
|
132
|
+
|
|
133
|
+
建议沿用现有 `log` / `print`,补充以下语义而非让每个插件自己控制终端:
|
|
134
|
+
|
|
135
|
+
| 信息 | 默认展示 | 展开详情/持久化 |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| 动作状态 | 插件与能力名称、执行中/等待确认/结果、耗时 | 输入输出、调用路径 |
|
|
138
|
+
| 进度 | 更新同一条进度;无百分比时显示阶段 | 保留必要的阶段事件,避免每帧刷一条日志 |
|
|
139
|
+
| log、stdout/stderr | 折叠 | Ctrl+O / 执行详情查看、可滚动 |
|
|
140
|
+
| print | 直接显示,保持调用归属 | 同样可在历史重读 |
|
|
141
|
+
| 错误 | 直接显示原因和所属插件 | 堆栈、退出码、stderr、建议处理信息 |
|
|
142
|
+
| 产物 | 文件/报告名称和位置 | 结构化引用,和日志清理分开 |
|
|
143
|
+
|
|
144
|
+
声明式表单、选择、确认、结果字段、详情块是第一步;自定义面板/状态栏插槽可以后补。TUI/Web 各有适配器,CLI 无交互时返回明确结果。插件查询当前支持哪些交互,不导入内核私有组件,不直接抢 stdin 或清屏。
|
|
145
|
+
|
|
146
|
+
默认输出 schema 足以提供基本结果展示,复杂插件再注册可选展示元数据。不把“为每个插件写 React 渲染器”变成接入门槛。审批内容由宿主统一显示,业务插件不自行伪装内核授权面板。
|
|
147
|
+
|
|
148
|
+
## 8. 内核、插件与暂缓范围
|
|
149
|
+
|
|
150
|
+
**内核公共服务:** 插件注册与 Cordis 生命周期、动作契约、编排执行、会话/Run/事件归属、日志与产物引用、Hook 调度、权限决策机制、交互请求协议、打包闭包和手册。
|
|
151
|
+
|
|
152
|
+
**由插件实现:** 环境探测、Python 业务逻辑、LLM 模型与对话循环、LLM 审核提供者、MCP/外部 Agent 适配、SSH/Kubernetes 执行、具体报告和可选界面扩展。
|
|
153
|
+
|
|
154
|
+
**当前不扩张到:** 不可信代码沙箱、企业组织权限后台、多机内核调度、任意动作自动回滚、崩溃后继续旧进程、全能任意代码审计、复制 Claude 全套前端或隐藏功能。
|
|
155
|
+
|
|
156
|
+
继续复用已有 Cordis、pi-tui、Execa、Ajv。第三方源码组件仅在明确许可和实际需要下引入;这次研究不增加依赖、不换 UI 框架。
|
|
157
|
+
|
|
158
|
+
## 9. 建议实施顺序与验收
|
|
159
|
+
|
|
160
|
+
本节是下一阶段的候选目标,不覆盖已完成里程碑,也不表示用户已批准每个 API 细节。
|
|
161
|
+
|
|
162
|
+
1. **会话与记录统一。** 实现延迟落盘、history/logs 分工、主面板恢复、会话归属及保留策略。验收:空启动→恢复不产生新文件;一会话多个工作流;失败记录保留;重启阅读原位置;后台事件不串会话;旧日志有备份与迁移回退。
|
|
163
|
+
2. **公共展示与交互。** 补进度/产物/确认请求协议,所有第三方通过公共接口使用。验收:独立插件的 print、log、错误、进度在 Windows/WSL/无 Node 的便携 Linux 包中一致;切菜单不丢记录;并发提问不抢焦点。
|
|
164
|
+
3. **Hook 与权限闭环。** 在统一受管调用处接入前置决策、后置通知、授权和审计。验收:工作流/命令/外部调用行为一致;明确 deny 不被模式覆盖;更改目标重新审批;Hook 超时/取消和无 TTY 可预测;注销后不残留回调。
|
|
165
|
+
4. **第三方扩展验证。** 仓库外做业务插件和审核插件,再用一个最小 LLM/Agent 适配样例验证 catalog、调用、会话状态与交互是否足够。核心中不能出现对该插件 ID 的特殊判断。长期后台任务接口有真实需要时再扩展。
|
|
166
|
+
|
|
167
|
+
每阶段同步随包离线手册、类型说明和可安装示例;新方法只有在文档、实现和仓库外接入验收一致后才标记为可用。先本地 `fst-preview` 试用,用户确认后再讨论发布。
|
package/manual/docs/roadmap.md
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# Fishtools 路线图与当前状态
|
|
2
2
|
|
|
3
|
-
更新:2026-10-
|
|
3
|
+
更新:2026-10-12,第三方插件开发体验阶段。本文是当前状态入口;早期设计和实施计划保留历史背景,发生冲突时以最新明确决策及验收记录为准。
|
|
4
4
|
|
|
5
5
|
## 当前所处阶段
|
|
6
6
|
|
|
7
|
+
0.4.0 已纳入 GitHub #1/#2 的插件创建、校验、源码引用、批次回收、状态目录、环境候选及编码/契约修复,并进入发布验收。见[本轮规范](superpowers/specs/2026-10-12-plugin-developer-experience.md)、[实施计划](superpowers/plans/2026-10-12-plugin-developer-experience.md)与[验收记录](verification.md),发布结果以[版本记录](releases.md)为准。运行时热重载、长度条件、截断模式及平台拒绝策略留待后续。以下“本地试用”描述记录之前日志阶段的历史过程。
|
|
8
|
+
|
|
9
|
+
当前增量:TUI 日志阅读与导航修复,处于**本地试用、待用户体验确认**阶段。首页 F4 进入统一运行记录,支持多个工作流的多次执行;不使用 `/resume`,避免与未来 LLM 会话恢复混淆。实时与历史使用同一阅读面板,默认简洁结果/错误,完整诊断按需查看。试用方式见 README,用户确认前不发布新版本。
|
|
10
|
+
|
|
11
|
+
后续交互调整:`/workflows` 收纳新建、编辑、保存和可恢复删除;`/config` 配置工具,`/plugin` 管理插件及插件配置,插件名进入二级能力菜单。`/run` 补全工作流,执行过程留在主面板,多任务与配置操作共存;F4/日志页供详细回看。仍为本地试用,未发布。
|
|
12
|
+
|
|
7
13
|
既有版本已交付顺序编排、第三方插件安装、CLI/TUI/Web、日志和选定工作流自包含导出,随后加入完整便携工具、独立可写工作区、插件斜杠命令、环境声明、共享服务生命周期,以及 Markdown 诊断日志和按项目保留数量。各历史版本的测试和 CI 结果见验收记录。
|
|
8
14
|
|
|
9
15
|
0.2.0 源码已实现条件分支、步骤执行条件、受限并发、正常提前结束、stdout/stderr 实时日志,以及 TUI/Web 的控制节点编辑和运行观察。本地 Windows 全量 143 项测试、Windows 便携包、WSL 真实 TUI、浏览器及断网 Docker 验收已通过。远端 CI 与 npm/Release 状态见验收记录。
|
|
@@ -78,6 +84,7 @@ N1 的历史验收对应提交 `061f0e4`,[Windows / Ubuntu CI](https://github.
|
|
|
78
84
|
|
|
79
85
|
## 文档导航
|
|
80
86
|
|
|
87
|
+
- 待确认的公共内核演进研究(会话、日志、Hook、权限与界面,不代表已实现):[研究记录](research/2026-10-11-plugin-kernel-capabilities.md)
|
|
81
88
|
- 使用与安装:`../README.md`
|
|
82
89
|
- 插件当前可用接口:`plugin-development.md`
|
|
83
90
|
- 分发和工作区:`deployment.md`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# 公共插件契约缺陷修复计划
|
|
2
|
+
|
|
3
|
+
> 执行方式:使用 superpowers:executing-plans 逐项实施,先写失败回归,再修复。完成后独立审查。
|
|
4
|
+
|
|
5
|
+
**目标:** 修复核心审查确认的三项 P2,让第三方插件遵循公开契约完成进程调用、安装升级和 Web 打包。
|
|
6
|
+
|
|
7
|
+
**架构:** 保留现有公共接口。进程查找以调用 cwd 为基准;打包按服务声明选择 Web 提供者并计算依赖闭包;schema 编译隔离不同定义的注册表,保留按对象缓存。
|
|
8
|
+
|
|
9
|
+
**技术:** Node.js、which/execa、Ajv、node:test。
|
|
10
|
+
|
|
11
|
+
**依据:** docs/plugin-development.md,docs/verification.md 中核心公开接入审查记录,以及用户本轮明确修复要求。
|
|
12
|
+
|
|
13
|
+
## 约束
|
|
14
|
+
|
|
15
|
+
- 分支 fix/public-plugin-contracts;仅本地试用,不发布 npm/tag/Release。
|
|
16
|
+
- 不修改 history/logs 产品边界、不迁移用户数据;集成验证用独立临时目录。
|
|
17
|
+
- 官方和第三方 Web 提供者同等处理;未选中但被依赖的插件仍进入闭包。
|
|
18
|
+
|
|
19
|
+
## 任务与验收
|
|
20
|
+
|
|
21
|
+
1. `packages/core/src/process.js`、`tests/process.test.js`:先复现相对 executable 与 cwd 不一致;验证含空格目录、相对 PATH、绝对程序、缺失程序、取消和超时。修复只影响查找基准,不修改全局 cwd。
|
|
22
|
+
2. `packages/pack/index.js`、`tests/service-pack.test.js`:外部 Web 插件加传递依赖;验证选中 Web 导出、便携包含/不包含 Web、工作流确实依赖 Web 时保留;生成独立包并实际加载调用服务,缺失提供者仍给明确错误。
|
|
23
|
+
3. `packages/core/src/validation.js`、`tests/application.test.js`:真实安装带 $id 的配置插件、升级、安装无关插件及移除;验证新旧同 ID schema 不串用、嵌套本地 $ref 仍有效、无效值仍拒绝。
|
|
24
|
+
4. 跑相关回归及 Windows/WSL 验证,独立审查修复 diff;更新文档与验收记录,提交本地分支。
|
|
25
|
+
|
|
26
|
+
## 审查重点
|
|
27
|
+
|
|
28
|
+
- 相对路径按子进程 cwd 查找,不能通过 process.chdir 影响并发调用。
|
|
29
|
+
- 同一个 $id 在不同插件或升级前后可以有不同约束,不能复用旧版校验器。
|
|
30
|
+
- Web 提供者自身的插件依赖必须递归打包,不能只添加入口插件。
|
|
31
|
+
- includeWeb=false 不得剔除工作流或其他插件真正需要的依赖。
|
|
32
|
+
- 回归失败需来自业务断言,而不是缺少测试资源或语法错误。
|
|
33
|
+
|
|
34
|
+
## 执行记录
|
|
35
|
+
|
|
36
|
+
- [x] 三项核心缺陷的五项新增回归先失败后通过,专项 14/14。
|
|
37
|
+
- [x] 补查发现 TUI pack 同类官方 ID 残留;裁定将其纳入 Web 缺陷修复,避免只修后端。新增 TUI 测试复现 TypeError 后通过。
|
|
38
|
+
- [x] 全量 181/181;最后 TUI 与文档 66/66;增强外部导出运行、依赖保留及含空格 cwd 后,进程与服务打包 9/9。
|
|
39
|
+
- [x] WSL 插件安装升级及进程 12/12;增强后的进程 7/7。
|
|
40
|
+
- [x] 独立审查无 P1/P2;非阻断的两项覆盖建议均已补验。文档已同步,保持本地未发布。
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# TUI 命令层级与主面板运行记录实施计划
|
|
2
|
+
|
|
3
|
+
> 执行方式:当前任务内逐项实现,使用 superpowers:executing-plans 与测试先行。
|
|
4
|
+
|
|
5
|
+
**目标:** 按用户确认的对象层级组织操作,执行工作流后实时输入输出留在主面板,管理配置不丢失执行过程。
|
|
6
|
+
|
|
7
|
+
**设计依据:** `/config` 配置 Fishtools;`/workflows` 浏览、创建、进入编辑和删除;`/run 工作流ID` 补全并执行;`/pack` 打包;`/logs` 阅读日志;`/plugin` 管理插件;插件自己的入口进入二级能力菜单。工具操作可合并。一个会话有多次工作流执行。
|
|
8
|
+
|
|
9
|
+
**技术:** 继续使用 Cordis、Pi TUI、已有 YAML 工作流及运行记录,不新增依赖。Windows/Linux 一致。仅本地试用,未获本轮发布确认前不推送 tag/npm/Release。
|
|
10
|
+
|
|
11
|
+
## 实现边界
|
|
12
|
+
|
|
13
|
+
- `terminal/navigation.js`:顶层可发现命令、插件分组及入口生成,内置/插件来源标签。旧命令保留兼容执行,不出现在顶层补全。
|
|
14
|
+
- `terminal/workflow-menu.js`:工作流列表及编辑子菜单,复用已有字段编辑方法。
|
|
15
|
+
- `workflows.js`/`application.js`:删除前拒绝仍被其他流程引用的工作流,移入项目 `.flow/deleted-workflows` 备份目录;不删除执行产物。可从备份复制 YAML 回 workflows 恢复。
|
|
16
|
+
- `terminal/view.js`:主面板保留每次运行的事件与输入输出、滚动阅读;配置菜单不清除运行内容。详细日志继续复用 RunViewer。
|
|
17
|
+
- `terminal/session.js`:运行非阻塞返回主输入区;连接生命周期及退出时取消确认;工具配置与插件配置分开。
|
|
18
|
+
- 工具配置本轮提供已有日志保留设置与工作区信息,不虚构尚未实现的设置。
|
|
19
|
+
|
|
20
|
+
## 步骤与验收
|
|
21
|
+
|
|
22
|
+
- [x] 补失败测试:顶层命令与插件分组、/run 补全、配置归属。
|
|
23
|
+
- [x] 实现分层与工作流编辑菜单;补删除备份、引用保护、只读与取消测试。
|
|
24
|
+
- [x] 主面板追踪运行、跨菜单保留、并行多次执行和翻页;补终端尺寸与订阅清理测试。
|
|
25
|
+
- [x] 更新 README、插件规范及试用说明;专项测试和 Windows/WSL 真终端验收。
|
|
26
|
+
|
|
27
|
+
## 实施记录
|
|
28
|
+
|
|
29
|
+
- 主面板采用 RunFeed 独立模块保存会话事件;详细运行观察器继续复用。真实执行支持返回输入区后打开菜单或启动另一条工作流。
|
|
30
|
+
- 审查发现监听器累积与整段排列遮挡较早任务的新事件,已改为单个应用订阅和事件顺序追加;管理提示也进入相同顺序。每个缺陷先添加失败测试,再修复。
|
|
31
|
+
- 命令来源为内置/插件,工作流属于操作对象;为兼容已有用法,旧顶层编辑命令保留执行但隐藏默认补全。
|
|
32
|
+
- 保留源文件备份,仅在隔离试用工作区与临时测试目录进行验证;发布仍需用户后续确认。
|
|
33
|
+
|
|
34
|
+
## 重点检查
|
|
35
|
+
|
|
36
|
+
- 插件入口名称冲突、动态卸载后命令过期,旧直达命令的兼容性。
|
|
37
|
+
- 工作流编辑取消保留原内容,删除备份可恢复,嵌套子流程引用不能漏检。
|
|
38
|
+
- 运行期间打开配置不结束任务、不清空输出,重复运行可区分。
|
|
39
|
+
- 窄窗口主输入始终可见;普通文本误输入显示输入提示。
|
|
40
|
+
- 主面板滚动不误提交输入;退出清理订阅与终端鼠标模式。
|