@codyswann/lisa 1.0.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 (322) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +867 -0
  3. package/all/copy-overwrite/.claude/README.md +205 -0
  4. package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
  5. package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
  6. package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
  7. package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
  8. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
  9. package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
  10. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
  11. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
  12. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
  13. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
  14. package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
  15. package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
  16. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
  17. package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
  18. package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
  19. package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
  20. package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
  21. package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
  22. package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
  23. package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
  24. package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
  25. package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
  26. package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
  27. package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
  28. package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
  29. package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
  30. package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
  31. package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
  32. package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
  33. package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
  34. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
  35. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
  36. package/all/copy-overwrite/.claude/hooks/README.md +301 -0
  37. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
  38. package/all/copy-overwrite/.claude/settings.json +41 -0
  39. package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
  40. package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
  41. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
  42. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
  43. package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
  44. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
  45. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
  46. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  47. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
  48. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
  49. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
  50. package/all/copy-overwrite/CLAUDE.md +77 -0
  51. package/all/copy-overwrite/HUMAN.md +17 -0
  52. package/all/copy-overwrite/specs/.keep +0 -0
  53. package/all/create-only/PROJECT_RULES.md +0 -0
  54. package/cdk/merge/package.json +20 -0
  55. package/dist/cli/index.d.ts +7 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +107 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/prompts.d.ts +45 -0
  60. package/dist/cli/prompts.d.ts.map +1 -0
  61. package/dist/cli/prompts.js +58 -0
  62. package/dist/cli/prompts.js.map +1 -0
  63. package/dist/core/config.d.ts +73 -0
  64. package/dist/core/config.d.ts.map +1 -0
  65. package/dist/core/config.js +36 -0
  66. package/dist/core/config.js.map +1 -0
  67. package/dist/core/index.d.ts +4 -0
  68. package/dist/core/index.d.ts.map +1 -0
  69. package/dist/core/index.js +4 -0
  70. package/dist/core/index.js.map +1 -0
  71. package/dist/core/lisa.d.ts +81 -0
  72. package/dist/core/lisa.d.ts.map +1 -0
  73. package/dist/core/lisa.js +459 -0
  74. package/dist/core/lisa.js.map +1 -0
  75. package/dist/core/manifest.d.ts +58 -0
  76. package/dist/core/manifest.d.ts.map +1 -0
  77. package/dist/core/manifest.js +104 -0
  78. package/dist/core/manifest.js.map +1 -0
  79. package/dist/detection/detector.interface.d.ts +15 -0
  80. package/dist/detection/detector.interface.d.ts.map +1 -0
  81. package/dist/detection/detector.interface.js +2 -0
  82. package/dist/detection/detector.interface.js.map +1 -0
  83. package/dist/detection/detectors/cdk.d.ts +10 -0
  84. package/dist/detection/detectors/cdk.d.ts.map +1 -0
  85. package/dist/detection/detectors/cdk.js +34 -0
  86. package/dist/detection/detectors/cdk.js.map +1 -0
  87. package/dist/detection/detectors/expo.d.ts +10 -0
  88. package/dist/detection/detectors/expo.d.ts.map +1 -0
  89. package/dist/detection/detectors/expo.js +30 -0
  90. package/dist/detection/detectors/expo.js.map +1 -0
  91. package/dist/detection/detectors/nestjs.d.ts +10 -0
  92. package/dist/detection/detectors/nestjs.d.ts.map +1 -0
  93. package/dist/detection/detectors/nestjs.js +34 -0
  94. package/dist/detection/detectors/nestjs.js.map +1 -0
  95. package/dist/detection/detectors/npm-package.d.ts +13 -0
  96. package/dist/detection/detectors/npm-package.d.ts.map +1 -0
  97. package/dist/detection/detectors/npm-package.js +30 -0
  98. package/dist/detection/detectors/npm-package.js.map +1 -0
  99. package/dist/detection/detectors/typescript.d.ts +10 -0
  100. package/dist/detection/detectors/typescript.d.ts.map +1 -0
  101. package/dist/detection/detectors/typescript.js +25 -0
  102. package/dist/detection/detectors/typescript.js.map +1 -0
  103. package/dist/detection/index.d.ts +24 -0
  104. package/dist/detection/index.d.ts.map +1 -0
  105. package/dist/detection/index.js +57 -0
  106. package/dist/detection/index.js.map +1 -0
  107. package/dist/errors/index.d.ts +69 -0
  108. package/dist/errors/index.d.ts.map +1 -0
  109. package/dist/errors/index.js +110 -0
  110. package/dist/errors/index.js.map +1 -0
  111. package/dist/index.d.ts +3 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +8 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/logging/console-logger.d.ts +12 -0
  116. package/dist/logging/console-logger.d.ts.map +1 -0
  117. package/dist/logging/console-logger.js +22 -0
  118. package/dist/logging/console-logger.js.map +1 -0
  119. package/dist/logging/index.d.ts +4 -0
  120. package/dist/logging/index.d.ts.map +1 -0
  121. package/dist/logging/index.js +3 -0
  122. package/dist/logging/index.js.map +1 -0
  123. package/dist/logging/logger.interface.d.ts +20 -0
  124. package/dist/logging/logger.interface.d.ts.map +1 -0
  125. package/dist/logging/logger.interface.js +2 -0
  126. package/dist/logging/logger.interface.js.map +1 -0
  127. package/dist/logging/silent-logger.d.ts +12 -0
  128. package/dist/logging/silent-logger.d.ts.map +1 -0
  129. package/dist/logging/silent-logger.js +21 -0
  130. package/dist/logging/silent-logger.js.map +1 -0
  131. package/dist/strategies/copy-contents.d.ts +14 -0
  132. package/dist/strategies/copy-contents.d.ts.map +1 -0
  133. package/dist/strategies/copy-contents.js +69 -0
  134. package/dist/strategies/copy-contents.js.map +1 -0
  135. package/dist/strategies/copy-overwrite.d.ts +14 -0
  136. package/dist/strategies/copy-overwrite.d.ts.map +1 -0
  137. package/dist/strategies/copy-overwrite.js +47 -0
  138. package/dist/strategies/copy-overwrite.js.map +1 -0
  139. package/dist/strategies/create-only.d.ts +13 -0
  140. package/dist/strategies/create-only.d.ts.map +1 -0
  141. package/dist/strategies/create-only.js +30 -0
  142. package/dist/strategies/create-only.js.map +1 -0
  143. package/dist/strategies/index.d.ts +31 -0
  144. package/dist/strategies/index.d.ts.map +1 -0
  145. package/dist/strategies/index.js +52 -0
  146. package/dist/strategies/index.js.map +1 -0
  147. package/dist/strategies/merge.d.ts +13 -0
  148. package/dist/strategies/merge.d.ts.map +1 -0
  149. package/dist/strategies/merge.js +60 -0
  150. package/dist/strategies/merge.js.map +1 -0
  151. package/dist/strategies/strategy.interface.d.ts +31 -0
  152. package/dist/strategies/strategy.interface.d.ts.map +1 -0
  153. package/dist/strategies/strategy.interface.js +2 -0
  154. package/dist/strategies/strategy.interface.js.map +1 -0
  155. package/dist/transaction/backup.d.ts +38 -0
  156. package/dist/transaction/backup.d.ts.map +1 -0
  157. package/dist/transaction/backup.js +97 -0
  158. package/dist/transaction/backup.js.map +1 -0
  159. package/dist/transaction/index.d.ts +4 -0
  160. package/dist/transaction/index.d.ts.map +1 -0
  161. package/dist/transaction/index.js +3 -0
  162. package/dist/transaction/index.js.map +1 -0
  163. package/dist/transaction/transaction.d.ts +34 -0
  164. package/dist/transaction/transaction.d.ts.map +1 -0
  165. package/dist/transaction/transaction.js +68 -0
  166. package/dist/transaction/transaction.js.map +1 -0
  167. package/dist/utils/file-operations.d.ts +29 -0
  168. package/dist/utils/file-operations.d.ts.map +1 -0
  169. package/dist/utils/file-operations.js +84 -0
  170. package/dist/utils/file-operations.js.map +1 -0
  171. package/dist/utils/index.d.ts +4 -0
  172. package/dist/utils/index.d.ts.map +1 -0
  173. package/dist/utils/index.js +4 -0
  174. package/dist/utils/index.js.map +1 -0
  175. package/dist/utils/json-utils.d.ts +22 -0
  176. package/dist/utils/json-utils.d.ts.map +1 -0
  177. package/dist/utils/json-utils.js +57 -0
  178. package/dist/utils/json-utils.js.map +1 -0
  179. package/dist/utils/path-utils.d.ts +21 -0
  180. package/dist/utils/path-utils.d.ts.map +1 -0
  181. package/dist/utils/path-utils.js +35 -0
  182. package/dist/utils/path-utils.js.map +1 -0
  183. package/eslint-plugin-code-organization/README.md +149 -0
  184. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
  185. package/eslint-plugin-code-organization/index.js +23 -0
  186. package/eslint-plugin-code-organization/package.json +10 -0
  187. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
  188. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
  189. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
  190. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
  191. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
  192. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
  193. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
  194. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
  195. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
  196. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
  197. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
  198. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
  199. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
  200. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
  201. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
  202. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
  203. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
  204. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
  205. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
  206. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
  207. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
  208. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
  209. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
  210. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
  211. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
  212. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
  213. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
  214. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
  215. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
  216. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
  217. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
  218. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
  219. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
  220. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
  221. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
  222. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
  223. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
  224. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
  225. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
  226. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
  227. package/expo/copy-overwrite/.easignore.extra +2 -0
  228. package/expo/copy-overwrite/.mcp.json +33 -0
  229. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
  230. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
  231. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
  232. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
  233. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
  234. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
  235. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
  236. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
  237. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
  238. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
  239. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
  240. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
  241. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
  242. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
  243. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
  244. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
  245. package/expo/copy-overwrite/eslint.config.mjs +560 -0
  246. package/expo/copy-overwrite/lighthouserc.js +194 -0
  247. package/expo/create-only/lighthouserc-config.json +28 -0
  248. package/expo/merge/package.json +132 -0
  249. package/lisa.sh +35 -0
  250. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
  251. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
  252. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
  253. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
  254. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
  255. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
  256. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
  257. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
  258. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
  259. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
  260. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
  261. package/nestjs/merge/package.json +75 -0
  262. package/package.json +124 -0
  263. package/typescript/copy-contents/.husky/commit-msg +91 -0
  264. package/typescript/copy-contents/.husky/pre-commit +96 -0
  265. package/typescript/copy-contents/.husky/pre-push +211 -0
  266. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
  267. package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
  268. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
  269. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
  270. package/typescript/copy-overwrite/.github/README.md +455 -0
  271. package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
  272. package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
  273. package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
  274. package/typescript/copy-overwrite/.github/k6/README.md +386 -0
  275. package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
  276. package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
  277. package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
  278. package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
  279. package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
  280. package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
  281. package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
  282. package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
  283. package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
  284. package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
  285. package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
  286. package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
  287. package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
  288. package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
  289. package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
  290. package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
  291. package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
  292. package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
  293. package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
  294. package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
  295. package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
  296. package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
  297. package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
  298. package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
  299. package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
  300. package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
  301. package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
  302. package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
  303. package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
  304. package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
  305. package/typescript/copy-overwrite/.gitleaksignore +28 -0
  306. package/typescript/copy-overwrite/.nvmrc +1 -0
  307. package/typescript/copy-overwrite/.prettierignore +23 -0
  308. package/typescript/copy-overwrite/.prettierrc.json +22 -0
  309. package/typescript/copy-overwrite/.versionrc +42 -0
  310. package/typescript/copy-overwrite/.yamllint +20 -0
  311. package/typescript/copy-overwrite/commitlint.config.js +11 -0
  312. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
  313. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
  314. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
  315. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
  316. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
  317. package/typescript/copy-overwrite/eslint.config.mjs +390 -0
  318. package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
  319. package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
  320. package/typescript/github-rulesets/base.json +106 -0
  321. package/typescript/merge/.claude/settings.json +28 -0
  322. package/typescript/merge/package.json +71 -0
@@ -0,0 +1,244 @@
1
+ import http from "k6/http";
2
+ import { check, group, sleep } from "k6";
3
+ import { Rate, Trend, Counter } from "k6/metrics";
4
+
5
+ // Custom metrics for soak testing
6
+ const errorRate = new Rate("errors");
7
+ const memoryLeakIndicator = new Trend("response_time_degradation");
8
+ const requestsPerMinute = new Counter("requests_per_minute");
9
+ const degradationRate = new Trend("degradation_rate");
10
+
11
+ export const options = {
12
+ vus: 10,
13
+ duration: __ENV.K6_DURATION || "30m", // Default 30 minutes, can override
14
+ thresholds: {
15
+ http_req_failed: ["rate<0.02"], // Very low error tolerance for soak
16
+ http_req_duration: ["p(95)<1000"], // Consistent performance expected
17
+ errors: ["rate<0.02"],
18
+ degradation_rate: ["value<0.1"], // Performance shouldn't degrade > 10%
19
+ },
20
+ };
21
+
22
+ const BASE_URL = __ENV.K6_BASE_URL || "http://localhost:3000";
23
+ const CUSTOM_HEADERS = __ENV.K6_CUSTOM_HEADERS
24
+ ? JSON.parse(__ENV.K6_CUSTOM_HEADERS)
25
+ : {};
26
+
27
+ // Track performance over time
28
+ const performanceHistory = [];
29
+ const historyInterval = 60; // Track every 60 seconds
30
+ let lastHistoryUpdate = Date.now();
31
+ let baselineResponseTime = null;
32
+
33
+ export default function () {
34
+ const headers = {
35
+ "Content-Type": "application/json",
36
+ ...CUSTOM_HEADERS,
37
+ };
38
+
39
+ const iterationStart = Date.now();
40
+
41
+ group("Soak Test Operations", () => {
42
+ // Standard operations that run continuously
43
+ group("Read Operations", () => {
44
+ const endpoints = [
45
+ "/api/items",
46
+ "/api/status",
47
+ "/api/health",
48
+ "/api/metrics",
49
+ ];
50
+
51
+ endpoints.forEach(endpoint => {
52
+ const response = http.get(`${BASE_URL}${endpoint}`, {
53
+ headers,
54
+ tags: { name: `GET ${endpoint}`, operation: "read" },
55
+ });
56
+
57
+ const isOk = check(response, {
58
+ [`${endpoint} status OK`]: r => r.status === 200,
59
+ [`${endpoint} response time OK`]: r => r.timings.duration < 1000,
60
+ });
61
+
62
+ if (!isOk) {
63
+ errorRate.add(1);
64
+ }
65
+
66
+ // Track response time degradation
67
+ if (endpoint === "/api/items") {
68
+ memoryLeakIndicator.add(response.timings.duration);
69
+
70
+ // Set baseline on first successful request
71
+ if (baselineResponseTime === null && response.status === 200) {
72
+ baselineResponseTime = response.timings.duration;
73
+ }
74
+
75
+ // Calculate degradation
76
+ if (baselineResponseTime !== null) {
77
+ const degradation =
78
+ (response.timings.duration - baselineResponseTime) /
79
+ baselineResponseTime;
80
+ degradationRate.add(degradation);
81
+ }
82
+ }
83
+ });
84
+ });
85
+
86
+ group("Write Operations", () => {
87
+ // Periodic write operations to test resource cleanup
88
+ if (__ITER % 10 === 0) {
89
+ // Every 10th iteration
90
+ const payload = JSON.stringify({
91
+ test: "soak",
92
+ iteration: __ITER,
93
+ timestamp: Date.now(),
94
+ vu: __VU,
95
+ data: Array(100).fill("x").join(""), // Small payload
96
+ });
97
+
98
+ const writeResponse = http.post(`${BASE_URL}/api/items`, payload, {
99
+ headers,
100
+ tags: { name: "POST /api/items", operation: "write" },
101
+ });
102
+
103
+ check(writeResponse, {
104
+ "write status OK": r => r.status === 201 || r.status === 200,
105
+ "write response time OK": r => r.timings.duration < 2000,
106
+ }) || errorRate.add(1);
107
+
108
+ // Test cleanup - delete old items periodically
109
+ if (__ITER % 50 === 0) {
110
+ const deleteResponse = http.del(`${BASE_URL}/api/items/old`, {
111
+ headers,
112
+ tags: { name: "DELETE old items", operation: "cleanup" },
113
+ });
114
+
115
+ check(deleteResponse, {
116
+ "cleanup successful": r => r.status === 200 || r.status === 204,
117
+ });
118
+ }
119
+ }
120
+ });
121
+
122
+ group("Complex Operations", () => {
123
+ // Simulate complex user workflows
124
+ if (__ITER % 5 === 0) {
125
+ // Every 5th iteration
126
+ const searchResponse = http.get(
127
+ `${BASE_URL}/api/search?q=test&limit=100`,
128
+ {
129
+ headers,
130
+ tags: { name: "Complex Search", operation: "search" },
131
+ }
132
+ );
133
+
134
+ check(searchResponse, {
135
+ "search completed": r => r.status === 200,
136
+ "search performance OK": r => r.timings.duration < 3000,
137
+ }) || errorRate.add(1);
138
+ }
139
+ });
140
+ });
141
+
142
+ // Track requests per minute
143
+ requestsPerMinute.add(1);
144
+
145
+ // Update performance history
146
+ const now = Date.now();
147
+ if (now - lastHistoryUpdate > historyInterval * 1000) {
148
+ performanceHistory.push({
149
+ timestamp: now,
150
+ avgResponseTime: memoryLeakIndicator.value,
151
+ errorRate: errorRate.value,
152
+ });
153
+ lastHistoryUpdate = now;
154
+ }
155
+
156
+ // Consistent pacing for soak test
157
+ const iterationDuration = Date.now() - iterationStart;
158
+ const targetPace = 1000; // 1 request per second per VU
159
+ const sleepTime = Math.max(0, targetPace - iterationDuration) / 1000;
160
+ sleep(sleepTime);
161
+ }
162
+
163
+ export function handleSummary(data) {
164
+ const { metrics } = data;
165
+ const duration = parseInt(__ENV.K6_DURATION || "30m");
166
+
167
+ const summary = {
168
+ timestamp: new Date().toISOString(),
169
+ test_type: "soak",
170
+ duration: __ENV.K6_DURATION || "30m",
171
+ total_requests: metrics.http_reqs?.values?.count || 0,
172
+ failed_requests: metrics.http_req_failed?.values?.passes || 0,
173
+ error_rate: metrics.errors?.values?.rate || 0,
174
+ performance: {
175
+ baseline_response_time: baselineResponseTime,
176
+ final_avg_response_time: Math.round(
177
+ metrics.http_req_duration?.values?.avg || 0
178
+ ),
179
+ p95_response_time: Math.round(
180
+ metrics.http_req_duration?.values["p(95)"] || 0
181
+ ),
182
+ p99_response_time: Math.round(
183
+ metrics.http_req_duration?.values["p(99)"] || 0
184
+ ),
185
+ degradation_percentage:
186
+ (metrics.degradation_rate?.values?.avg || 0) * 100,
187
+ },
188
+ resource_usage: {
189
+ requests_per_minute: Math.round(
190
+ (metrics.http_reqs?.values?.count || 0) / (duration / 60)
191
+ ),
192
+ avg_data_sent: Math.round(metrics.data_sent?.values?.avg || 0),
193
+ avg_data_received: Math.round(metrics.data_received?.values?.avg || 0),
194
+ },
195
+ stability: {
196
+ consistent_performance: metrics.degradation_rate?.values?.avg < 0.1,
197
+ low_error_rate: metrics.errors?.values?.rate < 0.02,
198
+ thresholds_passed: Object.entries(data.thresholds || {}).every(
199
+ ([, value]) => value.ok
200
+ ),
201
+ },
202
+ performance_history: performanceHistory,
203
+ };
204
+
205
+ return {
206
+ "k6-results/soak-summary.json": JSON.stringify(summary, null, 2),
207
+ stdout: createSoakSummary(summary),
208
+ };
209
+ }
210
+
211
+ function createSoakSummary(summary) {
212
+ let text = "\n=== Soak Test Summary ===\n\n";
213
+ text += `Test Duration: ${summary.duration}\n`;
214
+ text += `Timestamp: ${summary.timestamp}\n\n`;
215
+
216
+ text += "Overall Statistics:\n";
217
+ text += ` Total Requests: ${summary.total_requests}\n`;
218
+ text += ` Failed Requests: ${summary.failed_requests}\n`;
219
+ text += ` Error Rate: ${(summary.error_rate * 100).toFixed(2)}%\n\n`;
220
+
221
+ text += "Performance Analysis:\n";
222
+ text += ` Baseline Response Time: ${summary.performance.baseline_response_time}ms\n`;
223
+ text += ` Final Avg Response Time: ${summary.performance.final_avg_response_time}ms\n`;
224
+ text += ` 95th Percentile: ${summary.performance.p95_response_time}ms\n`;
225
+ text += ` 99th Percentile: ${summary.performance.p99_response_time}ms\n`;
226
+ text += ` Performance Degradation: ${summary.performance.degradation_percentage.toFixed(2)}%\n\n`;
227
+
228
+ text += "Resource Usage:\n";
229
+ text += ` Requests/Minute: ${summary.resource_usage.requests_per_minute}\n`;
230
+ text += ` Avg Data Sent: ${(summary.resource_usage.avg_data_sent / 1024).toFixed(2)} KB\n`;
231
+ text += ` Avg Data Received: ${(summary.resource_usage.avg_data_received / 1024).toFixed(2)} KB\n\n`;
232
+
233
+ text += "Stability Assessment:\n";
234
+ text += ` Consistent Performance: ${summary.stability.consistent_performance ? "✅ YES" : "❌ NO"}\n`;
235
+ text += ` Low Error Rate: ${summary.stability.low_error_rate ? "✅ YES" : "❌ NO"}\n`;
236
+ text += ` All Thresholds Passed: ${summary.stability.thresholds_passed ? "✅ YES" : "❌ NO"}\n`;
237
+
238
+ if (!summary.stability.consistent_performance) {
239
+ text +=
240
+ "\n⚠️ WARNING: Performance degradation detected over time. Possible memory leak or resource exhaustion.\n";
241
+ }
242
+
243
+ return text;
244
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "soak",
3
+ "description": "Extended duration test to identify memory leaks and performance degradation",
4
+ "executor": "constant-vus",
5
+ "vus": 10,
6
+ "duration": "30m",
7
+ "thresholds": {
8
+ "http_req_failed": ["rate<0.02"],
9
+ "http_req_duration": ["p(95)<1000", "p(99)<2000"],
10
+ "http_req_receiving": ["p(95)<500"],
11
+ "checks": ["rate>0.95"],
12
+ "iterations": ["count>1000"],
13
+ "vus": ["value==10"]
14
+ },
15
+ "env": {
16
+ "SCENARIO_NAME": "soak",
17
+ "SOAK_DURATION": "30m",
18
+ "MEMORY_CHECK_INTERVAL": "5m"
19
+ },
20
+ "tags": {
21
+ "test_type": "soak",
22
+ "environment": "${K6_ENVIRONMENT}",
23
+ "long_running": "true"
24
+ },
25
+ "notes": {
26
+ "monitoring": "Monitor memory usage, CPU, and response time trends over the duration",
27
+ "duration_override": "Can be extended to 1h, 2h, or 4h based on requirements"
28
+ }
29
+ }
@@ -0,0 +1,180 @@
1
+ import http from "k6/http";
2
+ import { check, group, sleep } from "k6";
3
+ import { Rate, Trend } from "k6/metrics";
4
+
5
+ // Custom metrics
6
+ const errorRate = new Rate("errors");
7
+ const spikeResponseTime = new Trend("spike_response_time");
8
+ const recoveryTime = new Trend("recovery_time");
9
+
10
+ export const options = {
11
+ stages: [
12
+ { duration: "30s", target: 5 }, // Baseline load
13
+ { duration: "1m", target: 5 }, // Stay at baseline
14
+ { duration: "30s", target: 100 }, // Spike to 100 users
15
+ { duration: "3m", target: 100 }, // Stay at peak
16
+ { duration: "30s", target: 5 }, // Drop back to baseline
17
+ { duration: "2m", target: 5 }, // Recovery period
18
+ { duration: "30s", target: 0 }, // Ramp down
19
+ ],
20
+ thresholds: {
21
+ http_req_failed: ["rate<0.15"], // Higher tolerance during spikes
22
+ http_req_duration: ["p(95)<3000"], // 95% of requests under 3s
23
+ errors: ["rate<0.2"], // 20% error rate threshold
24
+ spike_response_time: ["p(95)<5000"], // Spike-specific metric
25
+ },
26
+ };
27
+
28
+ const BASE_URL = __ENV.K6_BASE_URL || "http://localhost:3000";
29
+ const CUSTOM_HEADERS = __ENV.K6_CUSTOM_HEADERS
30
+ ? JSON.parse(__ENV.K6_CUSTOM_HEADERS)
31
+ : {};
32
+
33
+ // Track test phases
34
+ let currentPhase = "baseline";
35
+ let phaseStartTime = Date.now();
36
+
37
+ export default function () {
38
+ const headers = {
39
+ "Content-Type": "application/json",
40
+ ...CUSTOM_HEADERS,
41
+ };
42
+
43
+ // Determine current phase based on VU count
44
+ const vuCount = __VU;
45
+ let phase = "baseline";
46
+ if (vuCount > 50) phase = "spike";
47
+ else if (vuCount <= 10 && currentPhase === "spike") phase = "recovery";
48
+
49
+ if (phase !== currentPhase) {
50
+ const phaseDuration = Date.now() - phaseStartTime;
51
+ if (currentPhase === "spike") {
52
+ recoveryTime.add(phaseDuration);
53
+ }
54
+ currentPhase = phase;
55
+ phaseStartTime = Date.now();
56
+ }
57
+
58
+ group(`Spike Test - ${phase} phase`, () => {
59
+ // Critical user path that must handle spikes
60
+ const criticalResponse = http.get(`${BASE_URL}/api/critical-endpoint`, {
61
+ headers,
62
+ tags: { name: "CriticalPath", phase: phase },
63
+ timeout: "10s", // Longer timeout during spikes
64
+ });
65
+
66
+ const criticalCheck = check(criticalResponse, {
67
+ "critical path available": r => r.status === 200 || r.status === 503,
68
+ "response time acceptable": r =>
69
+ r.timings.duration < (phase === "spike" ? 5000 : 1000),
70
+ });
71
+
72
+ if (!criticalCheck) {
73
+ errorRate.add(1);
74
+ }
75
+
76
+ if (phase === "spike") {
77
+ spikeResponseTime.add(criticalResponse.timings.duration);
78
+ }
79
+
80
+ // Simulate various user behaviors during spike
81
+ if (Math.random() < 0.7) {
82
+ // 70% read operations
83
+ const readResponse = http.get(`${BASE_URL}/api/items`, {
84
+ headers,
85
+ tags: { name: "ReadOperation", phase: phase },
86
+ });
87
+
88
+ check(readResponse, {
89
+ "read operation successful": r => r.status === 200,
90
+ }) || errorRate.add(1);
91
+ } else {
92
+ // 30% write operations
93
+ const writePayload = JSON.stringify({
94
+ action: "spike_test",
95
+ timestamp: Date.now(),
96
+ phase: phase,
97
+ vu: __VU,
98
+ });
99
+
100
+ const writeResponse = http.post(`${BASE_URL}/api/items`, writePayload, {
101
+ headers,
102
+ tags: { name: "WriteOperation", phase: phase },
103
+ });
104
+
105
+ check(writeResponse, {
106
+ "write operation handled": r => [200, 201, 429, 503].includes(r.status),
107
+ }) || errorRate.add(1);
108
+ }
109
+ });
110
+
111
+ // Minimal sleep during spike phase, normal sleep otherwise
112
+ sleep(phase === "spike" ? 0.1 : 1);
113
+ }
114
+
115
+ export function handleSummary(data) {
116
+ const { metrics } = data;
117
+
118
+ const summary = {
119
+ timestamp: new Date().toISOString(),
120
+ test_type: "spike",
121
+ phases: {
122
+ baseline: {
123
+ avg_response_time: Math.round(
124
+ metrics.http_req_duration?.values?.avg || 0
125
+ ),
126
+ error_rate: metrics.errors?.values?.rate || 0,
127
+ },
128
+ spike: {
129
+ avg_response_time: Math.round(
130
+ metrics.spike_response_time?.values?.avg || 0
131
+ ),
132
+ p95_response_time: Math.round(
133
+ metrics.spike_response_time?.values["p(95)"] || 0
134
+ ),
135
+ max_response_time: Math.round(
136
+ metrics.spike_response_time?.values?.max || 0
137
+ ),
138
+ error_rate: metrics.errors?.values?.rate || 0,
139
+ },
140
+ recovery: {
141
+ time_to_normal: Math.round(metrics.recovery_time?.values?.avg || 0),
142
+ },
143
+ },
144
+ total_requests: metrics.http_reqs?.values?.count || 0,
145
+ failed_requests: metrics.http_req_failed?.values?.passes || 0,
146
+ thresholds_passed: Object.entries(data.thresholds || {}).every(
147
+ ([, value]) => value.ok
148
+ ),
149
+ };
150
+
151
+ return {
152
+ "k6-results/spike-summary.json": JSON.stringify(summary, null, 2),
153
+ stdout: createSpikeSummary(summary),
154
+ };
155
+ }
156
+
157
+ function createSpikeSummary(summary) {
158
+ let text = "\n=== Spike Test Summary ===\n\n";
159
+ text += `Timestamp: ${summary.timestamp}\n`;
160
+ text += `Total Requests: ${summary.total_requests}\n`;
161
+ text += `Failed Requests: ${summary.failed_requests}\n\n`;
162
+
163
+ text += "Phase Analysis:\n";
164
+ text += ` Baseline Phase:\n`;
165
+ text += ` - Avg Response Time: ${summary.phases.baseline.avg_response_time}ms\n`;
166
+ text += ` - Error Rate: ${(summary.phases.baseline.error_rate * 100).toFixed(2)}%\n`;
167
+
168
+ text += ` Spike Phase:\n`;
169
+ text += ` - Avg Response Time: ${summary.phases.spike.avg_response_time}ms\n`;
170
+ text += ` - 95th Percentile: ${summary.phases.spike.p95_response_time}ms\n`;
171
+ text += ` - Max Response Time: ${summary.phases.spike.max_response_time}ms\n`;
172
+ text += ` - Error Rate: ${(summary.phases.spike.error_rate * 100).toFixed(2)}%\n`;
173
+
174
+ text += ` Recovery Phase:\n`;
175
+ text += ` - Time to Normal: ${summary.phases.recovery.time_to_normal}ms\n\n`;
176
+
177
+ text += `All Thresholds Passed: ${summary.thresholds_passed ? "✅ YES" : "❌ NO"}\n`;
178
+
179
+ return text;
180
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "spike",
3
+ "description": "Test system's ability to handle sudden traffic spikes",
4
+ "executor": "ramping-vus",
5
+ "startVUs": 0,
6
+ "stages": [
7
+ { "duration": "30s", "target": 5 },
8
+ { "duration": "1m", "target": 5 },
9
+ { "duration": "30s", "target": 100 },
10
+ { "duration": "3m", "target": 100 },
11
+ { "duration": "30s", "target": 5 },
12
+ { "duration": "2m", "target": 5 },
13
+ { "duration": "30s", "target": 0 }
14
+ ],
15
+ "gracefulStop": "30s",
16
+ "thresholds": {
17
+ "http_req_failed": ["rate<0.15"],
18
+ "http_req_duration": ["p(95)<3000", "p(99)<10000"],
19
+ "http_req_receiving": ["p(95)<2000"],
20
+ "checks": ["rate>0.75"],
21
+ "http_req_waiting": ["p(95)<5000"]
22
+ },
23
+ "env": {
24
+ "SCENARIO_NAME": "spike",
25
+ "SPIKE_MULTIPLIER": "20",
26
+ "RECOVERY_TIME": "2m"
27
+ },
28
+ "tags": {
29
+ "test_type": "spike",
30
+ "environment": "${K6_ENVIRONMENT}"
31
+ }
32
+ }
@@ -0,0 +1,206 @@
1
+ import http from "k6/http";
2
+ import { check, group, sleep } from "k6";
3
+ import { Rate, Trend } from "k6/metrics";
4
+
5
+ // Custom metrics
6
+ const errorRate = new Rate("errors");
7
+ const responseTime = new Trend("custom_response_time");
8
+ const throughput = new Rate("throughput");
9
+
10
+ export const options = {
11
+ stages: [
12
+ { duration: "2m", target: 10 }, // Warm up
13
+ { duration: "5m", target: 10 }, // Normal load
14
+ { duration: "2m", target: 20 }, // Increase to 20 users
15
+ { duration: "5m", target: 20 }, // Stay at 20 users
16
+ { duration: "2m", target: 30 }, // Increase to 30 users
17
+ { duration: "5m", target: 30 }, // Stay at 30 users
18
+ { duration: "5m", target: 0 }, // Ramp down
19
+ ],
20
+ thresholds: {
21
+ http_req_failed: [
22
+ {
23
+ threshold: "rate<0.1",
24
+ abortOnFail: true,
25
+ delayAbortEval: "30s",
26
+ },
27
+ ], // Abort if error rate > 10%
28
+ http_req_duration: ["p(95)<1000", "p(99)<2000"], // More relaxed for stress
29
+ errors: ["rate<0.15"], // Allow up to 15% errors under stress
30
+ throughput: ["rate>0.8"], // At least 80% of requests should complete
31
+ },
32
+ };
33
+
34
+ const BASE_URL = __ENV.K6_BASE_URL || "http://localhost:3000";
35
+ const CUSTOM_HEADERS = __ENV.K6_CUSTOM_HEADERS
36
+ ? JSON.parse(__ENV.K6_CUSTOM_HEADERS)
37
+ : {};
38
+
39
+ export default function () {
40
+ const headers = {
41
+ "Content-Type": "application/json",
42
+ ...CUSTOM_HEADERS,
43
+ };
44
+
45
+ // Stress test focuses on system behavior under high load
46
+ group("Concurrent API Calls", () => {
47
+ const batch = http.batch([
48
+ [
49
+ "GET",
50
+ `${BASE_URL}/api/items`,
51
+ null,
52
+ { headers, tags: { name: "BatchGet1" } },
53
+ ],
54
+ [
55
+ "GET",
56
+ `${BASE_URL}/api/items?page=2`,
57
+ null,
58
+ { headers, tags: { name: "BatchGet2" } },
59
+ ],
60
+ [
61
+ "GET",
62
+ `${BASE_URL}/api/status`,
63
+ null,
64
+ { headers, tags: { name: "BatchStatus" } },
65
+ ],
66
+ ]);
67
+
68
+ batch.forEach((response, index) => {
69
+ const isOk = check(response, {
70
+ "batch request succeeded": r => r.status === 200,
71
+ });
72
+
73
+ if (!isOk) {
74
+ errorRate.add(1);
75
+ } else {
76
+ throughput.add(1);
77
+ }
78
+
79
+ responseTime.add(response.timings.duration);
80
+ });
81
+ });
82
+
83
+ // Heavy operations
84
+ group("Resource Intensive Operations", () => {
85
+ // Simulate large payload
86
+ const largePayload = JSON.stringify({
87
+ data: Array(100)
88
+ .fill(null)
89
+ .map((_, i) => ({
90
+ id: i,
91
+ name: `Item ${i}`,
92
+ description:
93
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit".repeat(
94
+ 10
95
+ ),
96
+ metadata: {
97
+ created: new Date().toISOString(),
98
+ tags: Array(20)
99
+ .fill(null)
100
+ .map((_, j) => `tag${j}`),
101
+ },
102
+ })),
103
+ });
104
+
105
+ const heavyResponse = http.post(
106
+ `${BASE_URL}/api/bulk-process`,
107
+ largePayload,
108
+ {
109
+ headers,
110
+ tags: { name: "HeavyOperation" },
111
+ timeout: "30s",
112
+ }
113
+ );
114
+
115
+ const heavyCheck = check(heavyResponse, {
116
+ "heavy operation completed": r => r.status === 200 || r.status === 202,
117
+ "heavy operation within timeout": r => r.timings.duration < 30000,
118
+ });
119
+
120
+ if (!heavyCheck) {
121
+ errorRate.add(1);
122
+ } else {
123
+ throughput.add(1);
124
+ }
125
+ });
126
+
127
+ // Rapid fire requests (no sleep)
128
+ group("Rapid Requests", () => {
129
+ for (let i = 0; i < 5; i++) {
130
+ const rapidResponse = http.get(
131
+ `${BASE_URL}/api/items/${Math.floor(Math.random() * 100)}`,
132
+ {
133
+ headers,
134
+ tags: { name: "RapidFire" },
135
+ }
136
+ );
137
+
138
+ check(rapidResponse, {
139
+ "rapid request handled": r => r.status === 200 || r.status === 404,
140
+ }) || errorRate.add(1);
141
+ }
142
+ });
143
+
144
+ // Minimal think time to maintain pressure
145
+ sleep(Math.random() * 0.5);
146
+ }
147
+
148
+ export function handleSummary(data) {
149
+ const { metrics } = data;
150
+
151
+ // Calculate stress test specific metrics
152
+ const totalRequests = metrics.http_reqs?.values?.count || 0;
153
+ const failedRequests = metrics.http_req_failed?.values?.passes || 0;
154
+ const errorPercentage =
155
+ totalRequests > 0 ? ((failedRequests / totalRequests) * 100).toFixed(2) : 0;
156
+
157
+ const summary = {
158
+ timestamp: new Date().toISOString(),
159
+ test_type: "stress",
160
+ total_requests: totalRequests,
161
+ failed_requests: failedRequests,
162
+ error_percentage: parseFloat(errorPercentage),
163
+ avg_response_time: Math.round(metrics.http_req_duration?.values?.avg || 0),
164
+ p95_response_time: Math.round(
165
+ metrics.http_req_duration?.values["p(95)"] || 0
166
+ ),
167
+ p99_response_time: Math.round(
168
+ metrics.http_req_duration?.values["p(99)"] || 0
169
+ ),
170
+ max_response_time: Math.round(metrics.http_req_duration?.values?.max || 0),
171
+ custom_metrics: {
172
+ error_rate: metrics.errors?.values?.rate || 0,
173
+ throughput_rate: metrics.throughput?.values?.rate || 0,
174
+ avg_custom_response_time: Math.round(
175
+ metrics.custom_response_time?.values?.avg || 0
176
+ ),
177
+ },
178
+ thresholds_passed: Object.entries(data.thresholds || {}).every(
179
+ ([, value]) => value.ok
180
+ ),
181
+ };
182
+
183
+ return {
184
+ "k6-results/stress-summary.json": JSON.stringify(summary, null, 2),
185
+ stdout: createTextSummary(summary),
186
+ };
187
+ }
188
+
189
+ function createTextSummary(summary) {
190
+ let text = "\n=== Stress Test Summary ===\n\n";
191
+ text += `Test Type: ${summary.test_type}\n`;
192
+ text += `Timestamp: ${summary.timestamp}\n\n`;
193
+ text += `Total Requests: ${summary.total_requests}\n`;
194
+ text += `Failed Requests: ${summary.failed_requests} (${summary.error_percentage}%)\n`;
195
+ text += `Average Response Time: ${summary.avg_response_time}ms\n`;
196
+ text += `95th Percentile: ${summary.p95_response_time}ms\n`;
197
+ text += `99th Percentile: ${summary.p99_response_time}ms\n`;
198
+ text += `Max Response Time: ${summary.max_response_time}ms\n\n`;
199
+ text += `Custom Metrics:\n`;
200
+ text += ` Error Rate: ${(summary.custom_metrics.error_rate * 100).toFixed(2)}%\n`;
201
+ text += ` Throughput Rate: ${(summary.custom_metrics.throughput_rate * 100).toFixed(2)}%\n`;
202
+ text += ` Avg Custom Response Time: ${summary.custom_metrics.avg_custom_response_time}ms\n\n`;
203
+ text += `All Thresholds Passed: ${summary.thresholds_passed ? "✅ YES" : "❌ NO"}\n`;
204
+
205
+ return text;
206
+ }