@zhixuan92/multi-model-agent 4.9.1 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/README.md +4 -3
  2. package/bin/mmagent.mjs +47 -0
  3. package/package.json +24 -43
  4. package/postinstall.mjs +8 -0
  5. package/dist/cli/index.d.ts +0 -62
  6. package/dist/cli/index.d.ts.map +0 -1
  7. package/dist/cli/index.js +0 -345
  8. package/dist/cli/index.js.map +0 -1
  9. package/dist/cli/info.d.ts +0 -22
  10. package/dist/cli/info.d.ts.map +0 -1
  11. package/dist/cli/info.js +0 -100
  12. package/dist/cli/info.js.map +0 -1
  13. package/dist/cli/logs.d.ts +0 -15
  14. package/dist/cli/logs.d.ts.map +0 -1
  15. package/dist/cli/logs.js +0 -102
  16. package/dist/cli/logs.js.map +0 -1
  17. package/dist/cli/print-token.d.ts +0 -18
  18. package/dist/cli/print-token.d.ts.map +0 -1
  19. package/dist/cli/print-token.js +0 -60
  20. package/dist/cli/print-token.js.map +0 -1
  21. package/dist/cli/serve.d.ts +0 -28
  22. package/dist/cli/serve.d.ts.map +0 -1
  23. package/dist/cli/serve.js +0 -405
  24. package/dist/cli/serve.js.map +0 -1
  25. package/dist/cli/status.d.ts +0 -49
  26. package/dist/cli/status.d.ts.map +0 -1
  27. package/dist/cli/status.js +0 -155
  28. package/dist/cli/status.js.map +0 -1
  29. package/dist/cli/sync-skills.d.ts +0 -58
  30. package/dist/cli/sync-skills.d.ts.map +0 -1
  31. package/dist/cli/sync-skills.js +0 -266
  32. package/dist/cli/sync-skills.js.map +0 -1
  33. package/dist/cli/telemetry.d.ts +0 -10
  34. package/dist/cli/telemetry.d.ts.map +0 -1
  35. package/dist/cli/telemetry.js +0 -161
  36. package/dist/cli/telemetry.js.map +0 -1
  37. package/dist/cli/toggle.d.ts +0 -26
  38. package/dist/cli/toggle.d.ts.map +0 -1
  39. package/dist/cli/toggle.js +0 -185
  40. package/dist/cli/toggle.js.map +0 -1
  41. package/dist/http/async-dispatch.d.ts +0 -44
  42. package/dist/http/async-dispatch.d.ts.map +0 -1
  43. package/dist/http/async-dispatch.js +0 -175
  44. package/dist/http/async-dispatch.js.map +0 -1
  45. package/dist/http/auth.d.ts +0 -20
  46. package/dist/http/auth.d.ts.map +0 -1
  47. package/dist/http/auth.js +0 -56
  48. package/dist/http/auth.js.map +0 -1
  49. package/dist/http/canonicalize-file-paths.d.ts +0 -8
  50. package/dist/http/canonicalize-file-paths.d.ts.map +0 -1
  51. package/dist/http/canonicalize-file-paths.js +0 -43
  52. package/dist/http/canonicalize-file-paths.js.map +0 -1
  53. package/dist/http/cwd-validator.d.ts +0 -11
  54. package/dist/http/cwd-validator.d.ts.map +0 -1
  55. package/dist/http/cwd-validator.js +0 -130
  56. package/dist/http/cwd-validator.js.map +0 -1
  57. package/dist/http/errors.d.ts +0 -4
  58. package/dist/http/errors.d.ts.map +0 -1
  59. package/dist/http/errors.js +0 -9
  60. package/dist/http/errors.js.map +0 -1
  61. package/dist/http/execution-context.d.ts +0 -18
  62. package/dist/http/execution-context.d.ts.map +0 -1
  63. package/dist/http/execution-context.js +0 -61
  64. package/dist/http/execution-context.js.map +0 -1
  65. package/dist/http/handler-deps.d.ts +0 -19
  66. package/dist/http/handler-deps.d.ts.map +0 -1
  67. package/dist/http/handler-deps.js +0 -2
  68. package/dist/http/handler-deps.js.map +0 -1
  69. package/dist/http/handlers/control/batch-slice.d.ts +0 -4
  70. package/dist/http/handlers/control/batch-slice.d.ts.map +0 -1
  71. package/dist/http/handlers/control/batch-slice.js +0 -40
  72. package/dist/http/handlers/control/batch-slice.js.map +0 -1
  73. package/dist/http/handlers/control/batch.d.ts +0 -23
  74. package/dist/http/handlers/control/batch.d.ts.map +0 -1
  75. package/dist/http/handlers/control/batch.js +0 -332
  76. package/dist/http/handlers/control/batch.js.map +0 -1
  77. package/dist/http/handlers/control/context-blocks.d.ts +0 -22
  78. package/dist/http/handlers/control/context-blocks.d.ts.map +0 -1
  79. package/dist/http/handlers/control/context-blocks.js +0 -111
  80. package/dist/http/handlers/control/context-blocks.js.map +0 -1
  81. package/dist/http/handlers/introspection/health.d.ts +0 -20
  82. package/dist/http/handlers/introspection/health.d.ts.map +0 -1
  83. package/dist/http/handlers/introspection/health.js +0 -18
  84. package/dist/http/handlers/introspection/health.js.map +0 -1
  85. package/dist/http/handlers/introspection/status.d.ts +0 -26
  86. package/dist/http/handlers/introspection/status.d.ts.map +0 -1
  87. package/dist/http/handlers/introspection/status.js +0 -136
  88. package/dist/http/handlers/introspection/status.js.map +0 -1
  89. package/dist/http/handlers/tools/audit.d.ts +0 -4
  90. package/dist/http/handlers/tools/audit.d.ts.map +0 -1
  91. package/dist/http/handlers/tools/audit.js +0 -43
  92. package/dist/http/handlers/tools/audit.js.map +0 -1
  93. package/dist/http/handlers/tools/debug.d.ts +0 -4
  94. package/dist/http/handlers/tools/debug.d.ts.map +0 -1
  95. package/dist/http/handlers/tools/debug.js +0 -43
  96. package/dist/http/handlers/tools/debug.js.map +0 -1
  97. package/dist/http/handlers/tools/delegate.d.ts +0 -4
  98. package/dist/http/handlers/tools/delegate.d.ts.map +0 -1
  99. package/dist/http/handlers/tools/delegate.js +0 -43
  100. package/dist/http/handlers/tools/delegate.js.map +0 -1
  101. package/dist/http/handlers/tools/execute-plan.d.ts +0 -4
  102. package/dist/http/handlers/tools/execute-plan.d.ts.map +0 -1
  103. package/dist/http/handlers/tools/execute-plan.js +0 -45
  104. package/dist/http/handlers/tools/execute-plan.js.map +0 -1
  105. package/dist/http/handlers/tools/investigate.d.ts +0 -4
  106. package/dist/http/handlers/tools/investigate.d.ts.map +0 -1
  107. package/dist/http/handlers/tools/investigate.js +0 -64
  108. package/dist/http/handlers/tools/investigate.js.map +0 -1
  109. package/dist/http/handlers/tools/journal-recall.d.ts +0 -4
  110. package/dist/http/handlers/tools/journal-recall.d.ts.map +0 -1
  111. package/dist/http/handlers/tools/journal-recall.js +0 -40
  112. package/dist/http/handlers/tools/journal-recall.js.map +0 -1
  113. package/dist/http/handlers/tools/journal-record.d.ts +0 -4
  114. package/dist/http/handlers/tools/journal-record.d.ts.map +0 -1
  115. package/dist/http/handlers/tools/journal-record.js +0 -35
  116. package/dist/http/handlers/tools/journal-record.js.map +0 -1
  117. package/dist/http/handlers/tools/research.d.ts +0 -4
  118. package/dist/http/handlers/tools/research.d.ts.map +0 -1
  119. package/dist/http/handlers/tools/research.js +0 -64
  120. package/dist/http/handlers/tools/research.js.map +0 -1
  121. package/dist/http/handlers/tools/retry.d.ts +0 -4
  122. package/dist/http/handlers/tools/retry.d.ts.map +0 -1
  123. package/dist/http/handlers/tools/retry.js +0 -73
  124. package/dist/http/handlers/tools/retry.js.map +0 -1
  125. package/dist/http/handlers/tools/review.d.ts +0 -4
  126. package/dist/http/handlers/tools/review.d.ts.map +0 -1
  127. package/dist/http/handlers/tools/review.js +0 -43
  128. package/dist/http/handlers/tools/review.js.map +0 -1
  129. package/dist/http/middleware/body-reader.d.ts +0 -16
  130. package/dist/http/middleware/body-reader.d.ts.map +0 -1
  131. package/dist/http/middleware/body-reader.js +0 -44
  132. package/dist/http/middleware/body-reader.js.map +0 -1
  133. package/dist/http/middleware/caller-identity.d.ts +0 -16
  134. package/dist/http/middleware/caller-identity.d.ts.map +0 -1
  135. package/dist/http/middleware/caller-identity.js +0 -16
  136. package/dist/http/middleware/caller-identity.js.map +0 -1
  137. package/dist/http/middleware/decompress.d.ts +0 -14
  138. package/dist/http/middleware/decompress.d.ts.map +0 -1
  139. package/dist/http/middleware/decompress.js +0 -51
  140. package/dist/http/middleware/decompress.js.map +0 -1
  141. package/dist/http/project-registry.d.ts +0 -54
  142. package/dist/http/project-registry.d.ts.map +0 -1
  143. package/dist/http/project-registry.js +0 -130
  144. package/dist/http/project-registry.js.map +0 -1
  145. package/dist/http/request-observability.d.ts +0 -8
  146. package/dist/http/request-observability.d.ts.map +0 -1
  147. package/dist/http/request-observability.js +0 -20
  148. package/dist/http/request-observability.js.map +0 -1
  149. package/dist/http/request-pipeline.d.ts +0 -16
  150. package/dist/http/request-pipeline.d.ts.map +0 -1
  151. package/dist/http/request-pipeline.js +0 -144
  152. package/dist/http/request-pipeline.js.map +0 -1
  153. package/dist/http/server.d.ts +0 -17
  154. package/dist/http/server.d.ts.map +0 -1
  155. package/dist/http/server.js +0 -300
  156. package/dist/http/server.js.map +0 -1
  157. package/dist/http/types.d.ts +0 -20
  158. package/dist/http/types.d.ts.map +0 -1
  159. package/dist/http/types.js +0 -2
  160. package/dist/http/types.js.map +0 -1
  161. package/dist/skill-install/disabled-state.d.ts +0 -35
  162. package/dist/skill-install/disabled-state.d.ts.map +0 -1
  163. package/dist/skill-install/disabled-state.js +0 -96
  164. package/dist/skill-install/disabled-state.js.map +0 -1
  165. package/dist/skill-install/discover.d.ts +0 -29
  166. package/dist/skill-install/discover.d.ts.map +0 -1
  167. package/dist/skill-install/discover.js +0 -104
  168. package/dist/skill-install/discover.js.map +0 -1
  169. package/dist/skill-install/include-utils.d.ts +0 -27
  170. package/dist/skill-install/include-utils.d.ts.map +0 -1
  171. package/dist/skill-install/include-utils.js +0 -90
  172. package/dist/skill-install/include-utils.js.map +0 -1
  173. package/dist/skill-install/manifest.d.ts +0 -82
  174. package/dist/skill-install/manifest.d.ts.map +0 -1
  175. package/dist/skill-install/manifest.js +0 -215
  176. package/dist/skill-install/manifest.js.map +0 -1
  177. package/dist/skill-install/skill-installer-common.d.ts +0 -26
  178. package/dist/skill-install/skill-installer-common.d.ts.map +0 -1
  179. package/dist/skill-install/skill-installer-common.js +0 -139
  180. package/dist/skill-install/skill-installer-common.js.map +0 -1
  181. package/dist/skill-install/skill-installers/claude-code.d.ts +0 -43
  182. package/dist/skill-install/skill-installers/claude-code.d.ts.map +0 -1
  183. package/dist/skill-install/skill-installers/claude-code.js +0 -65
  184. package/dist/skill-install/skill-installers/claude-code.js.map +0 -1
  185. package/dist/skill-install/skill-installers/codex-cli.d.ts +0 -27
  186. package/dist/skill-install/skill-installers/codex-cli.d.ts.map +0 -1
  187. package/dist/skill-install/skill-installers/codex-cli.js +0 -84
  188. package/dist/skill-install/skill-installers/codex-cli.js.map +0 -1
  189. package/dist/skill-install/skill-installers/cursor.d.ts +0 -72
  190. package/dist/skill-install/skill-installers/cursor.d.ts.map +0 -1
  191. package/dist/skill-install/skill-installers/cursor.js +0 -81
  192. package/dist/skill-install/skill-installers/cursor.js.map +0 -1
  193. package/dist/skill-install/skill-installers/gemini-cli.d.ts +0 -50
  194. package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +0 -1
  195. package/dist/skill-install/skill-installers/gemini-cli.js +0 -72
  196. package/dist/skill-install/skill-installers/gemini-cli.js.map +0 -1
  197. package/dist/skill-install/skill-manifest-sync.d.ts +0 -11
  198. package/dist/skill-install/skill-manifest-sync.d.ts.map +0 -1
  199. package/dist/skill-install/skill-manifest-sync.js +0 -65
  200. package/dist/skill-install/skill-manifest-sync.js.map +0 -1
  201. package/dist/skills/_shared/auth.md +0 -41
  202. package/dist/skills/_shared/error-handling.md +0 -31
  203. package/dist/skills/_shared/polling.md +0 -88
  204. package/dist/skills/_shared/response-shape.md +0 -55
  205. package/dist/skills/_shared/review-policy.md +0 -15
  206. package/dist/skills/mma-audit/SKILL.md +0 -270
  207. package/dist/skills/mma-context-blocks/SKILL.md +0 -148
  208. package/dist/skills/mma-debug/SKILL.md +0 -208
  209. package/dist/skills/mma-delegate/SKILL.md +0 -216
  210. package/dist/skills/mma-execute-plan/SKILL.md +0 -214
  211. package/dist/skills/mma-explore/SKILL.md +0 -190
  212. package/dist/skills/mma-investigate/SKILL.md +0 -258
  213. package/dist/skills/mma-journal-recall/SKILL.md +0 -242
  214. package/dist/skills/mma-journal-record/SKILL.md +0 -189
  215. package/dist/skills/mma-research/SKILL.md +0 -223
  216. package/dist/skills/mma-retry/SKILL.md +0 -221
  217. package/dist/skills/mma-review/SKILL.md +0 -209
  218. package/dist/skills/multi-model-agent/SKILL.md +0 -206
  219. package/dist/telemetry/consent.d.ts +0 -4
  220. package/dist/telemetry/consent.d.ts.map +0 -1
  221. package/dist/telemetry/consent.js +0 -40
  222. package/dist/telemetry/consent.js.map +0 -1
  223. package/dist/telemetry/flusher.d.ts +0 -19
  224. package/dist/telemetry/flusher.d.ts.map +0 -1
  225. package/dist/telemetry/flusher.js +0 -277
  226. package/dist/telemetry/flusher.js.map +0 -1
  227. package/dist/telemetry/generation.d.ts +0 -9
  228. package/dist/telemetry/generation.d.ts.map +0 -1
  229. package/dist/telemetry/generation.js +0 -33
  230. package/dist/telemetry/generation.js.map +0 -1
  231. package/dist/telemetry/identity.d.ts +0 -9
  232. package/dist/telemetry/identity.d.ts.map +0 -1
  233. package/dist/telemetry/identity.js +0 -35
  234. package/dist/telemetry/identity.js.map +0 -1
  235. package/dist/telemetry/install-id.d.ts +0 -13
  236. package/dist/telemetry/install-id.d.ts.map +0 -1
  237. package/dist/telemetry/install-id.js +0 -49
  238. package/dist/telemetry/install-id.js.map +0 -1
  239. package/dist/telemetry/install-meta.d.ts +0 -10
  240. package/dist/telemetry/install-meta.d.ts.map +0 -1
  241. package/dist/telemetry/install-meta.js +0 -15
  242. package/dist/telemetry/install-meta.js.map +0 -1
  243. package/dist/telemetry/queue.d.ts +0 -35
  244. package/dist/telemetry/queue.d.ts.map +0 -1
  245. package/dist/telemetry/queue.js +0 -287
  246. package/dist/telemetry/queue.js.map +0 -1
  247. package/dist/telemetry/recorder.d.ts +0 -39
  248. package/dist/telemetry/recorder.d.ts.map +0 -1
  249. package/dist/telemetry/recorder.js +0 -173
  250. package/dist/telemetry/recorder.js.map +0 -1
  251. package/scripts/postinstall.js +0 -36
@@ -1,209 +0,0 @@
1
- ---
2
- name: mma-review
3
- description: >-
4
- Use when source code needs a quality / security / correctness pass — pre-merge
5
- review, post-implementation sanity check, or focused look at a small file set
6
- — and the review can run in parallel per file
7
- when_to_use: >-
8
- User asks for a code review or pre-merge check, OR a methodology skill
9
- (superpowers:requesting-code-review, /review, /security-review) points at one,
10
- AND mmagent is running. Delegate so each file reviews on its own worker; the
11
- main agent only decides what to merge. Review on SOURCE CODE — use mma-audit
12
- for prose specs / configs.
13
- version: 4.9.1
14
- ---
15
-
16
- # mma-review
17
-
18
- ## Overview
19
-
20
- mma-review is the **pre-merge gate**. Send code files (or a diff) to a worker for structured review against an executability bar: would a maintainer who reads only the verdict and the diff understand which changes are required, why each is required, and where each lives — well enough to apply the fix and re-merge without re-investigating?
21
-
22
- Each file is reviewed independently in parallel; results are index-aligned with `filePaths`.
23
-
24
- **Core principle:** Reviewer is a different model from the implementer — different training, different blind spots. Cross-model review catches what self-review misses. The reviewer runs against a 10-category failure-mode taxonomy (test gap, cross-file ripple, missing edge case, race, resource leak, backward-compat break, security/performance regression, implicit-contract assumption, pre-existing-bug-vs-new-regression separation) and weighs every change through the security, performance, and correctness lenses regardless of `focus`.
25
-
26
- ## When to Use
27
-
28
- **Use when:**
29
- - 1+ source code files just changed (post-implementation review)
30
- - Pre-merge sanity check on a focused diff
31
- - Security-sensitive code path (`focus: ["security"]`)
32
- - A specialized review pass (e.g. `focus: ["performance"]` on hot-path code)
33
-
34
- **Don't use when:**
35
- - The thing being reviewed is prose / spec / config → `mma-audit` (better-suited prompt template)
36
- - You want to know whether a complete branch is mergeable → run `/ultrareview` (multi-model branch review) instead
37
- - The diff is one-line / one-character → reading inline is faster than dispatch
38
-
39
- ## How to invoke for cross-file ripple detection
40
-
41
- The cross-file ripple pass (changed-symbol → broken caller) only fires when the worker can identify what changed. Two patterns:
42
-
43
- - **Diff-as-input (preferred for cross-file ripple)**: pass the diff via the `code` field, plus the named files via `filePaths`. The worker treats the diff as the change-set and greps for callers of changed public symbols.
44
- - **Files-only (static review)**: pass only `filePaths`. The worker reviews the files in their current state without a change-set, so cross-file ripple is degenerate. Test gap, missing edge case, race, leak, and security/performance findings still fire.
45
-
46
- ## Endpoint
47
-
48
- `POST /review?cwd=<abs-path>`
49
-
50
- @include _shared/auth.md
51
-
52
- ## Request body
53
-
54
- ```json
55
- {
56
- "code": "inline code snippet (optional if filePaths given)",
57
- "focus": ["correctness", "security"],
58
- "subtype": "default",
59
- "filePaths": ["/project/src/auth/login.ts"],
60
- "contextBlockIds": []
61
- }
62
- ```
63
-
64
- | Field | Type | Required | Notes |
65
- |---|---|---|---|
66
- | `code` | string | no | Inline code snippet to review |
67
- | `focus` | string[] | no | Any of `security`, `performance`, `correctness`, `style`. Omit for general review. |
68
- | `subtype` | `'default'` | no (defaults to `'default'`) | Reserved for future criteria sets; only `default` is wired today. |
69
- | `filePaths` | string[] | no | Files to review (one worker per file, parallel) |
70
- | `contextBlockIds` | string[] | no | IDs from `mma-context-blocks` — useful for design docs the reviewer should validate against |
71
-
72
- Either `code` or `filePaths` (or both) must be provided.
73
-
74
- > Worker tier for `mma-review` is hardcoded to `complex` and is not caller-configurable. Sending `agentType` is rejected with HTTP 400.
75
-
76
- ## Full example
77
-
78
- ```bash
79
- BATCH=$(curl -f --show-error -s -X POST \
80
- -H "X-MMA-Client: $MMA_CLIENT" \
81
- -H "X-MMA-Main-Model: $MMA_MAIN_MODEL" \
82
- -H "Authorization: Bearer $TOKEN" \
83
- -H "Content-Type: application/json" \
84
- -d '{"focus":["security","correctness"],"filePaths":["/project/src/auth/login.ts"]}' \
85
- "http://localhost:$PORT/review?cwd=/project")
86
- BATCH_ID=$(echo "$BATCH" | jq -r '.batchId')
87
- ```
88
-
89
- @include _shared/polling.md
90
-
91
- @include _shared/response-shape.md
92
-
93
- ## Reading the findings
94
-
95
- The main agent reads `completed` + `message` + `findings` — the findings are the answer. For
96
- read-only routes, `filesChanged` is always `[]` and `commitSha` is always `null`.
97
-
98
- ```json
99
- {
100
- "completed": true,
101
- "message": "Review complete; 3 findings.",
102
- "findings": [
103
- { "id": "F1", "severity": "critical", "category": "test-gap",
104
- "claim": "login.ts has no test for null username edge case.",
105
- "evidence": "Worker read login.ts and grepped for test files — no null-case test found.",
106
- "suggestion": "Add test case: `login(null) throws ValidationError`.",
107
- "source": "reviewer" }
108
- ],
109
- "filesChanged": [],
110
- "commitSha": null,
111
- "summary": "...",
112
- "telemetry": { ... }
113
- }
114
- ```
115
-
116
- ### Finding shape
117
-
118
- Every finding has this shape:
119
-
120
- | Field | Type | Notes |
121
- |---|---|---|
122
- | `id` | string | Worker-assigned, e.g. `F1`, `F2`. Stable across chain. |
123
- | `severity` | `'critical' \| 'high' \| 'medium' \| 'low'` | 4-tier. |
124
- | `category` | string | Topical bucket, e.g. `test-gap`, `cross-file-ripple`. |
125
- | `claim` | string | One-sentence summary. |
126
- | `evidence` | string ≥20 chars | Verbatim from source when grounded. |
127
- | `suggestion?` | string | Optional fix recommendation. |
128
- | `source` | `'implementer' \| 'reviewer'` | Who produced the finding. |
129
-
130
- `annotatorConfidence` and `evidenceGrounded` are retired — they were v4 fields with no producers.
131
-
132
- ### Recommended rendering by the main agent
133
-
134
- 1. Show ALL findings — never silently drop. Severity and grounding are soft
135
- signals, not gates.
136
- 2. Default sort: severity (critical → low), then `id` ascending.
137
- 3. `severity` is the authoritative value — use it directly.
138
- 4. Mark findings with `evidence` shorter than 30 chars as "low-evidence"
139
- (lighter color or `(low evidence)` annotation). User decides what to do.
140
- 5. Severity-tier counts feed the dashboard.
141
-
142
- ## Best practices
143
-
144
- This skill is one step in the larger flow described in `multi-model-agent` → "Best practices". Recipes that involve `mma-review`:
145
-
146
- - **Recipe A (analog) — Review-iterate-clean.** `mma-review` → fix → `mma-review` again. Same shape as the audit recipe, applied to source code. Sequential rounds; register the file(s) via `mma-context-blocks` before round 1 and reuse the same ID across rounds.
147
-
148
- Anti-pattern alert: **`parallel-rounds-same-target`** (AP1). Three parallel reviews of the same source file re-flag the same issues. Run rounds sequentially with a fix between each.
149
-
150
- ## Common pitfalls
151
-
152
- ❌ **Reviewing a plan/spec markdown with `mma-review`**
153
- The reviewer is tuned for code constructs (types, call sites, test coverage). On prose it produces vague nits. **Fix:** use `mma-audit` for docs/specs, `mma-review` for source.
154
-
155
- ❌ **Omitting `focus` and getting watery findings**
156
- A general review surfaces low-signal style nits alongside real bugs. **Fix:** specify `focus: ["correctness"]` or `["security"]` to bias the reviewer toward the dimension you care about.
157
-
158
- ❌ **Inlining the spec the reviewer should validate against**
159
- If the reviewer needs to check the diff against a design doc, register the doc once via `mma-context-blocks` and pass the `contextBlockIds`. Inlining N times wastes tokens.
160
-
161
- ❌ **Skipping review because "I already read it"**
162
- Self-review and cross-model review are not the same thing. The whole reason to delegate is the different blind spots. Read the findings; merge what you agree with.
163
-
164
- ## Terminal context block
165
-
166
- Every completed **read-route** task (audit / review / debug / investigate / research) auto-registers a reusable terminal context block containing its report (headline + findings). The block id is returned on each per-task result as **`contextBlockId`**. Write routes (delegate / execute-plan / retry) return `contextBlockId: null` — their record is the commit, not a block. This block is immutable, lives for the session duration, and counts against the project's `maxEntries` quota (default 500).
167
-
168
- Use it for delta follow-ups — feed prior results' block ids into a later call's `contextBlockIds`, filtering out nulls:
169
-
170
- contextBlockIds: priorResults.map(r => r.contextBlockId).filter((id) => id !== null)
171
-
172
- **Use cases:**
173
- - Pass round-N review findings to round N+1 via `contextBlockIds`
174
- - Feed review results into a downstream `mma-delegate` fix step
175
- - Accumulate findings across iterative review rounds
176
-
177
- The block is registered server-side at task completion; no caller action is needed to create it. Delete it explicitly via `DELETE /context-blocks/:id` when no longer needed, or let it expire on session teardown.
178
-
179
- ## Outcome semantics
180
-
181
- Every task result carries outcome fields that describe the code review's conclusion status:
182
-
183
- | Field | Type | Meaning |
184
- |---|---|---|
185
- | `findingsOutcome` | `'found' \| 'clean' \| 'not_applicable'` | Answers the question: did the review uncover issues? |
186
- | `findingsOutcomeReason` | `string \| null` | When `findingsOutcome` is set, this explains why (e.g. "Test gap: login() has no null-username case" or "Code is clean across all review criteria"). |
187
- | `outcomeInferred` | `boolean` | `true` if the system inferred the outcome from findings count; `false` if the reviewer explicitly stated it. |
188
- | `outcomeMalformed` | `boolean` | `true` if the outcome line was malformed and had to be repaired; `false` otherwise. |
189
-
190
- ### Enum values
191
-
192
- - **`found`** — the review surfaced one or more issues (findings) across one or more review categories (test gap, cross-file ripple, race, leak, security, performance, etc.). This indicates the code needs rework before merge.
193
- - **`clean`** — the review completed and found zero issues. The code passes the review bar and is safe to merge.
194
- - **`not_applicable`** — the review could not proceed (e.g., wrong input type, missing preconditions, or system error). This is rare; most reviews resolve to `found` or `clean`.
195
-
196
- ### Empty findings ≠ failure
197
-
198
- A crucial semantic: **empty findings does NOT mean `completed: false` or a failed review.** Finding nothing wrong is a successful review outcome — it means the code passed inspection. A review with zero findings is `completed: true` with `findingsOutcome: 'clean'`.
199
-
200
- ### Per-route legal outcomes
201
-
202
- The legal outcomes for this route are: `['found', 'clean']`
203
-
204
- - **`found`** — one or more issues were detected across the review categories.
205
- - **`clean`** — zero issues were detected; the code is ready to merge.
206
-
207
- The outcome `not_applicable` is not legal for `mma-review` (except on actual precondition failures) because a code review always produces a verdict: either issues found or clean.
208
-
209
- @include _shared/error-handling.md
@@ -1,206 +0,0 @@
1
- ---
2
- name: multi-model-agent
3
- description: >-
4
- Use first whenever you're about to delegate any tool-using work — picks the
5
- right mma-* skill (audit, review, verify, debug, plan execution, codebase
6
- investigation, ad-hoc delegation, retry, context-block reuse) instead of
7
- defaulting to inline Agent dispatches
8
- when_to_use: >-
9
- The user asks for work you'd normally delegate — audit, code review, checklist
10
- verification, debugging, plan execution, codebase Q&A, or ad-hoc parallel
11
- tasks — AND mmagent is running. Read this once, pick the matching mma-* skill,
12
- and delegate there. Applies equally whether the user invoked a superpowers
13
- methodology skill or asked directly.
14
- version: 4.9.1
15
- ---
16
-
17
- # multi-model-agent (router)
18
-
19
- ## Overview
20
-
21
- Local HTTP service that fans out tool-using work to workers on different LLM providers (Claude, OpenAI-compatible, Codex). Workers run on cheap models; the main agent stays on judgment.
22
-
23
- **Core principle:** Pick the most specific `mma-*` skill that fits the task. Specificity reduces input — specialized skills know their route, schema, and defaults so you write less.
24
-
25
- ## Skill map
26
-
27
- ```dot
28
- digraph picker {
29
- "Plan/spec file on disk?" [shape=diamond];
30
- "Audit a doc?" [shape=diamond];
31
- "Review code?" [shape=diamond];
32
- "Verify a checklist?" [shape=diamond];
33
- "Debug a failure?" [shape=diamond];
34
- "Codebase question?" [shape=diamond];
35
- "Convergent or divergent?" [shape=diamond];
36
- "mma-execute-plan" [shape=box];
37
- "mma-audit" [shape=box];
38
- "mma-review" [shape=box];
39
- "mma-debug" [shape=box];
40
- "mma-investigate" [shape=box];
41
- "mma-explore" [shape=box];
42
- "mma-delegate" [shape=box];
43
-
44
- "Plan/spec file on disk?" -> "mma-execute-plan" [label="yes"];
45
- "Plan/spec file on disk?" -> "Audit a doc?" [label="no"];
46
- "Audit a doc?" -> "mma-audit" [label="yes"];
47
- "Audit a doc?" -> "Review code?" [label="no"];
48
- "Review code?" -> "mma-review" [label="yes"];
49
- "Review code?" -> "Debug a failure?" [label="no"];
50
- "Debug a failure?" -> "mma-debug" [label="yes"];
51
- "Debug a failure?" -> "Codebase question?" [label="no"];
52
- "Codebase question?" -> "Convergent or divergent?" [label="yes"];
53
- "Codebase question?" -> "mma-delegate" [label="no — ad-hoc"];
54
- "Convergent or divergent?" -> "mma-investigate" [label="convergent (one answer)"];
55
- "Convergent or divergent?" -> "mma-explore" [label="divergent (3-5 directions)"];
56
- }
57
- ```
58
-
59
- | Skill | Purpose |
60
- |---|---|
61
- | `mma-execute-plan` | Implement tasks from a plan or spec file (descriptors match plan headings) |
62
- | `mma-audit` | Audit a document/spec/config for security, correctness, style, or performance |
63
- | `mma-review` | Review code for quality, security, performance, correctness. Pass acceptance checklists in the brief if you need verification-style checks. |
64
- | `mma-debug` | Debug a failure with a structured hypothesis |
65
- | `mma-investigate` | Codebase Q&A — structured answer with `file:line` citations + confidence |
66
- | `mma-explore` | Divergent ideation from codebase + web research + prior-learnings recall — use before `superpowers:brainstorming` |
67
- | `mma-delegate` | Ad-hoc implementation / research with no plan file |
68
- | `mma-retry` | Re-run specific failed/incomplete tasks from a previous batch by index |
69
- | `mma-context-blocks` | Register a reused doc once; reference by ID across N tasks |
70
-
71
- ## Best practices
72
-
73
- ### The unifying principle
74
-
75
- The main session is for judgment, orchestration, and dialogue with the engineer. Everything else — read, grep, audit, review, debug, implement, verify — gets delegated. If you're about to do labor in main context, you've already taken the wrong turn.
76
-
77
- ### Judgment vs labor — what NEVER delegates
78
-
79
- Labor handles work whose answer is findable from the inputs. Main session keeps work whose answer is **judgment** — there is no "right answer" a worker could discover:
80
-
81
- - **Brainstorming** — exploring the problem space with the engineer before a spec exists.
82
- - **Spec writing** — deciding what to build, what success looks like, what's out of scope.
83
- - **Plan writing** — turning a spec into ordered, testable steps with the right decomposition.
84
- - **Architecture and design decisions** — choosing the shape of the solution.
85
- - **Final approval / merge decisions** — what ships.
86
- - **Dialogue with the engineer** — clarifying intent, negotiating tradeoffs, answering "should we?".
87
-
88
- The test: *if a worker can produce the answer from the given inputs, delegate; if the answer requires deciding what the inputs should be, it's main-session work.* Recipes A–D all keep these judgment steps in main context (e.g., Recipe C explicitly: `mma-investigate` → **write the plan (main)** → `mma-execute-plan`).
89
-
90
- ### C1 — Delegate by default, inline by exception
91
-
92
- If a task needs 3+ file reads or any grep, it goes to a worker. Inline `Read` is reserved for files already in context, single-file lookups, or 1-2 file reads with a known target.
93
-
94
- ### C2 — Parallel for independence, sequential for iteration
95
-
96
- Independent fan-out (5 unrelated audits, 5 unrelated bugs) → parallel batch. Coupled rounds where round N's fix produces round N+1's input (audit → fix → re-audit, debug → fix → verify) → sequential.
97
-
98
- ### C3 — Shared content lives in a context block, not in caller tokens
99
-
100
- Any artifact (spec, plan, prior-round findings, long error log) that crosses 2+ calls gets registered once via `mma-context-blocks` and referenced by ID.
101
-
102
- ### Recipe A — Audit-iterate-clean
103
-
104
- `mma-audit` → read findings → fix (inline if 1-2 lines, else `mma-delegate`) → `mma-audit` again. Sequential rounds, NOT parallel re-audits. The fix produces new edges; round 2 catches what round 1 couldn't see. Register the doc as a context block before round 1; reuse the same ID across all rounds. The same shape applies to `mma-review` for source code (review → fix → re-review).
105
-
106
- ### Recipe B — Debug-fix-review
107
-
108
- `mma-debug` (read/reproduce/trace) → `mma-delegate` (apply the fix the hypothesis implies) → `mma-review` with the acceptance criteria included in the brief. Three skills, strict order. Register the failing test output / reproduction log as a context block before the debug call; reuse it on the review call so the reviewer can compare against the same evidence.
109
-
110
- ### Recipe C — Investigate-plan-execute
111
-
112
- `mma-investigate` (codebase Q&A) → write the plan (main-context judgment task) → `mma-execute-plan` (workers implement against named plan headings) → `mma-retry` on any failed indices. Register the plan file as a context block before execute-plan; the retry call inherits the same configuration including `contextBlockIds`.
113
-
114
- ### Recipe D — Plan-execute-retry
115
-
116
- When `mma-execute-plan` returns mixed `done` / `done_with_concerns` / `failed`, the next step is `mma-retry` on the failed indices only — never a full-batch re-dispatch. Pass the **original `batchId`** as input, specify the failed task indices, keep the same configuration. (`mma-retry` produces a NEW `batchId` in its response — poll that one for terminal state, not the original.) Any `contextBlockIds` registered for the original batch carry forward into retry — no need to re-register.
117
-
118
- ### Anti-patterns
119
-
120
- 1. **`parallel-rounds-same-target`** — Caller fans out 3 parallel calls of the same skill on the same target — `mma-audit` on one document, or `mma-review` on the same source file. The reports overlap heavily; later rounds never see the fix from earlier rounds, so they re-flag the same issues. Corrective: sequential rounds with a fix between each (Recipe A).
121
-
122
- 2. **`inline-labor-leakage`** — Caller does 3+ `Read` calls, or any `grep`, in main context "just to understand the situation." Main tokens get burned on labor; the answer the caller actually needs is one paragraph of synthesis. Corrective: `mma-investigate` for codebase Q&A; if the goal is implementation, jump straight to `mma-delegate` with file paths and let the worker read.
123
-
124
- 3. **`re-inlined-shared-content`** — Caller pastes the same spec / plan / error log into 5 task prompts in one batch (or across rounds). Token cost scales linearly with N. Corrective: `mma-context-blocks` register once, pass `contextBlockIds` to every task. C3 fires the moment the same content is referenced a second time.
125
-
126
- 4. **`full-batch-redispatch`** — Caller re-runs `mma-execute-plan` with the entire task list when only 2 of 8 tasks failed. The 6 successful tasks get re-charged. Corrective: `mma-retry` with the failed indices. (The same anti-pattern applies to multi-task `mma-delegate` batches; `mma-retry` is the corrective there too.)
127
-
128
- ## Preflight: auto-start the daemon if it is not running
129
-
130
- ```bash
131
- PORT=7337
132
- if ! curl -sf "http://127.0.0.1:$PORT/health" >/dev/null 2>&1; then
133
- mmagent serve >/dev/null 2>&1 & disown
134
- for _ in 1 2 3 4 5 6 7 8 9 10; do
135
- sleep 0.5
136
- curl -sf "http://127.0.0.1:$PORT/health" >/dev/null 2>&1 && break
137
- done
138
- fi
139
- ```
140
-
141
- Idempotent: already-running daemon → curl succeeds → no-op. Background `mmagent serve` (with `& disown`) — never run it foreground (it would block the rest of the script).
142
-
143
- ## Auth token
144
-
145
- ```bash
146
- export MMAGENT_AUTH_TOKEN=$(mmagent print-token)
147
- ```
148
-
149
- Every request requires `Authorization: Bearer $MMAGENT_AUTH_TOKEN`. The token rotates on every `mmagent serve` restart — re-export after a `pkill`/upgrade.
150
-
151
- ## Worker tier: `agentType`
152
-
153
- Only `mma-delegate` accepts `agentType: "standard" | "complex"` per task — default `"standard"` (cheaper, faster). Pick `"complex"` when:
154
-
155
- - The task touches many files or requires multi-step reasoning a standard-tier model cannot hold in context.
156
- - A prior standard run came back with `filesWritten: 0` or `incompleteReason: "turn_cap"` / `"timeout"`.
157
- - The task is security-sensitive or ambiguous enough that being wrong is costly.
158
-
159
- Every other route hardcodes its tier and rejects `agentType` with HTTP 400:
160
-
161
- | Route | Hardcoded tier |
162
- |---|---|
163
- | `mma-execute-plan` | `standard` |
164
- | `mma-audit` | `complex` |
165
- | `mma-review` | `complex` |
166
- | `mma-debug` | `complex` |
167
- | `mma-investigate` | `complex` |
168
- | `mma-explore` | `complex` (all three workers — internal, external, synthesizer) |
169
-
170
- If you need `complex` tier on plan-style work, dispatch via `mma-delegate` with the plan task as the prompt and `agentType: "complex"`.
171
-
172
- ## Context block defaults
173
-
174
- | Default | Value | Notes |
175
- |---|---|---|
176
- | Idle TTL | 24 h | Block eligible for eviction after 24 h with no active batch references |
177
- | `maxEntries` | 500 | Per-project cap on total context blocks |
178
- | Body cap | 50 MiB | Maximum `content` size per block |
179
-
180
- Context blocks are immutable after creation. To update content, register a new block and switch `contextBlockIds` to the new ID.
181
-
182
- ## Terminal context block
183
-
184
- Every completed **read-route** task (audit / review / debug / investigate / research) auto-registers a reusable terminal context block containing its report (headline + findings). The block id is returned on each per-task result as **`contextBlockId`**. Write routes (delegate / execute-plan / retry) return `contextBlockId: null` — their record is the commit, not a block. This block is immutable, lives for the session duration, and counts against the project's `maxEntries` quota (default 500).
185
-
186
- Use it for delta follow-ups — feed prior results' block ids into a later call's `contextBlockIds`, filtering out nulls:
187
-
188
- contextBlockIds: priorResults.map(r => r.contextBlockId).filter((id) => id !== null)
189
-
190
- ## General flow
191
-
192
- 1. Call the matching `mma-*` skill → receive `{ batchId, statusUrl }`.
193
- 2. Poll `GET /batch/:id`: `202 text/plain` while pending (body is the running headline), `200 application/json` on terminal.
194
- 3. Read `results` / `error` from the 6-field terminal envelope.
195
-
196
- ## Common pitfalls
197
-
198
- ❌ **Defaulting to inline Agent dispatch when mmagent is up.** mmagent workers cost ~10× less and don't pollute main context. **Why:** every inline tool call burns flagship-model tokens; that's exactly what mmagent exists to avoid.
199
-
200
- ❌ **Picking `mma-delegate` when a more specific skill fits.** Audit / review / verify / debug / investigate workers know their route's defaults and emit structured reports. **Why:** specialized skills require less input and produce richer output.
201
-
202
- ❌ **Starting an investigation that needs to write code.** `mma-investigate` is read-only. **Fix:** dispatch `mma-delegate` with research-then-edit framing, or split: investigate → digest → edit.
203
-
204
- ## Diagnosing slow tasks
205
-
206
- `mmagent serve --verbose` (or `diagnostics.verbose: true` in config) records `tool_call`, `turn_complete`, and `heartbeat` events. Tail with `mmagent logs --follow --batch=$BATCH_ID`.
@@ -1,4 +0,0 @@
1
- import { type ConsentDecision } from '@zhixuan92/multi-model-agent-core/events/consent-rules';
2
- export declare function decide(homeDir: string): ConsentDecision;
3
- export declare function watchConfigForChanges(homeDir: string, onChange: (d: ConsentDecision) => void): () => void;
4
- //# sourceMappingURL=consent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../../src/telemetry/consent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,wDAAwD,CAAC;AAE7G,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAsBvD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI,CASzG"}
@@ -1,40 +0,0 @@
1
- import { readFileSync, watch } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { decideConsent } from '@zhixuan92/multi-model-agent-core/events/consent-rules';
4
- export function decide(homeDir) {
5
- const env = process.env.MMAGENT_TELEMETRY;
6
- const cfgPath = join(homeDir, 'config.json');
7
- let config = undefined;
8
- try {
9
- const txt = readFileSync(cfgPath, 'utf8');
10
- const obj = JSON.parse(txt);
11
- if (obj && typeof obj === 'object' && obj.telemetry &&
12
- typeof obj.telemetry === 'object' &&
13
- typeof obj.telemetry.enabled === 'boolean') {
14
- config = { enabled: obj.telemetry.enabled };
15
- }
16
- else if (obj && typeof obj === 'object' && typeof obj.enabled === 'boolean') {
17
- config = { enabled: obj.enabled };
18
- }
19
- }
20
- catch (e) {
21
- if (e.code !== 'ENOENT') {
22
- config = { kind: 'unreadable' };
23
- }
24
- }
25
- return decideConsent({ env, config });
26
- }
27
- export function watchConfigForChanges(homeDir, onChange) {
28
- const filename = 'config.json';
29
- let timer = null;
30
- const w = watch(homeDir, { persistent: false }, (_event, fname) => {
31
- if (fname !== filename)
32
- return;
33
- if (timer)
34
- clearTimeout(timer);
35
- timer = setTimeout(() => onChange(decide(homeDir)), 500);
36
- });
37
- return () => { w.close(); if (timer)
38
- clearTimeout(timer); };
39
- }
40
- //# sourceMappingURL=consent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../src/telemetry/consent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAwB,MAAM,wDAAwD,CAAC;AAE7G,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC7C,IAAI,MAAM,GAA8D,SAAS,CAAC;IAClF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAQ,CAAC;QACnC,IACE,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS;YAC/C,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ;YACjC,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,KAAK,SAAS,EAC1C,CAAC;YACD,MAAM,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC9C,CAAC;aAAM,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9E,MAAM,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnD,MAAM,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,QAAsC;IAC3F,MAAM,QAAQ,GAAG,aAAa,CAAC;IAC/B,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChE,IAAI,KAAK,KAAK,QAAQ;YAAE,OAAO;QAC/B,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,KAAK;QAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -1,19 +0,0 @@
1
- import { Queue } from './queue.js';
2
- export interface FlusherOptions {
3
- queue: Queue;
4
- dir: string;
5
- endpoint: string;
6
- }
7
- export declare class Flusher {
8
- #private;
9
- constructor(opts: FlusherOptions);
10
- get controller(): AbortController;
11
- get dropped(): number;
12
- get backoffActive(): boolean;
13
- start(): void;
14
- stop(): void;
15
- drain(): Promise<void>;
16
- flush(): Promise<void>;
17
- clearBackoff(): void;
18
- }
19
- //# sourceMappingURL=flusher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flusher.d.ts","sourceRoot":"","sources":["../../src/telemetry/flusher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMnC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AA2BD,qBAAa,OAAO;;gBAYN,IAAI,EAAE,cAAc;IAOhC,IAAI,UAAU,IAAI,eAAe,CAEhC;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,KAAK,IAAI,IAAI;IAeb,IAAI,IAAI,IAAI;IAaN,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyM5B,YAAY,IAAI,IAAI;CAOrB"}