@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,380 @@
1
+ // ── report_asset_activation (T2, read-only) ─────────────────────────
2
+ //
3
+ // Read-only distribution-insights tool. Measures how recently assets in
4
+ // the workspace have been "activated" by distribution activity (i.e.
5
+ // shared, embedded, or downloaded — currently inferred from share-link
6
+ // rows, the only distribution signal available without per-asset event
7
+ // streams).
8
+ //
9
+ // Activation signal:
10
+ // * Each share-link row references one or more `asset_ids` and carries
11
+ // a `created_at` and `view_count`.
12
+ // * An asset is considered "activated" when at least one share link
13
+ // covering it was created inside the requested date range.
14
+ //
15
+ // Denominators (workspace asset universe):
16
+ // * `total_assets` is sourced from `dashboard/common-data` via the
17
+ // `DashboardCommonDataReader` helper. The upstream shape is opaque
18
+ // (`unknown` at the client layer), so the reader narrows it through
19
+ // a zod schema and returns `null` when parsing fails — we never
20
+ // crash the tool on opaque-shape regressions.
21
+ //
22
+ // Cohort breakdowns:
23
+ // * `by_user` — populated when share-link rows carry a creator user id.
24
+ // * `by_collection` — populated when share-link rows carry a collection
25
+ // id (collection-share variant). Empty array when neither is present.
26
+ //
27
+ // Type discipline: never uses `any`. Mirrors the `analyze_share_links`
28
+ // builder/enumerator factoring exactly so a cache wrapper (T5) can plug
29
+ // in around `reportAssetActivation(...)` without touching the
30
+ // aggregation logic.
31
+ import { z } from 'zod';
32
+ import { createToolError } from '../../conventions/errors.js';
33
+ import { estimateTokens, HARD_CAP_TOKENS } from '../../conventions/response-budget.js';
34
+ // ── Tool description ────────────────────────────────────────────────
35
+ export const REPORT_ASSET_ACTIVATION_DESCRIPTION = 'Read-only report on asset activation across the workspace. ' +
36
+ 'Measures how recently assets have been touched by distribution ' +
37
+ 'activity (share links / embeds), distinguishing "activated" assets ' +
38
+ '(touched in the requested date range) from "dormant" ones. Returns ' +
39
+ 'structured metrics — totals, activation rate, first-share cohort ' +
40
+ 'time series, top-N activated assets, and cohort breakdowns by user ' +
41
+ 'and (when present on share-link rows) by collection. Filters: ' +
42
+ 'optional date range (defaults to last 30 days), collection scope, ' +
43
+ 'top_n. No mutation, no AI prose.';
44
+ // ── Input schema ────────────────────────────────────────────────────
45
+ export const DEFAULT_TOP_N = 10;
46
+ export const MAX_TOP_N = 50;
47
+ /** Default look-back window when neither `date_from` nor `date_to` is set. */
48
+ export const DEFAULT_LOOKBACK_DAYS = 30;
49
+ /**
50
+ * `date_from` / `date_to` are inclusive ISO-8601 date or datetime
51
+ * strings. If only a date is supplied (e.g. `2026-04-14`) it is
52
+ * interpreted as the start (00:00:00Z) for `date_from` or the end
53
+ * (23:59:59.999Z) for `date_to`. When BOTH are omitted, the analyzer
54
+ * defaults to the last {@link DEFAULT_LOOKBACK_DAYS} days.
55
+ */
56
+ export const ReportAssetActivationInputSchema = z
57
+ .object({
58
+ date_from: z
59
+ .string()
60
+ .min(1)
61
+ .refine((v) => !Number.isNaN(Date.parse(v)), {
62
+ message: 'date_from must be a valid ISO-8601 date or datetime string',
63
+ })
64
+ .optional(),
65
+ date_to: z
66
+ .string()
67
+ .min(1)
68
+ .refine((v) => !Number.isNaN(Date.parse(v)), {
69
+ message: 'date_to must be a valid ISO-8601 date or datetime string',
70
+ })
71
+ .optional(),
72
+ collection_id: z.string().min(1).optional(),
73
+ top_n: z.number().int().min(1).max(MAX_TOP_N).default(DEFAULT_TOP_N),
74
+ })
75
+ .strict();
76
+ export class ReportAssetActivationTool {
77
+ deps;
78
+ name = 'report_asset_activation';
79
+ description = REPORT_ASSET_ACTIVATION_DESCRIPTION;
80
+ constructor(deps) {
81
+ this.deps = deps;
82
+ }
83
+ async run(rawInput = {}) {
84
+ let parsed;
85
+ try {
86
+ parsed = ReportAssetActivationInputSchema.parse(rawInput);
87
+ }
88
+ catch (err) {
89
+ return {
90
+ ok: false,
91
+ error: createToolError('VALIDATION', err instanceof Error ? err.message : 'invalid input'),
92
+ };
93
+ }
94
+ // Cross-field validation: when both bounds are set, from <= to.
95
+ if (parsed.date_from !== undefined && parsed.date_to !== undefined) {
96
+ const fromMs = Date.parse(parsed.date_from);
97
+ const toMs = Date.parse(parsed.date_to);
98
+ if (fromMs > toMs) {
99
+ return {
100
+ ok: false,
101
+ error: createToolError('VALIDATION', 'date_from must be <= date_to'),
102
+ };
103
+ }
104
+ }
105
+ const enumerated = await this.deps.enumerator.enumerate();
106
+ if (!enumerated.ok) {
107
+ return { ok: false, error: enumerated.error };
108
+ }
109
+ // Dashboard-reader failure does NOT fail the report — we degrade to
110
+ // `total_assets: null` and surface the partial result. The reader
111
+ // distinguishes transport failure (returns `ok: false`) from
112
+ // shape-parse failure (returns `ok: true, snapshot: null`); both
113
+ // collapse to `null` here per the agreed degradation contract.
114
+ let dashboardSnapshot = null;
115
+ const dashboardResult = await this.deps.dashboard.read();
116
+ if (dashboardResult.ok) {
117
+ dashboardSnapshot = dashboardResult.snapshot;
118
+ }
119
+ const report = buildReport(enumerated.rows, enumerated.truncated, dashboardSnapshot, parsed);
120
+ return { ok: true, report };
121
+ }
122
+ }
123
+ export function buildReportAssetActivationTool(deps) {
124
+ return new ReportAssetActivationTool(deps);
125
+ }
126
+ // ── Aggregation (pure) ──────────────────────────────────────────────
127
+ /**
128
+ * Build the asset-activation report from a flat list of share-link rows
129
+ * plus an optional workspace-snapshot denominator. Pure function,
130
+ * exported for direct test access.
131
+ *
132
+ * `dashboardSnapshot === null` means the workspace asset-count is
133
+ * unavailable; the report surfaces `total_assets`, `activation_rate`,
134
+ * and `dormant_count` as `null` per the degradation contract.
135
+ */
136
+ export function buildReport(rows, enumeratorTruncated, dashboardSnapshot, input) {
137
+ // ── Resolve effective date range (defaults to last 30 days) ──
138
+ const { effectiveFrom, effectiveTo } = resolveDateRange(input.date_from, input.date_to);
139
+ // ── Filter share-link rows ──
140
+ const matching = rows.filter((row) => {
141
+ if (input.collection_id !== undefined) {
142
+ if (row.collection_id !== input.collection_id)
143
+ return false;
144
+ }
145
+ if (row.created_at === null)
146
+ return false;
147
+ const createdMs = Date.parse(row.created_at);
148
+ if (Number.isNaN(createdMs))
149
+ return false;
150
+ if (effectiveFrom !== null && createdMs < effectiveFrom)
151
+ return false;
152
+ if (effectiveTo !== null && createdMs > effectiveTo)
153
+ return false;
154
+ return true;
155
+ });
156
+ // ── Index per-asset activation ──
157
+ // `assetActivity` keys on asset id. For each asset we track:
158
+ // * earliest share-link created_at (for the first-shared time series)
159
+ // * total share-link count and view count (for top-N)
160
+ // * a representative title (from the most-recent share-link row)
161
+ // * cohort attributions (set of user ids, set of collection ids)
162
+ const assetActivity = new Map();
163
+ for (const row of matching) {
164
+ if (row.created_at === null)
165
+ continue;
166
+ const createdMs = Date.parse(row.created_at);
167
+ if (Number.isNaN(createdMs))
168
+ continue;
169
+ for (const assetId of row.asset_ids) {
170
+ const existing = assetActivity.get(assetId);
171
+ if (existing === undefined) {
172
+ const initialState = {
173
+ first_shared_ms: createdMs,
174
+ first_shared_iso: row.created_at,
175
+ most_recent_ms: createdMs,
176
+ title: row.title,
177
+ share_link_count: 1,
178
+ total_views: row.view_count,
179
+ user_ids: new Set(),
180
+ collection_ids: new Set(),
181
+ };
182
+ if (row.created_by_user_id !== null) {
183
+ initialState.user_ids.add(row.created_by_user_id);
184
+ }
185
+ if (row.collection_id !== null) {
186
+ initialState.collection_ids.add(row.collection_id);
187
+ }
188
+ assetActivity.set(assetId, initialState);
189
+ continue;
190
+ }
191
+ existing.share_link_count += 1;
192
+ existing.total_views += row.view_count;
193
+ if (createdMs < existing.first_shared_ms) {
194
+ existing.first_shared_ms = createdMs;
195
+ existing.first_shared_iso = row.created_at;
196
+ }
197
+ if (createdMs >= existing.most_recent_ms) {
198
+ existing.most_recent_ms = createdMs;
199
+ // Prefer non-null titles from the most-recent row.
200
+ if (row.title !== null)
201
+ existing.title = row.title;
202
+ }
203
+ if (row.created_by_user_id !== null) {
204
+ existing.user_ids.add(row.created_by_user_id);
205
+ }
206
+ if (row.collection_id !== null) {
207
+ existing.collection_ids.add(row.collection_id);
208
+ }
209
+ }
210
+ }
211
+ // ── Summary ──
212
+ const activatedCount = assetActivity.size;
213
+ const totalAssets = dashboardSnapshot?.total_assets ?? null;
214
+ const summary = {
215
+ total_assets: totalAssets,
216
+ assets_with_distribution_activity: activatedCount,
217
+ activation_rate: totalAssets !== null && totalAssets > 0
218
+ ? activatedCount / totalAssets
219
+ : totalAssets === 0
220
+ ? 0
221
+ : null,
222
+ dormant_count: totalAssets !== null ? Math.max(totalAssets - activatedCount, 0) : null,
223
+ };
224
+ // ── First-shared cohort time series ──
225
+ const dayBuckets = new Map();
226
+ for (const state of assetActivity.values()) {
227
+ const day = toIsoDay(state.first_shared_iso);
228
+ if (day === null)
229
+ continue;
230
+ dayBuckets.set(day, (dayBuckets.get(day) ?? 0) + 1);
231
+ }
232
+ const assetsFirstSharedPerDay = [...dayBuckets.entries()]
233
+ .map(([date, count]) => ({ date, count }))
234
+ .sort((a, b) => (a.date < b.date ? -1 : a.date > b.date ? 1 : 0));
235
+ // ── Top-N activated assets (by total views, ties broken by share_link_count then id) ──
236
+ const topActivatedAssets = [...assetActivity.entries()]
237
+ .map(([id, state]) => ({
238
+ id,
239
+ title: state.title,
240
+ share_link_count: state.share_link_count,
241
+ total_views: state.total_views,
242
+ }))
243
+ .sort((a, b) => {
244
+ if (b.total_views !== a.total_views)
245
+ return b.total_views - a.total_views;
246
+ if (b.share_link_count !== a.share_link_count) {
247
+ return b.share_link_count - a.share_link_count;
248
+ }
249
+ return a.id.localeCompare(b.id);
250
+ })
251
+ .slice(0, input.top_n);
252
+ // ── Cohort breakdowns ──
253
+ const byUserCounts = new Map();
254
+ const byCollectionCounts = new Map();
255
+ for (const state of assetActivity.values()) {
256
+ for (const userId of state.user_ids) {
257
+ byUserCounts.set(userId, (byUserCounts.get(userId) ?? 0) + 1);
258
+ }
259
+ for (const collectionId of state.collection_ids) {
260
+ byCollectionCounts.set(collectionId, (byCollectionCounts.get(collectionId) ?? 0) + 1);
261
+ }
262
+ }
263
+ const byUser = [...byUserCounts.entries()]
264
+ .map(([user_id, activated_assets]) => ({ user_id, activated_assets }))
265
+ .sort((a, b) => {
266
+ if (b.activated_assets !== a.activated_assets) {
267
+ return b.activated_assets - a.activated_assets;
268
+ }
269
+ return a.user_id.localeCompare(b.user_id);
270
+ });
271
+ const byCollection = [...byCollectionCounts.entries()]
272
+ .map(([collection_id, activated_assets]) => ({
273
+ collection_id,
274
+ activated_assets,
275
+ }))
276
+ .sort((a, b) => {
277
+ if (b.activated_assets !== a.activated_assets) {
278
+ return b.activated_assets - a.activated_assets;
279
+ }
280
+ return a.collection_id.localeCompare(b.collection_id);
281
+ });
282
+ const initial = {
283
+ filters: {
284
+ date_from: isoFromMs(effectiveFrom),
285
+ date_to: isoFromMs(effectiveTo),
286
+ collection_id: input.collection_id ?? null,
287
+ top_n: input.top_n,
288
+ },
289
+ summary,
290
+ time_series: {
291
+ assets_first_shared_per_day: assetsFirstSharedPerDay,
292
+ },
293
+ top_activated_assets: topActivatedAssets,
294
+ cohort_breakdown: {
295
+ by_user: byUser,
296
+ by_collection: byCollection,
297
+ },
298
+ truncated: enumeratorTruncated,
299
+ };
300
+ if (enumeratorTruncated) {
301
+ initial.truncation_reason =
302
+ 'Share-link enumerator stopped at its internal cap; report reflects a partial dataset.';
303
+ }
304
+ return enforceResponseBudget(initial);
305
+ }
306
+ // ── Helpers ─────────────────────────────────────────────────────────
307
+ function resolveDateRange(rawFrom, rawTo) {
308
+ // Defaults: when both omitted, look back DEFAULT_LOOKBACK_DAYS from now.
309
+ if (rawFrom === undefined && rawTo === undefined) {
310
+ const nowMs = Date.now();
311
+ const fromMs = nowMs - DEFAULT_LOOKBACK_DAYS * 24 * 60 * 60 * 1000;
312
+ return { effectiveFrom: fromMs, effectiveTo: nowMs };
313
+ }
314
+ return {
315
+ effectiveFrom: parseLowerBound(rawFrom),
316
+ effectiveTo: parseUpperBound(rawTo),
317
+ };
318
+ }
319
+ function parseLowerBound(value) {
320
+ if (value === undefined)
321
+ return null;
322
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
323
+ return Date.parse(`${value}T00:00:00.000Z`);
324
+ }
325
+ return Date.parse(value);
326
+ }
327
+ function parseUpperBound(value) {
328
+ if (value === undefined)
329
+ return null;
330
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
331
+ return Date.parse(`${value}T23:59:59.999Z`);
332
+ }
333
+ return Date.parse(value);
334
+ }
335
+ function isoFromMs(ms) {
336
+ if (ms === null)
337
+ return null;
338
+ return new Date(ms).toISOString();
339
+ }
340
+ function toIsoDay(value) {
341
+ const ms = Date.parse(value);
342
+ if (Number.isNaN(ms))
343
+ return null;
344
+ return new Date(ms).toISOString().slice(0, 10);
345
+ }
346
+ // ── Response-budget enforcement ─────────────────────────────────────
347
+ const REDUCED_TOP_LIMIT = 5;
348
+ const REDUCED_COHORT_LIMIT = 10;
349
+ const REDUCED_TIMESERIES_LIMIT = 30;
350
+ /**
351
+ * Aggregate reports tend to be small (totals + top-N + cohorts), but a
352
+ * very long date range or a wide cohort fan-out could push us over
353
+ * budget. If the serialised report exceeds {@link HARD_CAP_TOKENS}, trim
354
+ * sample-heavy fields in priority order:
355
+ * 1. cap `top_activated_assets`, cohort lists, and the time series to
356
+ * small limits;
357
+ * 2. mark `truncated: true` regardless of enumerator truncation.
358
+ */
359
+ function enforceResponseBudget(report) {
360
+ if (estimateTokens(JSON.stringify(report)) <= HARD_CAP_TOKENS) {
361
+ return report;
362
+ }
363
+ const trimmed = {
364
+ ...report,
365
+ top_activated_assets: report.top_activated_assets.slice(0, REDUCED_TOP_LIMIT),
366
+ time_series: {
367
+ assets_first_shared_per_day: report.time_series.assets_first_shared_per_day.slice(-REDUCED_TIMESERIES_LIMIT),
368
+ },
369
+ cohort_breakdown: {
370
+ by_user: report.cohort_breakdown.by_user.slice(0, REDUCED_COHORT_LIMIT),
371
+ by_collection: report.cohort_breakdown.by_collection.slice(0, REDUCED_COHORT_LIMIT),
372
+ },
373
+ truncated: true,
374
+ truncation_reason: report.truncation_reason !== undefined
375
+ ? `${report.truncation_reason} Additionally, top/cohort/time-series lists were trimmed to fit the response budget.`
376
+ : 'Top, cohort, and time-series lists were trimmed to fit the response budget.',
377
+ };
378
+ return trimmed;
379
+ }
380
+ //# sourceMappingURL=report-asset-activation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-asset-activation.js","sourceRoot":"","sources":["../../../src/tools/insights/report-asset-activation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import { z } from 'zod';
2
+ import { type McpToolError } from '../../conventions/errors.js';
3
+ import type { ShareLinkEnumerator, ShareLinkRow } from './analyze-share-links.js';
4
+ export declare const REPORT_STALE_ASSETS_DESCRIPTION: string;
5
+ export declare const DEFAULT_TOP_N = 10;
6
+ export declare const MAX_TOP_N = 100;
7
+ export declare const DEFAULT_STALENESS_DAYS = 90;
8
+ export declare const MAX_STALENESS_DAYS = 3650;
9
+ /**
10
+ * `as_of` is the reference point for the staleness window. Omit to use
11
+ * the current time. ISO-8601 date or datetime string; bare dates are
12
+ * interpreted as end-of-day in UTC (so "everything older than the end of
13
+ * 2026-04-01 by N days" is the same as "everything older than
14
+ * 2026-04-01T23:59:59.999Z by N days").
15
+ */
16
+ export declare const ReportStaleAssetsInputSchema: z.ZodObject<{
17
+ staleness_days: z.ZodDefault<z.ZodNumber>;
18
+ as_of: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
19
+ collection_id: z.ZodOptional<z.ZodString>;
20
+ top_n: z.ZodDefault<z.ZodNumber>;
21
+ }, "strict", z.ZodTypeAny, {
22
+ top_n: number;
23
+ staleness_days: number;
24
+ collection_id?: string | undefined;
25
+ as_of?: string | undefined;
26
+ }, {
27
+ collection_id?: string | undefined;
28
+ top_n?: number | undefined;
29
+ staleness_days?: number | undefined;
30
+ as_of?: string | undefined;
31
+ }>;
32
+ export type ReportStaleAssetsInput = z.input<typeof ReportStaleAssetsInputSchema>;
33
+ export type ReportStaleAssetsInputResolved = z.output<typeof ReportStaleAssetsInputSchema>;
34
+ export interface StaleAssetEntry {
35
+ id: string;
36
+ /** Best-effort title from the most-recent share-link row covering this asset. */
37
+ title: string | null;
38
+ /** Latest share-link `created_at` covering this asset (ISO-8601). */
39
+ last_shared_at: string;
40
+ /** Earliest share-link `created_at` covering this asset (ISO-8601). */
41
+ first_shared_at: string;
42
+ /** Days between `last_shared_at` and `as_of`. Always a non-negative integer (whole-day floor). */
43
+ days_since_last_share: number;
44
+ /** Number of share links that have ever covered this asset (within the matching collection scope). */
45
+ share_link_count: number;
46
+ /** True when every covering share link is revoked or expired. */
47
+ all_shares_revoked_or_expired: boolean;
48
+ }
49
+ export interface StaleAssetsSummary {
50
+ /** Distinct assets with any covering share link (within the matching collection scope). */
51
+ total_ever_shared_assets: number;
52
+ /** Distinct assets considered stale (days_since_last_share >= staleness_days OR all shares revoked/expired). */
53
+ stale_assets: number;
54
+ /** total_ever_shared_assets - stale_assets. */
55
+ fresh_assets: number;
56
+ /** Distinct assets whose every covering share link is revoked or expired. */
57
+ all_revoked_or_expired_assets: number;
58
+ /** stale_assets / total_ever_shared_assets; null when total_ever_shared_assets === 0. */
59
+ staleness_rate: number | null;
60
+ }
61
+ /**
62
+ * Age-bucket counts over the stale-asset population's
63
+ * `days_since_last_share`. Buckets are inclusive on the lower bound and
64
+ * exclusive on the upper bound, except `over_year` which is open-ended.
65
+ *
66
+ * Buckets are reported in days from the user's perspective even though
67
+ * the staleness_days threshold may exclude some buckets entirely (e.g.
68
+ * with `staleness_days: 180` the `month_to_quarter` bucket will be
69
+ * zero by construction).
70
+ */
71
+ export interface StalenessDistribution {
72
+ /** [staleness_days, 90) — stale but recently so. Empty by construction when staleness_days >= 90. */
73
+ month_to_quarter: number;
74
+ /** [90, 180) */
75
+ quarter_to_half_year: number;
76
+ /** [180, 365) */
77
+ half_year_to_year: number;
78
+ /** [365, ∞) */
79
+ over_year: number;
80
+ }
81
+ export interface StaleAssetsReport {
82
+ /** Inputs as resolved (after defaults applied). */
83
+ filters: {
84
+ staleness_days: number;
85
+ as_of: string;
86
+ collection_id: string | null;
87
+ top_n: number;
88
+ };
89
+ summary: StaleAssetsSummary;
90
+ staleness_distribution: StalenessDistribution;
91
+ /** Top N stale assets, sorted by `days_since_last_share` desc (oldest first). */
92
+ top_stale_assets: StaleAssetEntry[];
93
+ /** True when the share-link enumerator hit its hard cap or the response was trimmed for budget. */
94
+ truncated: boolean;
95
+ truncation_reason?: string;
96
+ }
97
+ export interface ReportStaleAssetsDeps {
98
+ enumerator: ShareLinkEnumerator;
99
+ }
100
+ export type ReportStaleAssetsOutcome = {
101
+ ok: true;
102
+ report: StaleAssetsReport;
103
+ } | {
104
+ ok: false;
105
+ error: McpToolError;
106
+ };
107
+ export declare class ReportStaleAssetsTool {
108
+ private readonly deps;
109
+ readonly name = "report_stale_assets";
110
+ readonly description: string;
111
+ constructor(deps: ReportStaleAssetsDeps);
112
+ run(rawInput?: ReportStaleAssetsInput): Promise<ReportStaleAssetsOutcome>;
113
+ }
114
+ export declare function buildReportStaleAssetsTool(deps: ReportStaleAssetsDeps): ReportStaleAssetsTool;
115
+ /**
116
+ * Build the stale-assets report from a flat list of share-link rows.
117
+ * Pure function, exported for direct test access.
118
+ */
119
+ export declare function buildReport(rows: ReadonlyArray<ShareLinkRow>, enumeratorTruncated: boolean, input: ReportStaleAssetsInputResolved): StaleAssetsReport;
120
+ //# sourceMappingURL=report-stale-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-stale-assets.d.ts","sourceRoot":"","sources":["../../../src/tools/insights/report-stale-assets.ts"],"names":[],"mappings":"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"}