@collage-dam/mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/.env.example +56 -0
  2. package/CHANGELOG.md +90 -0
  3. package/LICENSE +21 -0
  4. package/README.md +512 -0
  5. package/dist/client.d.ts +497 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +1162 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/conventions/confirmation.d.ts +89 -0
  10. package/dist/conventions/confirmation.d.ts.map +1 -0
  11. package/dist/conventions/confirmation.js +132 -0
  12. package/dist/conventions/confirmation.js.map +1 -0
  13. package/dist/conventions/dry-run/batch-executor.d.ts +36 -0
  14. package/dist/conventions/dry-run/batch-executor.d.ts.map +1 -0
  15. package/dist/conventions/dry-run/batch-executor.js +89 -0
  16. package/dist/conventions/dry-run/batch-executor.js.map +1 -0
  17. package/dist/conventions/dry-run/diff-renderer.d.ts +34 -0
  18. package/dist/conventions/dry-run/diff-renderer.d.ts.map +1 -0
  19. package/dist/conventions/dry-run/diff-renderer.js +158 -0
  20. package/dist/conventions/dry-run/diff-renderer.js.map +1 -0
  21. package/dist/conventions/dry-run/index.d.ts +13 -0
  22. package/dist/conventions/dry-run/index.d.ts.map +1 -0
  23. package/dist/conventions/dry-run/index.js +10 -0
  24. package/dist/conventions/dry-run/index.js.map +1 -0
  25. package/dist/conventions/dry-run/mutating-tool.d.ts +64 -0
  26. package/dist/conventions/dry-run/mutating-tool.d.ts.map +1 -0
  27. package/dist/conventions/dry-run/mutating-tool.js +88 -0
  28. package/dist/conventions/dry-run/mutating-tool.js.map +1 -0
  29. package/dist/conventions/dry-run/summary.d.ts +66 -0
  30. package/dist/conventions/dry-run/summary.d.ts.map +1 -0
  31. package/dist/conventions/dry-run/summary.js +185 -0
  32. package/dist/conventions/dry-run/summary.js.map +1 -0
  33. package/dist/conventions/dry-run/types.d.ts +597 -0
  34. package/dist/conventions/dry-run/types.d.ts.map +1 -0
  35. package/dist/conventions/dry-run/types.js +108 -0
  36. package/dist/conventions/dry-run/types.js.map +1 -0
  37. package/dist/conventions/dry-run/with-dry-run.d.ts +66 -0
  38. package/dist/conventions/dry-run/with-dry-run.d.ts.map +1 -0
  39. package/dist/conventions/dry-run/with-dry-run.js +219 -0
  40. package/dist/conventions/dry-run/with-dry-run.js.map +1 -0
  41. package/dist/conventions/env.d.ts +49 -0
  42. package/dist/conventions/env.d.ts.map +1 -0
  43. package/dist/conventions/env.js +84 -0
  44. package/dist/conventions/env.js.map +1 -0
  45. package/dist/conventions/errors.d.ts +68 -0
  46. package/dist/conventions/errors.d.ts.map +1 -0
  47. package/dist/conventions/errors.js +81 -0
  48. package/dist/conventions/errors.js.map +1 -0
  49. package/dist/conventions/logger.d.ts +28 -0
  50. package/dist/conventions/logger.d.ts.map +1 -0
  51. package/dist/conventions/logger.js +105 -0
  52. package/dist/conventions/logger.js.map +1 -0
  53. package/dist/conventions/pagination.d.ts +37 -0
  54. package/dist/conventions/pagination.d.ts.map +1 -0
  55. package/dist/conventions/pagination.js +53 -0
  56. package/dist/conventions/pagination.js.map +1 -0
  57. package/dist/conventions/rate-limiter.d.ts +54 -0
  58. package/dist/conventions/rate-limiter.d.ts.map +1 -0
  59. package/dist/conventions/rate-limiter.js +143 -0
  60. package/dist/conventions/rate-limiter.js.map +1 -0
  61. package/dist/conventions/response-budget.d.ts +66 -0
  62. package/dist/conventions/response-budget.d.ts.map +1 -0
  63. package/dist/conventions/response-budget.js +89 -0
  64. package/dist/conventions/response-budget.js.map +1 -0
  65. package/dist/conventions/schema-version.d.ts +27 -0
  66. package/dist/conventions/schema-version.d.ts.map +1 -0
  67. package/dist/conventions/schema-version.js +29 -0
  68. package/dist/conventions/schema-version.js.map +1 -0
  69. package/dist/conventions/state-store-redis.d.ts +32 -0
  70. package/dist/conventions/state-store-redis.d.ts.map +1 -0
  71. package/dist/conventions/state-store-redis.js +77 -0
  72. package/dist/conventions/state-store-redis.js.map +1 -0
  73. package/dist/conventions/state-store.d.ts +46 -0
  74. package/dist/conventions/state-store.d.ts.map +1 -0
  75. package/dist/conventions/state-store.js +105 -0
  76. package/dist/conventions/state-store.js.map +1 -0
  77. package/dist/index.d.ts +5 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +421 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/prompts/collection-audit.d.ts +13 -0
  82. package/dist/prompts/collection-audit.d.ts.map +1 -0
  83. package/dist/prompts/collection-audit.js +168 -0
  84. package/dist/prompts/collection-audit.js.map +1 -0
  85. package/dist/prompts/create-distribution.d.ts +15 -0
  86. package/dist/prompts/create-distribution.d.ts.map +1 -0
  87. package/dist/prompts/create-distribution.js +111 -0
  88. package/dist/prompts/create-distribution.js.map +1 -0
  89. package/dist/prompts/helpers.d.ts +20 -0
  90. package/dist/prompts/helpers.d.ts.map +1 -0
  91. package/dist/prompts/helpers.js +53 -0
  92. package/dist/prompts/helpers.js.map +1 -0
  93. package/dist/prompts/library-health-audit.d.ts +13 -0
  94. package/dist/prompts/library-health-audit.d.ts.map +1 -0
  95. package/dist/prompts/library-health-audit.js +131 -0
  96. package/dist/prompts/library-health-audit.js.map +1 -0
  97. package/dist/prompts/usage-insights.d.ts +13 -0
  98. package/dist/prompts/usage-insights.d.ts.map +1 -0
  99. package/dist/prompts/usage-insights.js +98 -0
  100. package/dist/prompts/usage-insights.js.map +1 -0
  101. package/dist/prompts/wrap-prompt-as-tool.d.ts +48 -0
  102. package/dist/prompts/wrap-prompt-as-tool.d.ts.map +1 -0
  103. package/dist/prompts/wrap-prompt-as-tool.js +61 -0
  104. package/dist/prompts/wrap-prompt-as-tool.js.map +1 -0
  105. package/dist/resources/asset-by-id.d.ts +4 -0
  106. package/dist/resources/asset-by-id.d.ts.map +1 -0
  107. package/dist/resources/asset-by-id.js +27 -0
  108. package/dist/resources/asset-by-id.js.map +1 -0
  109. package/dist/resources/collections.d.ts +5 -0
  110. package/dist/resources/collections.d.ts.map +1 -0
  111. package/dist/resources/collections.js +48 -0
  112. package/dist/resources/collections.js.map +1 -0
  113. package/dist/resources/custom-fields.d.ts +4 -0
  114. package/dist/resources/custom-fields.d.ts.map +1 -0
  115. package/dist/resources/custom-fields.js +30 -0
  116. package/dist/resources/custom-fields.js.map +1 -0
  117. package/dist/resources/folders.d.ts +5 -0
  118. package/dist/resources/folders.d.ts.map +1 -0
  119. package/dist/resources/folders.js +73 -0
  120. package/dist/resources/folders.js.map +1 -0
  121. package/dist/resources/helpers.d.ts +17 -0
  122. package/dist/resources/helpers.d.ts.map +1 -0
  123. package/dist/resources/helpers.js +59 -0
  124. package/dist/resources/helpers.js.map +1 -0
  125. package/dist/resources/portals.d.ts +5 -0
  126. package/dist/resources/portals.d.ts.map +1 -0
  127. package/dist/resources/portals.js +81 -0
  128. package/dist/resources/portals.js.map +1 -0
  129. package/dist/resources/recent-and-dashboard.d.ts +5 -0
  130. package/dist/resources/recent-and-dashboard.d.ts.map +1 -0
  131. package/dist/resources/recent-and-dashboard.js +42 -0
  132. package/dist/resources/recent-and-dashboard.js.map +1 -0
  133. package/dist/tools/asset-selection.d.ts +102 -0
  134. package/dist/tools/asset-selection.d.ts.map +1 -0
  135. package/dist/tools/asset-selection.js +133 -0
  136. package/dist/tools/asset-selection.js.map +1 -0
  137. package/dist/tools/audit/audit-folder-structure.d.ts +108 -0
  138. package/dist/tools/audit/audit-folder-structure.d.ts.map +1 -0
  139. package/dist/tools/audit/audit-folder-structure.js +260 -0
  140. package/dist/tools/audit/audit-folder-structure.js.map +1 -0
  141. package/dist/tools/audit/audit-naming-conventions.d.ts +83 -0
  142. package/dist/tools/audit/audit-naming-conventions.d.ts.map +1 -0
  143. package/dist/tools/audit/audit-naming-conventions.js +238 -0
  144. package/dist/tools/audit/audit-naming-conventions.js.map +1 -0
  145. package/dist/tools/audit/audit-tagging-hygiene.d.ts +77 -0
  146. package/dist/tools/audit/audit-tagging-hygiene.d.ts.map +1 -0
  147. package/dist/tools/audit/audit-tagging-hygiene.js +402 -0
  148. package/dist/tools/audit/audit-tagging-hygiene.js.map +1 -0
  149. package/dist/tools/audit/detect-duplicates.d.ts +62 -0
  150. package/dist/tools/audit/detect-duplicates.d.ts.map +1 -0
  151. package/dist/tools/audit/detect-duplicates.js +0 -0
  152. package/dist/tools/audit/detect-duplicates.js.map +1 -0
  153. package/dist/tools/audit/types.d.ts +526 -0
  154. package/dist/tools/audit/types.d.ts.map +1 -0
  155. package/dist/tools/audit/types.js +188 -0
  156. package/dist/tools/audit/types.js.map +1 -0
  157. package/dist/tools/bulk-move-assets.d.ts +78 -0
  158. package/dist/tools/bulk-move-assets.d.ts.map +1 -0
  159. package/dist/tools/bulk-move-assets.js +122 -0
  160. package/dist/tools/bulk-move-assets.js.map +1 -0
  161. package/dist/tools/bulk-normalize-filenames.d.ts +62 -0
  162. package/dist/tools/bulk-normalize-filenames.d.ts.map +1 -0
  163. package/dist/tools/bulk-normalize-filenames.js +237 -0
  164. package/dist/tools/bulk-normalize-filenames.js.map +1 -0
  165. package/dist/tools/bulk-rename-assets.d.ts +79 -0
  166. package/dist/tools/bulk-rename-assets.d.ts.map +1 -0
  167. package/dist/tools/bulk-rename-assets.js +139 -0
  168. package/dist/tools/bulk-rename-assets.js.map +1 -0
  169. package/dist/tools/bulk-tags.d.ts +107 -0
  170. package/dist/tools/bulk-tags.d.ts.map +1 -0
  171. package/dist/tools/bulk-tags.js +220 -0
  172. package/dist/tools/bulk-tags.js.map +1 -0
  173. package/dist/tools/client-adapters.d.ts +76 -0
  174. package/dist/tools/client-adapters.d.ts.map +1 -0
  175. package/dist/tools/client-adapters.js +648 -0
  176. package/dist/tools/client-adapters.js.map +1 -0
  177. package/dist/tools/collection-membership.d.ts +90 -0
  178. package/dist/tools/collection-membership.d.ts.map +1 -0
  179. package/dist/tools/collection-membership.js +195 -0
  180. package/dist/tools/collection-membership.js.map +1 -0
  181. package/dist/tools/create-collection.d.ts +63 -0
  182. package/dist/tools/create-collection.d.ts.map +1 -0
  183. package/dist/tools/create-collection.js +151 -0
  184. package/dist/tools/create-collection.js.map +1 -0
  185. package/dist/tools/create-folder.d.ts +46 -0
  186. package/dist/tools/create-folder.d.ts.map +1 -0
  187. package/dist/tools/create-folder.js +83 -0
  188. package/dist/tools/create-folder.js.map +1 -0
  189. package/dist/tools/create-share-link.d.ts +107 -0
  190. package/dist/tools/create-share-link.d.ts.map +1 -0
  191. package/dist/tools/create-share-link.js +239 -0
  192. package/dist/tools/create-share-link.js.map +1 -0
  193. package/dist/tools/get-asset-details.d.ts +401 -0
  194. package/dist/tools/get-asset-details.d.ts.map +1 -0
  195. package/dist/tools/get-asset-details.js +56 -0
  196. package/dist/tools/get-asset-details.js.map +1 -0
  197. package/dist/tools/get-collection.d.ts +126 -0
  198. package/dist/tools/get-collection.d.ts.map +1 -0
  199. package/dist/tools/get-collection.js +52 -0
  200. package/dist/tools/get-collection.js.map +1 -0
  201. package/dist/tools/get-embed-code.d.ts +195 -0
  202. package/dist/tools/get-embed-code.d.ts.map +1 -0
  203. package/dist/tools/get-embed-code.js +214 -0
  204. package/dist/tools/get-embed-code.js.map +1 -0
  205. package/dist/tools/insights/analyze-share-links.d.ts +159 -0
  206. package/dist/tools/insights/analyze-share-links.d.ts.map +1 -0
  207. package/dist/tools/insights/analyze-share-links.js +314 -0
  208. package/dist/tools/insights/analyze-share-links.js.map +1 -0
  209. package/dist/tools/insights/insight-cache.d.ts +36 -0
  210. package/dist/tools/insights/insight-cache.d.ts.map +1 -0
  211. package/dist/tools/insights/insight-cache.js +98 -0
  212. package/dist/tools/insights/insight-cache.js.map +1 -0
  213. package/dist/tools/insights/report-asset-activation.d.ts +149 -0
  214. package/dist/tools/insights/report-asset-activation.d.ts.map +1 -0
  215. package/dist/tools/insights/report-asset-activation.js +380 -0
  216. package/dist/tools/insights/report-asset-activation.js.map +1 -0
  217. package/dist/tools/insights/report-stale-assets.d.ts +120 -0
  218. package/dist/tools/insights/report-stale-assets.d.ts.map +1 -0
  219. package/dist/tools/insights/report-stale-assets.js +281 -0
  220. package/dist/tools/insights/report-stale-assets.js.map +1 -0
  221. package/dist/tools/insights/report-top-assets.d.ts +139 -0
  222. package/dist/tools/insights/report-top-assets.d.ts.map +1 -0
  223. package/dist/tools/insights/report-top-assets.js +407 -0
  224. package/dist/tools/insights/report-top-assets.js.map +1 -0
  225. package/dist/tools/list-categories.d.ts +127 -0
  226. package/dist/tools/list-categories.d.ts.map +1 -0
  227. package/dist/tools/list-categories.js +68 -0
  228. package/dist/tools/list-categories.js.map +1 -0
  229. package/dist/tools/list-collections.d.ts +127 -0
  230. package/dist/tools/list-collections.d.ts.map +1 -0
  231. package/dist/tools/list-collections.js +53 -0
  232. package/dist/tools/list-collections.js.map +1 -0
  233. package/dist/tools/list-custom-fields.d.ts +125 -0
  234. package/dist/tools/list-custom-fields.d.ts.map +1 -0
  235. package/dist/tools/list-custom-fields.js +51 -0
  236. package/dist/tools/list-custom-fields.js.map +1 -0
  237. package/dist/tools/list-share-links.d.ts +192 -0
  238. package/dist/tools/list-share-links.d.ts.map +1 -0
  239. package/dist/tools/list-share-links.js +92 -0
  240. package/dist/tools/list-share-links.js.map +1 -0
  241. package/dist/tools/list-workspaces.d.ts +88 -0
  242. package/dist/tools/list-workspaces.d.ts.map +1 -0
  243. package/dist/tools/list-workspaces.js +71 -0
  244. package/dist/tools/list-workspaces.js.map +1 -0
  245. package/dist/tools/move-asset.d.ts +48 -0
  246. package/dist/tools/move-asset.d.ts.map +1 -0
  247. package/dist/tools/move-asset.js +85 -0
  248. package/dist/tools/move-asset.js.map +1 -0
  249. package/dist/tools/rename-asset.d.ts +88 -0
  250. package/dist/tools/rename-asset.d.ts.map +1 -0
  251. package/dist/tools/rename-asset.js +100 -0
  252. package/dist/tools/rename-asset.js.map +1 -0
  253. package/dist/tools/rename-folder.d.ts +55 -0
  254. package/dist/tools/rename-folder.d.ts.map +1 -0
  255. package/dist/tools/rename-folder.js +101 -0
  256. package/dist/tools/rename-folder.js.map +1 -0
  257. package/dist/tools/revoke-share-link.d.ts +55 -0
  258. package/dist/tools/revoke-share-link.d.ts.map +1 -0
  259. package/dist/tools/revoke-share-link.js +77 -0
  260. package/dist/tools/revoke-share-link.js.map +1 -0
  261. package/dist/tools/search/facets.d.ts +34 -0
  262. package/dist/tools/search/facets.d.ts.map +1 -0
  263. package/dist/tools/search/facets.js +147 -0
  264. package/dist/tools/search/facets.js.map +1 -0
  265. package/dist/tools/search/filter-builder.d.ts +33 -0
  266. package/dist/tools/search/filter-builder.d.ts.map +1 -0
  267. package/dist/tools/search/filter-builder.js +111 -0
  268. package/dist/tools/search/filter-builder.js.map +1 -0
  269. package/dist/tools/search/search-assets.d.ts +41 -0
  270. package/dist/tools/search/search-assets.d.ts.map +1 -0
  271. package/dist/tools/search/search-assets.js +162 -0
  272. package/dist/tools/search/search-assets.js.map +1 -0
  273. package/dist/tools/search/search-collections.d.ts +35 -0
  274. package/dist/tools/search/search-collections.d.ts.map +1 -0
  275. package/dist/tools/search/search-collections.js +103 -0
  276. package/dist/tools/search/search-collections.js.map +1 -0
  277. package/dist/tools/search/types.d.ts +1047 -0
  278. package/dist/tools/search/types.d.ts.map +1 -0
  279. package/dist/tools/search/types.js +216 -0
  280. package/dist/tools/search/types.js.map +1 -0
  281. package/dist/tools/update-asset-metadata.d.ts +78 -0
  282. package/dist/tools/update-asset-metadata.d.ts.map +1 -0
  283. package/dist/tools/update-asset-metadata.js +203 -0
  284. package/dist/tools/update-asset-metadata.js.map +1 -0
  285. package/dist/tools/update-collection.d.ts +69 -0
  286. package/dist/tools/update-collection.d.ts.map +1 -0
  287. package/dist/tools/update-collection.js +142 -0
  288. package/dist/tools/update-collection.js.map +1 -0
  289. package/dist/tools/view-category-contents.d.ts +231 -0
  290. package/dist/tools/view-category-contents.d.ts.map +1 -0
  291. package/dist/tools/view-category-contents.js +97 -0
  292. package/dist/tools/view-category-contents.js.map +1 -0
  293. package/dist/types.d.ts +1326 -0
  294. package/dist/types.d.ts.map +1 -0
  295. package/dist/types.js +288 -0
  296. package/dist/types.js.map +1 -0
  297. package/dist/typesense.d.ts +84 -0
  298. package/dist/typesense.d.ts.map +1 -0
  299. package/dist/typesense.js +243 -0
  300. package/dist/typesense.js.map +1 -0
  301. package/docs/api-field-verification.md +244 -0
  302. package/docs/deployment-runbook.md +446 -0
  303. package/docs/security-review.md +195 -0
  304. package/docs/typesense-filter-schema.md +262 -0
  305. package/docs/verified-endpoints.md +38 -0
  306. package/package.json +72 -0
@@ -0,0 +1,188 @@
1
+ // ── Shared Audit Report Types (T1) ──────────────────────────────────
2
+ //
3
+ // All Phase 1 / Phase 1.5 audit tools (`audit_tagging_hygiene`, and later
4
+ // `audit_folder_structure`, `audit_naming_conventions`, `detect_duplicates`)
5
+ // produce a uniform `AuditReport<TFindingMeta>` envelope so consumers can
6
+ // render a consistent UI and route findings through the same fix-suggestion
7
+ // pipeline.
8
+ //
9
+ // Design notes:
10
+ // - Score is an integer 0–100, deterministic (no LLM, no randomness),
11
+ // computed by each audit's own scoring function. The shape lives here
12
+ // so result envelopes stay uniform.
13
+ // - Findings carry only structured fields. Human-readable copy lives in
14
+ // `message`, but downstream code MUST be able to act on findings using
15
+ // `id` / `category` / `severity` / `count` / `sample_asset_ids` alone.
16
+ // - Next-step hints are STRUCTURED, not prose. They point at concrete
17
+ // mutating tools (e.g. `bulk_set_tags`) plus the exact arguments that
18
+ // the caller should preview-confirm. This keeps the audit→fix loop
19
+ // deterministic and machine-routable.
20
+ // - The envelope is generic over a per-audit `TFindingMeta` type (defaults
21
+ // to `unknown`) so each audit can attach its own typed `meta` to a
22
+ // finding without polluting the shared shape. Phase 1.5 audits reuse
23
+ // this file unchanged — only the meta type parameter differs.
24
+ import { z } from 'zod';
25
+ // ── Score ────────────────────────────────────────────────────────────
26
+ /**
27
+ * Audit score. Always 0–100 inclusive, integer, deterministic.
28
+ *
29
+ * Each audit MUST document its scoring formula in code comments. A score
30
+ * of 100 means "no findings"; lower scores reflect penalties summed across
31
+ * findings, weighted by severity. Scores are clamped at 0 — they never go
32
+ * negative even if penalties exceed 100.
33
+ */
34
+ export const AuditScoreSchema = z.number().int().min(0).max(100);
35
+ // ── Severity ─────────────────────────────────────────────────────────
36
+ export const AuditSeveritySchema = z.enum(['info', 'warning', 'critical']);
37
+ // ── Finding ──────────────────────────────────────────────────────────
38
+ /**
39
+ * A single structured finding.
40
+ *
41
+ * id — stable identifier within this report; used by
42
+ * downstream code to correlate next-step hints
43
+ * back to the finding that produced them.
44
+ * category — bucket name (e.g. `untagged_assets`,
45
+ * `inconsistent_casing`). Stable across runs so
46
+ * clients can group / dedupe across reports.
47
+ * severity — `info` | `warning` | `critical`. Drives both UI
48
+ * styling and score penalty weight.
49
+ * count — total number of items in this category. Always
50
+ * equals the *underlying* count, even if
51
+ * `sample_asset_ids` is truncated.
52
+ * sample_asset_ids — bounded sample (caller decides bound; default
53
+ * suggestion is 10) of asset IDs for spot-checks.
54
+ * message — human-readable summary. Treat as display copy,
55
+ * not data — never parse it.
56
+ */
57
+ export function auditFindingSchema(metaSchema) {
58
+ return z.object({
59
+ id: z.string().min(1),
60
+ category: z.string().min(1),
61
+ severity: AuditSeveritySchema,
62
+ count: z.number().int().nonnegative(),
63
+ sample_asset_ids: z.array(z.string()),
64
+ message: z.string(),
65
+ meta: metaSchema.optional(),
66
+ });
67
+ }
68
+ export const BaseAuditFindingSchema = auditFindingSchema(z.unknown());
69
+ // ── Next-Step Hint ───────────────────────────────────────────────────
70
+ /**
71
+ * Structured next-step hint pointing at an existing mutating tool.
72
+ *
73
+ * Phase 1 only emits `add_tags` / `remove_tags` / `set_tags` actions and
74
+ * targets `bulk_add_tags` / `bulk_remove_tags` / `bulk_set_tags`. The
75
+ * `action` enum is intentionally extensible — Phase 1.5 will add
76
+ * `rename_assets`, `move_assets`, `normalize_filenames` without breaking
77
+ * the schema (additive only).
78
+ *
79
+ * The shape carries the exact argument set the caller would pass to the
80
+ * mutating tool, so a router can dispatch directly without re-interpreting
81
+ * the finding.
82
+ */
83
+ export const AuditNextStepActionSchema = z.enum([
84
+ 'add_tags',
85
+ 'remove_tags',
86
+ 'set_tags',
87
+ ]);
88
+ export const AuditNextStepSchema = z.object({
89
+ action: AuditNextStepActionSchema,
90
+ /**
91
+ * Name of the mutating tool that should be invoked to apply this hint.
92
+ * Stored as a string (not enum) so Phase 1.5 can introduce new tools
93
+ * without bumping the schema major version.
94
+ */
95
+ tool: z.string().min(1),
96
+ /** Asset IDs the caller should target. Always a non-empty list. */
97
+ target_asset_ids: z.array(z.string().min(1)).min(1),
98
+ /** Tags to add / remove / set, when `action` is tag-related. */
99
+ suggested_tags: z.array(z.string().min(1)).optional(),
100
+ /** Short rationale linking the hint back to its originating finding. */
101
+ reason: z.string().min(1),
102
+ /** ID of the finding this hint addresses (optional but encouraged). */
103
+ finding_id: z.string().optional(),
104
+ });
105
+ // ── Summary Counts ───────────────────────────────────────────────────
106
+ export const AuditSummaryCountsSchema = z.object({
107
+ total_assets_scanned: z.number().int().nonnegative(),
108
+ total_findings: z.number().int().nonnegative(),
109
+ by_severity: z.object({
110
+ info: z.number().int().nonnegative(),
111
+ warning: z.number().int().nonnegative(),
112
+ critical: z.number().int().nonnegative(),
113
+ }),
114
+ });
115
+ // ── Report Envelope ──────────────────────────────────────────────────
116
+ /**
117
+ * Top-level envelope returned by every audit tool.
118
+ *
119
+ * score — 0–100 (see {@link AuditScoreSchema})
120
+ * summary_counts — quick-glance roll-up
121
+ * findings — every detected issue, structured
122
+ * next_steps — structured fix suggestions pointing at existing
123
+ * mutating tools
124
+ * truncated — true when findings or next_steps were trimmed to
125
+ * stay under the response budget. When true, the
126
+ * report is *partial* and the caller should re-run
127
+ * with a tighter scope or paginated input.
128
+ * truncation_reason — populated when `truncated` is true.
129
+ */
130
+ export function auditReportSchema(metaSchema) {
131
+ return z.object({
132
+ score: AuditScoreSchema,
133
+ summary_counts: AuditSummaryCountsSchema,
134
+ findings: z.array(auditFindingSchema(metaSchema)),
135
+ next_steps: z.array(AuditNextStepSchema),
136
+ truncated: z.boolean(),
137
+ truncation_reason: z.string().optional(),
138
+ });
139
+ }
140
+ export const BaseAuditReportSchema = auditReportSchema(z.unknown());
141
+ // ── Severity weights (shared default) ────────────────────────────────
142
+ /**
143
+ * Default penalty weights per severity level. Individual audits MAY override
144
+ * but the shared default keeps cross-audit scores comparable.
145
+ */
146
+ export const DEFAULT_SEVERITY_WEIGHTS = {
147
+ info: 1,
148
+ warning: 5,
149
+ critical: 15,
150
+ };
151
+ /**
152
+ * Compute an `AuditScore` from a list of findings using the shared severity
153
+ * weight table (or a caller-supplied one). The score is `100 - sum(weights)`,
154
+ * clamped to `[0, 100]`. With no findings the score is 100.
155
+ *
156
+ * The formula is intentionally simple, deterministic, and easy to defend:
157
+ * - one weight per finding (NOT per affected asset) — keeps a single
158
+ * widespread issue from collapsing the score to 0
159
+ * - severity drives the weight; counts surface in the finding itself
160
+ * - clamped at 0; never negative
161
+ */
162
+ export function computeAuditScore(findings, weights = DEFAULT_SEVERITY_WEIGHTS) {
163
+ let penalty = 0;
164
+ for (const f of findings) {
165
+ penalty += weights[f.severity];
166
+ }
167
+ const raw = 100 - penalty;
168
+ if (raw < 0)
169
+ return 0;
170
+ if (raw > 100)
171
+ return 100;
172
+ return Math.trunc(raw);
173
+ }
174
+ /**
175
+ * Roll up findings into the summary-counts shape.
176
+ */
177
+ export function summarizeFindings(findings, totalAssetsScanned) {
178
+ const by_severity = { info: 0, warning: 0, critical: 0 };
179
+ for (const f of findings) {
180
+ by_severity[f.severity]++;
181
+ }
182
+ return {
183
+ total_assets_scanned: totalAssetsScanned,
184
+ total_findings: findings.length,
185
+ by_severity,
186
+ };
187
+ }
188
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/tools/audit/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ import { MutatingTool, type ApplyFn, type MutatingToolDeps, type PlanResult } from '../conventions/dry-run/index.js';
3
+ import type { DryRunPlan } from '../conventions/dry-run/index.js';
4
+ import { type McpToolError } from '../conventions/errors.js';
5
+ export declare const BulkMoveItemSchema: z.ZodObject<{
6
+ asset_id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
7
+ destination_category_id: z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
8
+ /** Optional current folder id for diff display. */
9
+ current_category_id: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ asset_id: string | number;
12
+ destination_category_id: string | number | null;
13
+ current_category_id?: string | number | null | undefined;
14
+ }, {
15
+ asset_id: string | number;
16
+ destination_category_id: string | number | null;
17
+ current_category_id?: string | number | null | undefined;
18
+ }>;
19
+ export type BulkMoveItem = z.infer<typeof BulkMoveItemSchema>;
20
+ export declare const BulkMoveAssetsInputSchema: z.ZodObject<{
21
+ moves: z.ZodArray<z.ZodObject<{
22
+ asset_id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
23
+ destination_category_id: z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
24
+ /** Optional current folder id for diff display. */
25
+ current_category_id: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ asset_id: string | number;
28
+ destination_category_id: string | number | null;
29
+ current_category_id?: string | number | null | undefined;
30
+ }, {
31
+ asset_id: string | number;
32
+ destination_category_id: string | number | null;
33
+ current_category_id?: string | number | null | undefined;
34
+ }>, "many">;
35
+ }, "strip", z.ZodTypeAny, {
36
+ moves: {
37
+ asset_id: string | number;
38
+ destination_category_id: string | number | null;
39
+ current_category_id?: string | number | null | undefined;
40
+ }[];
41
+ }, {
42
+ moves: {
43
+ asset_id: string | number;
44
+ destination_category_id: string | number | null;
45
+ current_category_id?: string | number | null | undefined;
46
+ }[];
47
+ }>;
48
+ export type BulkMoveAssetsInput = z.infer<typeof BulkMoveAssetsInputSchema>;
49
+ export declare const BULK_MOVE_ASSETS_DESCRIPTION: string;
50
+ export interface BulkMoveItemResult {
51
+ asset_id: string;
52
+ destination_category_id: string | null;
53
+ }
54
+ export interface BulkMoveClient {
55
+ moveAsset(input: {
56
+ asset_id: string;
57
+ destination_category_id: string | null;
58
+ }): Promise<{
59
+ ok: true;
60
+ } | {
61
+ ok: false;
62
+ error: McpToolError;
63
+ }>;
64
+ }
65
+ export interface BulkMoveAssetsDeps extends MutatingToolDeps<BulkMoveAssetsInput> {
66
+ client: BulkMoveClient;
67
+ }
68
+ export declare class BulkMoveAssetsTool extends MutatingTool<BulkMoveAssetsInput, BulkMoveItemResult> {
69
+ readonly name = "bulk_move_assets";
70
+ protected readonly chunkSize = 50;
71
+ private readonly client;
72
+ constructor(deps: BulkMoveAssetsDeps);
73
+ protected plan(input: BulkMoveAssetsInput): PlanResult;
74
+ protected apply: ApplyFn<BulkMoveItemResult>;
75
+ }
76
+ export declare function buildBulkMoveAssetsTool(deps: BulkMoveAssetsDeps): BulkMoveAssetsTool;
77
+ export type BulkMoveAssetsPlan = DryRunPlan<BulkMoveAssetsInput>;
78
+ //# sourceMappingURL=bulk-move-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-move-assets.d.ts","sourceRoot":"","sources":["../../src/tools/bulk-move-assets.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAK9E,eAAO,MAAM,kBAAkB;;;IAG7B,mDAAmD;;;;;;;;;;EAEnD,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,yBAAyB;;;;QALpC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;EAOnD,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,4BAA4B,QAIyB,CAAC;AAInE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAID,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,KAAK,EAAE;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;KACxC,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAChE;AAID,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB,CAAC,mBAAmB,CAAC;IAC/E,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,qBAAa,kBAAmB,SAAQ,YAAY,CAClD,mBAAmB,EACnB,kBAAkB,CACnB;IACC,QAAQ,CAAC,IAAI,sBAAsB;IACnC,mBAA4B,SAAS,MAAM;IAE3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,IAAI,EAAE,kBAAkB;IAKpC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,UAAU;IA+DtD,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAwB1C;CACH;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,kBAAkB,GACvB,kBAAkB,CAEpB;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,122 @@
1
+ // ── bulk_move_assets (T7, Phase 1.5) ─────────────────────────────────
2
+ //
3
+ // Mutating tool. Moves many assets to a destination folder in a single
4
+ // confirmed call. Built on the shared `MutatingTool` base.
5
+ //
6
+ // Input shape:
7
+ // { moves: [{ asset_id, destination_category_id, current_category_id? }] }
8
+ //
9
+ // `destination_category_id: null` moves the asset to the workspace root
10
+ // (uncategorised) — same semantic as `move_asset`. We allow per-item
11
+ // destinations because a common bulk-move case is "re-home a batch of
12
+ // orphaned assets into their correct folders" rather than "shove
13
+ // everything into one folder".
14
+ //
15
+ // Risk flags emitted in the plan phase:
16
+ // - `noop_move` (info) — destination matches the current folder
17
+ // - `empty_input` (warning) — zero moves in input
18
+ import { z } from 'zod';
19
+ import { MutatingTool, } from '../conventions/dry-run/index.js';
20
+ import { createToolError } from '../conventions/errors.js';
21
+ import { IdSchema } from '../types.js';
22
+ // ── Input ────────────────────────────────────────────────────────────
23
+ export const BulkMoveItemSchema = z.object({
24
+ asset_id: IdSchema,
25
+ destination_category_id: IdSchema.nullable(),
26
+ /** Optional current folder id for diff display. */
27
+ current_category_id: IdSchema.nullable().optional(),
28
+ });
29
+ export const BulkMoveAssetsInputSchema = z.object({
30
+ moves: z.array(BulkMoveItemSchema).min(1).max(1000),
31
+ });
32
+ export const BULK_MOVE_ASSETS_DESCRIPTION = 'Move many Collage assets to destination folders in a single confirmed ' +
33
+ 'call. Each entry is `{ asset_id, destination_category_id, ' +
34
+ 'current_category_id? }`. Pass `destination_category_id: null` to move ' +
35
+ 'an asset to the workspace root. Two-step preview/confirm flow.';
36
+ export class BulkMoveAssetsTool extends MutatingTool {
37
+ name = 'bulk_move_assets';
38
+ chunkSize = 50;
39
+ client;
40
+ constructor(deps) {
41
+ super(deps);
42
+ this.client = deps.client;
43
+ }
44
+ plan(input) {
45
+ const changes = [];
46
+ let noopCount = 0;
47
+ for (const item of input.moves) {
48
+ const id = String(item.asset_id);
49
+ const dest = item.destination_category_id === null
50
+ ? null
51
+ : String(item.destination_category_id);
52
+ const before = item.current_category_id === undefined
53
+ ? '(unknown)'
54
+ : item.current_category_id === null
55
+ ? null
56
+ : String(item.current_category_id);
57
+ if (item.current_category_id !== undefined &&
58
+ item.current_category_id !== null &&
59
+ String(item.current_category_id) === dest) {
60
+ noopCount++;
61
+ }
62
+ else if (item.current_category_id !== undefined &&
63
+ item.current_category_id === null &&
64
+ dest === null) {
65
+ noopCount++;
66
+ }
67
+ changes.push({
68
+ id,
69
+ operation: 'update',
70
+ before: { category_id: before },
71
+ after: { category_id: dest },
72
+ metadata: { asset_id: id, destination_category_id: dest },
73
+ });
74
+ }
75
+ const riskFlags = [];
76
+ if (input.moves.length === 0) {
77
+ riskFlags.push({
78
+ code: 'empty_input',
79
+ severity: 'warning',
80
+ message: 'bulk_move_assets received zero move entries',
81
+ count: 0,
82
+ });
83
+ }
84
+ if (noopCount > 0) {
85
+ riskFlags.push({
86
+ code: 'noop_move',
87
+ severity: 'info',
88
+ message: 'destination is the asset\'s current folder (no-op)',
89
+ count: noopCount,
90
+ });
91
+ }
92
+ return {
93
+ changes,
94
+ riskFlags,
95
+ extraAggregates: { moves: input.moves.length, noops: noopCount },
96
+ };
97
+ }
98
+ apply = async (change) => {
99
+ const meta = (change.metadata ?? {});
100
+ if (typeof meta.asset_id !== 'string' || meta.asset_id.length === 0) {
101
+ return {
102
+ ok: false,
103
+ error: createToolError('VALIDATION', `change ${change.id} missing asset_id`),
104
+ };
105
+ }
106
+ const dest = meta.destination_category_id ?? null;
107
+ const result = await this.client.moveAsset({
108
+ asset_id: meta.asset_id,
109
+ destination_category_id: dest,
110
+ });
111
+ if (!result.ok)
112
+ return { ok: false, error: result.error };
113
+ return {
114
+ ok: true,
115
+ result: { asset_id: meta.asset_id, destination_category_id: dest },
116
+ };
117
+ };
118
+ }
119
+ export function buildBulkMoveAssetsTool(deps) {
120
+ return new BulkMoveAssetsTool(deps);
121
+ }
122
+ //# sourceMappingURL=bulk-move-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-move-assets.js","sourceRoot":"","sources":["../../src/tools/bulk-move-assets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ import { MutatingTool, type ApplyFn, type MutatingToolDeps, type PlanResult } from '../conventions/dry-run/index.js';
3
+ import type { DryRunPlan } from '../conventions/dry-run/index.js';
4
+ import { type McpToolError } from '../conventions/errors.js';
5
+ export declare const NormalizeStyleSchema: z.ZodEnum<["kebab-case", "snake_case", "lowercase", "no_spaces", "PascalCase", "camelCase"]>;
6
+ export type NormalizeStyle = z.infer<typeof NormalizeStyleSchema>;
7
+ export declare const BulkNormalizeFilenamesInputSchema: z.ZodObject<{
8
+ asset_ids: z.ZodArray<z.ZodUnion<[z.ZodNumber, z.ZodString]>, "many">;
9
+ style: z.ZodEnum<["kebab-case", "snake_case", "lowercase", "no_spaces", "PascalCase", "camelCase"]>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ asset_ids: (string | number)[];
12
+ style: "kebab-case" | "snake_case" | "camelCase" | "PascalCase" | "lowercase" | "no_spaces";
13
+ }, {
14
+ asset_ids: (string | number)[];
15
+ style: "kebab-case" | "snake_case" | "camelCase" | "PascalCase" | "lowercase" | "no_spaces";
16
+ }>;
17
+ export type BulkNormalizeFilenamesInput = z.infer<typeof BulkNormalizeFilenamesInputSchema>;
18
+ export declare const BULK_NORMALIZE_FILENAMES_DESCRIPTION: string;
19
+ export interface BulkNormalizeItemResult {
20
+ asset_id: string;
21
+ before_name: string;
22
+ after_name: string;
23
+ }
24
+ export interface BulkNormalizeClient {
25
+ /** Read the current display_file_name. Null if unavailable. */
26
+ getCurrentName(assetId: string): Promise<string | null>;
27
+ /** Apply the rename. */
28
+ renameAsset(assetId: string, newName: string): Promise<{
29
+ ok: true;
30
+ } | {
31
+ ok: false;
32
+ error: McpToolError;
33
+ }>;
34
+ }
35
+ export interface BulkNormalizeFilenamesDeps extends MutatingToolDeps<BulkNormalizeFilenamesInput> {
36
+ client: BulkNormalizeClient;
37
+ }
38
+ export declare class BulkNormalizeFilenamesTool extends MutatingTool<BulkNormalizeFilenamesInput, BulkNormalizeItemResult> {
39
+ readonly name = "bulk_normalize_filenames";
40
+ protected readonly chunkSize = 50;
41
+ private readonly client;
42
+ constructor(deps: BulkNormalizeFilenamesDeps);
43
+ protected plan(input: BulkNormalizeFilenamesInput): Promise<PlanResult>;
44
+ protected apply: ApplyFn<BulkNormalizeItemResult>;
45
+ }
46
+ export declare function buildBulkNormalizeFilenamesTool(deps: BulkNormalizeFilenamesDeps): BulkNormalizeFilenamesTool;
47
+ export type BulkNormalizeFilenamesPlan = DryRunPlan<BulkNormalizeFilenamesInput>;
48
+ interface StripResult {
49
+ stem: string;
50
+ extension: string;
51
+ }
52
+ export declare function stripExtension(name: string): StripResult;
53
+ /**
54
+ * Normalise a single filename. Pure function; the file extension (the
55
+ * portion after the final `.`) is preserved verbatim, only the stem is
56
+ * normalised. If the resulting stem would be empty, the original name is
57
+ * returned unchanged (a `would_clear_name` flag is surfaced by the plan
58
+ * phase so the caller is informed).
59
+ */
60
+ export declare function normalizeFilename(name: string, style: NormalizeStyle): string;
61
+ export {};
62
+ //# sourceMappingURL=bulk-normalize-filenames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-normalize-filenames.d.ts","sourceRoot":"","sources":["../../src/tools/bulk-normalize-filenames.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAK9E,eAAO,MAAM,oBAAoB,8FAO/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,iCAAiC;;;;;;;;;EAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAC/C,OAAO,iCAAiC,CACzC,CAAC;AAEF,eAAO,MAAM,oCAAoC,QAIK,CAAC;AAIvD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,wBAAwB;IACxB,WAAW,CACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAC/D;AAID,MAAM,WAAW,0BACf,SAAQ,gBAAgB,CAAC,2BAA2B,CAAC;IACrD,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED,qBAAa,0BAA2B,SAAQ,YAAY,CAC1D,2BAA2B,EAC3B,uBAAuB,CACxB;IACC,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,mBAA4B,SAAS,MAAM;IAE3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAEjC,IAAI,EAAE,0BAA0B;cAK5B,IAAI,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,UAAU,CAAC;IA0F7E,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,uBAAuB,CAAC,CA6B/C;CACH;AAED,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,0BAA0B,GAC/B,0BAA0B,CAE5B;AAED,MAAM,MAAM,0BAA0B,GAAG,UAAU,CAAC,2BAA2B,CAAC,CAAC;AAIjF,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAIxD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAiC7E"}