@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.
- package/.env.example +56 -0
- package/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +512 -0
- package/dist/client.d.ts +497 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +1162 -0
- package/dist/client.js.map +1 -0
- package/dist/conventions/confirmation.d.ts +89 -0
- package/dist/conventions/confirmation.d.ts.map +1 -0
- package/dist/conventions/confirmation.js +132 -0
- package/dist/conventions/confirmation.js.map +1 -0
- package/dist/conventions/dry-run/batch-executor.d.ts +36 -0
- package/dist/conventions/dry-run/batch-executor.d.ts.map +1 -0
- package/dist/conventions/dry-run/batch-executor.js +89 -0
- package/dist/conventions/dry-run/batch-executor.js.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts +34 -0
- package/dist/conventions/dry-run/diff-renderer.d.ts.map +1 -0
- package/dist/conventions/dry-run/diff-renderer.js +158 -0
- package/dist/conventions/dry-run/diff-renderer.js.map +1 -0
- package/dist/conventions/dry-run/index.d.ts +13 -0
- package/dist/conventions/dry-run/index.d.ts.map +1 -0
- package/dist/conventions/dry-run/index.js +10 -0
- package/dist/conventions/dry-run/index.js.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts +64 -0
- package/dist/conventions/dry-run/mutating-tool.d.ts.map +1 -0
- package/dist/conventions/dry-run/mutating-tool.js +88 -0
- package/dist/conventions/dry-run/mutating-tool.js.map +1 -0
- package/dist/conventions/dry-run/summary.d.ts +66 -0
- package/dist/conventions/dry-run/summary.d.ts.map +1 -0
- package/dist/conventions/dry-run/summary.js +185 -0
- package/dist/conventions/dry-run/summary.js.map +1 -0
- package/dist/conventions/dry-run/types.d.ts +597 -0
- package/dist/conventions/dry-run/types.d.ts.map +1 -0
- package/dist/conventions/dry-run/types.js +108 -0
- package/dist/conventions/dry-run/types.js.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts +66 -0
- package/dist/conventions/dry-run/with-dry-run.d.ts.map +1 -0
- package/dist/conventions/dry-run/with-dry-run.js +219 -0
- package/dist/conventions/dry-run/with-dry-run.js.map +1 -0
- package/dist/conventions/env.d.ts +49 -0
- package/dist/conventions/env.d.ts.map +1 -0
- package/dist/conventions/env.js +84 -0
- package/dist/conventions/env.js.map +1 -0
- package/dist/conventions/errors.d.ts +68 -0
- package/dist/conventions/errors.d.ts.map +1 -0
- package/dist/conventions/errors.js +81 -0
- package/dist/conventions/errors.js.map +1 -0
- package/dist/conventions/logger.d.ts +28 -0
- package/dist/conventions/logger.d.ts.map +1 -0
- package/dist/conventions/logger.js +105 -0
- package/dist/conventions/logger.js.map +1 -0
- package/dist/conventions/pagination.d.ts +37 -0
- package/dist/conventions/pagination.d.ts.map +1 -0
- package/dist/conventions/pagination.js +53 -0
- package/dist/conventions/pagination.js.map +1 -0
- package/dist/conventions/rate-limiter.d.ts +54 -0
- package/dist/conventions/rate-limiter.d.ts.map +1 -0
- package/dist/conventions/rate-limiter.js +143 -0
- package/dist/conventions/rate-limiter.js.map +1 -0
- package/dist/conventions/response-budget.d.ts +66 -0
- package/dist/conventions/response-budget.d.ts.map +1 -0
- package/dist/conventions/response-budget.js +89 -0
- package/dist/conventions/response-budget.js.map +1 -0
- package/dist/conventions/schema-version.d.ts +27 -0
- package/dist/conventions/schema-version.d.ts.map +1 -0
- package/dist/conventions/schema-version.js +29 -0
- package/dist/conventions/schema-version.js.map +1 -0
- package/dist/conventions/state-store-redis.d.ts +32 -0
- package/dist/conventions/state-store-redis.d.ts.map +1 -0
- package/dist/conventions/state-store-redis.js +77 -0
- package/dist/conventions/state-store-redis.js.map +1 -0
- package/dist/conventions/state-store.d.ts +46 -0
- package/dist/conventions/state-store.d.ts.map +1 -0
- package/dist/conventions/state-store.js +105 -0
- package/dist/conventions/state-store.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/collection-audit.d.ts +13 -0
- package/dist/prompts/collection-audit.d.ts.map +1 -0
- package/dist/prompts/collection-audit.js +168 -0
- package/dist/prompts/collection-audit.js.map +1 -0
- package/dist/prompts/create-distribution.d.ts +15 -0
- package/dist/prompts/create-distribution.d.ts.map +1 -0
- package/dist/prompts/create-distribution.js +111 -0
- package/dist/prompts/create-distribution.js.map +1 -0
- package/dist/prompts/helpers.d.ts +20 -0
- package/dist/prompts/helpers.d.ts.map +1 -0
- package/dist/prompts/helpers.js +53 -0
- package/dist/prompts/helpers.js.map +1 -0
- package/dist/prompts/library-health-audit.d.ts +13 -0
- package/dist/prompts/library-health-audit.d.ts.map +1 -0
- package/dist/prompts/library-health-audit.js +131 -0
- package/dist/prompts/library-health-audit.js.map +1 -0
- package/dist/prompts/usage-insights.d.ts +13 -0
- package/dist/prompts/usage-insights.d.ts.map +1 -0
- package/dist/prompts/usage-insights.js +98 -0
- package/dist/prompts/usage-insights.js.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts +48 -0
- package/dist/prompts/wrap-prompt-as-tool.d.ts.map +1 -0
- package/dist/prompts/wrap-prompt-as-tool.js +61 -0
- package/dist/prompts/wrap-prompt-as-tool.js.map +1 -0
- package/dist/resources/asset-by-id.d.ts +4 -0
- package/dist/resources/asset-by-id.d.ts.map +1 -0
- package/dist/resources/asset-by-id.js +27 -0
- package/dist/resources/asset-by-id.js.map +1 -0
- package/dist/resources/collections.d.ts +5 -0
- package/dist/resources/collections.d.ts.map +1 -0
- package/dist/resources/collections.js +48 -0
- package/dist/resources/collections.js.map +1 -0
- package/dist/resources/custom-fields.d.ts +4 -0
- package/dist/resources/custom-fields.d.ts.map +1 -0
- package/dist/resources/custom-fields.js +30 -0
- package/dist/resources/custom-fields.js.map +1 -0
- package/dist/resources/folders.d.ts +5 -0
- package/dist/resources/folders.d.ts.map +1 -0
- package/dist/resources/folders.js +73 -0
- package/dist/resources/folders.js.map +1 -0
- package/dist/resources/helpers.d.ts +17 -0
- package/dist/resources/helpers.d.ts.map +1 -0
- package/dist/resources/helpers.js +59 -0
- package/dist/resources/helpers.js.map +1 -0
- package/dist/resources/portals.d.ts +5 -0
- package/dist/resources/portals.d.ts.map +1 -0
- package/dist/resources/portals.js +81 -0
- package/dist/resources/portals.js.map +1 -0
- package/dist/resources/recent-and-dashboard.d.ts +5 -0
- package/dist/resources/recent-and-dashboard.d.ts.map +1 -0
- package/dist/resources/recent-and-dashboard.js +42 -0
- package/dist/resources/recent-and-dashboard.js.map +1 -0
- package/dist/tools/asset-selection.d.ts +102 -0
- package/dist/tools/asset-selection.d.ts.map +1 -0
- package/dist/tools/asset-selection.js +133 -0
- package/dist/tools/asset-selection.js.map +1 -0
- package/dist/tools/audit/audit-folder-structure.d.ts +108 -0
- package/dist/tools/audit/audit-folder-structure.d.ts.map +1 -0
- package/dist/tools/audit/audit-folder-structure.js +260 -0
- package/dist/tools/audit/audit-folder-structure.js.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts +83 -0
- package/dist/tools/audit/audit-naming-conventions.d.ts.map +1 -0
- package/dist/tools/audit/audit-naming-conventions.js +238 -0
- package/dist/tools/audit/audit-naming-conventions.js.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts +77 -0
- package/dist/tools/audit/audit-tagging-hygiene.d.ts.map +1 -0
- package/dist/tools/audit/audit-tagging-hygiene.js +402 -0
- package/dist/tools/audit/audit-tagging-hygiene.js.map +1 -0
- package/dist/tools/audit/detect-duplicates.d.ts +62 -0
- package/dist/tools/audit/detect-duplicates.d.ts.map +1 -0
- package/dist/tools/audit/detect-duplicates.js +0 -0
- package/dist/tools/audit/detect-duplicates.js.map +1 -0
- package/dist/tools/audit/types.d.ts +526 -0
- package/dist/tools/audit/types.d.ts.map +1 -0
- package/dist/tools/audit/types.js +188 -0
- package/dist/tools/audit/types.js.map +1 -0
- package/dist/tools/bulk-move-assets.d.ts +78 -0
- package/dist/tools/bulk-move-assets.d.ts.map +1 -0
- package/dist/tools/bulk-move-assets.js +122 -0
- package/dist/tools/bulk-move-assets.js.map +1 -0
- package/dist/tools/bulk-normalize-filenames.d.ts +62 -0
- package/dist/tools/bulk-normalize-filenames.d.ts.map +1 -0
- package/dist/tools/bulk-normalize-filenames.js +237 -0
- package/dist/tools/bulk-normalize-filenames.js.map +1 -0
- package/dist/tools/bulk-rename-assets.d.ts +79 -0
- package/dist/tools/bulk-rename-assets.d.ts.map +1 -0
- package/dist/tools/bulk-rename-assets.js +139 -0
- package/dist/tools/bulk-rename-assets.js.map +1 -0
- package/dist/tools/bulk-tags.d.ts +107 -0
- package/dist/tools/bulk-tags.d.ts.map +1 -0
- package/dist/tools/bulk-tags.js +220 -0
- package/dist/tools/bulk-tags.js.map +1 -0
- package/dist/tools/client-adapters.d.ts +76 -0
- package/dist/tools/client-adapters.d.ts.map +1 -0
- package/dist/tools/client-adapters.js +648 -0
- package/dist/tools/client-adapters.js.map +1 -0
- package/dist/tools/collection-membership.d.ts +90 -0
- package/dist/tools/collection-membership.d.ts.map +1 -0
- package/dist/tools/collection-membership.js +195 -0
- package/dist/tools/collection-membership.js.map +1 -0
- package/dist/tools/create-collection.d.ts +63 -0
- package/dist/tools/create-collection.d.ts.map +1 -0
- package/dist/tools/create-collection.js +151 -0
- package/dist/tools/create-collection.js.map +1 -0
- package/dist/tools/create-folder.d.ts +46 -0
- package/dist/tools/create-folder.d.ts.map +1 -0
- package/dist/tools/create-folder.js +83 -0
- package/dist/tools/create-folder.js.map +1 -0
- package/dist/tools/create-share-link.d.ts +107 -0
- package/dist/tools/create-share-link.d.ts.map +1 -0
- package/dist/tools/create-share-link.js +239 -0
- package/dist/tools/create-share-link.js.map +1 -0
- package/dist/tools/get-asset-details.d.ts +401 -0
- package/dist/tools/get-asset-details.d.ts.map +1 -0
- package/dist/tools/get-asset-details.js +56 -0
- package/dist/tools/get-asset-details.js.map +1 -0
- package/dist/tools/get-collection.d.ts +126 -0
- package/dist/tools/get-collection.d.ts.map +1 -0
- package/dist/tools/get-collection.js +52 -0
- package/dist/tools/get-collection.js.map +1 -0
- package/dist/tools/get-embed-code.d.ts +195 -0
- package/dist/tools/get-embed-code.d.ts.map +1 -0
- package/dist/tools/get-embed-code.js +214 -0
- package/dist/tools/get-embed-code.js.map +1 -0
- package/dist/tools/insights/analyze-share-links.d.ts +159 -0
- package/dist/tools/insights/analyze-share-links.d.ts.map +1 -0
- package/dist/tools/insights/analyze-share-links.js +314 -0
- package/dist/tools/insights/analyze-share-links.js.map +1 -0
- package/dist/tools/insights/insight-cache.d.ts +36 -0
- package/dist/tools/insights/insight-cache.d.ts.map +1 -0
- package/dist/tools/insights/insight-cache.js +98 -0
- package/dist/tools/insights/insight-cache.js.map +1 -0
- package/dist/tools/insights/report-asset-activation.d.ts +149 -0
- package/dist/tools/insights/report-asset-activation.d.ts.map +1 -0
- package/dist/tools/insights/report-asset-activation.js +380 -0
- package/dist/tools/insights/report-asset-activation.js.map +1 -0
- package/dist/tools/insights/report-stale-assets.d.ts +120 -0
- package/dist/tools/insights/report-stale-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-stale-assets.js +281 -0
- package/dist/tools/insights/report-stale-assets.js.map +1 -0
- package/dist/tools/insights/report-top-assets.d.ts +139 -0
- package/dist/tools/insights/report-top-assets.d.ts.map +1 -0
- package/dist/tools/insights/report-top-assets.js +407 -0
- package/dist/tools/insights/report-top-assets.js.map +1 -0
- package/dist/tools/list-categories.d.ts +127 -0
- package/dist/tools/list-categories.d.ts.map +1 -0
- package/dist/tools/list-categories.js +68 -0
- package/dist/tools/list-categories.js.map +1 -0
- package/dist/tools/list-collections.d.ts +127 -0
- package/dist/tools/list-collections.d.ts.map +1 -0
- package/dist/tools/list-collections.js +53 -0
- package/dist/tools/list-collections.js.map +1 -0
- package/dist/tools/list-custom-fields.d.ts +125 -0
- package/dist/tools/list-custom-fields.d.ts.map +1 -0
- package/dist/tools/list-custom-fields.js +51 -0
- package/dist/tools/list-custom-fields.js.map +1 -0
- package/dist/tools/list-share-links.d.ts +192 -0
- package/dist/tools/list-share-links.d.ts.map +1 -0
- package/dist/tools/list-share-links.js +92 -0
- package/dist/tools/list-share-links.js.map +1 -0
- package/dist/tools/list-workspaces.d.ts +88 -0
- package/dist/tools/list-workspaces.d.ts.map +1 -0
- package/dist/tools/list-workspaces.js +71 -0
- package/dist/tools/list-workspaces.js.map +1 -0
- package/dist/tools/move-asset.d.ts +48 -0
- package/dist/tools/move-asset.d.ts.map +1 -0
- package/dist/tools/move-asset.js +85 -0
- package/dist/tools/move-asset.js.map +1 -0
- package/dist/tools/rename-asset.d.ts +88 -0
- package/dist/tools/rename-asset.d.ts.map +1 -0
- package/dist/tools/rename-asset.js +100 -0
- package/dist/tools/rename-asset.js.map +1 -0
- package/dist/tools/rename-folder.d.ts +55 -0
- package/dist/tools/rename-folder.d.ts.map +1 -0
- package/dist/tools/rename-folder.js +101 -0
- package/dist/tools/rename-folder.js.map +1 -0
- package/dist/tools/revoke-share-link.d.ts +55 -0
- package/dist/tools/revoke-share-link.d.ts.map +1 -0
- package/dist/tools/revoke-share-link.js +77 -0
- package/dist/tools/revoke-share-link.js.map +1 -0
- package/dist/tools/search/facets.d.ts +34 -0
- package/dist/tools/search/facets.d.ts.map +1 -0
- package/dist/tools/search/facets.js +147 -0
- package/dist/tools/search/facets.js.map +1 -0
- package/dist/tools/search/filter-builder.d.ts +33 -0
- package/dist/tools/search/filter-builder.d.ts.map +1 -0
- package/dist/tools/search/filter-builder.js +111 -0
- package/dist/tools/search/filter-builder.js.map +1 -0
- package/dist/tools/search/search-assets.d.ts +41 -0
- package/dist/tools/search/search-assets.d.ts.map +1 -0
- package/dist/tools/search/search-assets.js +162 -0
- package/dist/tools/search/search-assets.js.map +1 -0
- package/dist/tools/search/search-collections.d.ts +35 -0
- package/dist/tools/search/search-collections.d.ts.map +1 -0
- package/dist/tools/search/search-collections.js +103 -0
- package/dist/tools/search/search-collections.js.map +1 -0
- package/dist/tools/search/types.d.ts +1047 -0
- package/dist/tools/search/types.d.ts.map +1 -0
- package/dist/tools/search/types.js +216 -0
- package/dist/tools/search/types.js.map +1 -0
- package/dist/tools/update-asset-metadata.d.ts +78 -0
- package/dist/tools/update-asset-metadata.d.ts.map +1 -0
- package/dist/tools/update-asset-metadata.js +203 -0
- package/dist/tools/update-asset-metadata.js.map +1 -0
- package/dist/tools/update-collection.d.ts +69 -0
- package/dist/tools/update-collection.d.ts.map +1 -0
- package/dist/tools/update-collection.js +142 -0
- package/dist/tools/update-collection.js.map +1 -0
- package/dist/tools/view-category-contents.d.ts +231 -0
- package/dist/tools/view-category-contents.d.ts.map +1 -0
- package/dist/tools/view-category-contents.js +97 -0
- package/dist/tools/view-category-contents.js.map +1 -0
- package/dist/types.d.ts +1326 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +288 -0
- package/dist/types.js.map +1 -0
- package/dist/typesense.d.ts +84 -0
- package/dist/typesense.d.ts.map +1 -0
- package/dist/typesense.js +243 -0
- package/dist/typesense.js.map +1 -0
- package/docs/api-field-verification.md +244 -0
- package/docs/deployment-runbook.md +446 -0
- package/docs/security-review.md +195 -0
- package/docs/typesense-filter-schema.md +262 -0
- package/docs/verified-endpoints.md +38 -0
- 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":"AAAA,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,2DAA2D;AAC3D,EAAE;AACF,eAAe;AACf,6EAA6E;AAC7E,EAAE;AACF,wEAAwE;AACxE,qEAAqE;AACrE,sEAAsE;AACtE,iEAAiE;AACjE,+BAA+B;AAC/B,EAAE;AACF,wCAAwC;AACxC,0EAA0E;AAC1E,uDAAuD;AAEvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,YAAY,GAKb,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAqB,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,wEAAwE;AAExE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,QAAQ,EAAE,QAAQ;IAClB,uBAAuB,EAAE,QAAQ,CAAC,QAAQ,EAAE;IAC5C,mDAAmD;IACnD,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;CACpD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,4BAA4B,GACvC,wEAAwE;IACxE,4DAA4D;IAC5D,wEAAwE;IACxE,gEAAgE,CAAC;AAwBnE,MAAM,OAAO,kBAAmB,SAAQ,YAGvC;IACU,IAAI,GAAG,kBAAkB,CAAC;IACP,SAAS,GAAG,EAAE,CAAC;IAE1B,MAAM,CAAiB;IAExC,YAAY,IAAwB;QAClC,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAES,IAAI,CAAC,KAA0B;QACvC,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjC,MAAM,IAAI,GACR,IAAI,CAAC,uBAAuB,KAAK,IAAI;gBACnC,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAC3C,MAAM,MAAM,GACV,IAAI,CAAC,mBAAmB,KAAK,SAAS;gBACpC,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,IAAI,CAAC,mBAAmB,KAAK,IAAI;oBACjC,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACzC,IACE,IAAI,CAAC,mBAAmB,KAAK,SAAS;gBACtC,IAAI,CAAC,mBAAmB,KAAK,IAAI;gBACjC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,IAAI,EACzC,CAAC;gBACD,SAAS,EAAE,CAAC;YACd,CAAC;iBAAM,IACL,IAAI,CAAC,mBAAmB,KAAK,SAAS;gBACtC,IAAI,CAAC,mBAAmB,KAAK,IAAI;gBACjC,IAAI,KAAK,IAAI,EACb,CAAC;gBACD,SAAS,EAAE,CAAC;YACd,CAAC;YACD,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE;gBACF,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;gBAC/B,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;gBAC5B,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE;aAC1D,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAe,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,6CAA6C;gBACtD,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;QACL,CAAC;QACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,oDAAoD;gBAC7D,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,OAAO;YACP,SAAS;YACT,eAAe,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;SACjE,CAAC;IACJ,CAAC;IAES,KAAK,GAAgC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC9D,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAGlC,CAAC;QACF,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpE,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,eAAe,CACpB,YAAY,EACZ,UAAU,MAAM,CAAC,EAAE,mBAAmB,CACvC;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,uBAAuB,EAAE,IAAI;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1D,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,uBAAuB,EAAE,IAAI,EAAE;SACnE,CAAC;IACJ,CAAC,CAAC;CACH;AAED,MAAM,UAAU,uBAAuB,CACrC,IAAwB;IAExB,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -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"}
|