@jonathanleelx/meddle 0.0.1

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 (361) hide show
  1. package/CONFIG_STRUCTURE.md +315 -0
  2. package/LICENSE +21 -0
  3. package/README.md +298 -0
  4. package/bin/commands/mock/add.js +92 -0
  5. package/bin/commands/mock/delete.js +58 -0
  6. package/bin/commands/mock/index.js +50 -0
  7. package/bin/commands/mock/list.js +68 -0
  8. package/bin/commands/mock/toggle.js +64 -0
  9. package/bin/commands/mock/update.js +94 -0
  10. package/bin/commands/route/active.js +141 -0
  11. package/bin/commands/route/add.js +127 -0
  12. package/bin/commands/route/create.js +77 -0
  13. package/bin/commands/route/delete.js +120 -0
  14. package/bin/commands/route/index.js +59 -0
  15. package/bin/commands/route/list.js +67 -0
  16. package/bin/commands/route/preview.js +159 -0
  17. package/bin/commands/route/show.js +111 -0
  18. package/bin/commands/route/update.js +126 -0
  19. package/bin/commands/session/create.js +166 -0
  20. package/bin/commands/session/delete.js +69 -0
  21. package/bin/commands/session/index.js +61 -0
  22. package/bin/commands/session/list.js +42 -0
  23. package/bin/commands/session/prune.js +31 -0
  24. package/bin/commands/start.js +43 -0
  25. package/bin/commands/status.js +115 -0
  26. package/bin/commands/supervise.js +106 -0
  27. package/bin/commands/url.js +30 -0
  28. package/bin/doctor.js +356 -0
  29. package/bin/index +130 -0
  30. package/bin/lib/api-client.js +72 -0
  31. package/bin/lib/file-access.js +337 -0
  32. package/bin/lib/meddle-home.js +20 -0
  33. package/bin/lib/output.js +146 -0
  34. package/bin/lib/parsers.js +127 -0
  35. package/bin/lib/proxy-detect.js +105 -0
  36. package/bin/lib/route-preview.js +180 -0
  37. package/bin/lib/session-args.js +54 -0
  38. package/bin/lib/sessions.js +213 -0
  39. package/dist/cert.d.ts +10 -0
  40. package/dist/cert.d.ts.map +1 -0
  41. package/dist/cert.js +184 -0
  42. package/dist/cert.js.map +1 -0
  43. package/dist/core/application-identity.d.ts +55 -0
  44. package/dist/core/application-identity.d.ts.map +1 -0
  45. package/dist/core/application-identity.js +321 -0
  46. package/dist/core/application-identity.js.map +1 -0
  47. package/dist/core/body-utils.d.ts +2 -0
  48. package/dist/core/body-utils.d.ts.map +1 -0
  49. package/dist/core/body-utils.js +21 -0
  50. package/dist/core/body-utils.js.map +1 -0
  51. package/dist/core/browser.d.ts +2 -0
  52. package/dist/core/browser.d.ts.map +1 -0
  53. package/dist/core/browser.js +92 -0
  54. package/dist/core/browser.js.map +1 -0
  55. package/dist/core/client-identity.d.ts +27 -0
  56. package/dist/core/client-identity.d.ts.map +1 -0
  57. package/dist/core/client-identity.js +136 -0
  58. package/dist/core/client-identity.js.map +1 -0
  59. package/dist/core/config-diagnostics.d.ts +14 -0
  60. package/dist/core/config-diagnostics.d.ts.map +1 -0
  61. package/dist/core/config-diagnostics.js +137 -0
  62. package/dist/core/config-diagnostics.js.map +1 -0
  63. package/dist/core/connect-tunnel.d.ts +5 -0
  64. package/dist/core/connect-tunnel.d.ts.map +1 -0
  65. package/dist/core/connect-tunnel.js +45 -0
  66. package/dist/core/connect-tunnel.js.map +1 -0
  67. package/dist/core/content-encoding.d.ts +2 -0
  68. package/dist/core/content-encoding.d.ts.map +1 -0
  69. package/dist/core/content-encoding.js +77 -0
  70. package/dist/core/content-encoding.js.map +1 -0
  71. package/dist/core/custom-plugin-loader.d.ts +18 -0
  72. package/dist/core/custom-plugin-loader.d.ts.map +1 -0
  73. package/dist/core/custom-plugin-loader.js +178 -0
  74. package/dist/core/custom-plugin-loader.js.map +1 -0
  75. package/dist/core/h2-pool.d.ts +4 -0
  76. package/dist/core/h2-pool.d.ts.map +1 -0
  77. package/dist/core/h2-pool.js +180 -0
  78. package/dist/core/h2-pool.js.map +1 -0
  79. package/dist/core/inspection-dispatch.d.ts +5 -0
  80. package/dist/core/inspection-dispatch.d.ts.map +1 -0
  81. package/dist/core/inspection-dispatch.js +146 -0
  82. package/dist/core/inspection-dispatch.js.map +1 -0
  83. package/dist/core/log-rate-limit.d.ts +34 -0
  84. package/dist/core/log-rate-limit.d.ts.map +1 -0
  85. package/dist/core/log-rate-limit.js +52 -0
  86. package/dist/core/log-rate-limit.js.map +1 -0
  87. package/dist/core/map-local.d.ts +4 -0
  88. package/dist/core/map-local.d.ts.map +1 -0
  89. package/dist/core/map-local.js +195 -0
  90. package/dist/core/map-local.js.map +1 -0
  91. package/dist/core/meddle-home.d.ts +13 -0
  92. package/dist/core/meddle-home.d.ts.map +1 -0
  93. package/dist/core/meddle-home.js +56 -0
  94. package/dist/core/meddle-home.js.map +1 -0
  95. package/dist/core/mock-gate.d.ts +3 -0
  96. package/dist/core/mock-gate.d.ts.map +1 -0
  97. package/dist/core/mock-gate.js +20 -0
  98. package/dist/core/mock-gate.js.map +1 -0
  99. package/dist/core/mock-handler.d.ts +5 -0
  100. package/dist/core/mock-handler.d.ts.map +1 -0
  101. package/dist/core/mock-handler.js +339 -0
  102. package/dist/core/mock-handler.js.map +1 -0
  103. package/dist/core/on-mode-gate.d.ts +4 -0
  104. package/dist/core/on-mode-gate.d.ts.map +1 -0
  105. package/dist/core/on-mode-gate.js +64 -0
  106. package/dist/core/on-mode-gate.js.map +1 -0
  107. package/dist/core/pipeline-gate.d.ts +3 -0
  108. package/dist/core/pipeline-gate.d.ts.map +1 -0
  109. package/dist/core/pipeline-gate.js +34 -0
  110. package/dist/core/pipeline-gate.js.map +1 -0
  111. package/dist/core/pipeline.d.ts +6 -0
  112. package/dist/core/pipeline.d.ts.map +1 -0
  113. package/dist/core/pipeline.js +228 -0
  114. package/dist/core/pipeline.js.map +1 -0
  115. package/dist/core/plugin-bootstrap-runner.d.ts +6 -0
  116. package/dist/core/plugin-bootstrap-runner.d.ts.map +1 -0
  117. package/dist/core/plugin-bootstrap-runner.js +148 -0
  118. package/dist/core/plugin-bootstrap-runner.js.map +1 -0
  119. package/dist/core/plugin-bootstrap.d.ts +3 -0
  120. package/dist/core/plugin-bootstrap.d.ts.map +1 -0
  121. package/dist/core/plugin-bootstrap.js +15 -0
  122. package/dist/core/plugin-bootstrap.js.map +1 -0
  123. package/dist/core/plugin-compiler.d.ts +37 -0
  124. package/dist/core/plugin-compiler.d.ts.map +1 -0
  125. package/dist/core/plugin-compiler.js +172 -0
  126. package/dist/core/plugin-compiler.js.map +1 -0
  127. package/dist/core/plugin-context-factory.d.ts +29 -0
  128. package/dist/core/plugin-context-factory.d.ts.map +1 -0
  129. package/dist/core/plugin-context-factory.js +206 -0
  130. package/dist/core/plugin-context-factory.js.map +1 -0
  131. package/dist/core/plugin-generator.d.ts +47 -0
  132. package/dist/core/plugin-generator.d.ts.map +1 -0
  133. package/dist/core/plugin-generator.js +697 -0
  134. package/dist/core/plugin-generator.js.map +1 -0
  135. package/dist/core/plugin-health.d.ts +3 -0
  136. package/dist/core/plugin-health.d.ts.map +1 -0
  137. package/dist/core/plugin-health.js +54 -0
  138. package/dist/core/plugin-health.js.map +1 -0
  139. package/dist/core/plugin-intercept.d.ts +17 -0
  140. package/dist/core/plugin-intercept.d.ts.map +1 -0
  141. package/dist/core/plugin-intercept.js +133 -0
  142. package/dist/core/plugin-intercept.js.map +1 -0
  143. package/dist/core/plugin-runtime.d.ts +33 -0
  144. package/dist/core/plugin-runtime.d.ts.map +1 -0
  145. package/dist/core/plugin-runtime.js +254 -0
  146. package/dist/core/plugin-runtime.js.map +1 -0
  147. package/dist/core/proxy-context.d.ts +3 -0
  148. package/dist/core/proxy-context.d.ts.map +1 -0
  149. package/dist/core/proxy-context.js +129 -0
  150. package/dist/core/proxy-context.js.map +1 -0
  151. package/dist/core/proxy-record.d.ts +3 -0
  152. package/dist/core/proxy-record.d.ts.map +1 -0
  153. package/dist/core/proxy-record.js +32 -0
  154. package/dist/core/proxy-record.js.map +1 -0
  155. package/dist/core/refactor-config.d.ts +6 -0
  156. package/dist/core/refactor-config.d.ts.map +1 -0
  157. package/dist/core/refactor-config.js +45 -0
  158. package/dist/core/refactor-config.js.map +1 -0
  159. package/dist/core/refactor-status.d.ts +3 -0
  160. package/dist/core/refactor-status.d.ts.map +1 -0
  161. package/dist/core/refactor-status.js +19 -0
  162. package/dist/core/refactor-status.js.map +1 -0
  163. package/dist/core/remote-access.d.ts +40 -0
  164. package/dist/core/remote-access.d.ts.map +1 -0
  165. package/dist/core/remote-access.js +281 -0
  166. package/dist/core/remote-access.js.map +1 -0
  167. package/dist/core/route-decision.d.ts +3 -0
  168. package/dist/core/route-decision.d.ts.map +1 -0
  169. package/dist/core/route-decision.js +20 -0
  170. package/dist/core/route-decision.js.map +1 -0
  171. package/dist/core/route-loader.d.ts +14 -0
  172. package/dist/core/route-loader.d.ts.map +1 -0
  173. package/dist/core/route-loader.js +94 -0
  174. package/dist/core/route-loader.js.map +1 -0
  175. package/dist/core/route-preview.d.ts +15 -0
  176. package/dist/core/route-preview.d.ts.map +1 -0
  177. package/dist/core/route-preview.js +91 -0
  178. package/dist/core/route-preview.js.map +1 -0
  179. package/dist/core/runtime-health.d.ts +92 -0
  180. package/dist/core/runtime-health.d.ts.map +1 -0
  181. package/dist/core/runtime-health.js +205 -0
  182. package/dist/core/runtime-health.js.map +1 -0
  183. package/dist/core/sessions.d.ts +19 -0
  184. package/dist/core/sessions.d.ts.map +1 -0
  185. package/dist/core/sessions.js +93 -0
  186. package/dist/core/sessions.js.map +1 -0
  187. package/dist/core/shadow-compare.d.ts +8 -0
  188. package/dist/core/shadow-compare.d.ts.map +1 -0
  189. package/dist/core/shadow-compare.js +83 -0
  190. package/dist/core/shadow-compare.js.map +1 -0
  191. package/dist/core/shadow-readiness.d.ts +4 -0
  192. package/dist/core/shadow-readiness.d.ts.map +1 -0
  193. package/dist/core/shadow-readiness.js +118 -0
  194. package/dist/core/shadow-readiness.js.map +1 -0
  195. package/dist/core/short-response.d.ts +5 -0
  196. package/dist/core/short-response.d.ts.map +1 -0
  197. package/dist/core/short-response.js +18 -0
  198. package/dist/core/short-response.js.map +1 -0
  199. package/dist/core/static-server.d.ts +9 -0
  200. package/dist/core/static-server.d.ts.map +1 -0
  201. package/dist/core/static-server.js +136 -0
  202. package/dist/core/static-server.js.map +1 -0
  203. package/dist/core/types.d.ts +590 -0
  204. package/dist/core/types.d.ts.map +1 -0
  205. package/dist/core/types.js +4 -0
  206. package/dist/core/types.js.map +1 -0
  207. package/dist/helpers.d.ts +36 -0
  208. package/dist/helpers.d.ts.map +1 -0
  209. package/dist/helpers.js +290 -0
  210. package/dist/helpers.js.map +1 -0
  211. package/dist/plugins/builtin/index.d.ts +3 -0
  212. package/dist/plugins/builtin/index.d.ts.map +1 -0
  213. package/dist/plugins/builtin/index.js +23 -0
  214. package/dist/plugins/builtin/index.js.map +1 -0
  215. package/dist/plugins/builtin/logger-plugin.d.ts +8 -0
  216. package/dist/plugins/builtin/logger-plugin.d.ts.map +1 -0
  217. package/dist/plugins/builtin/logger-plugin.js +121 -0
  218. package/dist/plugins/builtin/logger-plugin.js.map +1 -0
  219. package/dist/plugins/builtin/mock-plugin.d.ts +3 -0
  220. package/dist/plugins/builtin/mock-plugin.d.ts.map +1 -0
  221. package/dist/plugins/builtin/mock-plugin.js +99 -0
  222. package/dist/plugins/builtin/mock-plugin.js.map +1 -0
  223. package/dist/plugins/builtin/router-plugin.d.ts +3 -0
  224. package/dist/plugins/builtin/router-plugin.d.ts.map +1 -0
  225. package/dist/plugins/builtin/router-plugin.js +36 -0
  226. package/dist/plugins/builtin/router-plugin.js.map +1 -0
  227. package/dist/server/agent/model.d.ts +30 -0
  228. package/dist/server/agent/model.d.ts.map +1 -0
  229. package/dist/server/agent/model.js +143 -0
  230. package/dist/server/agent/model.js.map +1 -0
  231. package/dist/server/agent/routes.d.ts +4 -0
  232. package/dist/server/agent/routes.d.ts.map +1 -0
  233. package/dist/server/agent/routes.js +188 -0
  234. package/dist/server/agent/routes.js.map +1 -0
  235. package/dist/server/agent/runtime.d.ts +12 -0
  236. package/dist/server/agent/runtime.d.ts.map +1 -0
  237. package/dist/server/agent/runtime.js +208 -0
  238. package/dist/server/agent/runtime.js.map +1 -0
  239. package/dist/server/agent/tools.d.ts +13 -0
  240. package/dist/server/agent/tools.d.ts.map +1 -0
  241. package/dist/server/agent/tools.js +1201 -0
  242. package/dist/server/agent/tools.js.map +1 -0
  243. package/dist/server/agent/types.d.ts +56 -0
  244. package/dist/server/agent/types.d.ts.map +1 -0
  245. package/dist/server/agent/types.js +3 -0
  246. package/dist/server/agent/types.js.map +1 -0
  247. package/dist/server/config.d.ts +9 -0
  248. package/dist/server/config.d.ts.map +1 -0
  249. package/dist/server/config.js +124 -0
  250. package/dist/server/config.js.map +1 -0
  251. package/dist/server/health.d.ts +4 -0
  252. package/dist/server/health.d.ts.map +1 -0
  253. package/dist/server/health.js +22 -0
  254. package/dist/server/health.js.map +1 -0
  255. package/dist/server/index.d.ts +239 -0
  256. package/dist/server/index.d.ts.map +1 -0
  257. package/dist/server/index.js +44 -0
  258. package/dist/server/index.js.map +1 -0
  259. package/dist/server/logs.d.ts +4 -0
  260. package/dist/server/logs.d.ts.map +1 -0
  261. package/dist/server/logs.js +40 -0
  262. package/dist/server/logs.js.map +1 -0
  263. package/dist/server/mocks.d.ts +9 -0
  264. package/dist/server/mocks.d.ts.map +1 -0
  265. package/dist/server/mocks.js +103 -0
  266. package/dist/server/mocks.js.map +1 -0
  267. package/dist/server/pipeline.d.ts +16 -0
  268. package/dist/server/pipeline.d.ts.map +1 -0
  269. package/dist/server/pipeline.js +159 -0
  270. package/dist/server/pipeline.js.map +1 -0
  271. package/dist/server/plugins.d.ts +32 -0
  272. package/dist/server/plugins.d.ts.map +1 -0
  273. package/dist/server/plugins.js +795 -0
  274. package/dist/server/plugins.js.map +1 -0
  275. package/dist/server/refactor.d.ts +4 -0
  276. package/dist/server/refactor.d.ts.map +1 -0
  277. package/dist/server/refactor.js +86 -0
  278. package/dist/server/refactor.js.map +1 -0
  279. package/dist/server/rule-files.d.ts +34 -0
  280. package/dist/server/rule-files.d.ts.map +1 -0
  281. package/dist/server/rule-files.js +389 -0
  282. package/dist/server/rule-files.js.map +1 -0
  283. package/dist/server/rules.d.ts +4 -0
  284. package/dist/server/rules.d.ts.map +1 -0
  285. package/dist/server/rules.js +40 -0
  286. package/dist/server/rules.js.map +1 -0
  287. package/dist/server/sessions.d.ts +4 -0
  288. package/dist/server/sessions.d.ts.map +1 -0
  289. package/dist/server/sessions.js +20 -0
  290. package/dist/server/sessions.js.map +1 -0
  291. package/index.js +950 -0
  292. package/mcp-server.js +794 -0
  293. package/package.json +92 -0
  294. package/plugins/builtin/index.ts +25 -0
  295. package/plugins/builtin/logger-plugin.ts +126 -0
  296. package/plugins/builtin/mock-plugin.ts +112 -0
  297. package/plugins/builtin/router-plugin.ts +35 -0
  298. package/web/README.md +111 -0
  299. package/web/dist/assets/ai-config-store-DQXVJVn_.js +1 -0
  300. package/web/dist/assets/alert-COF-DIAE.js +1 -0
  301. package/web/dist/assets/arrow-right-B4Mrlj2-.js +1 -0
  302. package/web/dist/assets/babel-DsprIpXZ.js +15 -0
  303. package/web/dist/assets/body-diff-view-D7dCWajG.js +6 -0
  304. package/web/dist/assets/button-BTToMaBW.js +1 -0
  305. package/web/dist/assets/checkbox-DIBarrJx.js +1 -0
  306. package/web/dist/assets/chevron-down-CPngAx4M.js +1 -0
  307. package/web/dist/assets/chevron-right-V1DGIDbL.js +1 -0
  308. package/web/dist/assets/circle-alert-Q8cZk9Rv.js +1 -0
  309. package/web/dist/assets/circle-x-C9USji_R.js +1 -0
  310. package/web/dist/assets/code-5_eJ_XpJ.js +1 -0
  311. package/web/dist/assets/code-fixer-fQtWZ5He.js +20 -0
  312. package/web/dist/assets/copy-BYjq1hdN.js +1 -0
  313. package/web/dist/assets/detail-panel-BX_hxeI0.js +3 -0
  314. package/web/dist/assets/dist-B8XUKgXe.js +1 -0
  315. package/web/dist/assets/dist-Bb9TeEub.js +1 -0
  316. package/web/dist/assets/dist-C5nMErq8.js +1 -0
  317. package/web/dist/assets/dist-C6eaYCUo.js +1 -0
  318. package/web/dist/assets/dist-Cn0y0IRn.js +1 -0
  319. package/web/dist/assets/dist-CxdY_A67.js +5 -0
  320. package/web/dist/assets/dist-D5Dj17P8.js +1 -0
  321. package/web/dist/assets/dist-DZJ9SMlJ.js +1 -0
  322. package/web/dist/assets/es2015-CfXu88Y7.js +41 -0
  323. package/web/dist/assets/estree-BP7k0NIt.js +44 -0
  324. package/web/dist/assets/file-system-access-CtcvBfj4.js +1 -0
  325. package/web/dist/assets/global-panel-shell-ChdO0dWd.js +6 -0
  326. package/web/dist/assets/health-panel-CQeCQ7gr.js +1 -0
  327. package/web/dist/assets/html-6FIWbqxX.js +25 -0
  328. package/web/dist/assets/index-CjqaTnE_.css +2 -0
  329. package/web/dist/assets/index-L7uWxTnp.js +18 -0
  330. package/web/dist/assets/mobile-proxy-panel-Dj1iLami.js +8 -0
  331. package/web/dist/assets/mock-config-BTTCw7RK.js +1 -0
  332. package/web/dist/assets/mock-editor-panel-C-aVfFme.js +1 -0
  333. package/web/dist/assets/monaco-editor-B3brLg8j.js +11 -0
  334. package/web/dist/assets/pencil-line-Cqe41E4h.js +1 -0
  335. package/web/dist/assets/plugin-code-editor-CPjCbJ9g.js +2 -0
  336. package/web/dist/assets/plugin-config-BzmCkvz3.js +1 -0
  337. package/web/dist/assets/plugin-generator-BnEafDF9.js +2 -0
  338. package/web/dist/assets/plugin-test-dialog-BWoWsWV4.js +7 -0
  339. package/web/dist/assets/plus-tVxSydJ8.js +1 -0
  340. package/web/dist/assets/postcss-Dnf30fQU.js +61 -0
  341. package/web/dist/assets/refresh-cw-CG3HaiQT.js +1 -0
  342. package/web/dist/assets/rotate-ccw-CAYM6Vv0.js +1 -0
  343. package/web/dist/assets/route-preview-BX7sfY0O.js +1 -0
  344. package/web/dist/assets/rule-ai-assistant-panel-WBiOOUw5.js +47 -0
  345. package/web/dist/assets/rule-config-CHpVij2M.css +1 -0
  346. package/web/dist/assets/rule-config-fTIZVwg1.js +15 -0
  347. package/web/dist/assets/select-CkFOB61l.js +1 -0
  348. package/web/dist/assets/server-Cpj4KNwN.js +1 -0
  349. package/web/dist/assets/settings-panel-COCYiIUg.js +1 -0
  350. package/web/dist/assets/shield-check-OqUmVLQt.js +1 -0
  351. package/web/dist/assets/smartphone-DKeDuJTU.js +1 -0
  352. package/web/dist/assets/standalone-CjxtLKw-.js +29 -0
  353. package/web/dist/assets/switch-C-Xk56TK.js +1 -0
  354. package/web/dist/assets/syntax-highlight-DVhPdkuV.js +5 -0
  355. package/web/dist/assets/table-CT97lAYq.js +1 -0
  356. package/web/dist/assets/textarea-C6NooVK1.js +1 -0
  357. package/web/dist/assets/wand-sparkles-wkul5vje.js +1 -0
  358. package/web/dist/assets/wifi-D9M35Ajj.js +1 -0
  359. package/web/dist/assets/zap-Djo4cgux.js +1 -0
  360. package/web/dist/index.html +24 -0
  361. package/web/dist/vite.svg +1 -0
@@ -0,0 +1,697 @@
1
+ "use strict";
2
+ /**
3
+ * AI插件生成器
4
+ * 根据用户需求,使用AI生成符合插件系统规范的插件代码
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.cleanAIResponse = cleanAIResponse;
8
+ exports.generatePluginStream = generatePluginStream;
9
+ exports.fixPluginWithAI = fixPluginWithAI;
10
+ exports.fixPluginWithAIStream = fixPluginWithAIStream;
11
+ exports.revisePluginWithAIStream = revisePluginWithAIStream;
12
+ exports.generatePlugin = generatePlugin;
13
+ const AI_CODE_MAX_TOKENS = 4000;
14
+ function extractTextContent(content) {
15
+ if (typeof content === 'string')
16
+ return content;
17
+ if (!Array.isArray(content))
18
+ return '';
19
+ return content
20
+ .map((part) => {
21
+ if (typeof part === 'string')
22
+ return part;
23
+ if (part && typeof part === 'object' && 'text' in part && typeof part.text === 'string') {
24
+ return part.text;
25
+ }
26
+ return '';
27
+ })
28
+ .join('');
29
+ }
30
+ function readOpenAIMessageContent(data) {
31
+ return extractTextContent(data?.choices?.[0]?.message?.content).trim();
32
+ }
33
+ function readOpenAIStreamChoice(data) {
34
+ const choice = data?.choices?.[0];
35
+ return {
36
+ content: extractTextContent(choice?.delta?.content),
37
+ finishReason: typeof choice?.finish_reason === 'string' ? choice.finish_reason : undefined,
38
+ };
39
+ }
40
+ async function readOpenAIStream(response, onChunk) {
41
+ const reader = response.body?.getReader();
42
+ const decoder = new TextDecoder();
43
+ if (!reader) {
44
+ throw new Error('无法读取响应流');
45
+ }
46
+ let fullCode = '';
47
+ let buffer = '';
48
+ let finishReason = '';
49
+ const consumeLine = (line) => {
50
+ if (!line.startsWith('data:'))
51
+ return;
52
+ const data = line.slice(5).trim();
53
+ if (!data || data === '[DONE]')
54
+ return;
55
+ try {
56
+ const parsed = JSON.parse(data);
57
+ const { content, finishReason: nextFinishReason } = readOpenAIStreamChoice(parsed);
58
+ if (nextFinishReason) {
59
+ finishReason = nextFinishReason;
60
+ }
61
+ if (content) {
62
+ fullCode += content;
63
+ onChunk(content);
64
+ }
65
+ }
66
+ catch (_) {
67
+ // Ignore malformed SSE lines from compatible providers.
68
+ }
69
+ };
70
+ try {
71
+ while (true) {
72
+ const { done, value } = await reader.read();
73
+ if (done)
74
+ break;
75
+ buffer += decoder.decode(value, { stream: true });
76
+ const lines = buffer.split('\n');
77
+ buffer = lines.pop() || '';
78
+ for (const line of lines) {
79
+ consumeLine(line);
80
+ }
81
+ }
82
+ if (buffer.trim()) {
83
+ consumeLine(buffer);
84
+ }
85
+ }
86
+ finally {
87
+ reader.releaseLock();
88
+ }
89
+ if (finishReason === 'length') {
90
+ throw new Error('AI 输出被截断,请缩短补充需求后重试');
91
+ }
92
+ if (!fullCode.trim()) {
93
+ throw new Error('OpenAI 返回了空结果');
94
+ }
95
+ return cleanAIResponse(fullCode);
96
+ }
97
+ /**
98
+ * 生成插件系统设计文档prompt
99
+ */
100
+ function getPluginSystemDesignPrompt() {
101
+ return `# Meddle 插件系统设计
102
+
103
+ ## 插件接口规范
104
+
105
+ 插件必须实现以下接口(JavaScript对象):
106
+
107
+ \`\`\`javascript
108
+ const plugin = {
109
+ manifest: {
110
+ id: 'local.plugin-name', // 唯一标识
111
+ name: '插件名称',
112
+ version: '1.0.0',
113
+ apiVersion: '1.x',
114
+ permissions: ['proxy:read'], // 权限列表
115
+ hooks: ['onRequestStart'], // Hook列表
116
+ priority: 100,
117
+ type: 'local'
118
+ },
119
+
120
+ // 必需:初始化方法
121
+ setup(context) {
122
+ context.log.info('插件初始化');
123
+ },
124
+
125
+ // 可选:启动方法
126
+ start() {
127
+ // 插件启动时执行
128
+ },
129
+
130
+ // 可选:Hook方法
131
+ async onRequestStart(context) {
132
+ context.log.info('请求开始');
133
+ }
134
+ }
135
+
136
+ export interface PluginManifest {
137
+ id: string; // 唯一标识,格式:org.plugin-name
138
+ name?: string; // 显示名称
139
+ version: string; // 版本号
140
+ apiVersion: string; // API版本(当前为 '1.x')
141
+ permissions: string[]; // 权限列表
142
+ hooks: string[]; // 声明的Hook列表
143
+ priority?: number; // 优先级(默认100,数字越小优先级越高)
144
+ type?: string; // 'builtin' | 'local'
145
+ }
146
+
147
+ export interface PluginContext {
148
+ manifest: PluginManifest;
149
+ log: Logger; // 日志接口
150
+ [key: string]: any;
151
+ }
152
+
153
+ export interface HookContext {
154
+ request: Request; // 请求信息
155
+ target: string; // 目标地址
156
+ meta: Record<string, any>; // 元数据存储
157
+ setTarget(target: string): void; // 设置目标地址
158
+ respond(response: Response): void; // 短路响应(仅 onBeforeProxy)
159
+ }
160
+
161
+ export interface ResponseContext {
162
+ request: Request; // 请求信息
163
+ target: string; // 目标地址
164
+ meta: Record<string, any>; // 元数据存储
165
+ response: Response; // 响应信息
166
+ }
167
+ \`\`\`
168
+
169
+ ## 权限模型
170
+
171
+ 可用权限:
172
+ - \`proxy:read\` - 读取请求/响应信息
173
+ - \`proxy:write\` - 修改请求/响应
174
+ - \`response:shortcircuit\` - 短路响应(Mock)
175
+ - \`config:read\` - 读取配置
176
+ - \`config:write\` - 写入配置
177
+ - \`storage:read\` - 读取存储
178
+ - \`storage:write\` - 写入存储
179
+ - \`network:outbound\` - 外部网络访问
180
+
181
+ ## Hook 生命周期
182
+
183
+ 1. \`onRequestStart\` - 请求刚进入代理时调用
184
+ 2. \`onBeforeProxy\` - 即将发起上游请求之前调用(可短路)
185
+ 3. \`onBeforeResponse\` - 收到上游响应,返回客户端之前调用
186
+ 4. \`onAfterResponse\` - 响应完成后异步调用
187
+ 5. \`onError\` - 任意阶段出现错误后调用
188
+
189
+ ## 插件示例
190
+
191
+ \`\`\`javascript
192
+ // example-plugin.js
193
+ exports.plugin = {
194
+ manifest: {
195
+ id: 'local.example',
196
+ name: 'Example Plugin',
197
+ version: '1.0.0',
198
+ apiVersion: '1.x',
199
+ permissions: ['proxy:read'],
200
+ hooks: ['onRequestStart', 'onAfterResponse'],
201
+ priority: 100,
202
+ type: 'local'
203
+ },
204
+
205
+ setup(context) {
206
+ context.log.info(this.manifest.name + ' setup complete');
207
+ },
208
+
209
+ async onRequestStart(context) {
210
+ context.log.info('Request: ' + context.request.method + ' ' + context.request.url);
211
+ },
212
+
213
+ async onAfterResponse(context) {
214
+ context.log.info('Response: ' + context.response.statusCode);
215
+ }
216
+ };
217
+ \`\`\`
218
+
219
+ **重要**: 必须使用 CommonJS 格式(exports.plugin),不要使用 ES6 模块(export const)。`;
220
+ }
221
+ /**
222
+ * 使用 OpenAI 生成插件代码(流式)
223
+ */
224
+ async function generateWithOpenAIStream(requirement, config, onChunk) {
225
+ const systemPrompt = `你是一个专业的插件开发助手,精通 JavaScript 和 Meddle 插件系统。你的任务是根据用户需求生成高质量的插件代码。
226
+
227
+ ${getPluginSystemDesignPrompt()}
228
+
229
+ ## 代码生成要求
230
+
231
+ 1. 必须遵循上述插件接口规范
232
+ 2. 代码必须是**纯 JavaScript**(不要使用TypeScript类型注解)
233
+ 3. 使用 CommonJS 格式:exports.plugin = { ... }
234
+ 4. 插件 ID 格式:local.{plugin-name}(小写,用连字符分隔)
235
+ 5. 只返回代码,不要包含任何解释性文字
236
+ 6. 不要使用 markdown 代码块标记
237
+ 7. 代码要有适当的注释说明功能
238
+ 8. 权限申请要最小化,只申请必需的权限
239
+ 9. 代码必须可以直接在Node.js中执行
240
+ 10. 使用 async/await 处理异步操作`;
241
+ const userPrompt = `请生成一个符合 Meddle 插件系统规范的插件代码。
242
+
243
+ 插件需求:
244
+ 名称:${requirement.name}
245
+ 描述:${requirement.description}
246
+ ${requirement.hooks ? `需要的 Hooks:${requirement.hooks.join(', ')}` : ''}
247
+ ${requirement.permissions ? `需要的权限:${requirement.permissions.join(', ')}` : ''}
248
+
249
+ 请直接返回完整的 JavaScript 插件代码,使用 exports.plugin = {...} 格式导出。
250
+ 代码必须可以直接在Node.js中执行,不要使用任何TypeScript语法。`;
251
+ const response = await fetch(config.baseUrl, {
252
+ method: 'POST',
253
+ headers: {
254
+ 'Content-Type': 'application/json',
255
+ 'Authorization': `Bearer ${config.apiKey}`
256
+ },
257
+ body: JSON.stringify({
258
+ model: config.model,
259
+ messages: [
260
+ { role: 'system', content: systemPrompt },
261
+ { role: 'user', content: userPrompt }
262
+ ],
263
+ temperature: 0.3,
264
+ max_tokens: AI_CODE_MAX_TOKENS,
265
+ stream: true
266
+ })
267
+ });
268
+ if (!response.ok) {
269
+ const errorText = await response.text();
270
+ throw new Error(`OpenAI API 错误 (${response.status}): ${errorText}`);
271
+ }
272
+ return readOpenAIStream(response, onChunk);
273
+ }
274
+ /**
275
+ * 使用 Anthropic 生成插件代码(流式)
276
+ */
277
+ async function generateWithAnthropicStream(requirement, config, onChunk) {
278
+ const systemPrompt = `你是一个专业的插件开发助手,精通 JavaScript 和 Meddle 插件系统。你的任务是根据用户需求生成高质量的插件代码。
279
+
280
+ ${getPluginSystemDesignPrompt()}
281
+
282
+ ## 代码生成要求
283
+
284
+ 1. 必须遵循上述插件接口规范
285
+ 2. 代码必须是**纯 JavaScript**(不要使用TypeScript类型注解)
286
+ 3. 使用 CommonJS 格式:exports.plugin = { ... }
287
+ 4. 插件 ID 格式:local.{plugin-name}(小写,用连字符分隔)
288
+ 5. 只返回代码,不要包含任何解释性文字
289
+ 6. 不要使用 markdown 代码块标记
290
+ 7. 代码要有适当的注释说明功能
291
+ 8. 权限申请要最小化,只申请必需的权限
292
+ 9. 代码必须可以直接在Node.js中执行
293
+ 10. 使用 async/await 处理异步操作`;
294
+ const userPrompt = `请生成一个符合 Meddle 插件系统规范的插件代码。
295
+
296
+ 插件需求:
297
+ 名称:${requirement.name}
298
+ 描述:${requirement.description}
299
+ ${requirement.hooks ? `需要的 Hooks:${requirement.hooks.join(', ')}` : ''}
300
+ ${requirement.permissions ? `需要的权限:${requirement.permissions.join(', ')}` : ''}
301
+
302
+ 请直接返回完整的 JavaScript 插件代码,使用 exports.plugin = {...} 格式导出。
303
+ 代码必须可以直接在Node.js中执行,不要使用任何TypeScript语法。`;
304
+ const response = await fetch(config.baseUrl, {
305
+ method: 'POST',
306
+ headers: {
307
+ 'Content-Type': 'application/json',
308
+ 'x-api-key': config.apiKey,
309
+ 'anthropic-version': '2023-06-01'
310
+ },
311
+ body: JSON.stringify({
312
+ model: config.model,
313
+ max_tokens: AI_CODE_MAX_TOKENS,
314
+ system: systemPrompt,
315
+ messages: [
316
+ { role: 'user', content: userPrompt }
317
+ ],
318
+ temperature: 0.3,
319
+ stream: true
320
+ })
321
+ });
322
+ if (!response.ok) {
323
+ const errorText = await response.text();
324
+ throw new Error(`Anthropic API 错误 (${response.status}): ${errorText}`);
325
+ }
326
+ let fullCode = '';
327
+ const reader = response.body?.getReader();
328
+ const decoder = new TextDecoder();
329
+ if (!reader) {
330
+ throw new Error('无法读取响应流');
331
+ }
332
+ try {
333
+ while (true) {
334
+ const { done, value } = await reader.read();
335
+ if (done)
336
+ break;
337
+ const chunk = decoder.decode(value, { stream: true });
338
+ const lines = chunk.split('\n').filter(line => line.trim() !== '');
339
+ for (const line of lines) {
340
+ if (line.startsWith('data: ')) {
341
+ const data = line.slice(6);
342
+ try {
343
+ const parsed = JSON.parse(data);
344
+ if (parsed.type === 'content_block_delta') {
345
+ const content = parsed.delta?.text;
346
+ if (content) {
347
+ fullCode += content;
348
+ onChunk(content);
349
+ }
350
+ }
351
+ }
352
+ catch (e) {
353
+ // 忽略解析错误
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ finally {
360
+ reader.releaseLock();
361
+ }
362
+ if (!fullCode.trim()) {
363
+ throw new Error('Anthropic 返回了空结果');
364
+ }
365
+ return cleanAIResponse(fullCode);
366
+ }
367
+ /**
368
+ * 清理 AI 响应,移除 markdown 代码块标记
369
+ */
370
+ function cleanAIResponse(text) {
371
+ // 移除可能的 markdown 代码块标记
372
+ let cleaned = text
373
+ .replace(/^```[a-z]*\n?/i, '')
374
+ .replace(/\n?```$/i, '')
375
+ .trim();
376
+ return cleaned;
377
+ }
378
+ /**
379
+ * 从生成的代码中提取 manifest 信息
380
+ */
381
+ function extractManifest(code) {
382
+ try {
383
+ // 尝试通过正则提取 manifest 对象
384
+ const manifestMatch = code.match(/manifest\s*:\s*{([^}]+({[^}]+}[^}]+)*[^}]+)}/s);
385
+ if (!manifestMatch) {
386
+ throw new Error('无法提取 manifest 信息');
387
+ }
388
+ const manifestText = manifestMatch[0];
389
+ // 提取各个字段
390
+ const idMatch = manifestText.match(/id\s*:\s*['"]([^'"]+)['"]/);
391
+ const nameMatch = manifestText.match(/name\s*:\s*['"]([^'"]+)['"]/);
392
+ const versionMatch = manifestText.match(/version\s*:\s*['"]([^'"]+)['"]/);
393
+ const apiVersionMatch = manifestText.match(/apiVersion\s*:\s*['"]([^'"]+)['"]/);
394
+ const permissionsMatch = manifestText.match(/permissions\s*:\s*\[([^\]]*)\]/);
395
+ const hooksMatch = manifestText.match(/hooks\s*:\s*\[([^\]]*)\]/);
396
+ const permissions = permissionsMatch
397
+ ? permissionsMatch[1].split(',').map(p => p.trim().replace(/['"]/g, '')).filter(Boolean)
398
+ : [];
399
+ const hooks = hooksMatch
400
+ ? hooksMatch[1].split(',').map(h => h.trim().replace(/['"]/g, '')).filter(Boolean)
401
+ : [];
402
+ return {
403
+ id: idMatch ? idMatch[1] : 'local.unknown',
404
+ name: nameMatch ? nameMatch[1] : 'Unknown Plugin',
405
+ version: versionMatch ? versionMatch[1] : '1.0.0',
406
+ apiVersion: apiVersionMatch ? apiVersionMatch[1] : '1.x',
407
+ permissions,
408
+ hooks
409
+ };
410
+ }
411
+ catch (error) {
412
+ // 返回默认 manifest
413
+ return {
414
+ id: 'local.unknown',
415
+ name: 'Unknown Plugin',
416
+ version: '1.0.0',
417
+ apiVersion: '1.x',
418
+ permissions: [],
419
+ hooks: []
420
+ };
421
+ }
422
+ }
423
+ /**
424
+ * 生成插件代码(流式)
425
+ */
426
+ async function generatePluginStream(requirement, config, onChunk) {
427
+ let code;
428
+ if (config.provider === 'anthropic') {
429
+ code = await generateWithAnthropicStream(requirement, config, onChunk);
430
+ }
431
+ else {
432
+ code = await generateWithOpenAIStream(requirement, config, onChunk);
433
+ }
434
+ // 提取 manifest 信息
435
+ const manifest = extractManifest(code);
436
+ // 生成文件名(直接是.js)
437
+ const pluginId = manifest.id.replace('local.', '');
438
+ const filename = `${pluginId}.js`;
439
+ return {
440
+ code,
441
+ filename,
442
+ manifest
443
+ };
444
+ }
445
+ /**
446
+ * 根据测试错误自动修复插件代码
447
+ */
448
+ async function fixPluginWithAI(originalCode, testError, requirement, config) {
449
+ const systemPrompt = `你是一个专业的插件调试助手。用户的插件代码在测试时出现了错误,你需要分析错误并修复代码。
450
+
451
+ ${getPluginSystemDesignPrompt()}
452
+
453
+ ## 修复要求
454
+
455
+ 1. 仔细分析测试错误信息
456
+ 2. 找出代码中的问题
457
+ 3. 修复bug,确保代码正确
458
+ 4. 返回修复后的完整代码
459
+ 5. 只返回代码,不要解释
460
+ 6. 代码必须是纯JavaScript(CommonJS格式)`;
461
+ const userPrompt = `以下是插件代码和测试错误,请修复代码中的问题。
462
+
463
+ 原始需求:
464
+ ${requirement.description}
465
+
466
+ 当前代码:
467
+ \`\`\`javascript
468
+ ${originalCode}
469
+ \`\`\`
470
+
471
+ 测试错误:
472
+ ${testError}
473
+
474
+ 请分析错误原因并返回修复后的完整JavaScript代码。`;
475
+ if (config.provider === 'anthropic') {
476
+ return fixWithAnthropicNonStream(userPrompt, systemPrompt, config);
477
+ }
478
+ else {
479
+ return fixWithOpenAINonStream(userPrompt, systemPrompt, config);
480
+ }
481
+ }
482
+ async function fixWithOpenAINonStream(userPrompt, systemPrompt, config) {
483
+ const response = await fetch(config.baseUrl, {
484
+ method: 'POST',
485
+ headers: {
486
+ 'Content-Type': 'application/json',
487
+ 'Authorization': `Bearer ${config.apiKey}`
488
+ },
489
+ body: JSON.stringify({
490
+ model: config.model,
491
+ messages: [
492
+ { role: 'system', content: systemPrompt },
493
+ { role: 'user', content: userPrompt }
494
+ ],
495
+ temperature: 0.3,
496
+ max_tokens: AI_CODE_MAX_TOKENS
497
+ })
498
+ });
499
+ if (!response.ok) {
500
+ const errorText = await response.text();
501
+ throw new Error(`OpenAI API 错误 (${response.status}): ${errorText}`);
502
+ }
503
+ const data = await response.json();
504
+ const code = readOpenAIMessageContent(data);
505
+ if (!code) {
506
+ throw new Error('OpenAI 返回了空结果');
507
+ }
508
+ return cleanAIResponse(code);
509
+ }
510
+ async function fixWithOpenAIStream(userPrompt, systemPrompt, config, onChunk) {
511
+ const response = await fetch(config.baseUrl, {
512
+ method: 'POST',
513
+ headers: {
514
+ 'Content-Type': 'application/json',
515
+ 'Authorization': `Bearer ${config.apiKey}`
516
+ },
517
+ body: JSON.stringify({
518
+ model: config.model,
519
+ messages: [
520
+ { role: 'system', content: systemPrompt },
521
+ { role: 'user', content: userPrompt }
522
+ ],
523
+ temperature: 0.3,
524
+ max_tokens: AI_CODE_MAX_TOKENS,
525
+ stream: true
526
+ })
527
+ });
528
+ if (!response.ok) {
529
+ const errorText = await response.text();
530
+ throw new Error(`OpenAI API 错误 (${response.status}): ${errorText}`);
531
+ }
532
+ return readOpenAIStream(response, onChunk);
533
+ }
534
+ async function fixWithAnthropicNonStream(userPrompt, systemPrompt, config) {
535
+ const response = await fetch(config.baseUrl, {
536
+ method: 'POST',
537
+ headers: {
538
+ 'Content-Type': 'application/json',
539
+ 'x-api-key': config.apiKey,
540
+ 'anthropic-version': '2023-06-01'
541
+ },
542
+ body: JSON.stringify({
543
+ model: config.model,
544
+ max_tokens: AI_CODE_MAX_TOKENS,
545
+ system: systemPrompt,
546
+ messages: [
547
+ { role: 'user', content: userPrompt }
548
+ ],
549
+ temperature: 0.3
550
+ })
551
+ });
552
+ if (!response.ok) {
553
+ const errorText = await response.text();
554
+ throw new Error(`Anthropic API 错误 (${response.status}): ${errorText}`);
555
+ }
556
+ const data = await response.json();
557
+ const code = data.content?.[0]?.text?.trim();
558
+ if (!code) {
559
+ throw new Error('Anthropic 返回了空结果');
560
+ }
561
+ return cleanAIResponse(code);
562
+ }
563
+ async function fixWithAnthropicStream(userPrompt, systemPrompt, config, onChunk) {
564
+ const response = await fetch(config.baseUrl, {
565
+ method: 'POST',
566
+ headers: {
567
+ 'Content-Type': 'application/json',
568
+ 'x-api-key': config.apiKey,
569
+ 'anthropic-version': '2023-06-01'
570
+ },
571
+ body: JSON.stringify({
572
+ model: config.model,
573
+ max_tokens: AI_CODE_MAX_TOKENS,
574
+ system: systemPrompt,
575
+ messages: [
576
+ { role: 'user', content: userPrompt }
577
+ ],
578
+ temperature: 0.3,
579
+ stream: true
580
+ })
581
+ });
582
+ if (!response.ok) {
583
+ const errorText = await response.text();
584
+ throw new Error(`Anthropic API 错误 (${response.status}): ${errorText}`);
585
+ }
586
+ const reader = response.body?.getReader();
587
+ const decoder = new TextDecoder();
588
+ if (!reader) {
589
+ throw new Error('无法读取响应流');
590
+ }
591
+ let fullCode = '';
592
+ try {
593
+ while (true) {
594
+ const { done, value } = await reader.read();
595
+ if (done)
596
+ break;
597
+ const chunk = decoder.decode(value, { stream: true });
598
+ const lines = chunk.split('\n').filter(line => line.trim() !== '');
599
+ for (const line of lines) {
600
+ if (!line.startsWith('data: '))
601
+ continue;
602
+ const data = line.slice(6);
603
+ try {
604
+ const parsed = JSON.parse(data);
605
+ if (parsed.type === 'content_block_delta') {
606
+ const content = parsed.delta?.text;
607
+ if (content) {
608
+ fullCode += content;
609
+ onChunk(content);
610
+ }
611
+ }
612
+ }
613
+ catch (_) {
614
+ // ignore parse errors
615
+ }
616
+ }
617
+ }
618
+ }
619
+ finally {
620
+ reader.releaseLock();
621
+ }
622
+ if (!fullCode.trim()) {
623
+ throw new Error('Anthropic 返回了空结果');
624
+ }
625
+ return cleanAIResponse(fullCode);
626
+ }
627
+ async function fixPluginWithAIStream(originalCode, testError, requirement, config, onChunk) {
628
+ const systemPrompt = `你是一个专业的插件调试助手。用户的插件代码在测试时出现了错误,你需要分析错误并修复代码。
629
+
630
+ ${getPluginSystemDesignPrompt()}
631
+
632
+ ## 修复要求
633
+
634
+ 1. 仔细分析测试错误信息
635
+ 2. 找出代码中的问题
636
+ 3. 修复bug,确保代码正确
637
+ 4. 返回修复后的完整代码
638
+ 5. 只返回代码,不要解释
639
+ 6. 代码必须是纯JavaScript(CommonJS格式)`;
640
+ const userPrompt = `以下是插件代码和测试错误,请修复代码中的问题。
641
+
642
+ 原始需求:
643
+ ${requirement.description}
644
+
645
+ 当前代码:
646
+ \`\`\`javascript
647
+ ${originalCode}
648
+ \`\`\`
649
+
650
+ 测试错误:
651
+ ${testError}
652
+
653
+ 请分析错误原因并返回修复后的完整JavaScript代码。`;
654
+ if (config.provider === 'anthropic') {
655
+ return fixWithAnthropicStream(userPrompt, systemPrompt, config, onChunk);
656
+ }
657
+ return fixWithOpenAIStream(userPrompt, systemPrompt, config, onChunk);
658
+ }
659
+ async function revisePluginWithAIStream(originalCode, instruction, requirement, config, onChunk) {
660
+ const systemPrompt = `你是一个专业的 Meddle 插件开发助手。用户会给你现有插件代码和额外修改要求,你需要在保持插件可运行的前提下更新代码。
661
+
662
+ ${getPluginSystemDesignPrompt()}
663
+
664
+ ## 更新要求
665
+
666
+ 1. 基于现有代码做增量修改,不要无关重写
667
+ 2. 严格保留插件 manifest 的核心语义,除非用户明确要求修改
668
+ 3. 保持已有 hooks 与权限声明正确
669
+ 4. 返回更新后的完整代码
670
+ 5. 只返回代码,不要解释
671
+ 6. 代码必须是纯JavaScript(CommonJS格式)`;
672
+ const userPrompt = `以下是当前插件代码和新的修改要求,请直接更新插件代码。
673
+
674
+ 原始需求:
675
+ ${requirement.description}
676
+
677
+ 当前代码:
678
+ \`\`\`javascript
679
+ ${originalCode}
680
+ \`\`\`
681
+
682
+ 额外修改要求:
683
+ ${instruction}
684
+
685
+ 请返回更新后的完整 JavaScript 插件代码。`;
686
+ if (config.provider === 'anthropic') {
687
+ return fixWithAnthropicStream(userPrompt, systemPrompt, config, onChunk);
688
+ }
689
+ return fixWithOpenAIStream(userPrompt, systemPrompt, config, onChunk);
690
+ }
691
+ /**
692
+ * 生成插件代码(非流式,向后兼容)
693
+ */
694
+ async function generatePlugin(requirement, config) {
695
+ return generatePluginStream(requirement, config, () => { });
696
+ }
697
+ //# sourceMappingURL=plugin-generator.js.map