@rotifer/playground 0.8.1 → 0.8.6

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 (453) hide show
  1. package/CHANGELOG.md +46 -11
  2. package/README.md +92 -58
  3. package/README.zh.md +90 -49
  4. package/dist/cloud/auth.d.ts +9 -3
  5. package/dist/cloud/auth.d.ts.map +1 -1
  6. package/dist/cloud/auth.js +28 -13
  7. package/dist/cloud/auth.js.map +1 -1
  8. package/dist/cloud/client.d.ts +4 -3
  9. package/dist/cloud/client.d.ts.map +1 -1
  10. package/dist/cloud/client.js +139 -68
  11. package/dist/cloud/client.js.map +1 -1
  12. package/dist/cloud/types.d.ts +3 -0
  13. package/dist/cloud/types.d.ts.map +1 -1
  14. package/dist/cloud/types.js.map +1 -1
  15. package/dist/commands/agent-create.d.ts +20 -0
  16. package/dist/commands/agent-create.d.ts.map +1 -1
  17. package/dist/commands/agent-create.js +91 -80
  18. package/dist/commands/agent-create.js.map +1 -1
  19. package/dist/commands/agent-list.d.ts.map +1 -1
  20. package/dist/commands/agent-list.js +27 -24
  21. package/dist/commands/agent-list.js.map +1 -1
  22. package/dist/commands/agent-run.d.ts +24 -0
  23. package/dist/commands/agent-run.d.ts.map +1 -1
  24. package/dist/commands/agent-run.js +166 -44
  25. package/dist/commands/agent-run.js.map +1 -1
  26. package/dist/commands/api-key.d.ts +3 -0
  27. package/dist/commands/api-key.d.ts.map +1 -0
  28. package/dist/commands/api-key.js +235 -0
  29. package/dist/commands/api-key.js.map +1 -0
  30. package/dist/commands/arena-list.d.ts.map +1 -1
  31. package/dist/commands/arena-list.js +113 -97
  32. package/dist/commands/arena-list.js.map +1 -1
  33. package/dist/commands/arena-submit.d.ts.map +1 -1
  34. package/dist/commands/arena-submit.js +114 -37
  35. package/dist/commands/arena-submit.js.map +1 -1
  36. package/dist/commands/arena-watch.d.ts.map +1 -1
  37. package/dist/commands/arena-watch.js +59 -87
  38. package/dist/commands/arena-watch.js.map +1 -1
  39. package/dist/commands/compare.d.ts.map +1 -1
  40. package/dist/commands/compare.js +40 -50
  41. package/dist/commands/compare.js.map +1 -1
  42. package/dist/commands/compile.d.ts.map +1 -1
  43. package/dist/commands/compile.js +80 -58
  44. package/dist/commands/compile.js.map +1 -1
  45. package/dist/commands/hello.d.ts +3 -0
  46. package/dist/commands/hello.d.ts.map +1 -0
  47. package/dist/commands/hello.js +575 -0
  48. package/dist/commands/hello.js.map +1 -0
  49. package/dist/commands/info.d.ts.map +1 -1
  50. package/dist/commands/info.js +130 -40
  51. package/dist/commands/info.js.map +1 -1
  52. package/dist/commands/init.d.ts.map +1 -1
  53. package/dist/commands/init.js +39 -60
  54. package/dist/commands/init.js.map +1 -1
  55. package/dist/commands/install.d.ts.map +1 -1
  56. package/dist/commands/install.js +35 -9
  57. package/dist/commands/install.js.map +1 -1
  58. package/dist/commands/list.d.ts.map +1 -1
  59. package/dist/commands/list.js +111 -58
  60. package/dist/commands/list.js.map +1 -1
  61. package/dist/commands/login.d.ts.map +1 -1
  62. package/dist/commands/login.js +23 -10
  63. package/dist/commands/login.js.map +1 -1
  64. package/dist/commands/network.d.ts.map +1 -1
  65. package/dist/commands/network.js +48 -67
  66. package/dist/commands/network.js.map +1 -1
  67. package/dist/commands/publish.d.ts.map +1 -1
  68. package/dist/commands/publish.js +152 -53
  69. package/dist/commands/publish.js.map +1 -1
  70. package/dist/commands/reputation.js +84 -85
  71. package/dist/commands/reputation.js.map +1 -1
  72. package/dist/commands/run.d.ts.map +1 -1
  73. package/dist/commands/run.js +32 -12
  74. package/dist/commands/run.js.map +1 -1
  75. package/dist/commands/scan.d.ts.map +1 -1
  76. package/dist/commands/scan.js +8 -9
  77. package/dist/commands/scan.js.map +1 -1
  78. package/dist/commands/search.d.ts.map +1 -1
  79. package/dist/commands/search.js +80 -54
  80. package/dist/commands/search.js.map +1 -1
  81. package/dist/commands/self-update.d.ts +7 -0
  82. package/dist/commands/self-update.d.ts.map +1 -0
  83. package/dist/commands/self-update.js +187 -0
  84. package/dist/commands/self-update.js.map +1 -0
  85. package/dist/commands/stats.d.ts.map +1 -1
  86. package/dist/commands/stats.js +20 -26
  87. package/dist/commands/stats.js.map +1 -1
  88. package/dist/commands/test.d.ts.map +1 -1
  89. package/dist/commands/test.js +104 -79
  90. package/dist/commands/test.js.map +1 -1
  91. package/dist/commands/user-config.d.ts +3 -0
  92. package/dist/commands/user-config.d.ts.map +1 -0
  93. package/dist/commands/user-config.js +82 -0
  94. package/dist/commands/user-config.js.map +1 -0
  95. package/dist/commands/versions.d.ts.map +1 -1
  96. package/dist/commands/versions.js +46 -33
  97. package/dist/commands/versions.js.map +1 -1
  98. package/dist/commands/vg.d.ts.map +1 -1
  99. package/dist/commands/vg.js +65 -63
  100. package/dist/commands/vg.js.map +1 -1
  101. package/dist/commands/whoami.d.ts.map +1 -1
  102. package/dist/commands/whoami.js +33 -23
  103. package/dist/commands/whoami.js.map +1 -1
  104. package/dist/commands/wrap.d.ts.map +1 -1
  105. package/dist/commands/wrap.js +57 -40
  106. package/dist/commands/wrap.js.map +1 -1
  107. package/dist/index.js +61 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/publish/pre-publish-check.d.ts +15 -0
  110. package/dist/publish/pre-publish-check.d.ts.map +1 -0
  111. package/dist/publish/pre-publish-check.js +228 -0
  112. package/dist/publish/pre-publish-check.js.map +1 -0
  113. package/dist/runtime/domain-failover.d.ts +1 -1
  114. package/dist/runtime/domain-failover.js +1 -1
  115. package/dist/runtime/network-gateway.d.ts +1 -1
  116. package/dist/runtime/network-gateway.d.ts.map +1 -1
  117. package/dist/runtime/network-gateway.js +10 -10
  118. package/dist/runtime/network-gateway.js.map +1 -1
  119. package/dist/scanner/scanner.js +3 -3
  120. package/dist/scanner/scanner.js.map +1 -1
  121. package/dist/utils/binding.d.ts +1 -0
  122. package/dist/utils/binding.d.ts.map +1 -1
  123. package/dist/utils/binding.js +37 -15
  124. package/dist/utils/binding.js.map +1 -1
  125. package/dist/utils/content-hash.d.ts +3 -0
  126. package/dist/utils/content-hash.d.ts.map +1 -0
  127. package/dist/utils/content-hash.js +25 -0
  128. package/dist/utils/content-hash.js.map +1 -0
  129. package/dist/utils/detect-source-language.d.ts +20 -0
  130. package/dist/utils/detect-source-language.d.ts.map +1 -0
  131. package/dist/utils/detect-source-language.js +83 -0
  132. package/dist/utils/detect-source-language.js.map +1 -0
  133. package/dist/utils/display.d.ts +44 -1
  134. package/dist/utils/display.d.ts.map +1 -1
  135. package/dist/utils/display.js +443 -14
  136. package/dist/utils/display.js.map +1 -1
  137. package/dist/utils/domain-suggest.d.ts.map +1 -1
  138. package/dist/utils/domain-suggest.js +3 -3
  139. package/dist/utils/domain-suggest.js.map +1 -1
  140. package/dist/utils/javy-compiler.d.ts.map +1 -1
  141. package/dist/utils/javy-compiler.js +10 -3
  142. package/dist/utils/javy-compiler.js.map +1 -1
  143. package/dist/utils/open-browser.d.ts +7 -3
  144. package/dist/utils/open-browser.d.ts.map +1 -1
  145. package/dist/utils/open-browser.js +15 -4
  146. package/dist/utils/open-browser.js.map +1 -1
  147. package/dist/utils/palette.d.ts +49 -0
  148. package/dist/utils/palette.d.ts.map +1 -0
  149. package/dist/utils/palette.js +80 -0
  150. package/dist/utils/palette.js.map +1 -0
  151. package/dist/utils/private-fs.d.ts +3 -0
  152. package/dist/utils/private-fs.d.ts.map +1 -0
  153. package/dist/utils/private-fs.js +25 -0
  154. package/dist/utils/private-fs.js.map +1 -0
  155. package/dist/utils/project-root.d.ts +2 -0
  156. package/dist/utils/project-root.d.ts.map +1 -0
  157. package/dist/utils/project-root.js +49 -0
  158. package/dist/utils/project-root.js.map +1 -0
  159. package/dist/utils/run-logger.d.ts +24 -0
  160. package/dist/utils/run-logger.d.ts.map +1 -0
  161. package/dist/utils/run-logger.js +70 -0
  162. package/dist/utils/run-logger.js.map +1 -0
  163. package/dist/utils/sandbox-defaults.d.ts +9 -0
  164. package/dist/utils/sandbox-defaults.d.ts.map +1 -0
  165. package/dist/utils/sandbox-defaults.js +12 -0
  166. package/dist/utils/sandbox-defaults.js.map +1 -0
  167. package/dist/utils/update-check.d.ts +20 -0
  168. package/dist/utils/update-check.d.ts.map +1 -0
  169. package/dist/utils/update-check.js +155 -0
  170. package/dist/utils/update-check.js.map +1 -0
  171. package/dist/utils/user-config.d.ts +10 -0
  172. package/dist/utils/user-config.d.ts.map +1 -0
  173. package/dist/utils/user-config.js +54 -0
  174. package/dist/utils/user-config.js.map +1 -0
  175. package/dist/utils/validate-gene-name.d.ts +7 -0
  176. package/dist/utils/validate-gene-name.d.ts.map +1 -0
  177. package/dist/utils/validate-gene-name.js +28 -0
  178. package/dist/utils/validate-gene-name.js.map +1 -0
  179. package/genes/genesis-code-format/phenotype.json +4 -3
  180. package/genes/genesis-file-read/phenotype.json +4 -3
  181. package/genes/genesis-l0-constraint/phenotype.json +4 -3
  182. package/genes/genesis-web-search/phenotype.json +5 -4
  183. package/genes/genesis-web-search-lite/phenotype.json +4 -3
  184. package/package.json +35 -8
  185. package/scripts/postinstall.js +38 -0
  186. package/dist/errors/formatter.d.ts +0 -25
  187. package/dist/errors/formatter.d.ts.map +0 -1
  188. package/dist/errors/formatter.js +0 -43
  189. package/dist/errors/formatter.js.map +0 -1
  190. package/genes/academic-writer/.cloud-manifest.json +0 -6
  191. package/genes/academic-writer/.gene-manifest.json +0 -8
  192. package/genes/academic-writer/SKILL.md +0 -274
  193. package/genes/academic-writer/phenotype.json +0 -28
  194. package/genes/ai-components/.cloud-manifest.json +0 -6
  195. package/genes/ai-components/.gene-manifest.json +0 -8
  196. package/genes/ai-components/SKILL.md +0 -381
  197. package/genes/ai-components/phenotype.json +0 -28
  198. package/genes/algorithmic-art/.cloud-manifest.json +0 -6
  199. package/genes/algorithmic-art/.gene-manifest.json +0 -8
  200. package/genes/algorithmic-art/SKILL.md +0 -405
  201. package/genes/algorithmic-art/phenotype.json +0 -28
  202. package/genes/answer-synthesizer/.cloud-manifest.json +0 -6
  203. package/genes/answer-synthesizer/index.ts +0 -194
  204. package/genes/answer-synthesizer/phenotype.json +0 -61
  205. package/genes/api-designer/.cloud-manifest.json +0 -6
  206. package/genes/api-designer/.gene-manifest.json +0 -8
  207. package/genes/api-designer/SKILL.md +0 -456
  208. package/genes/api-designer/phenotype.json +0 -28
  209. package/genes/auto-coder/.cloud-manifest.json +0 -6
  210. package/genes/auto-coder/.gene-manifest.json +0 -8
  211. package/genes/auto-coder/SKILL.md +0 -400
  212. package/genes/auto-coder/phenotype.json +0 -28
  213. package/genes/auto-writer/.cloud-manifest.json +0 -6
  214. package/genes/auto-writer/.gene-manifest.json +0 -8
  215. package/genes/auto-writer/SKILL.md +0 -361
  216. package/genes/auto-writer/phenotype.json +0 -28
  217. package/genes/brand-personality/.cloud-manifest.json +0 -6
  218. package/genes/brand-personality/.gene-manifest.json +0 -8
  219. package/genes/brand-personality/SKILL.md +0 -549
  220. package/genes/brand-personality/phenotype.json +0 -28
  221. package/genes/business-writer/.cloud-manifest.json +0 -6
  222. package/genes/business-writer/.gene-manifest.json +0 -8
  223. package/genes/business-writer/SKILL.md +0 -448
  224. package/genes/business-writer/phenotype.json +0 -28
  225. package/genes/citation-manager/.cloud-manifest.json +0 -6
  226. package/genes/citation-manager/.gene-manifest.json +0 -8
  227. package/genes/citation-manager/SKILL.md +0 -279
  228. package/genes/citation-manager/index.ts +0 -162
  229. package/genes/citation-manager/package.json +0 -1
  230. package/genes/citation-manager/phenotype.json +0 -50
  231. package/genes/code-complexity/.cloud-manifest.json +0 -6
  232. package/genes/code-complexity/README.md +0 -35
  233. package/genes/code-complexity/index.ts +0 -101
  234. package/genes/code-complexity/phenotype.json +0 -34
  235. package/genes/copywriter/.cloud-manifest.json +0 -6
  236. package/genes/copywriter/.gene-manifest.json +0 -8
  237. package/genes/copywriter/SKILL.md +0 -329
  238. package/genes/copywriter/phenotype.json +0 -28
  239. package/genes/creative-writer/.cloud-manifest.json +0 -6
  240. package/genes/creative-writer/.gene-manifest.json +0 -8
  241. package/genes/creative-writer/SKILL.md +0 -356
  242. package/genes/creative-writer/phenotype.json +0 -28
  243. package/genes/data-modeler/.cloud-manifest.json +0 -6
  244. package/genes/data-modeler/.gene-manifest.json +0 -8
  245. package/genes/data-modeler/SKILL.md +0 -486
  246. package/genes/data-modeler/phenotype.json +0 -28
  247. package/genes/debugger/.cloud-manifest.json +0 -6
  248. package/genes/debugger/.gene-manifest.json +0 -8
  249. package/genes/debugger/SKILL.md +0 -416
  250. package/genes/debugger/phenotype.json +0 -28
  251. package/genes/design-tokens/.cloud-manifest.json +0 -6
  252. package/genes/design-tokens/.gene-manifest.json +0 -8
  253. package/genes/design-tokens/SKILL.md +0 -222
  254. package/genes/design-tokens/index.ts +0 -128
  255. package/genes/design-tokens/package.json +0 -1
  256. package/genes/design-tokens/phenotype.json +0 -1
  257. package/genes/devops-automator/.cloud-manifest.json +0 -6
  258. package/genes/devops-automator/.gene-manifest.json +0 -8
  259. package/genes/devops-automator/SKILL.md +0 -490
  260. package/genes/devops-automator/phenotype.json +0 -28
  261. package/genes/doc-coauthoring/.cloud-manifest.json +0 -6
  262. package/genes/doc-coauthoring/.gene-manifest.json +0 -8
  263. package/genes/doc-coauthoring/SKILL.md +0 -375
  264. package/genes/doc-coauthoring/phenotype.json +0 -28
  265. package/genes/doc-retrieval/.cloud-manifest.json +0 -6
  266. package/genes/doc-retrieval/index.ts +0 -134
  267. package/genes/doc-retrieval/phenotype.json +0 -54
  268. package/genes/docs-writer/.cloud-manifest.json +0 -6
  269. package/genes/docs-writer/.gene-manifest.json +0 -8
  270. package/genes/docs-writer/SKILL.md +0 -492
  271. package/genes/docs-writer/phenotype.json +0 -28
  272. package/genes/evolve-life/.cloud-manifest.json +0 -6
  273. package/genes/evolve-life/.compile-result.json +0 -12
  274. package/genes/evolve-life/README.md +0 -52
  275. package/genes/evolve-life/gene.ir.wasm +0 -0
  276. package/genes/evolve-life/gene.wasm +0 -0
  277. package/genes/evolve-life/index.ts +0 -255
  278. package/genes/evolve-life/phenotype.json +0 -129
  279. package/genes/evolve-life-bitwise/.cloud-manifest.json +0 -6
  280. package/genes/evolve-life-bitwise/.compile-result.json +0 -12
  281. package/genes/evolve-life-bitwise/gene.ir.wasm +0 -0
  282. package/genes/evolve-life-bitwise/gene.wasm +0 -0
  283. package/genes/evolve-life-bitwise/index.ts +0 -273
  284. package/genes/evolve-life-bitwise/phenotype.json +0 -129
  285. package/genes/evolve-life-sparse/.cloud-manifest.json +0 -6
  286. package/genes/evolve-life-sparse/.compile-result.json +0 -12
  287. package/genes/evolve-life-sparse/gene.ir.wasm +0 -0
  288. package/genes/evolve-life-sparse/gene.wasm +0 -0
  289. package/genes/evolve-life-sparse/index.ts +0 -236
  290. package/genes/evolve-life-sparse/phenotype.json +0 -129
  291. package/genes/fact-checker/.cloud-manifest.json +0 -6
  292. package/genes/fact-checker/.gene-manifest.json +0 -8
  293. package/genes/fact-checker/SKILL.md +0 -373
  294. package/genes/fact-checker/phenotype.json +0 -28
  295. package/genes/git-workflow/.cloud-manifest.json +0 -6
  296. package/genes/git-workflow/.gene-manifest.json +0 -8
  297. package/genes/git-workflow/SKILL.md +0 -407
  298. package/genes/git-workflow/phenotype.json +0 -28
  299. package/genes/grammar-checker/.cloud-manifest.json +0 -6
  300. package/genes/grammar-checker/.gene-manifest.json +0 -8
  301. package/genes/grammar-checker/SKILL.md +0 -194
  302. package/genes/grammar-checker/index.ts +0 -168
  303. package/genes/grammar-checker/package.json +0 -1
  304. package/genes/grammar-checker/phenotype.json +0 -52
  305. package/genes/guard-balanced/.gene-manifest.json +0 -8
  306. package/genes/guard-balanced/phenotype.json +0 -105
  307. package/genes/guard-balanced/system-prompt.md +0 -23
  308. package/genes/guard-strict/.gene-manifest.json +0 -8
  309. package/genes/guard-strict/phenotype.json +0 -107
  310. package/genes/guard-strict/system-prompt.md +0 -18
  311. package/genes/json-validator/.cloud-manifest.json +0 -6
  312. package/genes/json-validator/README.md +0 -42
  313. package/genes/json-validator/index.ts +0 -112
  314. package/genes/json-validator/phenotype.json +0 -42
  315. package/genes/license-advisor/.cloud-manifest.json +0 -6
  316. package/genes/license-advisor/.gene-manifest.json +0 -8
  317. package/genes/license-advisor/SKILL.md +0 -117
  318. package/genes/license-advisor/phenotype.json +0 -28
  319. package/genes/logic-architect/.cloud-manifest.json +0 -6
  320. package/genes/logic-architect/.gene-manifest.json +0 -8
  321. package/genes/logic-architect/SKILL.md +0 -451
  322. package/genes/logic-architect/phenotype.json +0 -28
  323. package/genes/markdown-formatter/.cloud-manifest.json +0 -6
  324. package/genes/markdown-formatter/README.md +0 -34
  325. package/genes/markdown-formatter/index.ts +0 -86
  326. package/genes/markdown-formatter/phenotype.json +0 -32
  327. package/genes/orch/.cloud-manifest.json +0 -6
  328. package/genes/orch/.gene-manifest.json +0 -8
  329. package/genes/orch/SKILL.md +0 -504
  330. package/genes/orch/phenotype.json +0 -28
  331. package/genes/particle-barneshut/.cloud-manifest.json +0 -6
  332. package/genes/particle-barneshut/.compile-result.json +0 -12
  333. package/genes/particle-barneshut/README.md +0 -55
  334. package/genes/particle-barneshut/gene.ir.wasm +0 -0
  335. package/genes/particle-barneshut/gene.wasm +0 -0
  336. package/genes/particle-barneshut/index.ts +0 -486
  337. package/genes/particle-barneshut/phenotype.json +0 -137
  338. package/genes/particle-brute/.cloud-manifest.json +0 -6
  339. package/genes/particle-brute/.compile-result.json +0 -12
  340. package/genes/particle-brute/README.md +0 -55
  341. package/genes/particle-brute/gene.ir.wasm +0 -0
  342. package/genes/particle-brute/gene.wasm +0 -0
  343. package/genes/particle-brute/index.ts +0 -277
  344. package/genes/particle-brute/phenotype.json +0 -137
  345. package/genes/particle-spatial/.cloud-manifest.json +0 -6
  346. package/genes/particle-spatial/.compile-result.json +0 -12
  347. package/genes/particle-spatial/README.md +0 -53
  348. package/genes/particle-spatial/gene.ir.wasm +0 -0
  349. package/genes/particle-spatial/gene.wasm +0 -0
  350. package/genes/particle-spatial/index.ts +0 -352
  351. package/genes/particle-spatial/phenotype.json +0 -137
  352. package/genes/performance-optimizer/.cloud-manifest.json +0 -6
  353. package/genes/performance-optimizer/.gene-manifest.json +0 -8
  354. package/genes/performance-optimizer/SKILL.md +0 -480
  355. package/genes/performance-optimizer/phenotype.json +0 -28
  356. package/genes/plagiarism-checker/.cloud-manifest.json +0 -6
  357. package/genes/plagiarism-checker/.gene-manifest.json +0 -8
  358. package/genes/plagiarism-checker/SKILL.md +0 -342
  359. package/genes/plagiarism-checker/phenotype.json +0 -28
  360. package/genes/product-manager/.cloud-manifest.json +0 -6
  361. package/genes/product-manager/.gene-manifest.json +0 -8
  362. package/genes/product-manager/SKILL.md +0 -249
  363. package/genes/product-manager/phenotype.json +0 -28
  364. package/genes/project-reviewer/.cloud-manifest.json +0 -6
  365. package/genes/project-reviewer/.gene-manifest.json +0 -8
  366. package/genes/project-reviewer/SKILL.md +0 -312
  367. package/genes/project-reviewer/phenotype.json +0 -28
  368. package/genes/prompt-engineer/.cloud-manifest.json +0 -6
  369. package/genes/prompt-engineer/.gene-manifest.json +0 -8
  370. package/genes/prompt-engineer/SKILL.md +0 -411
  371. package/genes/prompt-engineer/phenotype.json +0 -28
  372. package/genes/prompt-review-perf/.gene-manifest.json +0 -8
  373. package/genes/prompt-review-perf/phenotype.json +0 -61
  374. package/genes/prompt-review-perf/system-prompt.md +0 -22
  375. package/genes/prompt-review-readability/.gene-manifest.json +0 -8
  376. package/genes/prompt-review-readability/phenotype.json +0 -60
  377. package/genes/prompt-review-readability/system-prompt.md +0 -21
  378. package/genes/prompt-review-security/.gene-manifest.json +0 -8
  379. package/genes/prompt-review-security/phenotype.json +0 -60
  380. package/genes/prompt-review-security/system-prompt.md +0 -21
  381. package/genes/readability-analyzer/.cloud-manifest.json +0 -6
  382. package/genes/readability-analyzer/.gene-manifest.json +0 -8
  383. package/genes/readability-analyzer/SKILL.md +0 -357
  384. package/genes/readability-analyzer/index.ts +0 -123
  385. package/genes/readability-analyzer/package.json +0 -1
  386. package/genes/readability-analyzer/phenotype.json +0 -35
  387. package/genes/rotifer-protocol/SKILL.md +0 -121
  388. package/genes/rule-router-frequency/.gene-manifest.json +0 -8
  389. package/genes/rule-router-frequency/phenotype.json +0 -76
  390. package/genes/rule-router-frequency/system-prompt.md +0 -26
  391. package/genes/rule-router-relevance/.gene-manifest.json +0 -8
  392. package/genes/rule-router-relevance/phenotype.json +0 -76
  393. package/genes/rule-router-relevance/system-prompt.md +0 -29
  394. package/genes/security-auditor/.cloud-manifest.json +0 -6
  395. package/genes/security-auditor/.gene-manifest.json +0 -8
  396. package/genes/security-auditor/SKILL.md +0 -494
  397. package/genes/security-auditor/phenotype.json +0 -28
  398. package/genes/seo-optimizer/.cloud-manifest.json +0 -6
  399. package/genes/seo-optimizer/.gene-manifest.json +0 -8
  400. package/genes/seo-optimizer/SKILL.md +0 -327
  401. package/genes/seo-optimizer/index.ts +0 -206
  402. package/genes/seo-optimizer/package.json +0 -1
  403. package/genes/seo-optimizer/phenotype.json +0 -1
  404. package/genes/source-linker/.cloud-manifest.json +0 -6
  405. package/genes/source-linker/index.ts +0 -88
  406. package/genes/source-linker/phenotype.json +0 -45
  407. package/genes/style-optimizer/.cloud-manifest.json +0 -6
  408. package/genes/style-optimizer/.gene-manifest.json +0 -8
  409. package/genes/style-optimizer/SKILL.md +0 -285
  410. package/genes/style-optimizer/phenotype.json +0 -28
  411. package/genes/tech-lead/.cloud-manifest.json +0 -6
  412. package/genes/tech-lead/.gene-manifest.json +0 -8
  413. package/genes/tech-lead/SKILL.md +0 -451
  414. package/genes/tech-lead/phenotype.json +0 -28
  415. package/genes/test-wrap/.cloud-manifest.json +0 -6
  416. package/genes/test-wrap/.gene-manifest.json +0 -8
  417. package/genes/test-wrap/phenotype.json +0 -28
  418. package/genes/testing-strategist/.cloud-manifest.json +0 -6
  419. package/genes/testing-strategist/.gene-manifest.json +0 -8
  420. package/genes/testing-strategist/SKILL.md +0 -500
  421. package/genes/testing-strategist/phenotype.json +0 -28
  422. package/genes/text-summarizer/.cloud-manifest.json +0 -6
  423. package/genes/text-summarizer/README.md +0 -34
  424. package/genes/text-summarizer/index.ts +0 -122
  425. package/genes/text-summarizer/phenotype.json +0 -32
  426. package/genes/tone-analyzer/.cloud-manifest.json +0 -6
  427. package/genes/tone-analyzer/.gene-manifest.json +0 -8
  428. package/genes/tone-analyzer/SKILL.md +0 -410
  429. package/genes/tone-analyzer/phenotype.json +0 -28
  430. package/genes/translator/.cloud-manifest.json +0 -6
  431. package/genes/translator/.gene-manifest.json +0 -8
  432. package/genes/translator/SKILL.md +0 -355
  433. package/genes/translator/phenotype.json +0 -28
  434. package/genes/ui-components/.cloud-manifest.json +0 -6
  435. package/genes/ui-components/.gene-manifest.json +0 -8
  436. package/genes/ui-components/SKILL.md +0 -467
  437. package/genes/ui-components/phenotype.json +0 -28
  438. package/genes/uiux-designer/.cloud-manifest.json +0 -6
  439. package/genes/uiux-designer/.gene-manifest.json +0 -8
  440. package/genes/uiux-designer/SKILL.md +0 -353
  441. package/genes/uiux-designer/phenotype.json +0 -28
  442. package/genes/url-extractor/.cloud-manifest.json +0 -6
  443. package/genes/url-extractor/README.md +0 -37
  444. package/genes/url-extractor/index.ts +0 -86
  445. package/genes/url-extractor/phenotype.json +0 -48
  446. package/genes/ux-patterns/.cloud-manifest.json +0 -6
  447. package/genes/ux-patterns/.gene-manifest.json +0 -8
  448. package/genes/ux-patterns/SKILL.md +0 -872
  449. package/genes/ux-patterns/phenotype.json +0 -28
  450. package/genes/web3-components/.cloud-manifest.json +0 -6
  451. package/genes/web3-components/.gene-manifest.json +0 -8
  452. package/genes/web3-components/SKILL.md +0 -390
  453. package/genes/web3-components/phenotype.json +0 -28
@@ -1,500 +0,0 @@
1
- ---
2
- name: testing-strategist
3
- description: Design testing strategies for AI and Web3 applications. Create test cases, mock data, and CI configurations. Use when writing tests, setting up test infrastructure, or when the user mentions testing, test coverage, unit test, integration test, or e2e.
4
- ---
5
-
6
- # Testing Strategist (测试策略师)
7
-
8
- **Goal**: 为 AI + Web3 应用设计高效的测试策略,确保代码质量和系统稳定性。
9
-
10
- **OPC 原则**: 测试要精准,不追求 100% 覆盖率,聚焦核心路径。
11
-
12
- ---
13
-
14
- ## Testing Philosophy
15
-
16
- ```
17
- 测试金字塔 (OPC 版):
18
- ┌─────────┐
19
- │ E2E │ ← 最少 (关键用户流程)
20
- ─┴─────────┴─
21
- ┌───────────────┐
22
- │ Integration │ ← 适量 (API/DB)
23
- ──┴───────────────┴──
24
- ┌───────────────────────┐
25
- │ Unit Tests │ ← 最多 (纯函数)
26
- ──┴───────────────────────┴──
27
- ```
28
-
29
- ---
30
-
31
- ## 1. Unit Testing
32
-
33
- ### Pure Functions (优先测试)
34
-
35
- ```typescript
36
- // utils/format.test.ts
37
- import { describe, it, expect } from 'vitest'
38
- import { truncateAddress, formatTokenAmount } from './format'
39
-
40
- describe('truncateAddress', () => {
41
- it('truncates correctly', () => {
42
- expect(truncateAddress('0x1234567890abcdef1234567890abcdef12345678'))
43
- .toBe('0x1234...5678')
44
- })
45
-
46
- it('handles short addresses', () => {
47
- expect(truncateAddress('0x1234')).toBe('0x1234')
48
- })
49
-
50
- it('handles empty input', () => {
51
- expect(truncateAddress('')).toBe('')
52
- })
53
- })
54
-
55
- describe('formatTokenAmount', () => {
56
- it('formats large numbers with decimals', () => {
57
- expect(formatTokenAmount(1500000000000000000n, 18)).toBe('1.5')
58
- })
59
-
60
- it('handles zero', () => {
61
- expect(formatTokenAmount(0n, 18)).toBe('0')
62
- })
63
- })
64
- ```
65
-
66
- ### Testing Hooks
67
-
68
- ```typescript
69
- // hooks/useWallet.test.ts
70
- import { renderHook, act } from '@testing-library/react'
71
- import { useWallet } from './useWallet'
72
-
73
- describe('useWallet', () => {
74
- it('starts disconnected', () => {
75
- const { result } = renderHook(() => useWallet())
76
- expect(result.current.status).toBe('disconnected')
77
- })
78
-
79
- it('connects successfully', async () => {
80
- const { result } = renderHook(() => useWallet())
81
-
82
- await act(async () => {
83
- await result.current.connect()
84
- })
85
-
86
- expect(result.current.status).toBe('connected')
87
- })
88
- })
89
- ```
90
-
91
- ---
92
-
93
- ## 2. AI Testing Strategies
94
-
95
- ### Response Structure Testing
96
-
97
- ```typescript
98
- // ai/analyzer.test.ts
99
- import { describe, it, expect } from 'vitest'
100
- import { analyzeText } from './analyzer'
101
- import { AnalysisSchema } from './schemas'
102
-
103
- describe('analyzeText', () => {
104
- it('returns valid schema', async () => {
105
- const result = await analyzeText('Test input')
106
-
107
- // 验证结构
108
- expect(() => AnalysisSchema.parse(result)).not.toThrow()
109
- })
110
-
111
- it('handles empty input gracefully', async () => {
112
- const result = await analyzeText('')
113
-
114
- expect(result.error).toBe('EMPTY_INPUT')
115
- })
116
- })
117
- ```
118
-
119
- ### AI Response Mocking
120
-
121
- ```typescript
122
- // __mocks__/ai.ts
123
- export const mockAIResponse = (response: unknown) => {
124
- vi.mock('ai', () => ({
125
- generateObject: vi.fn().mockResolvedValue({ object: response }),
126
- generateText: vi.fn().mockResolvedValue({ text: JSON.stringify(response) }),
127
- }))
128
- }
129
-
130
- // 使用
131
- describe('ChatService', () => {
132
- beforeEach(() => {
133
- mockAIResponse({
134
- summary: 'Test summary',
135
- sentiment: 'positive',
136
- })
137
- })
138
-
139
- it('processes AI response correctly', async () => {
140
- const result = await chatService.analyze('input')
141
- expect(result.summary).toBe('Test summary')
142
- })
143
- })
144
- ```
145
-
146
- ### Snapshot Testing for Prompts
147
-
148
- ```typescript
149
- // prompts/analyzer.test.ts
150
- import { buildAnalyzerPrompt } from './analyzer'
151
-
152
- describe('Analyzer Prompt', () => {
153
- it('generates consistent prompt', () => {
154
- const prompt = buildAnalyzerPrompt({
155
- input: 'Test data',
156
- context: 'Financial',
157
- })
158
-
159
- expect(prompt).toMatchSnapshot()
160
- })
161
- })
162
- ```
163
-
164
- ### Deterministic Testing
165
-
166
- ```typescript
167
- // 使用固定 seed 测试 AI 行为一致性
168
- describe('AI Consistency', () => {
169
- it('produces consistent output for same input', async () => {
170
- const input = 'Analyze this market data'
171
-
172
- const results = await Promise.all([
173
- analyzeWithSeed(input, 42),
174
- analyzeWithSeed(input, 42),
175
- ])
176
-
177
- expect(results[0]).toEqual(results[1])
178
- })
179
- })
180
- ```
181
-
182
- ---
183
-
184
- ## 3. Web3 Testing Strategies
185
-
186
- ### Contract Interaction Mocking
187
-
188
- ```typescript
189
- // __mocks__/wagmi.ts
190
- import { vi } from 'vitest'
191
-
192
- export const mockUseAccount = (overrides = {}) => {
193
- return {
194
- address: '0x1234567890abcdef1234567890abcdef12345678',
195
- isConnected: true,
196
- chainId: 1,
197
- ...overrides,
198
- }
199
- }
200
-
201
- export const mockUseWriteContract = () => ({
202
- writeContract: vi.fn(),
203
- isPending: false,
204
- error: null,
205
- })
206
- ```
207
-
208
- ### Transaction Flow Testing
209
-
210
- ```typescript
211
- // hooks/useTransfer.test.ts
212
- describe('useTransfer', () => {
213
- it('handles successful transfer', async () => {
214
- const { result } = renderHook(() => useTransfer())
215
-
216
- await act(async () => {
217
- await result.current.transfer('0x...', 1000000000000000000n)
218
- })
219
-
220
- expect(result.current.status).toBe('confirmed')
221
- expect(result.current.hash).toBeDefined()
222
- })
223
-
224
- it('handles insufficient balance', async () => {
225
- mockBalance(0n) // 余额为 0
226
-
227
- const { result } = renderHook(() => useTransfer())
228
-
229
- await act(async () => {
230
- await result.current.transfer('0x...', 1000000000000000000n)
231
- })
232
-
233
- expect(result.current.error?.code).toBe('INSUFFICIENT_BALANCE')
234
- })
235
-
236
- it('handles network switch during tx', async () => {
237
- const { result } = renderHook(() => useTransfer())
238
-
239
- // 发起交易
240
- act(() => { result.current.transfer('0x...', 1n) })
241
-
242
- // 模拟网络切换
243
- act(() => { mockChainSwitch(137) })
244
-
245
- expect(result.current.error?.code).toBe('NETWORK_CHANGED')
246
- })
247
- })
248
- ```
249
-
250
- ### BigInt Edge Cases
251
-
252
- ```typescript
253
- describe('BigInt Handling', () => {
254
- it('handles max uint256', () => {
255
- const maxUint256 = 2n ** 256n - 1n
256
- expect(formatTokenAmount(maxUint256, 18)).not.toThrow()
257
- })
258
-
259
- it('handles precision correctly', () => {
260
- // 0.000000000000000001 ETH (1 wei)
261
- expect(formatTokenAmount(1n, 18)).toBe('0.000000000000000001')
262
- })
263
- })
264
- ```
265
-
266
- ---
267
-
268
- ## 4. Integration Testing
269
-
270
- ### API Integration
271
-
272
- ```typescript
273
- // api/chat.integration.test.ts
274
- import { describe, it, expect } from 'vitest'
275
-
276
- describe('Chat API', () => {
277
- it('POST /api/chat returns streamed response', async () => {
278
- const response = await fetch('/api/chat', {
279
- method: 'POST',
280
- body: JSON.stringify({ message: 'Hello' }),
281
- })
282
-
283
- expect(response.status).toBe(200)
284
- expect(response.headers.get('content-type')).toContain('text/event-stream')
285
- })
286
-
287
- it('handles rate limiting', async () => {
288
- // 快速发送多个请求
289
- const responses = await Promise.all(
290
- Array(10).fill(null).map(() =>
291
- fetch('/api/chat', { method: 'POST', body: '{}' })
292
- )
293
- )
294
-
295
- const rateLimited = responses.filter(r => r.status === 429)
296
- expect(rateLimited.length).toBeGreaterThan(0)
297
- })
298
- })
299
- ```
300
-
301
- ### Database Integration
302
-
303
- ```typescript
304
- // db/users.integration.test.ts
305
- describe('User Repository', () => {
306
- beforeEach(async () => {
307
- await db.user.deleteMany()
308
- })
309
-
310
- it('creates and retrieves user', async () => {
311
- const user = await userRepo.create({
312
- address: '0x1234...',
313
- email: 'test@example.com',
314
- })
315
-
316
- const found = await userRepo.findByAddress('0x1234...')
317
- expect(found).toEqual(user)
318
- })
319
- })
320
- ```
321
-
322
- ---
323
-
324
- ## 5. E2E Testing
325
-
326
- ### Critical User Flows
327
-
328
- ```typescript
329
- // e2e/chat-flow.spec.ts
330
- import { test, expect } from '@playwright/test'
331
-
332
- test('complete chat flow', async ({ page }) => {
333
- await page.goto('/')
334
-
335
- // 连接钱包
336
- await page.click('[data-testid="connect-wallet"]')
337
- await page.click('[data-testid="metamask"]')
338
-
339
- // 发送消息
340
- await page.fill('[data-testid="chat-input"]', 'Hello AI')
341
- await page.click('[data-testid="send-button"]')
342
-
343
- // 等待响应
344
- await expect(page.locator('[data-testid="ai-response"]')).toBeVisible({
345
- timeout: 30000,
346
- })
347
-
348
- // 验证响应内容
349
- const response = await page.textContent('[data-testid="ai-response"]')
350
- expect(response?.length).toBeGreaterThan(0)
351
- })
352
- ```
353
-
354
- ### Web3 Flow
355
-
356
- ```typescript
357
- // e2e/transaction-flow.spec.ts
358
- test('complete transaction flow', async ({ page }) => {
359
- await page.goto('/swap')
360
-
361
- // 输入金额
362
- await page.fill('[data-testid="amount-input"]', '0.1')
363
-
364
- // 检查 gas 估算
365
- await expect(page.locator('[data-testid="gas-estimate"]')).toBeVisible()
366
-
367
- // 点击交易
368
- await page.click('[data-testid="swap-button"]')
369
-
370
- // 等待钱包确认
371
- await expect(page.locator('[data-testid="tx-pending"]')).toBeVisible()
372
-
373
- // 等待确认 (mock 环境)
374
- await expect(page.locator('[data-testid="tx-confirmed"]')).toBeVisible({
375
- timeout: 60000,
376
- })
377
- })
378
- ```
379
-
380
- ---
381
-
382
- ## 6. Test Data & Mocks
383
-
384
- ### Mock Data Factory
385
-
386
- ```typescript
387
- // __fixtures__/factory.ts
388
- import { faker } from '@faker-js/faker'
389
-
390
- export const createUser = (overrides = {}) => ({
391
- id: faker.string.uuid(),
392
- address: `0x${faker.string.hexadecimal({ length: 40 })}`,
393
- email: faker.internet.email(),
394
- createdAt: faker.date.past(),
395
- ...overrides,
396
- })
397
-
398
- export const createTransaction = (overrides = {}) => ({
399
- hash: `0x${faker.string.hexadecimal({ length: 64 })}`,
400
- from: `0x${faker.string.hexadecimal({ length: 40 })}`,
401
- to: `0x${faker.string.hexadecimal({ length: 40 })}`,
402
- value: BigInt(faker.number.int({ min: 1, max: 1000000 })) * 10n ** 18n,
403
- status: 'confirmed',
404
- ...overrides,
405
- })
406
- ```
407
-
408
- ### AI Response Fixtures
409
-
410
- ```typescript
411
- // __fixtures__/ai-responses.ts
412
- export const AI_RESPONSES = {
413
- ANALYSIS_SUCCESS: {
414
- summary: 'Market shows bullish trends',
415
- sentiment: 'positive',
416
- confidence: 0.87,
417
- },
418
- ANALYSIS_UNCERTAIN: {
419
- summary: 'Insufficient data',
420
- sentiment: 'neutral',
421
- confidence: 0.45,
422
- },
423
- ERROR_RATE_LIMITED: {
424
- ok: false,
425
- error: { code: 'RATE_LIMITED', retryAfter: 60 },
426
- },
427
- }
428
- ```
429
-
430
- ---
431
-
432
- ## 7. CI Configuration
433
-
434
- ### GitHub Actions
435
-
436
- ```yaml
437
- # .github/workflows/test.yml
438
- name: Test
439
-
440
- on: [push, pull_request]
441
-
442
- jobs:
443
- test:
444
- runs-on: ubuntu-latest
445
- steps:
446
- - uses: actions/checkout@v4
447
- - uses: pnpm/action-setup@v2
448
- - uses: actions/setup-node@v4
449
- with:
450
- node-version: 20
451
- cache: 'pnpm'
452
-
453
- - run: pnpm install
454
- - run: pnpm test:unit
455
- - run: pnpm test:integration
456
-
457
- e2e:
458
- runs-on: ubuntu-latest
459
- steps:
460
- - uses: actions/checkout@v4
461
- - uses: pnpm/action-setup@v2
462
- - run: pnpm install
463
- - run: pnpm exec playwright install
464
- - run: pnpm test:e2e
465
- ```
466
-
467
- ---
468
-
469
- ## Quick Reference
470
-
471
- ### 测试命令
472
-
473
- ```bash
474
- pnpm test # 运行所有测试
475
- pnpm test:unit # 仅单元测试
476
- pnpm test:integration # 仅集成测试
477
- pnpm test:e2e # 仅 E2E 测试
478
- pnpm test:coverage # 覆盖率报告
479
- pnpm test:watch # 监听模式
480
- ```
481
-
482
- ### 覆盖率目标 (OPC)
483
-
484
- | 层级 | 目标 | 理由 |
485
- |------|------|------|
486
- | 工具函数 | 90%+ | 纯函数,容易测试 |
487
- | Hooks | 70%+ | 核心逻辑 |
488
- | API Routes | 80%+ | 关键入口 |
489
- | 组件 | 50%+ | 视觉测试成本高 |
490
- | E2E | 核心流程 | 不追求覆盖率 |
491
-
492
- ### 推荐库
493
-
494
- ```
495
- vitest - 单元/集成测试
496
- @testing-library/react - React 组件测试
497
- playwright - E2E 测试
498
- msw - API mocking
499
- @faker-js/faker - 测试数据生成
500
- ```
@@ -1,28 +0,0 @@
1
- {
2
- "domain": "code.testing",
3
- "description": "Design testing strategies for AI and Web3 applications. Create test cases, mock data, and CI configurations. Use when writing tests, setting up test infrastructure, or when the user mentions testing, test coverage, unit test, integration test, or e2e.",
4
- "inputSchema": {
5
- "type": "object",
6
- "properties": {
7
- "prompt": {
8
- "type": "string"
9
- }
10
- },
11
- "required": []
12
- },
13
- "outputSchema": {
14
- "type": "object",
15
- "properties": {
16
- "result": {
17
- "type": "string"
18
- }
19
- }
20
- },
21
- "dependencies": [],
22
- "version": "0.1.0",
23
- "author": "rotifer-team",
24
- "createdAt": 1771939409560,
25
- "fidelity": "Wrapped",
26
- "transparency": "Open",
27
- "source": "skill"
28
- }
@@ -1,6 +0,0 @@
1
- {
2
- "cloud_id": "587a8430-1434-418b-b79b-7e9176ec1c96",
3
- "owner": "Rotifer Protocol",
4
- "version": "0.1.0",
5
- "published_at": "2026-03-17T14:13:49.845Z"
6
- }
@@ -1,34 +0,0 @@
1
- # text-summarizer
2
-
3
- A Native Gene that extracts key sentences from text to produce concise summaries.
4
-
5
- ## Usage
6
-
7
- ```bash
8
- rotifer test text-summarizer --input '{"text": "Long article content here...", "maxWords": 50}'
9
- ```
10
-
11
- ## Features
12
-
13
- - Extractive summarization using sentence scoring
14
- - Configurable word limit
15
- - Two output formats: paragraph or bullet points
16
- - Key phrase extraction
17
- - Compression ratio reporting
18
-
19
- ## Input
20
-
21
- | Field | Type | Required | Description |
22
- |-------|------|----------|-------------|
23
- | `text` | string | Yes | The text to summarize |
24
- | `maxWords` | number | No | Maximum words (default: 100) |
25
- | `format` | string | No | `"paragraph"` or `"bullets"` |
26
-
27
- ## Output
28
-
29
- | Field | Type | Description |
30
- |-------|------|-------------|
31
- | `summary` | string | The generated summary |
32
- | `wordCount` | number | Word count of summary |
33
- | `compressionRatio` | number | Summary/original length ratio |
34
- | `keyPhrases` | string[] | Extracted key phrases |
@@ -1,122 +0,0 @@
1
- interface SummarizerInput {
2
- text: string;
3
- maxWords?: number;
4
- format?: "paragraph" | "bullets";
5
- }
6
-
7
- interface SummarizerOutput {
8
- summary: string;
9
- wordCount: number;
10
- compressionRatio: number;
11
- keyPhrases: string[];
12
- }
13
-
14
- function splitSentences(text: string): string[] {
15
- return text
16
- .replace(/([.!?])\s+/g, "$1\n")
17
- .split("\n")
18
- .map((s) => s.trim())
19
- .filter((s) => s.length > 0);
20
- }
21
-
22
- function wordCount(text: string): number {
23
- return text.split(/\s+/).filter((w) => w.length > 0).length;
24
- }
25
-
26
- function scoreSentence(sentence: string, wordFreq: Map<string, number>, position: number, total: number): number {
27
- const words = sentence.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
28
- if (words.length === 0) return 0;
29
-
30
- let freqScore = 0;
31
- for (const w of words) freqScore += wordFreq.get(w) || 0;
32
- freqScore /= words.length;
33
-
34
- const posScore = position < total * 0.2 ? 1.5 : position > total * 0.8 ? 1.2 : 1.0;
35
- const lenPenalty = words.length > 35 ? 0.7 : words.length < 5 ? 0.8 : 1.0;
36
-
37
- return freqScore * posScore * lenPenalty;
38
- }
39
-
40
- function extractKeyPhrases(text: string, topN: number): string[] {
41
- const stopWords = new Set([
42
- "the", "a", "an", "is", "are", "was", "were", "be", "been", "being",
43
- "have", "has", "had", "do", "does", "did", "will", "would", "could",
44
- "should", "may", "might", "shall", "can", "to", "of", "in", "for",
45
- "on", "with", "at", "by", "from", "as", "into", "through", "during",
46
- "before", "after", "above", "below", "between", "and", "but", "or",
47
- "not", "no", "nor", "so", "yet", "both", "either", "neither", "each",
48
- "every", "all", "any", "few", "more", "most", "other", "some", "such",
49
- "than", "too", "very", "just", "about", "also", "only", "own", "same",
50
- "that", "this", "these", "those", "it", "its", "they", "them", "their",
51
- "we", "us", "our", "you", "your", "he", "him", "his", "she", "her",
52
- ]);
53
-
54
- const freq = new Map<string, number>();
55
- const words = text.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 3 && !stopWords.has(w));
56
- for (const w of words) freq.set(w, (freq.get(w) || 0) + 1);
57
-
58
- return [...freq.entries()]
59
- .sort((a, b) => b[1] - a[1])
60
- .slice(0, topN)
61
- .map(([w]) => w);
62
- }
63
-
64
- export async function express(input: SummarizerInput): Promise<SummarizerOutput> {
65
- const text = (input.text || "").trim();
66
- const maxWords = input.maxWords ?? 100;
67
- const format = input.format ?? "paragraph";
68
-
69
- if (!text) {
70
- return { summary: "", wordCount: 0, compressionRatio: 0, keyPhrases: [] };
71
- }
72
-
73
- const originalWc = wordCount(text);
74
- const sentences = splitSentences(text);
75
-
76
- if (sentences.length <= 2 || originalWc <= maxWords) {
77
- return {
78
- summary: text,
79
- wordCount: originalWc,
80
- compressionRatio: 1,
81
- keyPhrases: extractKeyPhrases(text, 5),
82
- };
83
- }
84
-
85
- const stopWords = new Set(["the", "a", "an", "is", "are", "was", "were", "and", "or", "but", "in", "on", "at", "to", "for", "of", "with", "by"]);
86
- const freq = new Map<string, number>();
87
- const allWords = text.toLowerCase().split(/\s+/).filter((w) => w.length > 2 && !stopWords.has(w));
88
- for (const w of allWords) freq.set(w, (freq.get(w) || 0) + 1);
89
-
90
- const scored = sentences.map((s, i) => ({
91
- text: s,
92
- score: scoreSentence(s, freq, i, sentences.length),
93
- index: i,
94
- }));
95
-
96
- scored.sort((a, b) => b.score - a.score);
97
-
98
- const selected: typeof scored = [];
99
- let currentWords = 0;
100
- for (const s of scored) {
101
- const wc = wordCount(s.text);
102
- if (currentWords + wc > maxWords && selected.length > 0) break;
103
- selected.push(s);
104
- currentWords += wc;
105
- }
106
-
107
- selected.sort((a, b) => a.index - b.index);
108
-
109
- let summary: string;
110
- if (format === "bullets") {
111
- summary = selected.map((s) => `- ${s.text}`).join("\n");
112
- } else {
113
- summary = selected.map((s) => s.text).join(" ");
114
- }
115
-
116
- return {
117
- summary,
118
- wordCount: wordCount(summary),
119
- compressionRatio: +(wordCount(summary) / originalWc).toFixed(2),
120
- keyPhrases: extractKeyPhrases(text, 5),
121
- };
122
- }