@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,90 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var fs = require('fs');
5
+ var acorn = require('./acorn.js');
6
+
7
+ function _interopNamespaceDefault(e) {
8
+ var n = Object.create(null);
9
+ if (e) {
10
+ Object.keys(e).forEach(function (k) {
11
+ if (k !== 'default') {
12
+ var d = Object.getOwnPropertyDescriptor(e, k);
13
+ Object.defineProperty(n, k, d.get ? d : {
14
+ enumerable: true,
15
+ get: function () { return e[k]; }
16
+ });
17
+ }
18
+ });
19
+ }
20
+ n.default = e;
21
+ return Object.freeze(n);
22
+ }
23
+
24
+ var acorn__namespace = /*#__PURE__*/_interopNamespaceDefault(acorn);
25
+
26
+ var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false;
27
+ var options = {};
28
+
29
+ function help(status) {
30
+ var print = (status === 0) ? console.log : console.error;
31
+ print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]");
32
+ print(" [--tokenize] [--locations] [--allow-hash-bang] [--allow-await-outside-function] [--compact] [--silent] [--module] [--help] [--] [<infile>...]");
33
+ process.exit(status);
34
+ }
35
+
36
+ for (var i = 2; i < process.argv.length; ++i) {
37
+ var arg = process.argv[i];
38
+ if (arg[0] !== "-" || arg === "-") { inputFilePaths.push(arg); }
39
+ else if (arg === "--") {
40
+ inputFilePaths.push.apply(inputFilePaths, process.argv.slice(i + 1));
41
+ forceFileName = true;
42
+ break
43
+ } else if (arg === "--locations") { options.locations = true; }
44
+ else if (arg === "--allow-hash-bang") { options.allowHashBang = true; }
45
+ else if (arg === "--allow-await-outside-function") { options.allowAwaitOutsideFunction = true; }
46
+ else if (arg === "--silent") { silent = true; }
47
+ else if (arg === "--compact") { compact = true; }
48
+ else if (arg === "--help") { help(0); }
49
+ else if (arg === "--tokenize") { tokenize = true; }
50
+ else if (arg === "--module") { options.sourceType = "module"; }
51
+ else {
52
+ var match = arg.match(/^--ecma(\d+)$/);
53
+ if (match)
54
+ { options.ecmaVersion = +match[1]; }
55
+ else
56
+ { help(1); }
57
+ }
58
+ }
59
+
60
+ function run(codeList) {
61
+ var result = [], fileIdx = 0;
62
+ try {
63
+ codeList.forEach(function (code, idx) {
64
+ fileIdx = idx;
65
+ if (!tokenize) {
66
+ result = acorn__namespace.parse(code, options);
67
+ options.program = result;
68
+ } else {
69
+ var tokenizer = acorn__namespace.tokenizer(code, options), token;
70
+ do {
71
+ token = tokenizer.getToken();
72
+ result.push(token);
73
+ } while (token.type !== acorn__namespace.tokTypes.eof)
74
+ }
75
+ });
76
+ } catch (e) {
77
+ console.error(fileMode ? e.message.replace(/\(\d+:\d+\)$/, function (m) { return m.slice(0, 1) + inputFilePaths[fileIdx] + " " + m.slice(1); }) : e.message);
78
+ process.exit(1);
79
+ }
80
+ if (!silent) { console.log(JSON.stringify(result, function (_, value) { return typeof value === "bigint" ? null : value; }, compact ? null : 2)); }
81
+ }
82
+
83
+ if (fileMode = inputFilePaths.length && (forceFileName || !inputFilePaths.includes("-") || inputFilePaths.length !== 1)) {
84
+ run(inputFilePaths.map(function (path) { return fs.readFileSync(path, "utf8"); }));
85
+ } else {
86
+ var code = "";
87
+ process.stdin.resume();
88
+ process.stdin.on("data", function (chunk) { return code += chunk; });
89
+ process.stdin.on("end", function () { return run([code]); });
90
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "acorn",
3
+ "description": "ECMAScript parser",
4
+ "homepage": "https://github.com/acornjs/acorn",
5
+ "main": "dist/acorn.js",
6
+ "types": "dist/acorn.d.ts",
7
+ "module": "dist/acorn.mjs",
8
+ "exports": {
9
+ ".": [
10
+ {
11
+ "import": "./dist/acorn.mjs",
12
+ "require": "./dist/acorn.js",
13
+ "default": "./dist/acorn.js"
14
+ },
15
+ "./dist/acorn.js"
16
+ ],
17
+ "./package.json": "./package.json"
18
+ },
19
+ "version": "8.19.0",
20
+ "engines": {
21
+ "node": ">=0.4.0"
22
+ },
23
+ "maintainers": [
24
+ {
25
+ "name": "Marijn Haverbeke",
26
+ "email": "marijn@haverbeke.berlin",
27
+ "web": "https://marijnhaverbeke.nl"
28
+ },
29
+ {
30
+ "name": "Ingvar Stepanyan",
31
+ "email": "me@rreverser.com",
32
+ "web": "https://rreverser.com/"
33
+ },
34
+ {
35
+ "name": "Adrian Heine",
36
+ "web": "http://adrianheine.de"
37
+ }
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/acornjs/acorn.git"
42
+ },
43
+ "license": "MIT",
44
+ "scripts": {
45
+ "prepare": "cd ..; npm run build:main"
46
+ },
47
+ "bin": {
48
+ "acorn": "bin/acorn"
49
+ }
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yanglaofish/fishtools",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Fishtools 插件式工作流工作台",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,67 +27,20 @@
27
27
  "manual"
28
28
  ],
29
29
  "dependencies": {
30
- "@mytools/core": "0.1.0",
31
- "@mariozechner/pi-tui": "0.50.0",
32
- "@types/mime-types": "2.1.4",
33
- "chalk": "5.6.2",
34
- "get-east-asian-width": "1.7.0",
35
- "marked": "15.0.12",
36
- "mime-types": "3.0.2",
37
- "mime-db": "1.54.0",
30
+ "@mytools/fst-cli": "0.1.0",
38
31
  "@mytools/sdk": "0.1.0",
39
32
  "ajv": "8.20.0",
40
33
  "fast-deep-equal": "3.1.3",
41
34
  "fast-uri": "3.1.8",
42
35
  "json-schema-traverse": "1.0.0",
43
36
  "require-from-string": "2.0.2",
44
- "commander": "14.0.3",
45
- "cordis": "3.18.1",
46
- "@cordisjs/core": "3.18.1",
47
- "cosmokit": "1.8.1",
48
- "@cordisjs/loader": "0.13.1",
49
- "dotenv": "16.6.1",
50
- "js-yaml": "4.3.2",
51
- "argparse": "2.0.1",
52
- "@cordisjs/logger": "0.3.3",
53
- "reggol": "1.7.1",
54
- "object-inspect": "1.13.4",
55
- "supports-color": "8.1.1",
56
- "has-flag": "4.0.0",
57
- "@cordisjs/schema": "0.1.1",
58
- "schemastery": "3.18.0",
59
- "@standard-schema/spec": "1.1.0",
60
- "@cordisjs/timer": "0.3.2",
61
- "cac": "6.7.14",
62
- "kleur": "4.1.5",
63
- "execa": "10.1.0",
64
- "@sindresorhus/merge-streams": "4.0.0",
65
- "figures": "6.1.0",
66
- "is-unicode-supported": "2.1.0",
67
- "get-stream": "9.0.1",
68
- "@sec-ant/readable-stream": "0.4.1",
69
- "is-stream": "4.0.1",
70
- "human-signals": "8.0.1",
71
- "is-plain-obj": "4.1.0",
72
- "npm-run-path": "6.0.0",
73
- "path-key": "4.0.0",
74
- "unicorn-magic": "0.3.0",
75
- "pretty-ms": "9.3.1",
76
- "parse-ms": "4.0.0",
77
- "signal-exit": "4.1.0",
78
- "strip-final-newline": "4.0.0",
79
- "which-command": "0.1.0",
80
- "yoctocolors": "2.2.0",
81
- "semver": "7.7.4",
82
- "tree-kill": "1.2.2",
83
- "which": "7.0.0",
84
- "isexe": "4.0.0",
85
- "yaml": "2.9.1",
37
+ "@mytools/core": "0.1.0",
86
38
  "@mytools/pack": "0.1.0",
87
39
  "@npmcli/arborist": "10.0.3",
88
40
  "@gar/promise-retry": "1.0.3",
89
41
  "@isaacs/string-locale-compare": "1.1.0",
90
42
  "@npmcli/fs": "6.0.0",
43
+ "semver": "7.7.4",
91
44
  "@npmcli/installed-package-contents": "5.0.0",
92
45
  "npm-bundled": "6.0.0",
93
46
  "npm-normalize-package-bin": "6.0.0",
@@ -96,6 +49,8 @@
96
49
  "@npmcli/package-json": "8.0.0",
97
50
  "@npmcli/git": "8.0.0",
98
51
  "@npmcli/promise-spawn": "10.0.0",
52
+ "which": "7.0.0",
53
+ "isexe": "4.0.0",
99
54
  "ini": "7.0.0",
100
55
  "lru-cache": "11.5.3",
101
56
  "npm-pick-manifest": "12.0.0",
@@ -182,6 +137,7 @@
182
137
  "cmd-shim": "9.0.2",
183
138
  "read-cmd-shim": "7.0.1",
184
139
  "write-file-atomic": "8.0.0",
140
+ "signal-exit": "4.1.0",
185
141
  "common-ancestor-path": "2.0.0",
186
142
  "diff": "8.0.4",
187
143
  "json-stringify-nice": "1.1.4",
@@ -196,6 +152,7 @@
196
152
  "archiver": "8.0.0",
197
153
  "async": "3.2.6",
198
154
  "buffer-crc32": "1.0.0",
155
+ "is-stream": "4.0.1",
199
156
  "lazystream": "1.0.1",
200
157
  "readable-stream": "2.3.8",
201
158
  "core-util-is": "1.0.3",
@@ -229,6 +186,57 @@
229
186
  "compress-commons": "7.0.1",
230
187
  "crc-32": "1.2.2",
231
188
  "crc32-stream": "7.0.1",
189
+ "yaml": "2.9.1",
190
+ "@mytools/fst-platform": "0.1.0",
191
+ "execa": "10.1.0",
192
+ "@sindresorhus/merge-streams": "4.0.0",
193
+ "figures": "6.1.0",
194
+ "is-unicode-supported": "2.1.0",
195
+ "get-stream": "9.0.1",
196
+ "@sec-ant/readable-stream": "0.4.1",
197
+ "human-signals": "8.0.1",
198
+ "is-plain-obj": "4.1.0",
199
+ "npm-run-path": "6.0.0",
200
+ "path-key": "4.0.0",
201
+ "unicorn-magic": "0.3.0",
202
+ "pretty-ms": "9.3.1",
203
+ "parse-ms": "4.0.0",
204
+ "strip-final-newline": "4.0.0",
205
+ "which-command": "0.1.0",
206
+ "yoctocolors": "2.2.0",
207
+ "tree-kill": "1.2.2",
208
+ "@mytools/fst-devtools": "0.1.0",
209
+ "@mytools/fst-plugin": "0.1.0",
210
+ "cordis": "3.18.1",
211
+ "@cordisjs/core": "3.18.1",
212
+ "cosmokit": "1.8.1",
213
+ "@cordisjs/loader": "0.13.1",
214
+ "dotenv": "16.6.1",
215
+ "js-yaml": "4.3.2",
216
+ "argparse": "2.0.1",
217
+ "@cordisjs/logger": "0.3.3",
218
+ "reggol": "1.7.1",
219
+ "object-inspect": "1.13.4",
220
+ "supports-color": "8.1.1",
221
+ "has-flag": "4.0.0",
222
+ "@cordisjs/schema": "0.1.1",
223
+ "schemastery": "3.18.0",
224
+ "@standard-schema/spec": "1.1.0",
225
+ "@cordisjs/timer": "0.3.2",
226
+ "cac": "6.7.14",
227
+ "kleur": "4.1.5",
228
+ "acorn": "8.19.0",
229
+ "@mytools/fst-logs": "0.1.0",
230
+ "@mytools/fst-workflow": "0.1.0",
231
+ "@mytools/fst-workspace": "0.1.0",
232
+ "@mariozechner/pi-tui": "0.50.0",
233
+ "@types/mime-types": "2.1.4",
234
+ "chalk": "5.6.2",
235
+ "get-east-asian-width": "1.7.0",
236
+ "marked": "15.0.12",
237
+ "mime-types": "3.0.2",
238
+ "mime-db": "1.54.0",
239
+ "commander": "14.0.3",
232
240
  "@mytools/environment": "0.1.0",
233
241
  "@mytools/examples": "0.1.0",
234
242
  "@mytools/web": "0.1.0",
@@ -289,67 +297,20 @@
289
297
  "vary": "1.1.2"
290
298
  },
291
299
  "bundleDependencies": [
292
- "@mytools/core",
293
- "@mariozechner/pi-tui",
294
- "@types/mime-types",
295
- "chalk",
296
- "get-east-asian-width",
297
- "marked",
298
- "mime-types",
299
- "mime-db",
300
+ "@mytools/fst-cli",
300
301
  "@mytools/sdk",
301
302
  "ajv",
302
303
  "fast-deep-equal",
303
304
  "fast-uri",
304
305
  "json-schema-traverse",
305
306
  "require-from-string",
306
- "commander",
307
- "cordis",
308
- "@cordisjs/core",
309
- "cosmokit",
310
- "@cordisjs/loader",
311
- "dotenv",
312
- "js-yaml",
313
- "argparse",
314
- "@cordisjs/logger",
315
- "reggol",
316
- "object-inspect",
317
- "supports-color",
318
- "has-flag",
319
- "@cordisjs/schema",
320
- "schemastery",
321
- "@standard-schema/spec",
322
- "@cordisjs/timer",
323
- "cac",
324
- "kleur",
325
- "execa",
326
- "@sindresorhus/merge-streams",
327
- "figures",
328
- "is-unicode-supported",
329
- "get-stream",
330
- "@sec-ant/readable-stream",
331
- "is-stream",
332
- "human-signals",
333
- "is-plain-obj",
334
- "npm-run-path",
335
- "path-key",
336
- "unicorn-magic",
337
- "pretty-ms",
338
- "parse-ms",
339
- "signal-exit",
340
- "strip-final-newline",
341
- "which-command",
342
- "yoctocolors",
343
- "semver",
344
- "tree-kill",
345
- "which",
346
- "isexe",
347
- "yaml",
307
+ "@mytools/core",
348
308
  "@mytools/pack",
349
309
  "@npmcli/arborist",
350
310
  "@gar/promise-retry",
351
311
  "@isaacs/string-locale-compare",
352
312
  "@npmcli/fs",
313
+ "semver",
353
314
  "@npmcli/installed-package-contents",
354
315
  "npm-bundled",
355
316
  "npm-normalize-package-bin",
@@ -358,6 +319,8 @@
358
319
  "@npmcli/package-json",
359
320
  "@npmcli/git",
360
321
  "@npmcli/promise-spawn",
322
+ "which",
323
+ "isexe",
361
324
  "ini",
362
325
  "lru-cache",
363
326
  "npm-pick-manifest",
@@ -444,6 +407,7 @@
444
407
  "cmd-shim",
445
408
  "read-cmd-shim",
446
409
  "write-file-atomic",
410
+ "signal-exit",
447
411
  "common-ancestor-path",
448
412
  "diff",
449
413
  "json-stringify-nice",
@@ -458,6 +422,7 @@
458
422
  "archiver",
459
423
  "async",
460
424
  "buffer-crc32",
425
+ "is-stream",
461
426
  "lazystream",
462
427
  "readable-stream",
463
428
  "core-util-is",
@@ -491,6 +456,57 @@
491
456
  "compress-commons",
492
457
  "crc-32",
493
458
  "crc32-stream",
459
+ "yaml",
460
+ "@mytools/fst-platform",
461
+ "execa",
462
+ "@sindresorhus/merge-streams",
463
+ "figures",
464
+ "is-unicode-supported",
465
+ "get-stream",
466
+ "@sec-ant/readable-stream",
467
+ "human-signals",
468
+ "is-plain-obj",
469
+ "npm-run-path",
470
+ "path-key",
471
+ "unicorn-magic",
472
+ "pretty-ms",
473
+ "parse-ms",
474
+ "strip-final-newline",
475
+ "which-command",
476
+ "yoctocolors",
477
+ "tree-kill",
478
+ "@mytools/fst-devtools",
479
+ "@mytools/fst-plugin",
480
+ "cordis",
481
+ "@cordisjs/core",
482
+ "cosmokit",
483
+ "@cordisjs/loader",
484
+ "dotenv",
485
+ "js-yaml",
486
+ "argparse",
487
+ "@cordisjs/logger",
488
+ "reggol",
489
+ "object-inspect",
490
+ "supports-color",
491
+ "has-flag",
492
+ "@cordisjs/schema",
493
+ "schemastery",
494
+ "@standard-schema/spec",
495
+ "@cordisjs/timer",
496
+ "cac",
497
+ "kleur",
498
+ "acorn",
499
+ "@mytools/fst-logs",
500
+ "@mytools/fst-workflow",
501
+ "@mytools/fst-workspace",
502
+ "@mariozechner/pi-tui",
503
+ "@types/mime-types",
504
+ "chalk",
505
+ "get-east-asian-width",
506
+ "marked",
507
+ "mime-types",
508
+ "mime-db",
509
+ "commander",
494
510
  "@mytools/environment",
495
511
  "@mytools/examples",
496
512
  "@mytools/web",
@@ -1,124 +0,0 @@
1
- import { Context } from 'cordis';
2
- import semver from 'semver';
3
- import { SDK_VERSION, FlowError } from '@mytools/sdk';
4
- import { validate, emptyObject } from './validation.js';
5
- import {validateDeclarations,validateCommands} from './contracts.js';
6
- import {resolveEnvironments} from './environments.js';
7
- import {createRuntime} from './runtime.js';
8
- import {pluginError} from './diagnostics.js';
9
-
10
- export async function createHost({ plugins = [], config = {}, services = {}, environmentOverrides={},runtimeEnabled=true } = {}) {
11
- const ctx = new Context();
12
- const actions = new Map();
13
- const definitions = new Map();
14
- const extensions = new Map();
15
- const serviceNames = new Set();
16
- const commandNames=new Set(),commands=new Map();
17
- function bindContext(context){
18
- const bound={...services,...context},execute=bound.runProcess;
19
- // 面向用户的输出与诊断日志共用持久化通道,只区分默认可见性。
20
- bound.print=(message,data)=>Promise.resolve(bound.log?.(message,data,{audience:'user'}));
21
- if(typeof execute==='function')bound.runProcess=(file,args,options={})=>{
22
- const signal=context.signal&&options.signal?AbortSignal.any([context.signal,options.signal]):context.signal??options.signal;
23
- return execute(file,args,{...options,signal,onOutput:async({stream,message})=>{
24
- await bound.log?.(message,undefined,{stream});
25
- await options.onOutput?.({stream,message});
26
- }});
27
- };
28
- return bound;
29
- }
30
- for (const entry of plugins) {
31
- const plugin = entry.plugin ?? entry;
32
- validateDeclarations(plugin);validateCommands(plugin,commandNames);
33
- if (!plugin.id || definitions.has(plugin.id)) throw new FlowError(`插件标识缺失或重复:${plugin.id}`, {code:'VALIDATION'});
34
- if (!semver.satisfies(SDK_VERSION, plugin.sdk ?? '^0.1.0')) throw new FlowError(`插件 ${plugin.id} 与 SDK ${SDK_VERSION} 不兼容`, {code:'VALIDATION'});
35
- for(const [name,action] of Object.entries(plugin.actions??{})){
36
- if(typeof action?.run!=='function')throw new FlowError(`动作 ${plugin.id}:${name} 缺少执行函数`);
37
- }
38
- for(const [name,extension] of Object.entries(plugin.services??{})){
39
- if(serviceNames.has(name))throw new FlowError(`服务重复:${name}`);
40
- if(typeof extension!=='function')throw new FlowError(`服务 ${name} 缺少执行函数`);
41
- serviceNames.add(name);
42
- }
43
- definitions.set(plugin.id, {...plugin, root:entry.root});
44
- }
45
- const settingsById=new Map();
46
- for (const plugin of definitions.values()) {
47
- for (const [id, range] of Object.entries(plugin.dependencies ?? {})) {
48
- if (!definitions.has(id) || !semver.satisfies(definitions.get(id).version,range)) throw new FlowError(`插件 ${plugin.id} 缺少兼容依赖 ${id}@${range}`,{code:'VALIDATION'});
49
- }
50
- const settings = validate(plugin.config, config[plugin.id] ?? {}, `${plugin.id} 配置`);
51
- settingsById.set(plugin.id,settings);
52
- }
53
- const runtime=createRuntime(ctx,definitions,{enabled:runtimeEnabled});
54
- try{
55
- for (const plugin of definitions.values()) {
56
- const settings=settingsById.get(plugin.id);
57
- runtime.register(plugin,settings,scope=>{
58
- for(const [name,command] of Object.entries(plugin.commands??{})){
59
- const action=command.action?plugin.actions[command.action]:command;
60
- commands.set(name,{...command,name,plugin:plugin.id,input:action.input,output:action.output,description:command.description??action.description??action.title??name,config:settings});
61
- scope.on('dispose',()=>commands.delete(name));
62
- }
63
- for (const [name, action] of Object.entries(plugin.actions ?? {})) {
64
- const id = `${plugin.id}:${name}`;
65
- if (typeof action.run !== 'function') throw new FlowError(`动作 ${id} 缺少执行函数`);
66
- actions.set(id, {...action, id, plugin:plugin.id, config:settings, root:plugin.root});
67
- scope.on('dispose', () => actions.delete(id));
68
- }
69
- for (const [name, extension] of Object.entries(plugin.services ?? {})) {
70
- if (extensions.has(name)) throw new FlowError(`服务重复:${name}`);
71
- extensions.set(name, {run:extension,plugin:plugin.id});
72
- scope.on('dispose',()=>extensions.delete(name));
73
- }
74
- });
75
- }
76
- await runtime.start();
77
- }catch(error){
78
- try{await runtime.close();}catch(cleanup){if(cleanup.message!==error.message)throw new AggregateError([error,cleanup],`${error.message};${cleanup.message}`);}
79
- throw error;
80
- }
81
- return {
82
- definitions, actions,
83
- hasRuntime:runtime.hasRuntime,
84
- runtimeStatus:()=>runtime.status(),
85
- commands(){return [...commands.values()].map(({run,config,...metadata})=>structuredClone(metadata));},
86
- async invokeCommand(name,input,context={}){
87
- runtime.assertOpen();
88
- const command=commands.get(name);if(!command)throw new FlowError(`命令不存在:/${name}`);
89
- if(command.action)return this.invoke(`${command.plugin}:${command.action}`,input,context);
90
- if(!context.ui)throw new FlowError(`交互命令 /${name} 需要在 TUI 中调用`);
91
- const plugin=definitions.get(command.plugin);
92
- try{
93
- const getService=runtime.bindServices(plugin.id);
94
- context.signal?.throwIfAborted();
95
- const result=await command.run(validate(command.input??emptyObject,input,`/${name} 输入`),{...bindContext(context),getService,config:command.config,resourceDir:plugin.root,environments:resolveEnvironments(plugin,undefined,environmentOverrides[plugin.id])});
96
- context.signal?.throwIfAborted();
97
- return validate(command.output,JSON.parse(JSON.stringify(result??{})),`/${name} 输出`);
98
- }catch(cause){throw pluginError(cause,{plugin:plugin.id,command:`/${name}`});}
99
- },
100
- catalog() { return [...actions.values()].map(({run,config,root,...metadata})=>structuredClone(metadata)); },
101
- async invoke(id, input, context = {}) {
102
- runtime.assertOpen();
103
- const action = actions.get(id);
104
- if (!action) throw new FlowError(`动作不存在:${id}`, {code:'VALIDATION'});
105
- try{
106
- const getService=runtime.bindServices(action.plugin);
107
- context.signal?.throwIfAborted();
108
- const result = await action.run(validate(action.input ?? emptyObject,input,`${id} 输入`), {...bindContext(context),getService, config:action.config, resourceDir:action.root,environments:resolveEnvironments(definitions.get(action.plugin),action,environmentOverrides[action.plugin])});
109
- context.signal?.throwIfAborted();
110
- // 通过 JSON 边界验证返回值,避免函数、循环引用等进入工作流状态。
111
- const encoded = JSON.stringify(result);
112
- if (encoded === undefined) throw new FlowError(`${id} 输出必须可 JSON 序列化`);
113
- return validate(action.output, JSON.parse(encoded),`${id} 输出`);
114
- }catch(cause){throw pluginError(cause,{plugin:action.plugin,action:id});}
115
- },
116
- async service(name,options) {
117
- runtime.assertOpen();
118
- if (!extensions.has(name)) throw new FlowError(`未安装提供 ${name} 的插件`);
119
- const extension=extensions.get(name);runtime.assertActive(extension.plugin);
120
- return extension.run(services,options);
121
- },
122
- close:()=>runtime.close(),
123
- };
124
- }
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import { readFile, access } from 'node:fs/promises';
4
- import path from 'node:path';
5
- import { createApplication } from '../src/application.js';
6
- import { verifyBundle } from '../src/bundle.js';
7
- import { resolveProject, initializeProject } from '../src/project.js';
8
- import {waitForCliRun,cliRunResult} from '../src/cli-run.js';
9
- import {VERSION} from '../src/version.js';
10
- import {listDocumentation,readDocumentation,findDocumentationRoot,exportDocumentation} from '../src/documentation.js';
11
-
12
- const program=new Command().name('fst').description('Fishtools · 插件式工作流工作台').version(VERSION);
13
- program.option('--maintenance','维护模式:不启动有状态服务插件');
14
- program.option('--project <directory>','项目目录(默认当前项目或用户工作区)').option('--workspace <directory>','便携包的可写工作区').option('--output <directory>','日志与结果目录').option('--config <file>','插件配置覆盖文件').option('--host <host>','Web 监听地址','127.0.0.1').option('--port <port>','Web 监听端口','8765');
15
- async function app(){const o=program.opts();return createApplication({projectDir:await resolveProject(o.project,o.workspace),outputDir:o.output,maintenance:!!o.maintenance,config:o.config?JSON.parse(await readFile(o.config,'utf8')):{}});}
16
- async function use(fn){const a=await app();try{return await fn(a);}finally{await a.close();}}
17
- program.command('init [directory]').description('创建项目,保留已有配置与工作流').action(async directory=>console.log(`Fishtools 项目:${await initializeProject(path.resolve(directory??process.cwd()))}`));
18
- program.command('docs [topic]').description('阅读或导出随安装提供的离线文档').option('--path','只打印文档路径').option('--export <directory>','导出完整资料到新目录').action(async(topic,options)=>{
19
- if(options.export){if(topic||options.path)throw new Error('--export 不可与文档主题或 --path 同用');console.log(await exportDocumentation(options.export));return;}
20
- if(topic){const document=await readDocumentation(topic);console.log(options.path?document.path:document.text);return;}
21
- if(options.path){console.log(await findDocumentationRoot());return;}
22
- console.log((await listDocumentation()).map(document=>`${document.id}\t${document.title}`).join('\n'));
23
- console.log('\nfst docs <主题> 阅读正文;fst docs <主题> --path 查看路径;fst docs --export <新目录> 导出全部资料');
24
- });
25
- const workflow=program.command('workflow').description('查看和检查工作流');
26
- workflow.command('list').action(()=>use(async a=>console.log(JSON.stringify(await a.listWorkflows(),null,2))));
27
- workflow.command('check <id>').action(id=>use(async a=>{await a.checkWorkflow(id);console.log('工作流校验通过');}));
28
- program.command('run <id>').option('--input <file>','JSON 输入文件').action((id,o)=>use(async a=>{
29
- const run=await a.startRun(id,o.input?JSON.parse(await readFile(o.input,'utf8')):{});
30
- const result=cliRunResult(await waitForCliRun(a,run));console.log(JSON.stringify(result.value,null,2));
31
- process.exitCode=result.exitCode;
32
- }));
33
- const plugin=program.command('plugin').description('管理插件');
34
- plugin.command('list').action(()=>use(a=>console.log(JSON.stringify(a.listPlugins(),null,2))));
35
- plugin.command('add <source>').action(source=>use(async a=>console.log(JSON.stringify(await a.installPlugin(source),null,2))));
36
- plugin.command('remove <name>').action(name=>use(async a=>console.log(JSON.stringify(await a.removePlugin(name),null,2))));
37
- const packOptions=command=>command.requiredOption('--target <target>','win32-x64 或 linux-x64-glibc').option('--out <directory>','导出目录','dist').option('--read-only','导出只读精简运行包').option('--environments <file>','环境来源覆盖 JSON').option('--plan','只查看打包资源计划');
38
- async function pack(a,entries,o,portable=false){
39
- const options={entries,target:o.target,outDir:o.out,includeWeb:!!o.web,readOnly:!!o.readOnly,portable,environments:o.environments?JSON.parse(await readFile(o.environments,'utf8')):{}};
40
- console.log(JSON.stringify(await (o.plan?a.packPlan(options):a.pack(options)),null,2));
41
- }
42
- packOptions(program.command('pack <entries...>')).option('--web','包含 Web 界面').action((entries,o)=>use(a=>pack(a,entries,o)));
43
- packOptions(program.command('portable').description('导出完整便携工具、当前全部流程和插件')).option('--no-web','不额外携带 Web').action(o=>use(a=>pack(a,[],o,true)));
44
- program.command('command [name]').description('列出插件命令或执行动作命令').option('--input <file>','JSON 输入').action((name,o)=>use(async a=>{
45
- if(!name){console.log(JSON.stringify(a.listCommands(),null,2));return;}
46
- const run=await a.startCommand(name,o.input?JSON.parse(await readFile(o.input,'utf8')):{});
47
- const result=cliRunResult(await waitForCliRun(a,run));console.log(JSON.stringify(result.value,null,2));process.exitCode=result.exitCode;
48
- }));
49
- program.command('configure <plugin> <file>').description('从 JSON 保存插件配置').action((id,file)=>use(async a=>{await a.configurePlugin(id,JSON.parse(await readFile(file,'utf8')));console.log('插件配置已保存');}));
50
- async function web(o){
51
- const a=await app();let server;
52
- try{server=await a.startWeb({host:o.host,port:Number(o.port)});}catch(error){await a.close();throw error;}
53
- console.log(`Fishtools:${server.url}`);
54
- const stop=async()=>{await server.close();await a.close();};process.once('SIGINT',stop);process.once('SIGTERM',stop);
55
- }
56
- program.action(async()=>{
57
- if(!process.stdin.isTTY||!process.stdout.isTTY){program.outputHelp();return;}
58
- const {startTerminal}=await import('../src/terminal/session.js');
59
- await use(a=>startTerminal(a,{webOptions:{host:program.opts().host,port:Number(program.opts().port)}}));
60
- });
61
- program.command('web').description('启动可选的 Fishtools Web 工作台').option('--host <host>','监听地址').option('--port <port>','监听端口').action(o=>web({...program.opts(),...o}));
62
- program.command('doctor').action(()=>use(async a=>{
63
- let integrity;
64
- const bundleRoot=a.project.baseBundle?.root??a.projectDir;
65
- try{await access(path.join(bundleRoot,'manifest.json'));integrity=await verifyBundle(bundleRoot);}
66
- catch(error){if(error.code!=='ENOENT')throw error;}
67
- console.log(JSON.stringify({node:process.version,platform:process.platform,arch:process.arch,plugins:a.listPlugins(),integrity},null,2));
68
- if(integrity&&!integrity.ok)process.exitCode=1;
69
- }));
70
- try {await program.parseAsync();}catch(error){console.error(error.message);process.exitCode=error.code==='CANCELLED'?130:2;}