llm-mock-server 1.0.6 → 1.0.7

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 (250) hide show
  1. package/dist/cli/cli.d.ts +3 -0
  2. package/dist/cli/cli.d.ts.map +1 -0
  3. package/dist/cli/cli.js +103 -0
  4. package/dist/cli/cli.js.map +1 -0
  5. package/dist/cli/validators.d.ts +7 -0
  6. package/dist/cli/validators.d.ts.map +1 -0
  7. package/dist/cli/validators.js +53 -0
  8. package/dist/cli/validators.js.map +1 -0
  9. package/dist/formats/anthropic/index.d.ts +1 -1
  10. package/dist/formats/anthropic/index.d.ts.map +1 -1
  11. package/dist/formats/anthropic/index.js +1 -1
  12. package/dist/formats/anthropic/index.js.map +1 -1
  13. package/dist/formats/anthropic/parse.d.ts +2 -2
  14. package/dist/formats/anthropic/parse.d.ts.map +1 -1
  15. package/dist/formats/anthropic/parse.js +4 -2
  16. package/dist/formats/anthropic/parse.js.map +1 -1
  17. package/dist/formats/anthropic/schema.d.ts +1 -1
  18. package/dist/formats/anthropic/schema.d.ts.map +1 -1
  19. package/dist/formats/anthropic/schema.js +9 -4
  20. package/dist/formats/anthropic/schema.js.map +1 -1
  21. package/dist/formats/anthropic/serialize.d.ts +2 -2
  22. package/dist/formats/anthropic/serialize.d.ts.map +1 -1
  23. package/dist/formats/anthropic/serialize.js +76 -19
  24. package/dist/formats/anthropic/serialize.js.map +1 -1
  25. package/dist/formats/openai/chat-completions/index.d.ts +3 -0
  26. package/dist/formats/openai/chat-completions/index.d.ts.map +1 -0
  27. package/dist/formats/openai/chat-completions/index.js +13 -0
  28. package/dist/formats/openai/chat-completions/index.js.map +1 -0
  29. package/dist/formats/openai/chat-completions/parse.d.ts +4 -0
  30. package/dist/formats/openai/chat-completions/parse.d.ts.map +1 -0
  31. package/dist/formats/openai/chat-completions/parse.js +33 -0
  32. package/dist/formats/openai/chat-completions/parse.js.map +1 -0
  33. package/dist/formats/openai/chat-completions/schema.d.ts +93 -0
  34. package/dist/formats/openai/chat-completions/schema.d.ts.map +1 -0
  35. package/dist/formats/openai/chat-completions/schema.js +74 -0
  36. package/dist/formats/openai/chat-completions/schema.js.map +1 -0
  37. package/dist/formats/openai/chat-completions/serialize.d.ts +10 -0
  38. package/dist/formats/openai/chat-completions/serialize.d.ts.map +1 -0
  39. package/dist/formats/openai/chat-completions/serialize.js +99 -0
  40. package/dist/formats/openai/chat-completions/serialize.js.map +1 -0
  41. package/dist/formats/openai/responses/index.d.ts +3 -0
  42. package/dist/formats/openai/responses/index.d.ts.map +1 -0
  43. package/dist/formats/openai/responses/index.js +13 -0
  44. package/dist/formats/openai/responses/index.js.map +1 -0
  45. package/dist/formats/openai/responses/parse.d.ts +4 -0
  46. package/dist/formats/openai/responses/parse.d.ts.map +1 -0
  47. package/dist/formats/openai/responses/parse.js +51 -0
  48. package/dist/formats/openai/responses/parse.js.map +1 -0
  49. package/dist/formats/openai/responses/schema.d.ts +103 -0
  50. package/dist/formats/openai/responses/schema.d.ts.map +1 -0
  51. package/dist/formats/openai/responses/schema.js +71 -0
  52. package/dist/formats/openai/responses/schema.js.map +1 -0
  53. package/dist/formats/openai/responses/serialize.d.ts +10 -0
  54. package/dist/formats/openai/responses/serialize.d.ts.map +1 -0
  55. package/dist/formats/openai/responses/serialize.js +273 -0
  56. package/dist/formats/openai/responses/serialize.js.map +1 -0
  57. package/dist/formats/request-helpers.d.ts +1 -1
  58. package/dist/formats/request-helpers.d.ts.map +1 -1
  59. package/dist/formats/request-helpers.js.map +1 -1
  60. package/dist/formats/serialize-helpers.d.ts +1 -1
  61. package/dist/formats/serialize-helpers.d.ts.map +1 -1
  62. package/dist/formats/serialize-helpers.js +6 -3
  63. package/dist/formats/serialize-helpers.js.map +1 -1
  64. package/dist/formats/types.d.ts +2 -1
  65. package/dist/formats/types.d.ts.map +1 -1
  66. package/dist/history.d.ts +6 -2
  67. package/dist/history.d.ts.map +1 -1
  68. package/dist/history.js +2 -0
  69. package/dist/history.js.map +1 -1
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/loader.d.ts +1 -1
  73. package/dist/loader.d.ts.map +1 -1
  74. package/dist/loader.js +26 -9
  75. package/dist/loader.js.map +1 -1
  76. package/dist/logger.d.ts.map +1 -1
  77. package/dist/logger.js +12 -4
  78. package/dist/logger.js.map +1 -1
  79. package/dist/mock-server.d.ts +44 -48
  80. package/dist/mock-server.d.ts.map +1 -1
  81. package/dist/mock-server.js +37 -85
  82. package/dist/mock-server.js.map +1 -1
  83. package/dist/route-handler.d.ts +1 -1
  84. package/dist/route-handler.d.ts.map +1 -1
  85. package/dist/route-handler.js +19 -7
  86. package/dist/route-handler.js.map +1 -1
  87. package/dist/rule-builder.d.ts +21 -0
  88. package/dist/rule-builder.d.ts.map +1 -0
  89. package/dist/rule-builder.js +58 -0
  90. package/dist/rule-builder.js.map +1 -0
  91. package/dist/rule-engine.d.ts +3 -1
  92. package/dist/rule-engine.d.ts.map +1 -1
  93. package/dist/rule-engine.js +7 -2
  94. package/dist/rule-engine.js.map +1 -1
  95. package/dist/sse-writer.d.ts +1 -1
  96. package/dist/sse-writer.d.ts.map +1 -1
  97. package/dist/types/reply.d.ts +51 -8
  98. package/dist/types/reply.d.ts.map +1 -1
  99. package/dist/types/request.d.ts +21 -6
  100. package/dist/types/request.d.ts.map +1 -1
  101. package/dist/types/rule.d.ts +65 -7
  102. package/dist/types/rule.d.ts.map +1 -1
  103. package/dist/types.d.ts +3 -3
  104. package/dist/types.d.ts.map +1 -1
  105. package/package.json +15 -9
  106. package/.claude/skills/desloppify/SKILL.md +0 -308
  107. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000801.json +0 -242
  108. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000905.json +0 -248
  109. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000917.json +0 -248
  110. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/canonical_import_20260315_000950.json +0 -311
  111. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/claude_launch_prompt.md +0 -17
  112. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/review_result.json +0 -255
  113. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/review_result.template.json +0 -22
  114. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/reviewer_instructions.md +0 -20
  115. package/.desloppify/external_review_sessions/ext_20260315_000339_a6cdc3e6/session.json +0 -20
  116. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/canonical_import_20260315_050000.json +0 -286
  117. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/canonical_import_20260315_050028.json +0 -303
  118. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/claude_launch_prompt.md +0 -17
  119. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/review_result.json +0 -297
  120. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/review_result.template.json +0 -22
  121. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/reviewer_instructions.md +0 -20
  122. package/.desloppify/external_review_sessions/ext_20260315_045546_0587ea3b/session.json +0 -20
  123. package/.desloppify/query.json +0 -1312
  124. package/.desloppify/review_packet_blind.json +0 -1249
  125. package/.desloppify/review_packets/holistic_packet_20260315_000339.json +0 -1471
  126. package/.desloppify/review_packets/holistic_packet_20260315_045546.json +0 -1480
  127. package/.desloppify/review_packets/holistic_packet_20260315_185401.json +0 -1407
  128. package/.desloppify/review_packets/holistic_packet_20260315_185613.json +0 -1407
  129. package/.desloppify/state-typescript.json +0 -8438
  130. package/.desloppify/state-typescript.json.bak +0 -8432
  131. package/.desloppify/subagents/runs/20260315_185401/logs/batch-1.log +0 -384
  132. package/.desloppify/subagents/runs/20260315_185401/logs/batch-10.log +0 -484
  133. package/.desloppify/subagents/runs/20260315_185401/logs/batch-2.log +0 -408
  134. package/.desloppify/subagents/runs/20260315_185401/logs/batch-3.log +0 -416
  135. package/.desloppify/subagents/runs/20260315_185401/logs/batch-4.log +0 -360
  136. package/.desloppify/subagents/runs/20260315_185401/logs/batch-5.log +0 -360
  137. package/.desloppify/subagents/runs/20260315_185401/logs/batch-6.log +0 -364
  138. package/.desloppify/subagents/runs/20260315_185401/logs/batch-7.log +0 -428
  139. package/.desloppify/subagents/runs/20260315_185401/logs/batch-8.log +0 -388
  140. package/.desloppify/subagents/runs/20260315_185401/logs/batch-9.log +0 -500
  141. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-1.md +0 -83
  142. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-10.md +0 -108
  143. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-2.md +0 -89
  144. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-3.md +0 -91
  145. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-4.md +0 -77
  146. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-5.md +0 -77
  147. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-6.md +0 -78
  148. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-7.md +0 -94
  149. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-8.md +0 -84
  150. package/.desloppify/subagents/runs/20260315_185401/prompts/batch-9.md +0 -112
  151. package/.desloppify/subagents/runs/20260315_185401/results/batch-1.raw.txt +0 -0
  152. package/.desloppify/subagents/runs/20260315_185401/results/batch-10.raw.txt +0 -0
  153. package/.desloppify/subagents/runs/20260315_185401/results/batch-2.raw.txt +0 -0
  154. package/.desloppify/subagents/runs/20260315_185401/results/batch-3.raw.txt +0 -0
  155. package/.desloppify/subagents/runs/20260315_185401/results/batch-4.raw.txt +0 -0
  156. package/.desloppify/subagents/runs/20260315_185401/results/batch-5.raw.txt +0 -0
  157. package/.desloppify/subagents/runs/20260315_185401/results/batch-6.raw.txt +0 -0
  158. package/.desloppify/subagents/runs/20260315_185401/results/batch-7.raw.txt +0 -0
  159. package/.desloppify/subagents/runs/20260315_185401/results/batch-8.raw.txt +0 -0
  160. package/.desloppify/subagents/runs/20260315_185401/results/batch-9.raw.txt +0 -0
  161. package/.desloppify/subagents/runs/20260315_185401/run.log +0 -36
  162. package/.desloppify/subagents/runs/20260315_185401/run_summary.json +0 -156
  163. package/.desloppify/subagents/runs/20260315_185613/holistic_findings_merged.json +0 -741
  164. package/.desloppify/subagents/runs/20260315_185613/logs/batch-1.log +0 -579
  165. package/.desloppify/subagents/runs/20260315_185613/logs/batch-10.log +0 -1537
  166. package/.desloppify/subagents/runs/20260315_185613/logs/batch-2.log +0 -829
  167. package/.desloppify/subagents/runs/20260315_185613/logs/batch-3.log +0 -927
  168. package/.desloppify/subagents/runs/20260315_185613/logs/batch-4.log +0 -429
  169. package/.desloppify/subagents/runs/20260315_185613/logs/batch-5.log +0 -276
  170. package/.desloppify/subagents/runs/20260315_185613/logs/batch-6.log +0 -450
  171. package/.desloppify/subagents/runs/20260315_185613/logs/batch-7.log +0 -730
  172. package/.desloppify/subagents/runs/20260315_185613/logs/batch-8.log +0 -698
  173. package/.desloppify/subagents/runs/20260315_185613/logs/batch-9.log +0 -938
  174. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-1.md +0 -83
  175. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-10.md +0 -108
  176. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-2.md +0 -89
  177. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-3.md +0 -91
  178. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-4.md +0 -77
  179. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-5.md +0 -77
  180. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-6.md +0 -78
  181. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-7.md +0 -94
  182. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-8.md +0 -84
  183. package/.desloppify/subagents/runs/20260315_185613/prompts/batch-9.md +0 -112
  184. package/.desloppify/subagents/runs/20260315_185613/results/batch-1.raw.txt +0 -78
  185. package/.desloppify/subagents/runs/20260315_185613/results/batch-10.raw.txt +0 -242
  186. package/.desloppify/subagents/runs/20260315_185613/results/batch-2.raw.txt +0 -102
  187. package/.desloppify/subagents/runs/20260315_185613/results/batch-3.raw.txt +0 -94
  188. package/.desloppify/subagents/runs/20260315_185613/results/batch-4.raw.txt +0 -86
  189. package/.desloppify/subagents/runs/20260315_185613/results/batch-5.raw.txt +0 -1
  190. package/.desloppify/subagents/runs/20260315_185613/results/batch-6.raw.txt +0 -87
  191. package/.desloppify/subagents/runs/20260315_185613/results/batch-7.raw.txt +0 -1
  192. package/.desloppify/subagents/runs/20260315_185613/results/batch-8.raw.txt +0 -107
  193. package/.desloppify/subagents/runs/20260315_185613/results/batch-9.raw.txt +0 -67
  194. package/.desloppify/subagents/runs/20260315_185613/run.log +0 -96
  195. package/.desloppify/subagents/runs/20260315_185613/run_summary.json +0 -156
  196. package/.editorconfig +0 -12
  197. package/.github/dependabot.yml +0 -11
  198. package/.github/workflows/docs.yml +0 -46
  199. package/.github/workflows/test.yml +0 -40
  200. package/.markdownlint.jsonc +0 -11
  201. package/.node-version +0 -1
  202. package/.oxfmtrc.json +0 -9
  203. package/.oxlintrc.json +0 -35
  204. package/docs/ARCHITECTURE.md +0 -125
  205. package/scorecard.png +0 -0
  206. package/src/cli/cli.ts +0 -141
  207. package/src/cli/validators.ts +0 -68
  208. package/src/formats/anthropic/index.ts +0 -14
  209. package/src/formats/anthropic/parse.ts +0 -70
  210. package/src/formats/anthropic/schema.ts +0 -74
  211. package/src/formats/anthropic/serialize.ts +0 -179
  212. package/src/formats/openai/chat-completions/index.ts +0 -14
  213. package/src/formats/openai/chat-completions/parse.ts +0 -47
  214. package/src/formats/openai/chat-completions/schema.ts +0 -92
  215. package/src/formats/openai/chat-completions/serialize.ts +0 -146
  216. package/src/formats/openai/responses/index.ts +0 -14
  217. package/src/formats/openai/responses/parse.ts +0 -73
  218. package/src/formats/openai/responses/schema.ts +0 -86
  219. package/src/formats/openai/responses/serialize.ts +0 -328
  220. package/src/formats/request-helpers.ts +0 -56
  221. package/src/formats/serialize-helpers.ts +0 -43
  222. package/src/formats/types.ts +0 -26
  223. package/src/history.ts +0 -70
  224. package/src/index.ts +0 -46
  225. package/src/loader.ts +0 -246
  226. package/src/logger.ts +0 -70
  227. package/src/mock-server.ts +0 -203
  228. package/src/route-handler.ts +0 -144
  229. package/src/rule-builder.ts +0 -73
  230. package/src/rule-engine.ts +0 -165
  231. package/src/sse-writer.ts +0 -35
  232. package/src/types/reply.ts +0 -92
  233. package/src/types/request.ts +0 -56
  234. package/src/types/rule.ts +0 -125
  235. package/src/types.ts +0 -24
  236. package/test/cli-validators.test.ts +0 -151
  237. package/test/formats/anthropic.test.ts +0 -336
  238. package/test/formats/openai.test.ts +0 -316
  239. package/test/formats/parse-helpers.test.ts +0 -315
  240. package/test/formats/responses.test.ts +0 -380
  241. package/test/helpers/make-req.ts +0 -18
  242. package/test/history.test.ts +0 -361
  243. package/test/loader.test.ts +0 -333
  244. package/test/logger.test.ts +0 -344
  245. package/test/mock-server.test.ts +0 -619
  246. package/test/rule-engine.test.ts +0 -229
  247. package/tsconfig.json +0 -24
  248. package/tsconfig.test.json +0 -11
  249. package/typedoc.json +0 -9
  250. package/vitest.config.ts +0 -18
@@ -1,927 +0,0 @@
1
- ATTEMPT 1/3
2
- $ codex exec --ephemeral -C /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server -s workspace-write -c approval_policy="never" -c model_reasoning_effort="low" -o /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server/.desloppify/subagents/runs/20260315_185613/results/batch-3.raw.txt You are a focused subagent reviewer for a single holistic investigation batch.
3
-
4
- Repository root: /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server
5
- Blind packet: /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server/.desloppify/review_packet_blind.json
6
- Batch index: 3
7
- Batch name: Abstractions & Dependencies
8
- Batch dimensions: abstraction_fitness, mid_level_elegance, low_level_elegance
9
- Batch rationale: abstraction hotspots (wrappers/interfaces/param bags), dep cycles
10
-
11
- Files assigned:
12
- - test/cli-validators.test.ts
13
- - src/mock-server.ts
14
- - test/formats/anthropic.test.ts
15
- - src/cli.ts
16
- - test/mock-server.test.ts
17
- - src/formats/responses/serialize.ts
18
- - test/formats/responses.test.ts
19
- - test/history.test.ts
20
- - src/rule-engine.ts
21
- - src/history.ts
22
- - src/loader.ts
23
- - test/formats/openai.test.ts
24
- - test/loader.test.ts
25
- - test/logger.test.ts
26
- - src/formats/openai/serialize.ts
27
-
28
- Task requirements:
29
- 1. Read the blind packet and follow `system_prompt` constraints exactly.
30
- 1a. If previously flagged issues are listed above, use them as context for your review.
31
- Verify whether each still applies to the current code. Do not re-report fixed or
32
- wontfix issues. Use them as starting points to look deeper — inspect adjacent code
33
- and related modules for defects the prior review may have missed.
34
- 1c. Think structurally: when you spot multiple individual issues that share a common
35
- root cause (missing abstraction, duplicated pattern, inconsistent convention),
36
- explain the deeper structural issue in the finding, not just the surface symptom.
37
- If the pattern is significant enough, report the structural issue as its own finding
38
- with appropriate fix_scope ('multi_file_refactor' or 'architectural_change') and
39
- use `root_cause_cluster` to connect related symptom findings together.
40
- 2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
41
- 3. Return 0-10 high-quality findings for this batch (empty array allowed).
42
- 3a. Do not suppress real defects to keep scores high; report every material issue you can support with evidence.
43
- 3b. Do not default to 100. Reserve 100 for genuinely exemplary evidence in this batch.
44
- 4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
45
- 4a. Any dimension scored below 85.0 MUST include explicit feedback: add at least one finding with the same `dimension` and a non-empty actionable `suggestion`.
46
- 5. Every finding must include `related_files` with at least 2 files when possible.
47
- 6. Every finding must include `dimension`, `identifier`, `summary`, `evidence`, `suggestion`, and `confidence`.
48
- 7. Every finding must include `impact_scope` and `fix_scope`.
49
- 8. Every scored dimension MUST include dimension_notes with concrete evidence.
50
- 9. If a dimension score is >85.0, include `issues_preventing_higher_score` in dimension_notes.
51
- 10. Use exactly one decimal place for every assessment and abstraction sub-axis score.
52
- 11. Ignore prior chat context and any target-threshold assumptions.
53
- 12. Do not edit repository files.
54
- 13. Return ONLY valid JSON, no markdown fences.
55
-
56
- Scope enums:
57
- - impact_scope: "local" | "module" | "subsystem" | "codebase"
58
- - fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
59
-
60
- Output schema:
61
- {
62
- "batch": "Abstractions & Dependencies",
63
- "batch_index": 3,
64
- "assessments": {"<dimension>": <0-100 with one decimal place>},
65
- "dimension_notes": {
66
- "<dimension>": {
67
- "evidence": ["specific code observations"],
68
- "impact_scope": "local|module|subsystem|codebase",
69
- "fix_scope": "single_edit|multi_file_refactor|architectural_change",
70
- "confidence": "high|medium|low",
71
- "issues_preventing_higher_score": "required when score >85.0",
72
- "sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
73
- }
74
- },
75
- "findings": [{
76
- "dimension": "<dimension>",
77
- "identifier": "short_id",
78
- "summary": "one-line defect summary",
79
- "related_files": ["relative/path.py"],
80
- "evidence": ["specific code observation"],
81
- "suggestion": "concrete fix recommendation",
82
- "confidence": "high|medium|low",
83
- "impact_scope": "local|module|subsystem|codebase",
84
- "fix_scope": "single_edit|multi_file_refactor|architectural_change",
85
- "root_cause_cluster": "optional_cluster_name_when_supported_by_history"
86
- }],
87
- "retrospective": {
88
- "root_causes": ["optional: concise root-cause hypotheses"],
89
- "likely_symptoms": ["optional: identifiers that look symptom-level"],
90
- "possible_false_positives": ["optional: prior concept keys likely mis-scoped"]
91
- }
92
- }
93
-
94
-
95
- STDOUT:
96
- {
97
- "batch": "Abstractions & Dependencies",
98
- "batch_index": 3,
99
- "assessments": {
100
- "abstraction_fitness": 82.0,
101
- "mid_level_elegance": 84.0,
102
- "low_level_elegance": 88.0
103
- },
104
- "dimension_notes": {
105
- "abstraction_fitness": {
106
- "evidence": [
107
- "src/mock-server.ts builds sequence rules inline in when().replySequence(), including mapping entries and calling createSequenceResolver, then sets rule.remaining.",
108
- "src/loader.ts repeats near-identical sequence rule wiring in addSequenceRule(), including entry mapping, createSequenceResolver, and rule.remaining."
109
- ],
110
- "impact_scope": "module",
111
- "fix_scope": "multi_file_refactor",
112
- "confidence": "high",
113
- "issues_preventing_higher_score": "Sequence-rule construction is duplicated in two modules, making future option/behavior changes easy to miss in one path.",
114
- "sub_axes": {
115
- "abstraction_leverage": 79.0,
116
- "indirection_cost": 84.0,
117
- "interface_honesty": 83.0
118
- }
119
- },
120
- "mid_level_elegance": {
121
- "evidence": [
122
- "src/mock-server.ts registers routes from the formats array (openaiFormat/anthropicFormat/responsesFormat) and relies on each format’s route.",
123
- "src/cli.ts prints a hard-coded endpoints string instead of deriving from the same formats registry."
124
- ],
125
- "impact_scope": "module",
126
- "fix_scope": "multi_file_refactor",
127
- "confidence": "medium",
128
- "issues_preventing_higher_score": "Endpoint listing is a manual seam between CLI output and runtime route registration, which can drift when adding/removing formats."
129
- },
130
- "low_level_elegance": {
131
- "evidence": [
132
- "src/formats/responses/serialize.ts serialize() mixes header creation, block construction, chunk flattening, and response finalization in one dense function.",
133
- "src/formats/openai/serialize.ts serialize() builds text/tool chunks, finish/usage chunks, and envelopes inline without local extraction."
134
- ],
135
- "impact_scope": "local",
136
- "fix_scope": "single_edit",
137
- "confidence": "medium",
138
- "issues_preventing_higher_score": "Serialization functions are readable but locally dense; small extractions would make the control flow more intention-revealing."
139
- }
140
- },
141
- "findings": [
142
- {
143
- "dimension": "abstraction_fitness",
144
- "identifier": "sequence_rule_duplication",
145
- "summary": "Sequence rule construction is duplicated across MockServer and loader, risking drift.",
146
- "related_files": [
147
- "src/mock-server.ts",
148
- "src/loader.ts",
149
- "src/rule-engine.ts"
150
- ],
151
- "evidence": [
152
- "src/mock-server.ts when().replySequence() maps entries, calls createSequenceResolver, mutates rule.resolve and rule.remaining.",
153
- "src/loader.ts addSequenceRule() performs the same mapping/resolve/remaining steps with a slightly different entry shape."
154
- ],
155
- "suggestion": "Extract a shared helper (e.g., in src/rule-engine.ts) that accepts normalized sequence steps and applies createSequenceResolver + remaining, then reuse it from both MockServer and loader.",
156
- "confidence": "high",
157
- "impact_scope": "module",
158
- "fix_scope": "multi_file_refactor",
159
- "root_cause_cluster": "sequence_rule_duplication"
160
- },
161
- {
162
- "dimension": "mid_level_elegance",
163
- "identifier": "format_registry_split",
164
- "summary": "CLI hard-codes endpoints while MockServer derives routes from format modules.",
165
- "related_files": [
166
- "src/mock-server.ts",
167
- "src/cli.ts"
168
- ],
169
- "evidence": [
170
- "src/mock-server.ts registers routes by iterating formats[] with per-format route values.",
171
- "src/cli.ts prints a static endpoints list string that must be updated manually."
172
- ],
173
- "suggestion": "Expose a single formats registry (or route list) and have the CLI render endpoints from it, avoiding cross-module drift.",
174
- "confidence": "medium",
175
- "impact_scope": "module",
176
- "fix_scope": "multi_file_refactor"
177
- }
178
- ],
179
- "retrospective": {
180
- "root_causes": [
181
- "Shared logic exists without a single owning abstraction, leading to duplication across modules."
182
- ],
183
- "likely_symptoms": [
184
- "sequence_rule_duplication",
185
- "format_registry_split"
186
- ],
187
- "possible_false_positives": []
188
- }
189
- }
190
-
191
-
192
- STDERR:
193
- OpenAI Codex v0.114.0 (research preview)
194
- --------
195
- workdir: /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server
196
- model: gpt-5.2-codex
197
- provider: openai
198
- approval: never
199
- sandbox: workspace-write [workdir, /tmp, $TMPDIR, /Users/suyash.x.srijan/.codex/memories]
200
- reasoning effort: low
201
- reasoning summaries: none
202
- session id: 019cf2dd-bc97-7be0-b843-65bc1c0098fd
203
- --------
204
- user
205
- You are a focused subagent reviewer for a single holistic investigation batch.
206
-
207
- Repository root: /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server
208
- Blind packet: /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server/.desloppify/review_packet_blind.json
209
- Batch index: 3
210
- Batch name: Abstractions & Dependencies
211
- Batch dimensions: abstraction_fitness, mid_level_elegance, low_level_elegance
212
- Batch rationale: abstraction hotspots (wrappers/interfaces/param bags), dep cycles
213
-
214
- Files assigned:
215
- - test/cli-validators.test.ts
216
- - src/mock-server.ts
217
- - test/formats/anthropic.test.ts
218
- - src/cli.ts
219
- - test/mock-server.test.ts
220
- - src/formats/responses/serialize.ts
221
- - test/formats/responses.test.ts
222
- - test/history.test.ts
223
- - src/rule-engine.ts
224
- - src/history.ts
225
- - src/loader.ts
226
- - test/formats/openai.test.ts
227
- - test/loader.test.ts
228
- - test/logger.test.ts
229
- - src/formats/openai/serialize.ts
230
-
231
- Task requirements:
232
- 1. Read the blind packet and follow `system_prompt` constraints exactly.
233
- 1a. If previously flagged issues are listed above, use them as context for your review.
234
- Verify whether each still applies to the current code. Do not re-report fixed or
235
- wontfix issues. Use them as starting points to look deeper — inspect adjacent code
236
- and related modules for defects the prior review may have missed.
237
- 1c. Think structurally: when you spot multiple individual issues that share a common
238
- root cause (missing abstraction, duplicated pattern, inconsistent convention),
239
- explain the deeper structural issue in the finding, not just the surface symptom.
240
- If the pattern is significant enough, report the structural issue as its own finding
241
- with appropriate fix_scope ('multi_file_refactor' or 'architectural_change') and
242
- use `root_cause_cluster` to connect related symptom findings together.
243
- 2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
244
- 3. Return 0-10 high-quality findings for this batch (empty array allowed).
245
- 3a. Do not suppress real defects to keep scores high; report every material issue you can support with evidence.
246
- 3b. Do not default to 100. Reserve 100 for genuinely exemplary evidence in this batch.
247
- 4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
248
- 4a. Any dimension scored below 85.0 MUST include explicit feedback: add at least one finding with the same `dimension` and a non-empty actionable `suggestion`.
249
- 5. Every finding must include `related_files` with at least 2 files when possible.
250
- 6. Every finding must include `dimension`, `identifier`, `summary`, `evidence`, `suggestion`, and `confidence`.
251
- 7. Every finding must include `impact_scope` and `fix_scope`.
252
- 8. Every scored dimension MUST include dimension_notes with concrete evidence.
253
- 9. If a dimension score is >85.0, include `issues_preventing_higher_score` in dimension_notes.
254
- 10. Use exactly one decimal place for every assessment and abstraction sub-axis score.
255
- 11. Ignore prior chat context and any target-threshold assumptions.
256
- 12. Do not edit repository files.
257
- 13. Return ONLY valid JSON, no markdown fences.
258
-
259
- Scope enums:
260
- - impact_scope: "local" | "module" | "subsystem" | "codebase"
261
- - fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
262
-
263
- Output schema:
264
- {
265
- "batch": "Abstractions & Dependencies",
266
- "batch_index": 3,
267
- "assessments": {"<dimension>": <0-100 with one decimal place>},
268
- "dimension_notes": {
269
- "<dimension>": {
270
- "evidence": ["specific code observations"],
271
- "impact_scope": "local|module|subsystem|codebase",
272
- "fix_scope": "single_edit|multi_file_refactor|architectural_change",
273
- "confidence": "high|medium|low",
274
- "issues_preventing_higher_score": "required when score >85.0",
275
- "sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
276
- }
277
- },
278
- "findings": [{
279
- "dimension": "<dimension>",
280
- "identifier": "short_id",
281
- "summary": "one-line defect summary",
282
- "related_files": ["relative/path.py"],
283
- "evidence": ["specific code observation"],
284
- "suggestion": "concrete fix recommendation",
285
- "confidence": "high|medium|low",
286
- "impact_scope": "local|module|subsystem|codebase",
287
- "fix_scope": "single_edit|multi_file_refactor|architectural_change",
288
- "root_cause_cluster": "optional_cluster_name_when_supported_by_history"
289
- }],
290
- "retrospective": {
291
- "root_causes": ["optional: concise root-cause hypotheses"],
292
- "likely_symptoms": ["optional: identifiers that look symptom-level"],
293
- "possible_false_positives": ["optional: prior concept keys likely mis-scoped"]
294
- }
295
- }
296
-
297
- mcp startup: no servers
298
-
299
- thinking
300
- **Reading blind packet with cat**
301
- exec
302
- /bin/zsh -lc ls in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
303
- LICENCE
304
- README.md
305
- coverage
306
- dist
307
- docs
308
- node_modules
309
- package-lock.json
310
- package.json
311
- scorecard.png
312
- src
313
- test
314
- tsconfig.json
315
- tsconfig.test.json
316
- vitest.config.ts
317
- exec
318
- /bin/zsh -lc 'cat .desloppify/review_packet_blind.json' in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
319
- {
320
- "command": "review",
321
- "mode": "holistic",
322
- "language": "typescript",
323
- "dimensions": [
324
- "cross_module_architecture",
325
- "convention_outlier",
326
- "error_consistency",
327
- "abstraction_fitness",
328
- "api_surface_coherence",
329
- "authorization_consistency",
330
- "ai_generated_debt",
331
- "incomplete_migration",
332
- "package_organization",
333
- "high_level_elegance",
334
- "mid_level_elegance",
335
- "low_level_elegance",
336
- "design_coherence"
337
- ],
338
- "dimension_prompts": {
339
-
340
- thinking
341
- **Preparing to read relevant files**
342
- exec
343
- /bin/zsh -lc "sed -n '1,200p' src/mock-server.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
344
- import Fastify from "fastify";
345
- import type { FastifyInstance } from "fastify";
346
- import type {
347
- Match,
348
- PendingRule,
349
- Reply,
350
- ReplyOptions,
351
- Resolver,
352
- Rule,
353
- RuleHandle,
354
- RuleSummary,
355
- SequenceEntry,
356
- } from "./types.js";
357
- import { RuleEngine, createSequenceResolver } from "./rule-engine.js";
358
- import { RequestHistory } from "./history.js";
359
- import { openaiFormat } from "./formats/openai/index.js";
360
- import { anthropicFormat } from "./formats/anthropic/index.js";
361
- import { responsesFormat } from "./formats/responses/index.js";
362
- import type { Format } from "./formats/types.js";
363
- import { Logger } from "./logger.js";
364
- exec
365
- /bin/zsh -lc "sed -n '1,200p' src/cli.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
366
- #!/usr/bin/env node
367
-
368
- import { watch } from "node:fs";
369
- import { createRequire } from "node:module";
370
- import { Command } from "commander";
371
- import pc from "picocolors";
372
- import { MockServer } from "./mock-server.js";
373
- import { Logger } from "./logger.js";
374
- import {
375
- parsePort,
376
- parseHost,
377
- parseLogLevel,
378
- parseChunkSize,
379
- parseLatency,
380
- } from "./cli-validators.js";
381
-
382
- const require = createRequire(import.meta.url);
383
- const { version } = require("../package.json") as { version: string };
384
-
385
- const WATCH_DEBOUNCE_MS = 100;
386
- exec
387
- /bin/zsh -lc "sed -n '1,200p' src/formats/responses/serialize.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
388
- import type { ReplyObject, ReplyOptions, ToolCall } from "../../types.js";
389
- import type { SSEChunk } from "../types.js";
390
- import {
391
- splitText,
392
- genId,
393
- toolId,
394
- shouldEmitText,
395
- MS_PER_SECOND,
396
- DEFAULT_USAGE,
397
- } from "../serialize-helpers.js";
398
-
399
- function buildUsage(usage: { input: number; output: number }) {
400
- return {
401
- input_tokens: usage.input,
402
- output_tokens: usage.output,
403
- total_tokens: usage.input + usage.output,
404
- };
405
- }
406
-
407
- interface StreamBlock {
408
- exec
409
- /bin/zsh -lc "sed -n '1,200p' src/rule-engine.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
410
- import type {
411
- Match,
412
- MatchObject,
413
- MockRequest,
414
- Resolver,
415
- Reply,
416
- ReplyOptions,
417
- Rule,
418
- RuleSummary,
419
- } from "./types.js";
420
-
421
- function safeRegex(re: RegExp): RegExp {
422
- return re.global || re.sticky
423
- ? new RegExp(re.source, re.flags.replace(/[gy]/g, ""))
424
- : re;
425
- }
426
-
427
- function compilePattern(pattern: string | RegExp): (value: string) => boolean {
428
- if (typeof pattern === "string") {
429
- const lower = pattern.toLowerCase();
430
-
431
- thinking
432
- **Identifying key files to locate**
433
-
434
- I'm noting that history, loader, OpenAI serialization, and test files are needed next for a comprehensive understanding and implementation.
435
- exec
436
- /bin/zsh -lc "sed -n '1,200p' src/history.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
437
- import type { MockRequest } from "./types.js";
438
-
439
- /** A recorded request with the rule that matched and when it happened. */
440
- export interface RecordedRequest {
441
- readonly request: MockRequest;
442
- /** The rule that matched, or `undefined` if the fallback was used. */
443
- readonly rule: string | undefined;
444
- readonly timestamp: number;
445
- }
446
-
447
- /**
448
- * Records every request the server handles.
449
- * Iterable and has fluent query methods for test assertions.
450
- *
451
- * @example
452
- * ```ts
453
- * expect(server.history.count()).toBe(3);
454
- * expect(server.history.last()?.request.lastMessage).toBe("hello");
455
- * const matched = server.history.where(r => r.rule !== undefined);
456
- * ```
457
- exec
458
- /bin/zsh -lc "sed -n '1,200p' src/loader.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
459
- import { readFile, readdir, stat } from "node:fs/promises";
460
- import { join, extname } from "node:path";
461
- import JSON5 from "json5";
462
- import { z } from "zod";
463
- import type { Handler, Match, MatchObject, Reply } from "./types.js";
464
- import { type RuleEngine, createSequenceResolver } from "./rule-engine.js";
465
-
466
- interface LoadContext {
467
- engine: RuleEngine;
468
- setFallback?: (reply: Reply) => void;
469
- }
470
-
471
- const json5MatchSchema = z.union([
472
- z.string(),
473
- z.object({
474
- message: z.string().optional(),
475
- model: z.string().optional(),
476
- system: z.string().optional(),
477
- format: z.enum(["openai", "anthropic", "responses"]).optional(),
478
- }),
479
- exec
480
- /bin/zsh -lc "sed -n '1,200p' src/formats/openai/serialize.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
481
- import type { ReplyObject, ReplyOptions } from "../../types.js";
482
- import type { SSEChunk } from "../types.js";
483
- import {
484
- splitText,
485
- genId,
486
- toolId,
487
- finishReason,
488
- MS_PER_SECOND,
489
- DEFAULT_USAGE,
490
- } from "../serialize-helpers.js";
491
-
492
- function buildUsage(usage: { input: number; output: number }) {
493
- return {
494
- prompt_tokens: usage.input,
495
- completion_tokens: usage.output,
496
- total_tokens: usage.input + usage.output,
497
- prompt_tokens_details: { cached_tokens: 0, audio_tokens: 0 },
498
- completion_tokens_details: {
499
- reasoning_tokens: 0,
500
- audio_tokens: 0,
501
- exec
502
- /bin/zsh -lc "sed -n '200,400p' src/formats/responses/serialize.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
503
- }),
504
- c({
505
- type: "response.output_item.done",
506
- output_index: i,
507
- item: outputItem,
508
- }),
509
- ],
510
- };
511
- }
512
-
513
- export function serialize(
514
- reply: ReplyObject,
515
- model: string,
516
- options: ReplyOptions = {},
517
- ): readonly SSEChunk[] {
518
- const id = genId("resp");
519
- const createdAt = Math.floor(Date.now() / MS_PER_SECOND);
520
- const usage = reply.usage ?? DEFAULT_USAGE;
521
- const c = createChunk();
522
- let i = 0;
523
- exec
524
- /bin/zsh -lc "sed -n '200,400p' src/loader.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
525
- handler.respond,
526
- `(handler: ${filePath})`,
527
- );
528
- }
529
- }
530
-
531
- type FileLoader = (filePath: string, ctx: LoadContext) => Promise<void>;
532
-
533
- const loaderByExtension: ReadonlyMap<string, FileLoader> = new Map([
534
- [".json5", loadJson5File],
535
- [".json", loadJson5File],
536
- [".ts", loadHandlerFile],
537
- [".js", loadHandlerFile],
538
- [".mjs", loadHandlerFile],
539
- ]);
540
-
541
- export async function loadRulesFromPath(
542
- pathOrDir: string,
543
- ctx: LoadContext,
544
- ): Promise<void> {
545
-
546
- thinking
547
- **Flagging need for tests to clarify abstractions**
548
- exec
549
- /bin/zsh -lc "sed -n '1,200p' test/history.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
550
- import { describe, it, expect, beforeEach } from "vitest";
551
- import { RequestHistory, type RecordedRequest } from "../src/history.js";
552
- import { makeReq } from "./helpers/make-req.js";
553
-
554
- describe("RequestHistory", () => {
555
- let history: RequestHistory;
556
-
557
- beforeEach(() => {
558
- history = new RequestHistory();
559
- });
560
-
561
- describe("record()", () => {
562
- it("adds an entry", () => {
563
- history.record(makeReq(), "rule-1");
564
- expect(history.count()).toBe(1);
565
- });
566
-
567
- it("adds multiple entries in order", () => {
568
- history.record(makeReq({ lastMessage: "first" }), "r1");
569
- history.record(makeReq({ lastMessage: "second" }), "r2");
570
- exec
571
- /bin/zsh -lc "sed -n '1,200p' test/mock-server.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
572
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
573
- import { createMock, MockServer } from "../src/index.js";
574
-
575
- interface OpenAIResponse {
576
- choices: {
577
- message: { role: string; content: string };
578
- finish_reason: string;
579
- }[];
580
- error?: { type: string; message: string };
581
- }
582
-
583
- interface AnthropicResponse {
584
- content: { type: string; text?: string; thinking?: string }[];
585
- error?: { type: string; message: string };
586
- }
587
-
588
- interface ResponsesAPIResponse {
589
- output: { type: string; content: { type: string; text: string }[] }[];
590
- }
591
-
592
- exec
593
- /bin/zsh -lc "sed -n '1,200p' test/formats/openai.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
594
- import { describe, it, expect } from "vitest";
595
- import { openaiFormat } from "../../src/formats/openai/index.js";
596
- import type {
597
- OpenAIChunk,
598
- OpenAIComplete,
599
- OpenAIError,
600
- } from "../../src/formats/openai/schema.js";
601
-
602
- function parse<T>(chunk: { data: string }): T {
603
- return JSON.parse(chunk.data) as T;
604
- }
605
-
606
- describe("OpenAI Format", () => {
607
- describe("parseRequest", () => {
608
- it("parses a basic chat completion request", () => {
609
- const req = openaiFormat.parseRequest({
610
- model: "gpt-5.4",
611
- messages: [
612
- { role: "system", content: "You are helpful" },
613
- { role: "user", content: "Hello" },
614
- exec
615
- /bin/zsh -lc "sed -n '1,200p' test/formats/responses.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
616
- import { describe, it, expect } from "vitest";
617
- import { responsesFormat } from "../../src/formats/responses/index.js";
618
- import type {
619
- ResponsesEvent,
620
- ResponsesComplete,
621
- ResponsesError,
622
- } from "../../src/formats/responses/schema.js";
623
-
624
- function parse<T>(chunk: { data: string }): T {
625
- return JSON.parse(chunk.data) as T;
626
- }
627
-
628
- describe("Responses Format", () => {
629
- describe("parseRequest", () => {
630
- it("parses string input", () => {
631
- const req = responsesFormat.parseRequest({
632
- model: "codex-mini",
633
- input: "Hello world",
634
- });
635
- expect(req.format).toBe("responses");
636
- exec
637
- /bin/zsh -lc "sed -n '200,400p' test/formats/responses.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
638
- );
639
- });
640
- expect(parse<ResponsesEvent>(done!).item?.status).toBe("completed");
641
- });
642
-
643
- it("includes annotations on output_text parts", () => {
644
- const chunks = responsesFormat.serialize({ text: "Hello" }, "codex-mini");
645
- const partAdded = chunks.find(
646
- (c) => parse<ResponsesEvent>(c).type === "response.content_part.added",
647
- );
648
- expect(parse<ResponsesEvent>(partAdded!).part?.annotations).toEqual([]);
649
- });
650
-
651
- it("includes content_part.done event with full text", () => {
652
- const chunks = responsesFormat.serialize({ text: "Hello" }, "codex-mini");
653
- const partDone = chunks.find(
654
- (c) => parse<ResponsesEvent>(c).type === "response.content_part.done",
655
- );
656
- expect(partDone).toBeDefined();
657
- expect(parse<ResponsesEvent>(partDone!).part?.text).toBe("Hello");
658
-
659
- thinking
660
- **Listing additional needed tests**
661
- exec
662
- /bin/zsh -lc "sed -n '1,200p' test/logger.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
663
- import { describe, it, expect, vi, afterEach } from "vitest";
664
- import { Logger, LEVEL_PRIORITY } from "../src/logger.js";
665
- import type { LogLevel } from "../src/logger.js";
666
-
667
- afterEach(() => {
668
- vi.restoreAllMocks();
669
- });
670
-
671
- describe("LEVEL_PRIORITY", () => {
672
- it("has the expected keys and ascending values", () => {
673
- expect(LEVEL_PRIORITY).toEqual({
674
- none: 0,
675
- error: 1,
676
- warning: 2,
677
- info: 3,
678
- debug: 4,
679
- all: 5,
680
- });
681
- });
682
-
683
- exec
684
- /bin/zsh -lc "sed -n '1,200p' test/cli-validators.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
685
- import { describe, it, expect } from "vitest";
686
- import {
687
- parsePort,
688
- parseHost,
689
- parseChunkSize,
690
- parseLogLevel,
691
- parseLatency,
692
- } from "../src/cli-validators.js";
693
-
694
- describe("parsePort", () => {
695
- it("parses a valid port", () => {
696
- expect(parsePort("5555")).toBe(5555);
697
- });
698
-
699
- it("accepts port 1", () => {
700
- expect(parsePort("1")).toBe(1);
701
- });
702
-
703
- it("accepts port 65535", () => {
704
- expect(parsePort("65535")).toBe(65535);
705
- exec
706
- /bin/zsh -lc "sed -n '1,200p' test/loader.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
707
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
708
- import { writeFile, mkdir, rm } from "node:fs/promises";
709
- import { join } from "node:path";
710
- import { RuleEngine } from "../src/rule-engine.js";
711
- import { loadRulesFromPath } from "../src/loader.js";
712
- import type { MockRequest } from "../src/types.js";
713
- import { makeReq } from "./helpers/make-req.js";
714
-
715
- const tmpDir = join(import.meta.dirname, ".tmp-loader-test");
716
-
717
- describe("Loader", () => {
718
- let engine: RuleEngine;
719
-
720
- beforeEach(async () => {
721
- engine = new RuleEngine();
722
- await mkdir(tmpDir, { recursive: true });
723
- });
724
-
725
- afterEach(async () => {
726
- await rm(tmpDir, { recursive: true, force: true });
727
- exec
728
- /bin/zsh -lc "sed -n '1,200p' test/formats/anthropic.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
729
- import { describe, it, expect } from "vitest";
730
- import { anthropicFormat } from "../../src/formats/anthropic/index.js";
731
- import type {
732
- AnthropicMessageStart,
733
- AnthropicBlockEvent,
734
- AnthropicDelta,
735
- AnthropicComplete,
736
- AnthropicError,
737
- } from "../../src/formats/anthropic/schema.js";
738
-
739
- function parse<T>(chunk: { data: string }): T {
740
- return JSON.parse(chunk.data) as T;
741
- }
742
-
743
- describe("Anthropic Format", () => {
744
- describe("parseRequest", () => {
745
- it("parses messages with top-level system", () => {
746
- const req = anthropicFormat.parseRequest({
747
- model: "claude-sonnet-4-6",
748
- system: "You are a pirate",
749
- exec
750
- /bin/zsh -lc "sed -n '200,400p' test/formats/anthropic.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
751
- it("includes tool_use blocks with correct structure", () => {
752
- const chunks = anthropicFormat.serialize(
753
- { tools: [{ name: "read_file", args: { path: "/tmp" } }] },
754
- "claude-sonnet-4-6",
755
- );
756
- const toolStart = chunks.find((c) => {
757
- if (c.event !== "content_block_start") return false;
758
- return parse<AnthropicBlockEvent>(c).content_block?.type === "tool_use";
759
- });
760
- expect(toolStart).toBeDefined();
761
- const block = parse<AnthropicBlockEvent>(toolStart!).content_block!;
762
- expect(block.name).toBe("read_file");
763
- expect(block.id).toBeTypeOf("string");
764
- expect(block.input).toEqual({});
765
- });
766
-
767
- it("sets stop_reason to tool_use when tools present", () => {
768
- const chunks = anthropicFormat.serialize(
769
- { tools: [{ name: "read_file", args: {} }] },
770
- "claude-sonnet-4-6",
771
-
772
- thinking
773
- **Checking remaining mock-server tests**
774
-
775
- Planning to review the rest of the mock-server tests to verify coverage of rule behavior before deciding if additional tests for abstractions or OpenAI are needed.
776
- exec
777
- /bin/zsh -lc "sed -n '200,400p' test/mock-server.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
778
-
779
- const j1 = await postOpenAI("once");
780
- expect(j1.choices[0]!.message.content).toBe("First time!");
781
-
782
- const j2 = await postOpenAI("once");
783
- expect(j2.choices[0]!.message.content).toBe("Fallback.");
784
- });
785
- });
786
-
787
- describe("fallback", () => {
788
- it("uses fallback when no rule matches", async () => {
789
- server.fallback("I don't understand.");
790
- const json = await postOpenAI("something random");
791
- expect(json.choices[0]!.message.content).toBe("I don't understand.");
792
- });
793
- });
794
-
795
- describe("history", () => {
796
- it("records requests with matched rule info", async () => {
797
- server.when("hello").reply("Hi!");
798
- exec
799
- /bin/zsh -lc "sed -n '400,800p' test/mock-server.test.ts" in /Users/suyash.x.srijan/Documents/Personal_Projects/llm-mock-server succeeded in 0ms:
800
- describe("url property", () => {
801
- it("returns the base URL", () => {
802
- expect(server.url).toMatch(/^http:\/\/127\.0\.0\.1:\d+$/);
803
- });
804
- });
805
-
806
- describe("error injection", () => {
807
- it("nextError returns a one-shot error response", async () => {
808
- server.nextError(429, "Rate limited", "rate_limit_error");
809
- server.when("hello").reply("Hi!");
810
-
811
- const r1 = await post("/v1/chat/completions", {
812
- model: "gpt-5.4",
813
- messages: [{ role: "user", content: "hello" }],
814
- stream: false,
815
- });
816
- expect(r1.status).toBe(429);
817
- const err = (await r1.json()) as OpenAIResponse;
818
- expect(err.error?.message).toBe("Rate limited");
819
-
820
-
821
-
822
- thinking
823
- **Identifying abstraction duplication issues**
824
-
825
- Noticed duplicated sequence rule-building logic between mock-server and loader/rule-engine that suggests a shared helper could reduce divergence and improve mid-level abstraction; also spotted similar buildUsage functions across serialization files hinting at potential abstraction fitness concerns.
826
- thinking
827
- **Scoping abstraction and elegance findings**
828
-
829
- I've pinpointed two main abstraction issues: duplicated sequence rule construction across MockServer and loader needing a shared helper, and format endpoint lists split between MockServer and CLI risking maintenance drift; low-level code shows dense serialization logic but no critical defects, supporting moderate scores with targeted notes.
830
- codex
831
- {
832
- "batch": "Abstractions & Dependencies",
833
- "batch_index": 3,
834
- "assessments": {
835
- "abstraction_fitness": 82.0,
836
- "mid_level_elegance": 84.0,
837
- "low_level_elegance": 88.0
838
- },
839
- "dimension_notes": {
840
- "abstraction_fitness": {
841
- "evidence": [
842
- "src/mock-server.ts builds sequence rules inline in when().replySequence(), including mapping entries and calling createSequenceResolver, then sets rule.remaining.",
843
- "src/loader.ts repeats near-identical sequence rule wiring in addSequenceRule(), including entry mapping, createSequenceResolver, and rule.remaining."
844
- ],
845
- "impact_scope": "module",
846
- "fix_scope": "multi_file_refactor",
847
- "confidence": "high",
848
- "issues_preventing_higher_score": "Sequence-rule construction is duplicated in two modules, making future option/behavior changes easy to miss in one path.",
849
- "sub_axes": {
850
- "abstraction_leverage": 79.0,
851
- "indirection_cost": 84.0,
852
- "interface_honesty": 83.0
853
- }
854
- },
855
- "mid_level_elegance": {
856
- "evidence": [
857
- "src/mock-server.ts registers routes from the formats array (openaiFormat/anthropicFormat/responsesFormat) and relies on each format’s route.",
858
- "src/cli.ts prints a hard-coded endpoints string instead of deriving from the same formats registry."
859
- ],
860
- "impact_scope": "module",
861
- "fix_scope": "multi_file_refactor",
862
- "confidence": "medium",
863
- "issues_preventing_higher_score": "Endpoint listing is a manual seam between CLI output and runtime route registration, which can drift when adding/removing formats."
864
- },
865
- "low_level_elegance": {
866
- "evidence": [
867
- "src/formats/responses/serialize.ts serialize() mixes header creation, block construction, chunk flattening, and response finalization in one dense function.",
868
- "src/formats/openai/serialize.ts serialize() builds text/tool chunks, finish/usage chunks, and envelopes inline without local extraction."
869
- ],
870
- "impact_scope": "local",
871
- "fix_scope": "single_edit",
872
- "confidence": "medium",
873
- "issues_preventing_higher_score": "Serialization functions are readable but locally dense; small extractions would make the control flow more intention-revealing."
874
- }
875
- },
876
- "findings": [
877
- {
878
- "dimension": "abstraction_fitness",
879
- "identifier": "sequence_rule_duplication",
880
- "summary": "Sequence rule construction is duplicated across MockServer and loader, risking drift.",
881
- "related_files": [
882
- "src/mock-server.ts",
883
- "src/loader.ts",
884
- "src/rule-engine.ts"
885
- ],
886
- "evidence": [
887
- "src/mock-server.ts when().replySequence() maps entries, calls createSequenceResolver, mutates rule.resolve and rule.remaining.",
888
- "src/loader.ts addSequenceRule() performs the same mapping/resolve/remaining steps with a slightly different entry shape."
889
- ],
890
- "suggestion": "Extract a shared helper (e.g., in src/rule-engine.ts) that accepts normalized sequence steps and applies createSequenceResolver + remaining, then reuse it from both MockServer and loader.",
891
- "confidence": "high",
892
- "impact_scope": "module",
893
- "fix_scope": "multi_file_refactor",
894
- "root_cause_cluster": "sequence_rule_duplication"
895
- },
896
- {
897
- "dimension": "mid_level_elegance",
898
- "identifier": "format_registry_split",
899
- "summary": "CLI hard-codes endpoints while MockServer derives routes from format modules.",
900
- "related_files": [
901
- "src/mock-server.ts",
902
- "src/cli.ts"
903
- ],
904
- "evidence": [
905
- "src/mock-server.ts registers routes by iterating formats[] with per-format route values.",
906
- "src/cli.ts prints a static endpoints list string that must be updated manually."
907
- ],
908
- "suggestion": "Expose a single formats registry (or route list) and have the CLI render endpoints from it, avoiding cross-module drift.",
909
- "confidence": "medium",
910
- "impact_scope": "module",
911
- "fix_scope": "multi_file_refactor"
912
- }
913
- ],
914
- "retrospective": {
915
- "root_causes": [
916
- "Shared logic exists without a single owning abstraction, leading to duplication across modules."
917
- ],
918
- "likely_symptoms": [
919
- "sequence_rule_duplication",
920
- "format_registry_split"
921
- ],
922
- "possible_false_positives": []
923
- }
924
- }
925
- tokens used
926
- 54,720
927
-