@yanglaofish/fishtools 0.3.0 → 0.5.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.
Files changed (247) hide show
  1. package/README.md +33 -5
  2. package/bin/fst.js +1 -1
  3. package/manual/README.md +33 -5
  4. package/manual/docs/deployment.md +3 -3
  5. package/manual/docs/examples/script-plugin/LICENSE +21 -0
  6. package/manual/docs/examples/script-plugin/README.md +64 -0
  7. package/manual/docs/examples/script-plugin/index.js +39 -0
  8. package/manual/docs/examples/script-plugin/package.json +9 -0
  9. package/manual/docs/examples/script-plugin/scripts/benchmark.py +23 -0
  10. package/manual/docs/kernel-generation.md +97 -0
  11. package/manual/docs/modules.md +57 -0
  12. package/manual/docs/plugin-development.md +163 -12
  13. package/manual/docs/releases.md +23 -0
  14. package/manual/docs/research/2026-10-11-plugin-kernel-capabilities.md +6 -6
  15. package/manual/docs/roadmap.md +16 -3
  16. package/manual/docs/superpowers/plans/2026-10-09-workflow-mvp.md +5 -5
  17. package/manual/docs/superpowers/plans/2026-10-11-public-plugin-fixes.md +2 -2
  18. package/manual/docs/superpowers/plans/2026-10-12-kernel-generation.md +22 -0
  19. package/manual/docs/superpowers/plans/2026-10-12-modular-kernel.md +40 -0
  20. package/manual/docs/superpowers/plans/2026-10-12-plugin-developer-experience.md +50 -0
  21. package/manual/docs/superpowers/reviews/2026-10-12-kernel-generation-review.md +27 -0
  22. package/manual/docs/superpowers/reviews/2026-10-12-modular-kernel-review.md +32 -0
  23. package/manual/docs/superpowers/reviews/2026-10-12-plugin-release-review.md +20 -0
  24. package/manual/docs/superpowers/reviews/2026-10-13-kernel-runtime-release-review.md +19 -0
  25. package/manual/docs/superpowers/specs/2026-10-12-action-network-policy-design.md +52 -0
  26. package/manual/docs/superpowers/specs/2026-10-12-kernel-generation-design.md +38 -0
  27. package/manual/docs/superpowers/specs/2026-10-12-modular-kernel-design.md +70 -0
  28. package/manual/docs/superpowers/specs/2026-10-12-plugin-developer-experience.md +22 -0
  29. package/manual/docs/superpowers/specs/2026-10-12-plugin-readiness-design.md +21 -0
  30. package/manual/docs/superpowers/specs/2026-10-12-runtime-maintenance-granularity-design.md +35 -0
  31. package/manual/docs/superpowers/specs/2026-10-12-workflow-variation-design.md +19 -0
  32. package/manual/docs/verification.md +58 -1
  33. package/manual/packages/core/README.md +44 -0
  34. package/manual/packages/core/package.json +38 -0
  35. package/manual/packages/core/src/application.js +268 -87
  36. package/manual/packages/core/src/bundle.js +2 -0
  37. package/manual/packages/core/src/development-watch-worker.js +69 -0
  38. package/manual/packages/core/src/development.js +146 -0
  39. package/manual/packages/core/src/environments.js +2 -0
  40. package/manual/packages/core/src/export-snapshot.js +42 -0
  41. package/manual/packages/core/src/plugin-update.js +108 -0
  42. package/manual/packages/core/src/process.js +2 -0
  43. package/manual/packages/core/src/resources.js +31 -0
  44. package/manual/packages/core/src/version.js +2 -0
  45. package/manual/packages/fst-cli/LICENSE +21 -0
  46. package/manual/packages/fst-cli/README.md +54 -0
  47. package/manual/packages/fst-cli/bin/fst.js +124 -0
  48. package/manual/packages/fst-cli/package.json +49 -0
  49. package/manual/packages/fst-cli/src/development.js +53 -0
  50. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/model.js +1 -1
  51. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/navigation.js +1 -1
  52. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/presentation.js +9 -1
  53. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/run-feed.js +31 -5
  54. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/run-viewer.js +9 -7
  55. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/schema.js +1 -1
  56. package/manual/packages/{core → fst-cli}/src/terminal/session.js +137 -9
  57. package/manual/packages/{core → fst-cli}/src/terminal/view.js +20 -3
  58. package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/workflow-menu.js +17 -2
  59. package/manual/packages/fst-devtools/LICENSE +21 -0
  60. package/manual/packages/fst-devtools/README.md +28 -0
  61. package/manual/packages/fst-devtools/package.json +29 -0
  62. package/{node_modules/@mytools/core → manual/packages/fst-devtools}/src/documentation.js +3 -1
  63. package/manual/packages/fst-devtools/src/plugin-quality.js +136 -0
  64. package/manual/packages/fst-devtools/src/plugin-tools.js +152 -0
  65. package/manual/packages/fst-logs/LICENSE +21 -0
  66. package/manual/packages/fst-logs/README.md +56 -0
  67. package/manual/packages/fst-logs/package.json +24 -0
  68. package/manual/packages/fst-logs/src/log-bounds.js +91 -0
  69. package/manual/packages/fst-logs/src/run-logs.js +239 -0
  70. package/manual/packages/fst-platform/LICENSE +21 -0
  71. package/manual/packages/fst-platform/README.md +67 -0
  72. package/manual/packages/fst-platform/package.json +33 -0
  73. package/manual/packages/fst-platform/src/bundle.js +17 -0
  74. package/manual/packages/fst-platform/src/environments.js +67 -0
  75. package/manual/packages/fst-platform/src/file-probe-engine.js +183 -0
  76. package/manual/packages/fst-platform/src/file-probe-worker.js +43 -0
  77. package/manual/packages/fst-platform/src/file-probe.js +6 -0
  78. package/manual/packages/fst-platform/src/json.js +5 -0
  79. package/manual/packages/fst-platform/src/network.js +199 -0
  80. package/manual/packages/fst-platform/src/npm.js +11 -0
  81. package/manual/packages/fst-platform/src/process.js +110 -0
  82. package/manual/packages/fst-plugin/LICENSE +21 -0
  83. package/manual/packages/fst-plugin/README.md +29 -0
  84. package/manual/packages/fst-plugin/package.json +29 -0
  85. package/manual/packages/fst-plugin/src/contracts.js +86 -0
  86. package/manual/packages/fst-plugin/src/host.js +232 -0
  87. package/manual/packages/fst-plugin/src/loader.js +21 -0
  88. package/manual/packages/fst-plugin/src/privileges.js +91 -0
  89. package/manual/packages/{core → fst-plugin}/src/runtime.js +20 -4
  90. package/manual/packages/fst-workflow/LICENSE +21 -0
  91. package/manual/packages/fst-workflow/README.md +28 -0
  92. package/manual/packages/fst-workflow/package.json +24 -0
  93. package/{node_modules/@mytools/core → manual/packages/fst-workflow}/src/control.js +3 -2
  94. package/manual/packages/{core → fst-workflow}/src/engine.js +2 -2
  95. package/manual/packages/fst-workspace/LICENSE +21 -0
  96. package/manual/packages/fst-workspace/README.md +32 -0
  97. package/manual/packages/fst-workspace/package.json +34 -0
  98. package/{node_modules/@mytools/core → manual/packages/fst-workspace}/src/bundle-workspace.js +1 -1
  99. package/manual/packages/fst-workspace/src/index.js +3 -0
  100. package/manual/packages/fst-workspace/src/plugin-installations.js +84 -0
  101. package/manual/packages/fst-workspace/src/plugins.js +35 -0
  102. package/{node_modules/@mytools/core → manual/packages/fst-workspace}/src/workflows.js +41 -21
  103. package/manual/packages/pack/LICENSE +21 -0
  104. package/manual/packages/pack/README.md +31 -0
  105. package/manual/packages/pack/archive.js +15 -0
  106. package/manual/packages/pack/dependencies.js +105 -0
  107. package/manual/packages/pack/environments.js +50 -0
  108. package/manual/packages/pack/index.js +103 -0
  109. package/manual/packages/pack/package.json +29 -0
  110. package/manual/packages/pack/runtime.js +61 -0
  111. package/manual/packages/sdk/README.md +31 -0
  112. package/manual/packages/sdk/conditions.js +1 -0
  113. package/manual/packages/sdk/package.json +23 -1
  114. package/manual/packages/sdk/schema-path.js +31 -0
  115. package/{node_modules/@mytools/core/src → manual/packages/sdk}/validation.js +22 -9
  116. package/manual/plugins/web/README.md +29 -0
  117. package/manual/tests/application.test.js +6 -4
  118. package/node_modules/@mytools/core/README.md +44 -0
  119. package/node_modules/@mytools/core/package.json +17 -15
  120. package/node_modules/@mytools/core/src/application.js +268 -87
  121. package/node_modules/@mytools/core/src/bundle.js +2 -17
  122. package/node_modules/@mytools/core/src/development-watch-worker.js +69 -0
  123. package/node_modules/@mytools/core/src/development.js +146 -0
  124. package/node_modules/@mytools/core/src/environments.js +2 -29
  125. package/node_modules/@mytools/core/src/export-snapshot.js +42 -0
  126. package/node_modules/@mytools/core/src/plugin-update.js +108 -0
  127. package/node_modules/@mytools/core/src/process.js +2 -71
  128. package/node_modules/@mytools/core/src/version.js +1 -1
  129. package/node_modules/@mytools/fst-cli/LICENSE +21 -0
  130. package/node_modules/@mytools/fst-cli/README.md +54 -0
  131. package/node_modules/@mytools/fst-cli/bin/fst.js +124 -0
  132. package/node_modules/@mytools/fst-cli/package.json +49 -0
  133. package/node_modules/@mytools/fst-cli/src/cli-run.js +12 -0
  134. package/node_modules/@mytools/fst-cli/src/development.js +53 -0
  135. package/node_modules/@mytools/fst-cli/src/terminal/conditions.js +32 -0
  136. package/node_modules/@mytools/fst-cli/src/terminal/log-viewer.js +45 -0
  137. package/node_modules/@mytools/fst-cli/src/terminal/model.js +104 -0
  138. package/node_modules/@mytools/fst-cli/src/terminal/navigation.js +17 -0
  139. package/node_modules/@mytools/fst-cli/src/terminal/presentation.js +50 -0
  140. package/{manual/packages/core → node_modules/@mytools/fst-cli}/src/terminal/run-feed.js +31 -5
  141. package/node_modules/@mytools/fst-cli/src/terminal/run-presentation.js +60 -0
  142. package/node_modules/@mytools/fst-cli/src/terminal/run-viewer.js +106 -0
  143. package/node_modules/@mytools/fst-cli/src/terminal/schema.js +52 -0
  144. package/node_modules/@mytools/{core → fst-cli}/src/terminal/session.js +137 -9
  145. package/node_modules/@mytools/fst-cli/src/terminal/theme.js +29 -0
  146. package/node_modules/@mytools/{core → fst-cli}/src/terminal/view.js +20 -3
  147. package/node_modules/@mytools/fst-cli/src/terminal/workflow-menu.js +65 -0
  148. package/node_modules/@mytools/fst-devtools/LICENSE +21 -0
  149. package/node_modules/@mytools/fst-devtools/README.md +28 -0
  150. package/node_modules/@mytools/fst-devtools/package.json +29 -0
  151. package/node_modules/@mytools/fst-devtools/src/documentation.js +67 -0
  152. package/node_modules/@mytools/fst-devtools/src/plugin-quality.js +136 -0
  153. package/node_modules/@mytools/fst-devtools/src/plugin-tools.js +152 -0
  154. package/node_modules/@mytools/fst-logs/LICENSE +21 -0
  155. package/node_modules/@mytools/fst-logs/README.md +56 -0
  156. package/node_modules/@mytools/fst-logs/package.json +24 -0
  157. package/node_modules/@mytools/fst-logs/src/log-bounds.js +91 -0
  158. package/node_modules/@mytools/fst-logs/src/markdown-log.js +55 -0
  159. package/node_modules/@mytools/fst-logs/src/run-logs.js +239 -0
  160. package/node_modules/@mytools/fst-platform/LICENSE +21 -0
  161. package/node_modules/@mytools/fst-platform/README.md +67 -0
  162. package/node_modules/@mytools/fst-platform/package.json +33 -0
  163. package/node_modules/@mytools/fst-platform/src/bundle.js +17 -0
  164. package/node_modules/@mytools/fst-platform/src/environments.js +67 -0
  165. package/node_modules/@mytools/fst-platform/src/file-probe-engine.js +183 -0
  166. package/node_modules/@mytools/fst-platform/src/file-probe-worker.js +43 -0
  167. package/node_modules/@mytools/fst-platform/src/file-probe.js +6 -0
  168. package/node_modules/@mytools/fst-platform/src/json.js +5 -0
  169. package/node_modules/@mytools/fst-platform/src/network.js +199 -0
  170. package/node_modules/@mytools/fst-platform/src/npm.js +11 -0
  171. package/node_modules/@mytools/fst-platform/src/process.js +110 -0
  172. package/node_modules/@mytools/fst-plugin/LICENSE +21 -0
  173. package/node_modules/@mytools/fst-plugin/README.md +29 -0
  174. package/node_modules/@mytools/fst-plugin/package.json +29 -0
  175. package/node_modules/@mytools/fst-plugin/src/contracts.js +86 -0
  176. package/node_modules/@mytools/fst-plugin/src/host.js +232 -0
  177. package/node_modules/@mytools/fst-plugin/src/loader.js +21 -0
  178. package/node_modules/@mytools/fst-plugin/src/privileges.js +91 -0
  179. package/node_modules/@mytools/{core → fst-plugin}/src/runtime.js +20 -4
  180. package/node_modules/@mytools/fst-workflow/LICENSE +21 -0
  181. package/node_modules/@mytools/fst-workflow/README.md +28 -0
  182. package/node_modules/@mytools/fst-workflow/package.json +24 -0
  183. package/node_modules/@mytools/fst-workflow/src/control.js +64 -0
  184. package/node_modules/@mytools/{core → fst-workflow}/src/engine.js +2 -2
  185. package/node_modules/@mytools/fst-workspace/LICENSE +21 -0
  186. package/node_modules/@mytools/fst-workspace/README.md +32 -0
  187. package/node_modules/@mytools/fst-workspace/package.json +34 -0
  188. package/node_modules/@mytools/fst-workspace/src/bundle-workspace.js +39 -0
  189. package/node_modules/@mytools/fst-workspace/src/index.js +3 -0
  190. package/node_modules/@mytools/fst-workspace/src/plugin-installations.js +84 -0
  191. package/node_modules/@mytools/fst-workspace/src/plugins.js +35 -0
  192. package/node_modules/@mytools/fst-workspace/src/project.js +29 -0
  193. package/node_modules/@mytools/fst-workspace/src/workflows.js +150 -0
  194. package/node_modules/@mytools/fst-workspace/templates/control-demo.yaml +47 -0
  195. package/node_modules/@mytools/fst-workspace/templates/hello.yaml +35 -0
  196. package/node_modules/@mytools/fst-workspace/templates/python-check.yaml +26 -0
  197. package/node_modules/@mytools/fst-workspace/templates/system-check.yaml +11 -0
  198. package/node_modules/@mytools/pack/README.md +31 -0
  199. package/node_modules/@mytools/pack/dependencies.js +15 -3
  200. package/node_modules/@mytools/pack/environments.js +1 -1
  201. package/node_modules/@mytools/pack/index.js +33 -25
  202. package/node_modules/@mytools/pack/package.json +29 -1
  203. package/node_modules/@mytools/sdk/README.md +31 -0
  204. package/node_modules/@mytools/sdk/conditions.js +1 -0
  205. package/node_modules/@mytools/sdk/diagnostics.js +27 -0
  206. package/node_modules/@mytools/sdk/package.json +23 -1
  207. package/node_modules/@mytools/sdk/schema-path.js +31 -0
  208. package/node_modules/@mytools/sdk/validation.js +78 -0
  209. package/node_modules/@mytools/web/README.md +29 -0
  210. package/node_modules/@mytools/web/package.json +7 -0
  211. package/node_modules/@mytools/web/public/THIRD_PARTY_NOTICES.txt +1275 -1076
  212. package/node_modules/@mytools/web/public/assets/index-BaVzHycP.js +70 -0
  213. package/node_modules/@mytools/web/public/assets/index-DA8Ae92t.css +1 -0
  214. package/node_modules/@mytools/web/public/index.html +2 -2
  215. package/node_modules/@mytools/web/server.js +24 -17
  216. package/node_modules/@mytools/web/src/model.js +84 -0
  217. package/node_modules/acorn/CHANGELOG.md +1012 -0
  218. package/node_modules/acorn/LICENSE +21 -0
  219. package/node_modules/acorn/README.md +309 -0
  220. package/node_modules/acorn/bin/acorn +4 -0
  221. package/node_modules/acorn/dist/acorn.d.mts +897 -0
  222. package/node_modules/acorn/dist/acorn.d.ts +897 -0
  223. package/node_modules/acorn/dist/acorn.js +6370 -0
  224. package/node_modules/acorn/dist/acorn.mjs +6341 -0
  225. package/node_modules/acorn/dist/bin.js +90 -0
  226. package/node_modules/acorn/package.json +50 -0
  227. package/package.json +117 -101
  228. package/manual/packages/core/src/host.js +0 -124
  229. package/node_modules/@mytools/core/bin/fst.js +0 -70
  230. package/node_modules/@mytools/core/src/contracts.js +0 -41
  231. package/node_modules/@mytools/core/src/host.js +0 -124
  232. package/node_modules/@mytools/core/src/plugins.js +0 -55
  233. package/node_modules/@mytools/core/src/run-logs.js +0 -63
  234. package/node_modules/@mytools/web/public/assets/index-DT2B4tMV.js +0 -70
  235. package/node_modules/@mytools/web/public/assets/index-vuZvrUTT.css +0 -1
  236. /package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/cli-run.js +0 -0
  237. /package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/conditions.js +0 -0
  238. /package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/log-viewer.js +0 -0
  239. /package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/run-presentation.js +0 -0
  240. /package/{node_modules/@mytools/core → manual/packages/fst-cli}/src/terminal/theme.js +0 -0
  241. /package/{node_modules/@mytools/core → manual/packages/fst-logs}/src/markdown-log.js +0 -0
  242. /package/{node_modules/@mytools/core → manual/packages/fst-workspace}/src/project.js +0 -0
  243. /package/{node_modules/@mytools/core → manual/packages/fst-workspace}/templates/control-demo.yaml +0 -0
  244. /package/{node_modules/@mytools/core → manual/packages/fst-workspace}/templates/hello.yaml +0 -0
  245. /package/{node_modules/@mytools/core → manual/packages/fst-workspace}/templates/python-check.yaml +0 -0
  246. /package/{node_modules/@mytools/core → manual/packages/fst-workspace}/templates/system-check.yaml +0 -0
  247. /package/{node_modules/@mytools/core/src → manual/packages/sdk}/diagnostics.js +0 -0
@@ -0,0 +1,31 @@
1
+ # SDK模块
2
+
3
+ 包名:`@mytools/sdk`。内部 workspace 包,随 `@yanglaofish/fishtools` 统一交付。
4
+
5
+ ## 职责与边界
6
+
7
+ 插件定义、错误和共享 schema/条件契约。不承接宿主生命周期、磁盘持久化或界面行为。
8
+
9
+ 内部依赖:无。
10
+ ## 公开入口
11
+
12
+ | 导入路径 | 实现位置 |
13
+ | --- | --- |
14
+ | `@mytools/sdk` | `./index.js` |
15
+ | `@mytools/sdk/schema` | `./validation.js` |
16
+ | `@mytools/sdk/schema-path` | `./schema-path.js` |
17
+ | `@mytools/sdk/diagnostics` | `./diagnostics.js` |
18
+ | `@mytools/sdk/conditions` | `./conditions.js` |
19
+ | `@mytools/sdk/package.json` | `./package.json` |
20
+
21
+ 仅依赖 exports 声明的入口,禁止消费者跨包读取 src/bin 私有文件。入口路径由本模块维护,修改协议时同步消费方回归。
22
+
23
+ ## 维护与验证
24
+
25
+ 本模块负责上述职责的实现、文档与回归;跨模块接口调整需要同时检查生产者与消费者。具体维护人员尚未指定。
26
+
27
+ 在仓库根目录执行:
28
+
29
+ ```sh
30
+ node --test tests/modules.test.js tests/plugin-contract.test.js tests/schema-diagnostics.test.js
31
+ ```
@@ -0,0 +1 @@
1
+ export const conditionOperators=['eq','ne','gt','gte','lt','lte','contains','exists'];
@@ -1 +1,23 @@
1
- {"name":"@mytools/sdk","version":"0.1.0","type":"module","main":"index.js","exports":"./index.js","files":["index.js","README.md"],"license":"MIT"}
1
+ {
2
+ "name": "@mytools/sdk",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "index.js",
6
+ "exports": {
7
+ ".": "./index.js",
8
+ "./schema": "./validation.js",
9
+ "./schema-path": "./schema-path.js",
10
+ "./diagnostics": "./diagnostics.js",
11
+ "./conditions": "./conditions.js",
12
+ "./package.json": "./package.json"
13
+ },
14
+ "files": [
15
+ "*.js",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "ajv": "8.20.0"
22
+ }
23
+ }
@@ -0,0 +1,31 @@
1
+ import {FlowError} from '@mytools/sdk';
2
+
3
+ const forbidden=new Set(['__proto__','constructor','prototype']);
4
+ const missing=ref=>{throw new FlowError(`引用字段不存在:${ref}`,{code:'VALIDATION'});};
5
+
6
+ // 路径只用于已声明的字段;开放对象可继续引用,带类型的动态键则继续逐层检查。
7
+ export function resolveSchemaPath(schema,fields,ref=Array.isArray(fields)?fields.join('.'):fields){
8
+ const parts=Array.isArray(fields)?fields:typeof fields==='string'?fields.split('.'):[];
9
+ if(!parts.length)return schema;
10
+ if(parts.some(part=>typeof part!=='string'||!part||forbidden.has(part)))missing(ref);
11
+ let current=schema;
12
+ for(const field of parts){
13
+ if(current===true){continue;}
14
+ if(current===false||!current||typeof current!=='object'||Array.isArray(current))missing(ref);
15
+ const types=Array.isArray(current.type)?current.type:[current.type];
16
+ const isArray=types.includes('array')||current.items!==undefined;
17
+ if(isArray){
18
+ if(!/^(0|[1-9]\d*)$/.test(field))missing(ref);
19
+ if(Array.isArray(current.items))current=current.items[Number(field)]??current.additionalItems??true;
20
+ else current=current.items??true;
21
+ continue;
22
+ }
23
+ if(current.properties&&Object.hasOwn(current.properties,field)){
24
+ current=current.properties[field];continue;
25
+ }
26
+ if(!types.includes('object')&&types.some(type=>type!==undefined))missing(ref);
27
+ current=current.additionalProperties??true;
28
+ }
29
+ if(current===false)missing(ref);
30
+ return current;
31
+ }
@@ -1,29 +1,42 @@
1
1
  import Ajv from 'ajv';
2
2
  import { FlowError } from '@mytools/sdk';
3
3
 
4
- const ajv = new Ajv({ allErrors: true, strict: false, useDefaults: true });
5
- const validators = new WeakMap();
6
- const booleanValidators = new Map();
4
+ const ajv = new Ajv({ allErrors: true, strict: false });
5
+ const validators = {true:new WeakMap(),false:new WeakMap()};
6
+ const booleanValidators = {true:new Map(),false:new Map()};
7
7
  export const emptyObject = { type: 'object', properties: {}, additionalProperties: false };
8
8
 
9
- export function assertSchema(schema,label) {
9
+ export function assertSchema(schema,label,{useDefaults=true}={}) {
10
10
  if (!(typeof schema==='boolean'||schema&&typeof schema==='object'&&!Array.isArray(schema))) throw new FlowError(`${label} 必须声明有效的 JSON Schema`,{code:'VALIDATION'});
11
- const cache=typeof schema==='boolean'?booleanValidators:validators;
11
+ const cache=(typeof schema==='boolean'?booleanValidators:validators)[Boolean(useDefaults)];
12
12
  let check=cache.get(schema);
13
13
  if(!check){
14
14
  // 每份定义独立解析 $id/$ref,避免插件重载或不同插件共用 ID 时串用约束。
15
15
  // 编译结果仍按对象缓存;注册表随校验器释放,不污染后续安装批次。
16
- try{check=new Ajv({allErrors:true,strict:false,useDefaults:true}).compile(schema);cache.set(schema,check);}
16
+ try{check=new Ajv({allErrors:true,strict:false,useDefaults:Boolean(useDefaults)}).compile(schema);cache.set(schema,check);}
17
17
  catch(cause){throw new FlowError(`${label} JSON Schema 无效:${cause.message}`,{code:'VALIDATION',cause});}
18
18
  }
19
19
  return check;
20
20
  }
21
21
 
22
- export function validate(schema, value, label) {
22
+ const pointerToken=value=>String(value).replaceAll('~','~0').replaceAll('/','~1');
23
+ function diagnostic(error){
24
+ let instancePath=error.instancePath;
25
+ if(error.keyword==='required')instancePath+=`/${pointerToken(error.params.missingProperty)}`;
26
+ if(error.keyword==='additionalProperties')instancePath+=`/${pointerToken(error.params.additionalProperty)}`;
27
+ // 保留 Ajv 原有 instancePath 语义,新字段提供指向缺失/额外属性的完整位置。
28
+ return {...error,jsonPointer:instancePath};
29
+ }
30
+
31
+ export function validate(schema, value, label,{useDefaults=true}={}) {
23
32
  if (schema==null) return structuredClone(value);
24
- const check = assertSchema(schema,label);
33
+ const check = assertSchema(schema,label,{useDefaults});
25
34
  const copy = structuredClone(value);
26
- if (!check(copy)) throw new FlowError(`${label}: ${ajv.errorsText(check.errors, { separator: ';' })}`, { code: 'VALIDATION', details: check.errors });
35
+ if (!check(copy)) {
36
+ const details=check.errors.map(diagnostic);
37
+ const locations=details.map(error=>`${error.jsonPointer||'/'} (${error.schemaPath})`).join(';');
38
+ throw new FlowError(`${label}: ${ajv.errorsText(check.errors, { separator: ';' })};位置 ${locations}`, { code: 'VALIDATION', details });
39
+ }
27
40
  return copy;
28
41
  }
29
42
 
@@ -0,0 +1,29 @@
1
+ # Web模块
2
+
3
+ 包名:`@mytools/web`。内部 workspace 包,随 `@yanglaofish/fishtools` 统一交付。
4
+
5
+ ## 职责与边界
6
+
7
+ 官方 Web 插件、HTTP 服务、前端交互及模型投影。通过服务工厂参数获得应用接口,前端构建产物仍在本包 public 中。
8
+
9
+ 内部依赖:`@mytools/sdk`。
10
+ ## 公开入口
11
+
12
+ | 导入路径 | 实现位置 |
13
+ | --- | --- |
14
+ | `@mytools/web` | `./index.js` |
15
+ | `@mytools/web/server` | `./server.js` |
16
+ | `@mytools/web/model` | `./src/model.js` |
17
+ | `@mytools/web/package.json` | `./package.json` |
18
+
19
+ 仅依赖 exports 声明的入口,禁止消费者跨包读取 src/bin 私有文件。入口路径由本模块维护,修改协议时同步消费方回归。
20
+
21
+ ## 维护与验证
22
+
23
+ 本模块负责上述职责的实现、文档与回归;跨模块接口调整需要同时检查生产者与消费者。具体维护人员尚未指定。
24
+
25
+ 在仓库根目录执行:
26
+
27
+ ```sh
28
+ node --test tests/modules.test.js tests/web.test.js tests/web-control.test.js
29
+ ```
@@ -2,9 +2,9 @@ import test from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { mkdir, writeFile, readFile } from 'node:fs/promises';
4
4
  import path from 'node:path';
5
- import { createApplication } from '../packages/core/src/application.js';
5
+ import { createApplication } from '@mytools/core';
6
6
  import { temporary, testPlugin, object } from './helpers.js';
7
- import {validate} from '../packages/core/src/validation.js';
7
+ import {validate} from '@mytools/sdk/schema';
8
8
 
9
9
  test('同 ID schema 隔离编译,保留内嵌引用且不串用旧约束',()=>{
10
10
  const schema=type=>({$id:'https://fishtools.test/review/config',type:'object',definitions:{value:{type}},properties:{value:{$ref:'#/definitions/value'}},required:['value']});
@@ -47,7 +47,8 @@ test('运行快照独立于之后保存,状态与日志持久化',async t=>{
47
47
  assert.deepEqual(app.getRun(run.id).output,{text:'HELLO'});
48
48
  const events=(await readFile(path.join(app.outputDir,run.id,'events.jsonl'),'utf8')).trim().split('\n').map(JSON.parse);
49
49
  assert.ok(events.some(e=>e.type==='run.succeeded'));
50
- assert.ok(!events.some(e=>Object.hasOwn(e,'output')));
50
+ assert.deepEqual(events.find(e=>e.type==='run.result').output,{text:'HELLO'});
51
+ assert.deepEqual(events.find(e=>e.type==='step.succeeded').output,{text:'HELLO'});
51
52
  });
52
53
 
53
54
  test('仓库外本地插件可以安装、加载并执行,移除后目录同步',async t=>{
@@ -61,7 +62,8 @@ test('仓库外本地插件可以安装、加载并执行,移除后目录同
61
62
  await app.saveWorkflow({id:'external',schemaVersion:1,inputs:object(),steps:[{id:'hello',action:'external-flow-test:hello',with:{}}],outputs:{answer:{$ref:'steps.hello.output.value'}}});
62
63
  const run=await app.startRun('external',{});await run.done;
63
64
  assert.deepEqual(app.getRun(run.id).output,{answer:42});
64
- await app.removePlugin('external-flow-test');
65
+ await assert.rejects(app.removePlugin('external-flow-test'),error=>error.code==='PLUGIN_IN_USE'&&error.details.workflows[0].id==='external');
66
+ await app.removePlugin('external-flow-test',{force:true});
65
67
  assert.ok(!app.catalog().some(a=>a.id==='external-flow-test:hello'));
66
68
  });
67
69
 
@@ -0,0 +1,44 @@
1
+ # 应用内核模块
2
+
3
+ 包名:`@mytools/core`。内部 workspace 包,随 `@yanglaofish/fishtools` 统一交付。
4
+
5
+ ## 职责与边界
6
+
7
+ 组合各能力模块、协调运行与关闭、提供 CLI/Web 共用应用接口及导出声明快照。日志写入和缓存由 logs 负责;导出实现通过可选 pack 依赖加载。
8
+
9
+ 内部依赖:`@mytools/sdk`、`@mytools/fst-platform`、`@mytools/fst-logs`、`@mytools/fst-workflow`、`@mytools/fst-plugin`、`@mytools/fst-workspace`、`@mytools/pack`。
10
+ `@mytools/pack` 是可选 peer 依赖;普通发行包含它,只读发行省略它。既有 `/process`、`/bundle`、`/environments` 子入口保留兼容转发。
11
+
12
+ ## 公开入口
13
+
14
+ | 导入路径 | 实现位置 |
15
+ | --- | --- |
16
+ | `@mytools/core` | `./src/application.js` |
17
+ | `@mytools/core/version` | `./src/version.js` |
18
+ | `@mytools/core/process` | `./src/process.js` |
19
+ | `@mytools/core/environments` | `./src/environments.js` |
20
+ | `@mytools/core/bundle` | `./src/bundle.js` |
21
+ | `@mytools/core/development` | `./src/development.js` |
22
+ | `@mytools/core/package.json` | `./package.json` |
23
+
24
+ 仅依赖 exports 声明的入口,禁止消费者跨包读取 src/bin 私有文件。入口路径由本模块维护,修改协议时同步消费方回归。
25
+
26
+ ## 维护与验证
27
+
28
+ 本模块负责上述职责的实现、文档与回归;跨模块接口调整需要同时检查生产者与消费者。具体维护人员尚未指定。
29
+
30
+ 在仓库根目录执行:
31
+
32
+ ```sh
33
+ node --test tests/modules.test.js tests/application.test.js tests/lifecycle.test.js tests/module-interfaces.test.js
34
+ ```
35
+
36
+ ## 开发监督进程
37
+
38
+ `createDevelopmentSupervisor({projectDir,entry,args,env,configFile,onEvent})` 启动文件监听 worker 和应用子进程,返回 `status()`、幂等 `close()`。父进程不加载插件运行模块;每次重启使用全新的 Node 进程,完整更新 ESM 导入依赖。`bindDevelopmentChild(app,{details,closePresentation})` 通过 IPC 报告就绪,收到重启请求后等待 `app.developmentStatus()` 的运行和管理操作均为空闲,再调用 `app.close()` 及界面清理。
39
+
40
+ 监听来源为项目 `.flow/plugins.json` 的 `links`,同时监听项目配置、插件状态和显式配置覆盖文件。独立 worker 跳过 `node_modules`、`.git`、`.flow`、`dist` 及符号链接;默认限制 512 个源码目录、20000 个扫描条目和 24 层深度。超出预算或扫描超时会明确报告未完整监听,独立进程扫描避免挂载目录的 I/O 阻塞监督器。只读项目拒绝启用开发模式。
41
+
42
+ 源码变化默认合并 180 ms。关闭超时从应用报告空闲并开始关闭后计时,默认 5 秒;启动超时默认 15 秒。强制终止后最多等待 2 秒确认回收,未确认退出的子进程继续占用预算,不能启动重叠宿主。`onEvent` 提供 `ready/changed/waiting/restarting/failed/forced/blocked/watchError/closed` 等状态,启动失败保留源码监听,修复后可再次启动。
43
+
44
+ 验证:`node --test tests/development-watch.test.js` 使用真实非交互子进程验证完整模块图、忙碌等待、连续保存、源码修复、关闭与配置刷新,并验证真实 Web 重启。
@@ -5,32 +5,34 @@
5
5
  "main": "src/application.js",
6
6
  "exports": {
7
7
  ".": "./src/application.js",
8
+ "./version": "./src/version.js",
8
9
  "./process": "./src/process.js",
10
+ "./environments": "./src/environments.js",
9
11
  "./bundle": "./src/bundle.js",
10
- "./environments": "./src/environments.js"
11
- },
12
- "bin": {
13
- "fst": "bin/fst.js"
12
+ "./development": "./src/development.js",
13
+ "./package.json": "./package.json"
14
14
  },
15
15
  "files": [
16
16
  "src",
17
- "bin",
18
- "templates"
17
+ "README.md",
18
+ "LICENSE"
19
19
  ],
20
20
  "license": "MIT",
21
21
  "engines": {
22
22
  "node": ">=24.15.0"
23
23
  },
24
24
  "dependencies": {
25
- "@mariozechner/pi-tui": "0.50.0",
26
25
  "@mytools/sdk": "0.1.0",
27
- "ajv": "8.20.0",
28
- "commander": "14.0.3",
29
- "cordis": "3.18.1",
30
- "execa": "10.1.0",
31
- "semver": "7.7.4",
32
- "tree-kill": "1.2.2",
33
- "which": "7.0.0",
34
- "yaml": "2.9.1"
26
+ "@mytools/fst-platform": "0.1.0",
27
+ "@mytools/fst-logs": "0.1.0",
28
+ "@mytools/fst-workflow": "0.1.0",
29
+ "@mytools/fst-plugin": "0.1.0",
30
+ "@mytools/fst-workspace": "0.1.0"
31
+ },
32
+ "peerDependencies": {
33
+ "@mytools/pack": "0.1.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "@mytools/pack": {"optional": true}
35
37
  }
36
38
  }