@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,168 @@
1
+ // ── collection_audit ────────────────────────────────────────────────
2
+ // Two modes: single-collection deep-dive (when collection_id provided)
3
+ // or portfolio analysis (when omitted). Single-collection is fully
4
+ // supported in MVP; portfolio mode is a degraded slice that depends on
5
+ // Phase 1.5 audit-depth tools — the prompt names that limitation
6
+ // explicitly so the LLM communicates it.
7
+ import { z } from 'zod';
8
+ import { playbookMessage } from './helpers.js';
9
+ export const COLLECTION_AUDIT_NAME = 'collection_audit';
10
+ export const COLLECTION_AUDIT_DESCRIPTION = 'Audit a single collection (deep-dive on members and pattern-derived ' +
11
+ 'suggestions) or your whole portfolio of collections (coverage gaps, ' +
12
+ 'overlap, stale collections). Pass `collection_id` for single-collection ' +
13
+ 'mode; omit it for portfolio mode.';
14
+ export const COLLECTION_AUDIT_ARGS = {
15
+ collection_id: z
16
+ .string()
17
+ .optional()
18
+ .describe('A specific Collage collection id. If provided, runs single-collection deep-dive. If omitted, runs portfolio mode.'),
19
+ suggest_members: z
20
+ .string()
21
+ .optional()
22
+ .describe('Whether to run pattern-derivation and propose new members for single-collection mode. "true" or "false". Default true.'),
23
+ };
24
+ export function buildCollectionAuditPrompt(args) {
25
+ const id = args.collection_id?.trim();
26
+ const suggest = args.suggest_members === undefined
27
+ ? true
28
+ : args.suggest_members === 'true';
29
+ const mode = id !== undefined && id !== '' ? 'single' : 'portfolio';
30
+ const body = mode === 'single'
31
+ ? buildSingleMode(id, suggest)
32
+ : buildPortfolioMode();
33
+ return playbookMessage(mode === 'single'
34
+ ? `Collection audit (single-collection deep-dive on ${id})`
35
+ : 'Collection audit (portfolio mode — degraded; depends on Phase 1.5 depth tools)', body);
36
+ }
37
+ function buildSingleMode(id, suggest) {
38
+ return {
39
+ workflow: 'collection_audit',
40
+ mode: 'single',
41
+ collection_id: id,
42
+ suggest_members: suggest,
43
+ instructions: 'Audit one collection. Read its current members, derive a frequency ' +
44
+ 'pattern over their tags, custom-field values, and filename tokens, ' +
45
+ 'then optionally rank non-member assets by how well they match. ' +
46
+ 'Pattern derivation is statistical (term frequency), NOT image content ' +
47
+ 'analysis — we explicitly do not look at pixels.',
48
+ orchestration: [
49
+ {
50
+ step: 1,
51
+ action: 'Load the collection',
52
+ tools: ['get_collection'],
53
+ args: { collection_id: id },
54
+ purpose: 'Pull current members and metadata.',
55
+ },
56
+ {
57
+ step: 2,
58
+ action: 'Derive the membership pattern',
59
+ purpose: 'For each member asset, fetch tags + custom fields via get_asset_details. ' +
60
+ 'Compute term frequency across: tag names (case-folded), custom-field ' +
61
+ 'values, and tokenised display_file_name (split on whitespace + ' +
62
+ 'punctuation, lowercase, stem optional). Top 10 terms per dimension ' +
63
+ 'is the pattern.',
64
+ },
65
+ ...(suggest
66
+ ? [
67
+ {
68
+ step: 3,
69
+ action: 'Score candidate non-members',
70
+ tools: ['search_assets'],
71
+ purpose: 'Search the workspace for assets that match the top-pattern ' +
72
+ "terms (one search per term cluster, then deduplicate). For each " +
73
+ 'hit, score it 0-100 by counting the number of pattern terms it ' +
74
+ 'shares. Return the top 25 candidates with their scores and the ' +
75
+ 'specific terms that matched.',
76
+ },
77
+ {
78
+ step: 4,
79
+ action: 'Propose add_to_collection actions',
80
+ purpose: 'Group the top candidates into a single proposed `add_to_collection` ' +
81
+ 'tool call (dry-run). User picks which to include before execution.',
82
+ degraded_in_mvp: false,
83
+ },
84
+ ]
85
+ : []),
86
+ {
87
+ step: suggest ? 5 : 3,
88
+ action: 'Compile findings',
89
+ purpose: 'Output the derived pattern, current member count, suggested ' +
90
+ 'additions (if any), and any anomalies (members that match the ' +
91
+ 'pattern poorly — possibly mis-categorised).',
92
+ },
93
+ ],
94
+ output_shape: {
95
+ collection: '{ id, name, description, member_count }',
96
+ pattern: '{ top_tags: string[], top_custom_fields: Record<string, string[]>, top_filename_tokens: string[] }',
97
+ suggestions: suggest
98
+ ? 'Array<{ asset_id, score, matched_terms }> — top 25 by score'
99
+ : 'omitted (suggest_members=false)',
100
+ anomalies: 'Array<{ asset_id, reason }> — members matching the pattern poorly',
101
+ next_actions: 'Array<{ tool, args }> — typically a single add_to_collection dry-run with the candidate set',
102
+ },
103
+ guardrails: [
104
+ 'Pattern derivation is statistical only — no vision/semantic analysis.',
105
+ 'Cap candidate scoring at 25 to keep response within budget.',
106
+ 'add_to_collection is a mutation; dry-run preview is mandatory.',
107
+ ],
108
+ };
109
+ }
110
+ function buildPortfolioMode() {
111
+ return {
112
+ workflow: 'collection_audit',
113
+ mode: 'portfolio',
114
+ degraded_in_mvp: true,
115
+ degraded_reason: 'Portfolio-mode coverage analysis depends on the Phase 1.5 ' +
116
+ 'collections-audit-depth tools (overlap detection, staleness ' +
117
+ 'scoring, coverage-gap detection). The MVP slice below uses only ' +
118
+ 'list_collections + simple counts. Tell the user that deeper ' +
119
+ 'analysis ships in a future release.',
120
+ instructions: 'Run a portfolio-wide overview. List all collections, surface ones ' +
121
+ 'with very few members (<5), and flag any whose names or descriptions ' +
122
+ 'duplicate one another. Stop short of the deeper overlap and staleness ' +
123
+ 'analysis until Phase 1.5 tools land — and tell the user that limit.',
124
+ orchestration: [
125
+ {
126
+ step: 1,
127
+ action: 'List collections',
128
+ tools: ['list_collections'],
129
+ purpose: 'Pull every collection in the workspace.',
130
+ },
131
+ {
132
+ step: 2,
133
+ action: 'Surface low-membership collections',
134
+ purpose: 'Flag collections with < 5 assets (configurable threshold; ask the ' +
135
+ 'user if they want a different cutoff).',
136
+ },
137
+ {
138
+ step: 3,
139
+ action: 'Detect duplicate names and descriptions',
140
+ purpose: 'Case-insensitive compare across collection names and trimmed ' +
141
+ 'descriptions. Group exact and near-exact matches (Levenshtein <= 3).',
142
+ },
143
+ {
144
+ step: 4,
145
+ action: 'Communicate the degraded mode',
146
+ purpose: 'In the final report, explicitly note that overlap detection, ' +
147
+ 'staleness scoring, and coverage-gap analysis are part of a Phase ' +
148
+ '1.5 release — not currently available. Offer to re-run the audit ' +
149
+ 'in single-collection mode (`collection_audit` with collection_id) ' +
150
+ 'as the next-best step.',
151
+ },
152
+ ],
153
+ output_shape: {
154
+ summary: 'string — one paragraph overview',
155
+ total_collections: 'number',
156
+ low_membership: 'Array<{ collection_id, name, asset_count }> — < 5 members',
157
+ duplicate_names: 'Array<{ collection_ids: string[], name }>',
158
+ duplicate_descriptions: 'Array<{ collection_ids: string[], description }>',
159
+ degraded_notice: 'string — friendly "deeper analysis available in future release" copy',
160
+ next_actions: 'Array<{ tool, args }> — typically a single collection_audit invocation in single-collection mode',
161
+ },
162
+ guardrails: [
163
+ 'Do not pretend to do overlap detection — be explicit about the degraded slice.',
164
+ 'No mutations in portfolio mode; this is a read-only survey.',
165
+ ],
166
+ };
167
+ }
168
+ //# sourceMappingURL=collection-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-audit.js","sourceRoot":"","sources":["../../src/prompts/collection-audit.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,uEAAuE;AACvE,mEAAmE;AACnE,uEAAuE;AACvE,iEAAiE;AACjE,yCAAyC;AAEzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,MAAM,CAAC,MAAM,4BAA4B,GACvC,sEAAsE;IACtE,sEAAsE;IACtE,0EAA0E;IAC1E,mCAAmC,CAAC;AAEtC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,mHAAmH,CACpH;IACH,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,wHAAwH,CACzH;CACK,CAAC;AAEX,MAAM,UAAU,0BAA0B,CACxC,IAAkF;IAElF,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,KAAK,SAAS;QAChD,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAAC,eAAe,KAAK,MAAM,CAAC;IACpC,MAAM,IAAI,GAA2B,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;IAE5F,MAAM,IAAI,GAAG,IAAI,KAAK,QAAQ;QAC5B,CAAC,CAAC,eAAe,CAAC,EAAY,EAAE,OAAO,CAAC;QACxC,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAEzB,OAAO,eAAe,CACpB,IAAI,KAAK,QAAQ;QACf,CAAC,CAAC,oDAAoD,EAAE,GAAG;QAC3D,CAAC,CAAC,gFAAgF,EACpF,IAAI,CACL,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,EAAU,EAAE,OAAgB;IACnD,OAAO;QACL,QAAQ,EAAE,kBAAkB;QAC5B,IAAI,EAAE,QAAQ;QACd,aAAa,EAAE,EAAE;QACjB,eAAe,EAAE,OAAO;QACxB,YAAY,EACV,qEAAqE;YACrE,qEAAqE;YACrE,iEAAiE;YACjE,wEAAwE;YACxE,iDAAiD;QACnD,aAAa,EAAE;YACb;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,qBAAqB;gBAC7B,KAAK,EAAE,CAAC,gBAAgB,CAAC;gBACzB,IAAI,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;gBAC3B,OAAO,EAAE,oCAAoC;aAC9C;YACD;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,+BAA+B;gBACvC,OAAO,EACL,2EAA2E;oBAC3E,uEAAuE;oBACvE,iEAAiE;oBACjE,qEAAqE;oBACrE,iBAAiB;aACpB;YACD,GAAG,CAAC,OAAO;gBACT,CAAC,CAAC;oBACE;wBACE,IAAI,EAAE,CAAC;wBACP,MAAM,EAAE,6BAA6B;wBACrC,KAAK,EAAE,CAAC,eAAe,CAAC;wBACxB,OAAO,EACL,6DAA6D;4BAC7D,kEAAkE;4BAClE,iEAAiE;4BACjE,iEAAiE;4BACjE,8BAA8B;qBACjC;oBACD;wBACE,IAAI,EAAE,CAAC;wBACP,MAAM,EAAE,mCAAmC;wBAC3C,OAAO,EACL,sEAAsE;4BACtE,oEAAoE;wBACtE,eAAe,EAAE,KAAK;qBACvB;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;YACP;gBACE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrB,MAAM,EAAE,kBAAkB;gBAC1B,OAAO,EACL,8DAA8D;oBAC9D,gEAAgE;oBAChE,6CAA6C;aAChD;SACF;QACD,YAAY,EAAE;YACZ,UAAU,EAAE,yCAAyC;YACrD,OAAO,EAAE,oGAAoG;YAC7G,WAAW,EAAE,OAAO;gBAClB,CAAC,CAAC,8DAA8D;gBAChE,CAAC,CAAC,iCAAiC;YACrC,SAAS,EAAE,oEAAoE;YAC/E,YAAY,EACV,8FAA8F;SACjG;QACD,UAAU,EAAE;YACV,uEAAuE;YACvE,6DAA6D;YAC7D,gEAAgE;SACjE;KACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB;IACzB,OAAO;QACL,QAAQ,EAAE,kBAAkB;QAC5B,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE,IAAI;QACrB,eAAe,EACb,4DAA4D;YAC5D,8DAA8D;YAC9D,kEAAkE;YAClE,8DAA8D;YAC9D,qCAAqC;QACvC,YAAY,EACV,oEAAoE;YACpE,uEAAuE;YACvE,wEAAwE;YACxE,qEAAqE;QACvE,aAAa,EAAE;YACb;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,kBAAkB;gBAC1B,KAAK,EAAE,CAAC,kBAAkB,CAAC;gBAC3B,OAAO,EAAE,yCAAyC;aACnD;YACD;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,oCAAoC;gBAC5C,OAAO,EACL,oEAAoE;oBACpE,wCAAwC;aAC3C;YACD;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,yCAAyC;gBACjD,OAAO,EACL,+DAA+D;oBAC/D,sEAAsE;aACzE;YACD;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,+BAA+B;gBACvC,OAAO,EACL,+DAA+D;oBAC/D,mEAAmE;oBACnE,mEAAmE;oBACnE,oEAAoE;oBACpE,wBAAwB;aAC3B;SACF;QACD,YAAY,EAAE;YACZ,OAAO,EAAE,iCAAiC;YAC1C,iBAAiB,EAAE,QAAQ;YAC3B,cAAc,EAAE,4DAA4D;YAC5E,eAAe,EAAE,2CAA2C;YAC5D,sBAAsB,EAAE,kDAAkD;YAC1E,eAAe,EACb,sEAAsE;YACxE,YAAY,EACV,mGAAmG;SACtG;QACD,UAAU,EAAE;YACV,gFAAgF;YAChF,6DAA6D;SAC9D;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { z } from 'zod';
2
+ import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
3
+ export declare const CREATE_DISTRIBUTION_NAME = "create_distribution";
4
+ export declare const CREATE_DISTRIBUTION_DESCRIPTION: string;
5
+ export declare const CREATE_DISTRIBUTION_ARGS: {
6
+ readonly audience: z.ZodString;
7
+ readonly source_query: z.ZodOptional<z.ZodString>;
8
+ readonly target_surface: z.ZodOptional<z.ZodString>;
9
+ };
10
+ export declare function buildCreateDistributionPrompt(args: {
11
+ audience: string;
12
+ source_query?: string | undefined;
13
+ target_surface?: string | undefined;
14
+ }): GetPromptResult;
15
+ //# sourceMappingURL=create-distribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-distribution.d.ts","sourceRoot":"","sources":["../../src/prompts/create-distribution.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAG1E,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D,eAAO,MAAM,+BAA+B,QAI+B,CAAC;AAE5E,eAAO,MAAM,wBAAwB;;;;CAkB3B,CAAC;AAIX,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE;IACJ,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,GACA,eAAe,CAgGjB"}
@@ -0,0 +1,111 @@
1
+ // ── create_distribution ─────────────────────────────────────────────
2
+ // Guided "build a distribution surface" workflow. MVP ships a degraded
3
+ // flow that stops at share-link creation — portal escalation is Phase 2.
4
+ import { z } from 'zod';
5
+ import { parseEnum, playbookMessage } from './helpers.js';
6
+ export const CREATE_DISTRIBUTION_NAME = 'create_distribution';
7
+ export const CREATE_DISTRIBUTION_DESCRIPTION = 'Guided workflow for assembling a distribution — pick assets for a ' +
8
+ 'specific audience, group them into a collection, and publish a share ' +
9
+ 'link with appropriate expiry and access settings. In MVP the flow ' +
10
+ 'stops at share-link creation; portal creation ships in a later release.';
11
+ export const CREATE_DISTRIBUTION_ARGS = {
12
+ audience: z
13
+ .string()
14
+ .describe('Who is this distribution for? e.g. "Q2 dealer network enablement", "press kit for product launch".'),
15
+ source_query: z
16
+ .string()
17
+ .optional()
18
+ .describe('Optional initial search query to seed the asset selection (e.g. "product photography 2026").'),
19
+ target_surface: z
20
+ .string()
21
+ .optional()
22
+ .describe('Desired output: share_link | collection | portal. Default share_link. (portal is Phase 2 — degrades to share_link in MVP.)'),
23
+ };
24
+ const TARGETS = ['share_link', 'collection', 'portal'];
25
+ export function buildCreateDistributionPrompt(args) {
26
+ const target = parseEnum(args.target_surface, TARGETS, 'share_link');
27
+ const audience = args.audience.trim();
28
+ const sourceQuery = args.source_query?.trim();
29
+ const portalRequested = target === 'portal';
30
+ const body = {
31
+ workflow: 'create_distribution',
32
+ audience,
33
+ source_query: sourceQuery ?? null,
34
+ target_surface: target,
35
+ degraded_in_mvp: portalRequested,
36
+ instructions: 'Walk the user through assembling a distribution. Confirm intent at ' +
37
+ 'each step before mutating. Every mutation routes through the dry-run ' +
38
+ 'preview flow. If the user requested portal as their target surface, ' +
39
+ 'tell them clearly that portal creation is not yet available and ' +
40
+ 'offer share-link creation as the available alternative.',
41
+ orchestration: [
42
+ {
43
+ step: 1,
44
+ action: 'Interpret the audience and seed an asset set',
45
+ tools: ['search_assets'],
46
+ purpose: sourceQuery !== undefined
47
+ ? `Search with q="${sourceQuery}" to seed the candidate list.`
48
+ : 'Translate the audience description into 1-3 candidate search queries (e.g. for "Q2 dealer enablement" try "product photography Q2", "dealer kit", "2026 launch"). Run each, deduplicate, and present a candidate set of 25-50 assets to the user.',
49
+ },
50
+ {
51
+ step: 2,
52
+ action: 'Refine the asset set with the user',
53
+ purpose: 'Show the candidate list with thumbnails (use display_file_name + ' +
54
+ 'view_url from search results). Ask the user which to include, ' +
55
+ 'remove, or replace. Iterate until the set is tight (typically 5-30 assets).',
56
+ },
57
+ {
58
+ step: 3,
59
+ action: 'Group into a collection',
60
+ purpose: 'Propose a collection name + description derived from the audience ' +
61
+ "(e.g. \"Q2 Dealer Enablement\"). Ask the user to confirm/edit. " +
62
+ 'create_collection is a Phase 2 tool — until it lands, look for an ' +
63
+ 'existing collection that matches and use add_to_collection (a ' +
64
+ 'Phase 1 tool) instead. If no good match exists, surface this and ' +
65
+ 'tell the user collection creation is in a future release.',
66
+ tools: ['list_collections', 'add_to_collection'],
67
+ phase_2_tool: 'create_collection',
68
+ },
69
+ {
70
+ step: 4,
71
+ action: 'Create a share link',
72
+ tools: ['create_share_link'],
73
+ purpose: 'Propose share-link settings derived from the audience: title, ' +
74
+ 'expiration (default 90 days), password (offer optional, default ' +
75
+ 'off), download permissions (default allow). Show the dry-run ' +
76
+ 'preview. User confirms → execute.',
77
+ },
78
+ ...(portalRequested
79
+ ? [
80
+ {
81
+ step: 5,
82
+ action: 'Communicate portal degraded mode',
83
+ purpose: "User asked for a portal as the target surface. Portal " +
84
+ 'creation (`create_portal`, `update_portal_content`) is part ' +
85
+ 'of a future release — not yet available. Tell them clearly. ' +
86
+ 'Suggest the share link from step 4 as the working alternative ' +
87
+ 'and confirm whether they want to proceed with share-link only.',
88
+ },
89
+ ]
90
+ : []),
91
+ ],
92
+ output_shape: {
93
+ audience: 'string',
94
+ asset_ids: 'string[] — the final selected set after user refinement',
95
+ collection: '{ id, name, description } | null — null if create_collection unavailable and no good existing match',
96
+ share_link: '{ id, url, expiration, password_protected }',
97
+ portal: 'null — Phase 2',
98
+ degraded_notice: portalRequested ? 'string — explicit note about portal availability' : 'null',
99
+ next_actions: 'Array<{ tool, args }> — typically empty after the share link executes',
100
+ },
101
+ guardrails: [
102
+ 'Mutations only via dry-run preview + explicit user confirm. No exceptions.',
103
+ 'When the user picks portal as target_surface, name the limitation clearly. Do not silently fall back.',
104
+ 'Cap the candidate asset set at 50 in step 1 to keep token usage bounded.',
105
+ ],
106
+ };
107
+ return playbookMessage(portalRequested
108
+ ? `Create distribution for "${audience}" (portal target — degraded to share-link in MVP)`
109
+ : `Create distribution for "${audience}" (target: ${target})`, body);
110
+ }
111
+ //# sourceMappingURL=create-distribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-distribution.js","sourceRoot":"","sources":["../../src/prompts/create-distribution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
2
+ /**
3
+ * Build a single-message GetPromptResult containing a structured
4
+ * playbook. The body is JSON-stringified so the consuming LLM gets a
5
+ * stable, parseable payload.
6
+ */
7
+ export declare function playbookMessage(description: string, body: unknown): GetPromptResult;
8
+ /**
9
+ * Coerce a string-shaped MCP prompt argument into one of a known set of
10
+ * enum values. Falls back to `defaultValue` if the input is missing or
11
+ * unrecognised. Prompt args are always strings on the wire, so each
12
+ * prompt that wants enum semantics has to do this client-side.
13
+ */
14
+ export declare function parseEnum<T extends string>(raw: string | undefined, allowed: readonly T[], defaultValue: T): T;
15
+ /**
16
+ * Parse and clamp a numeric prompt argument. Falls back to `defaultValue`
17
+ * for missing/unparseable input; clamps to `[min, max]` otherwise.
18
+ */
19
+ export declare function parseClampedInt(raw: string | undefined, defaultValue: number, min: number, max: number): number;
20
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/prompts/helpers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,OAAO,GACZ,eAAe,CAajB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EACxC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,YAAY,EAAE,CAAC,GACd,CAAC,CAIH;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,MAAM,CAKR"}
@@ -0,0 +1,53 @@
1
+ // ── Prompt helpers ───────────────────────────────────────────────────
2
+ // Small utilities for constructing GetPromptResult payloads.
3
+ //
4
+ // MCP prompts return a `{ description?, messages: [...] }` envelope. Per
5
+ // our spec, every prompt emits a single user-role message containing a
6
+ // structured playbook: what the user asked for, what tools/resources the
7
+ // LLM should call in what order, and how to shape the final report.
8
+ // Keeping the playbook in a single message simplifies token accounting
9
+ // and lets us version individual prompts independently.
10
+ /**
11
+ * Build a single-message GetPromptResult containing a structured
12
+ * playbook. The body is JSON-stringified so the consuming LLM gets a
13
+ * stable, parseable payload.
14
+ */
15
+ export function playbookMessage(description, body) {
16
+ return {
17
+ description,
18
+ messages: [
19
+ {
20
+ role: 'user',
21
+ content: {
22
+ type: 'text',
23
+ text: JSON.stringify(body, null, 2),
24
+ },
25
+ },
26
+ ],
27
+ };
28
+ }
29
+ /**
30
+ * Coerce a string-shaped MCP prompt argument into one of a known set of
31
+ * enum values. Falls back to `defaultValue` if the input is missing or
32
+ * unrecognised. Prompt args are always strings on the wire, so each
33
+ * prompt that wants enum semantics has to do this client-side.
34
+ */
35
+ export function parseEnum(raw, allowed, defaultValue) {
36
+ if (raw === undefined || raw === '')
37
+ return defaultValue;
38
+ const found = allowed.find((v) => v === raw);
39
+ return found ?? defaultValue;
40
+ }
41
+ /**
42
+ * Parse and clamp a numeric prompt argument. Falls back to `defaultValue`
43
+ * for missing/unparseable input; clamps to `[min, max]` otherwise.
44
+ */
45
+ export function parseClampedInt(raw, defaultValue, min, max) {
46
+ if (raw === undefined || raw === '')
47
+ return defaultValue;
48
+ const n = Number(raw);
49
+ if (!Number.isFinite(n) || !Number.isInteger(n))
50
+ return defaultValue;
51
+ return Math.max(min, Math.min(max, n));
52
+ }
53
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/prompts/helpers.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,6DAA6D;AAC7D,EAAE;AACF,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,oEAAoE;AACpE,uEAAuE;AACvE,wDAAwD;AAIxD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,WAAmB,EACnB,IAAa;IAEb,OAAO;QACL,WAAW;QACX,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBACpC;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,GAAuB,EACvB,OAAqB,EACrB,YAAe;IAEf,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAC7C,OAAO,KAAK,IAAI,YAAY,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAuB,EACvB,YAAoB,EACpB,GAAW,EACX,GAAW;IAEX,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,YAAY,CAAC;IACzD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,YAAY,CAAC;IACrE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
3
+ export declare const LIBRARY_HEALTH_AUDIT_NAME = "library_health_audit";
4
+ export declare const LIBRARY_HEALTH_AUDIT_DESCRIPTION: string;
5
+ export declare const LIBRARY_HEALTH_AUDIT_ARGS: {
6
+ readonly scope: z.ZodOptional<z.ZodString>;
7
+ readonly max_assets: z.ZodOptional<z.ZodString>;
8
+ };
9
+ export declare function buildLibraryHealthAuditPrompt(args: {
10
+ scope?: string | undefined;
11
+ max_assets?: string | undefined;
12
+ }): GetPromptResult;
13
+ //# sourceMappingURL=library-health-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-health-audit.d.ts","sourceRoot":"","sources":["../../src/prompts/library-health-audit.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAO1E,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,eAAO,MAAM,gCAAgC,QAKT,CAAC;AAErC,eAAO,MAAM,yBAAyB;;;CAa5B,CAAC;AAKX,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACpE,eAAe,CAwHjB"}
@@ -0,0 +1,131 @@
1
+ // ── library_health_audit ─────────────────────────────────────────────
2
+ // Workspace-wide health check: metadata completeness, tag hygiene,
3
+ // folder structure, orphans. The prompt emits a structured playbook;
4
+ // the client LLM does the actual orchestration via Tools and Resources.
5
+ import { z } from 'zod';
6
+ import { parseClampedInt, parseEnum, playbookMessage, } from './helpers.js';
7
+ export const LIBRARY_HEALTH_AUDIT_NAME = 'library_health_audit';
8
+ export const LIBRARY_HEALTH_AUDIT_DESCRIPTION = 'Run a comprehensive health check on a Collage workspace. Looks at ' +
9
+ 'metadata completeness, tag hygiene, folder structure, and orphaned ' +
10
+ 'assets, then returns a scored report with concrete fixes you can ' +
11
+ 'execute. Pair with `bulk_set_tags`, `update_asset_metadata`, and ' +
12
+ '`move_asset` to act on findings.';
13
+ export const LIBRARY_HEALTH_AUDIT_ARGS = {
14
+ scope: z
15
+ .string()
16
+ .optional()
17
+ .describe('Which dimensions to audit: full | metadata_only | tags_only | structure_only. Default full.'),
18
+ max_assets: z
19
+ .string()
20
+ .optional()
21
+ .describe('Asset sample size cap. Default 1000, max 5000 — protects against runaway API usage on large workspaces.'),
22
+ };
23
+ const SCOPES = ['full', 'metadata_only', 'tags_only', 'structure_only'];
24
+ export function buildLibraryHealthAuditPrompt(args) {
25
+ const scope = parseEnum(args.scope, SCOPES, 'full');
26
+ const maxAssets = parseClampedInt(args.max_assets, 1000, 1, 5000);
27
+ const dimensions = scope === 'full'
28
+ ? ['metadata', 'tags', 'structure']
29
+ : scope === 'metadata_only'
30
+ ? ['metadata']
31
+ : scope === 'tags_only'
32
+ ? ['tags']
33
+ : ['structure'];
34
+ const body = {
35
+ workflow: 'library_health_audit',
36
+ scope,
37
+ max_assets: maxAssets,
38
+ instructions: 'Run a workspace-wide library health audit. Execute the orchestration ' +
39
+ 'plan below in order. Use the listed MCP resources and tools — do not ' +
40
+ 'invent endpoints. Return a scored report (0-100 per dimension) with ' +
41
+ 'structured findings. For every fix you propose, name the exact tool ' +
42
+ 'and arguments — but never execute mutating tools without an explicit ' +
43
+ 'user confirmation; route every mutation through the dry-run preview ' +
44
+ 'flow these tools already provide.',
45
+ orchestration: [
46
+ {
47
+ step: 1,
48
+ action: 'Load read-only references',
49
+ resources: [
50
+ 'collage://folders',
51
+ // tags/custom-fields resources land in a follow-up; tools below are
52
+ // the live alternative until then.
53
+ ],
54
+ tools: ['list_custom_fields'],
55
+ purpose: 'Establish the workspace shape: folder tree, custom-field schema. ' +
56
+ 'Cache these in memory for the rest of the audit.',
57
+ },
58
+ {
59
+ step: 2,
60
+ action: 'Sample assets',
61
+ tools: ['search_assets'],
62
+ args: {
63
+ per_page: Math.min(maxAssets, 250),
64
+ page: 1,
65
+ q: '*',
66
+ sort_by: 'modified_at:desc',
67
+ projection: 'verbose',
68
+ },
69
+ purpose: 'Pull a representative sample (cap at max_assets across pages). ' +
70
+ 'Page through with the cursor returned in each response — stop at ' +
71
+ 'max_assets even if more remain.',
72
+ included_when: dimensions.includes('metadata') || dimensions.includes('tags'),
73
+ },
74
+ {
75
+ step: 3,
76
+ action: 'Score metadata completeness',
77
+ purpose: 'For each sampled asset compute: has_title, has_description, ' +
78
+ 'custom_field_coverage (filled / total). Aggregate to ' +
79
+ '{ total, missing_title, missing_description, mean_custom_field_coverage }. ' +
80
+ 'Score 0-100: 100 if every asset has title+description and 100% custom ' +
81
+ 'fields filled; subtract proportional to gaps.',
82
+ included_when: dimensions.includes('metadata'),
83
+ },
84
+ {
85
+ step: 4,
86
+ action: 'Score tag hygiene',
87
+ tools: ['audit_tagging_hygiene'],
88
+ purpose: 'Run audit_tagging_hygiene to surface orphan tags, casing ' +
89
+ 'inconsistencies, duplicate stems, and low-coverage tags. The tool ' +
90
+ 'returns a structured report — pass its findings through into the ' +
91
+ 'final audit output.',
92
+ included_when: dimensions.includes('tags'),
93
+ },
94
+ {
95
+ step: 5,
96
+ action: 'Score folder structure',
97
+ purpose: 'Compute from collage://folders: depth distribution, root-folder ' +
98
+ 'count, mean folder branching factor, count of folders with ' +
99
+ 'sub_category_count=0 AND no assets (orphan folders). Score 0-100: ' +
100
+ 'penalise excessive depth (>5), single-folder workspaces, and orphan folders.',
101
+ included_when: dimensions.includes('structure'),
102
+ },
103
+ {
104
+ step: 6,
105
+ action: 'Compile fix-path proposals',
106
+ purpose: 'For each finding, name the exact tool call that fixes it. ' +
107
+ 'Examples: orphan tag → bulk_remove_tags; missing title → ' +
108
+ 'update_asset_metadata; deeply nested orphan folder → move_asset. ' +
109
+ 'Group fixes by tool and present them as a checklist the user can ' +
110
+ 'green-light item by item — never auto-execute.',
111
+ },
112
+ ],
113
+ output_shape: {
114
+ summary: 'string — one paragraph executive summary',
115
+ scores: {
116
+ metadata: 'number 0-100 | null if not in scope',
117
+ tags: 'number 0-100 | null if not in scope',
118
+ structure: 'number 0-100 | null if not in scope',
119
+ },
120
+ findings: 'Array<{ dimension, severity, count, examples, fix_path }>',
121
+ next_actions: 'Array<{ tool, args, expected_count, rationale }> — proposed mutations the user can execute',
122
+ },
123
+ guardrails: [
124
+ 'Every mutation MUST go through the dry-run framework. Show the preview before executing.',
125
+ 'Stop sampling at max_assets even if more pages exist.',
126
+ 'If a tool/resource returns an UPSTREAM error, surface the error code and request_id in the report; do not pretend the dimension scored cleanly.',
127
+ ],
128
+ };
129
+ return playbookMessage(`Library health audit (scope: ${scope}, sample: ${maxAssets} assets)`, body);
130
+ }
131
+ //# sourceMappingURL=library-health-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-health-audit.js","sourceRoot":"","sources":["../../src/prompts/library-health-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ import type { GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
3
+ export declare const USAGE_INSIGHTS_NAME = "usage_insights";
4
+ export declare const USAGE_INSIGHTS_DESCRIPTION: string;
5
+ export declare const USAGE_INSIGHTS_ARGS: {
6
+ readonly time_window: z.ZodOptional<z.ZodString>;
7
+ readonly scope: z.ZodOptional<z.ZodString>;
8
+ };
9
+ export declare function buildUsageInsightsPrompt(args: {
10
+ time_window?: string | undefined;
11
+ scope?: string | undefined;
12
+ }): GetPromptResult;
13
+ //# sourceMappingURL=usage-insights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-insights.d.ts","sourceRoot":"","sources":["../../src/prompts/usage-insights.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAG1E,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,eAAO,MAAM,0BAA0B,QAI+B,CAAC;AAEvE,eAAO,MAAM,mBAAmB;;;CAStB,CAAC;AAKX,wBAAgB,wBAAwB,CACtC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrE,eAAe,CAoFjB"}