@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,55 @@
|
|
|
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 RenameFolderInputSchema: z.ZodObject<{
|
|
6
|
+
category_id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
7
|
+
new_name: z.ZodString;
|
|
8
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
9
|
+
/** Optional current name for diff display; looked up if absent. */
|
|
10
|
+
current_name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
category_id: string | number;
|
|
13
|
+
new_name: string;
|
|
14
|
+
description?: string | null | undefined;
|
|
15
|
+
current_name?: string | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
category_id: string | number;
|
|
18
|
+
new_name: string;
|
|
19
|
+
description?: string | null | undefined;
|
|
20
|
+
current_name?: string | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
export type RenameFolderInput = z.infer<typeof RenameFolderInputSchema>;
|
|
23
|
+
export declare const RENAME_FOLDER_DESCRIPTION: string;
|
|
24
|
+
export interface RenameFolderItemResult {
|
|
25
|
+
folder_id: string;
|
|
26
|
+
new_name: string;
|
|
27
|
+
description: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface RenameFolderClient {
|
|
30
|
+
/** Lookup current name for diff display. Returns null if unavailable. */
|
|
31
|
+
getCurrentFolderName(categoryId: string): Promise<string | null>;
|
|
32
|
+
renameFolder(input: {
|
|
33
|
+
category_id: string;
|
|
34
|
+
folder_name: string;
|
|
35
|
+
description?: string | null;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
ok: true;
|
|
38
|
+
} | {
|
|
39
|
+
ok: false;
|
|
40
|
+
error: McpToolError;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
export interface RenameFolderDeps extends MutatingToolDeps<RenameFolderInput> {
|
|
44
|
+
client: RenameFolderClient;
|
|
45
|
+
}
|
|
46
|
+
export declare class RenameFolderTool extends MutatingTool<RenameFolderInput, RenameFolderItemResult> {
|
|
47
|
+
readonly name = "rename_folder";
|
|
48
|
+
protected readonly chunkSize = 1;
|
|
49
|
+
private readonly client;
|
|
50
|
+
constructor(deps: RenameFolderDeps);
|
|
51
|
+
protected plan(input: RenameFolderInput): Promise<PlanResult>;
|
|
52
|
+
protected apply: ApplyFn<RenameFolderItemResult>;
|
|
53
|
+
}
|
|
54
|
+
export type RenameFolderPlan = DryRunPlan<RenameFolderInput>;
|
|
55
|
+
//# sourceMappingURL=rename-folder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-folder.d.ts","sourceRoot":"","sources":["../../src/tools/rename-folder.ts"],"names":[],"mappings":"AASA,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;AAG9E,eAAO,MAAM,uBAAuB;;;;IAIlC,mEAAmE;;;;;;;;;;;;EAEnE,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,eAAO,MAAM,yBAAyB,QAGG,CAAC;AAE1C,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjE,YAAY,CAAC,KAAK,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB,CAAC,iBAAiB,CAAC;IAC3E,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,qBAAa,gBAAiB,SAAQ,YAAY,CAChD,iBAAiB,EACjB,sBAAsB,CACvB;IACC,QAAQ,CAAC,IAAI,mBAAmB;IAChC,mBAA4B,SAAS,KAAK;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEhC,IAAI,EAAE,gBAAgB;cAKlB,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC;IA6CnE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,sBAAsB,CAAC,CA0C9C;CACH;AAED,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// ── rename_folder ────────────────────────────────────────────────────
|
|
2
|
+
// Renames one folder, optionally updating its description. Two-step
|
|
3
|
+
// dry-run flow.
|
|
4
|
+
//
|
|
5
|
+
// Upstream surface:
|
|
6
|
+
// POST digital-assets/category/rename/{id} { workspace_id, folder_name, description? }
|
|
7
|
+
//
|
|
8
|
+
// MVP scope: one folder per call. Bulk rename is Phase 1.5.
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { MutatingTool, } from '../conventions/dry-run/index.js';
|
|
11
|
+
import { createToolError } from '../conventions/errors.js';
|
|
12
|
+
import { IdSchema } from '../types.js';
|
|
13
|
+
export const RenameFolderInputSchema = z.object({
|
|
14
|
+
category_id: IdSchema,
|
|
15
|
+
new_name: z.string().min(1).max(255),
|
|
16
|
+
description: z.string().max(10_000).nullable().optional(),
|
|
17
|
+
/** Optional current name for diff display; looked up if absent. */
|
|
18
|
+
current_name: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
export const RENAME_FOLDER_DESCRIPTION = 'Rename a folder (and optionally update its description). Two-step: ' +
|
|
21
|
+
'first call returns a preview plus a confirmation_token; second call ' +
|
|
22
|
+
'(with the token) executes the rename.';
|
|
23
|
+
export class RenameFolderTool extends MutatingTool {
|
|
24
|
+
name = 'rename_folder';
|
|
25
|
+
chunkSize = 1;
|
|
26
|
+
client;
|
|
27
|
+
constructor(deps) {
|
|
28
|
+
super(deps);
|
|
29
|
+
this.client = deps.client;
|
|
30
|
+
}
|
|
31
|
+
async plan(input) {
|
|
32
|
+
const id = String(input.category_id);
|
|
33
|
+
const before = input.current_name ??
|
|
34
|
+
(await this.client.getCurrentFolderName(id)) ??
|
|
35
|
+
'(unknown)';
|
|
36
|
+
const after = { folder_name: input.new_name };
|
|
37
|
+
if (input.description !== undefined) {
|
|
38
|
+
after['description'] = input.description ?? '';
|
|
39
|
+
}
|
|
40
|
+
const change = {
|
|
41
|
+
id,
|
|
42
|
+
operation: 'update',
|
|
43
|
+
before: { folder_name: before },
|
|
44
|
+
after,
|
|
45
|
+
metadata: {
|
|
46
|
+
category_id: id,
|
|
47
|
+
new_name: input.new_name,
|
|
48
|
+
description: input.description ?? null,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
const riskFlags = [];
|
|
52
|
+
if (before === input.new_name) {
|
|
53
|
+
riskFlags.push({
|
|
54
|
+
code: 'noop_rename',
|
|
55
|
+
severity: 'info',
|
|
56
|
+
message: 'rename to identical name (no-op)',
|
|
57
|
+
count: 1,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (input.new_name.length > 100) {
|
|
61
|
+
riskFlags.push({
|
|
62
|
+
code: 'long_folder_name',
|
|
63
|
+
severity: 'warning',
|
|
64
|
+
message: 'name exceeds 100 characters',
|
|
65
|
+
count: 1,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return { changes: [change], riskFlags };
|
|
69
|
+
}
|
|
70
|
+
apply = async (change) => {
|
|
71
|
+
const meta = (change.metadata ?? {});
|
|
72
|
+
if (typeof meta.category_id !== 'string' ||
|
|
73
|
+
typeof meta.new_name !== 'string' ||
|
|
74
|
+
meta.new_name.length === 0) {
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
error: createToolError('VALIDATION', `change ${change.id} missing category_id or new_name`),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const callInput = {
|
|
81
|
+
category_id: meta.category_id,
|
|
82
|
+
folder_name: meta.new_name,
|
|
83
|
+
};
|
|
84
|
+
if (meta.description !== undefined && meta.description !== null) {
|
|
85
|
+
callInput.description = meta.description;
|
|
86
|
+
}
|
|
87
|
+
const result = await this.client.renameFolder(callInput);
|
|
88
|
+
if (!result.ok) {
|
|
89
|
+
return { ok: false, error: result.error };
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
result: {
|
|
94
|
+
folder_id: meta.category_id,
|
|
95
|
+
new_name: meta.new_name,
|
|
96
|
+
description: meta.description ?? null,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=rename-folder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-folder.js","sourceRoot":"","sources":["../../src/tools/rename-folder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
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 RevokeShareLinkInputSchema: z.ZodObject<{
|
|
6
|
+
share_id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
share_id: string | number;
|
|
9
|
+
}, {
|
|
10
|
+
share_id: string | number;
|
|
11
|
+
}>;
|
|
12
|
+
export type RevokeShareLinkInput = z.infer<typeof RevokeShareLinkInputSchema>;
|
|
13
|
+
export declare const REVOKE_SHARE_LINK_DESCRIPTION: string;
|
|
14
|
+
export interface RevokeShareLinkItemResult {
|
|
15
|
+
share_id: string;
|
|
16
|
+
revoked: true;
|
|
17
|
+
}
|
|
18
|
+
export interface ShareLinkSnapshot {
|
|
19
|
+
id: string;
|
|
20
|
+
title: string | null;
|
|
21
|
+
share_url: string | null;
|
|
22
|
+
expiration: string | null;
|
|
23
|
+
password_protected: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface RevokeShareLinkClient {
|
|
26
|
+
/** Read the current state of the share link for diff display. */
|
|
27
|
+
getShareLink(shareId: string): Promise<{
|
|
28
|
+
ok: true;
|
|
29
|
+
snapshot: ShareLinkSnapshot;
|
|
30
|
+
} | {
|
|
31
|
+
ok: false;
|
|
32
|
+
error: McpToolError;
|
|
33
|
+
}>;
|
|
34
|
+
/** Revoke the share link. */
|
|
35
|
+
revokeShareLink(shareId: string): Promise<{
|
|
36
|
+
ok: true;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
error: McpToolError;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export interface RevokeShareLinkDeps extends MutatingToolDeps<RevokeShareLinkInput> {
|
|
43
|
+
client: RevokeShareLinkClient;
|
|
44
|
+
}
|
|
45
|
+
export declare class RevokeShareLinkTool extends MutatingTool<RevokeShareLinkInput, RevokeShareLinkItemResult> {
|
|
46
|
+
readonly name = "revoke_share_link";
|
|
47
|
+
protected readonly chunkSize = 1;
|
|
48
|
+
private readonly client;
|
|
49
|
+
constructor(deps: RevokeShareLinkDeps);
|
|
50
|
+
protected plan(input: RevokeShareLinkInput): Promise<PlanResult>;
|
|
51
|
+
protected apply: ApplyFn<RevokeShareLinkItemResult>;
|
|
52
|
+
}
|
|
53
|
+
export declare function buildRevokeShareLinkTool(deps: RevokeShareLinkDeps): RevokeShareLinkTool;
|
|
54
|
+
export type RevokeShareLinkPlan = DryRunPlan<RevokeShareLinkInput>;
|
|
55
|
+
//# sourceMappingURL=revoke-share-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke-share-link.d.ts","sourceRoot":"","sources":["../../src/tools/revoke-share-link.ts"],"names":[],"mappings":"AAcA,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,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAK7D,eAAO,MAAM,0BAA0B;;;;;;EAErC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,6BAA6B,QAIF,CAAC;AAIzC,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,IAAI,CAAC;CACf;AAID,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,YAAY,CACV,OAAO,EAAE,MAAM,GACd,OAAO,CACN;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAA;KAAE,GACzC;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CACrC,CAAC;IACF,6BAA6B;IAC7B,eAAe,CACb,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,mBACf,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IAC9C,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED,qBAAa,mBAAoB,SAAQ,YAAY,CACnD,oBAAoB,EACpB,yBAAyB,CAC1B;IACC,QAAQ,CAAC,IAAI,uBAAuB;IACpC,mBAA4B,SAAS,KAAK;IAE1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAEnC,IAAI,EAAE,mBAAmB;cAKrB,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;IAsCtE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,yBAAyB,CAAC,CASjD;CACH;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,mBAAmB,GACxB,mBAAmB,CAErB;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ── revoke_share_link ────────────────────────────────────────────────
|
|
2
|
+
// Revokes a single share link — once revoked, the URL stops working.
|
|
3
|
+
// Wraps the dry-run framework so the preview shows the link being revoked
|
|
4
|
+
// plus its current state before execute.
|
|
5
|
+
//
|
|
6
|
+
// Upstream surface (verified via Admin-Frontend
|
|
7
|
+
// `pages/_workspace_id/dam/sharing/index.vue:1059`):
|
|
8
|
+
// POST digital-assets/dashboard/delete-share-assets-url
|
|
9
|
+
// body: { workspace_id, share_url_id: number[] }
|
|
10
|
+
//
|
|
11
|
+
// We send a single-id list because this tool is one-at-a-time. Bulk
|
|
12
|
+
// revocation can be layered on later via the same upstream endpoint
|
|
13
|
+
// (`delete-multiple-share-assets-url`) if SOW priorities shift.
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { MutatingTool, } from '../conventions/dry-run/index.js';
|
|
16
|
+
import { IdSchema } from '../types.js';
|
|
17
|
+
// ── Tool I/O Schema ──────────────────────────────────────────────────
|
|
18
|
+
export const RevokeShareLinkInputSchema = z.object({
|
|
19
|
+
share_id: IdSchema,
|
|
20
|
+
});
|
|
21
|
+
export const REVOKE_SHARE_LINK_DESCRIPTION = 'Revoke a single share link. Two-step: first call returns a preview ' +
|
|
22
|
+
'(with the link being revoked and its current state) plus a ' +
|
|
23
|
+
'confirmation_token; second call (with the token) executes the revoke. ' +
|
|
24
|
+
'Once revoked, the URL stops working.';
|
|
25
|
+
export class RevokeShareLinkTool extends MutatingTool {
|
|
26
|
+
name = 'revoke_share_link';
|
|
27
|
+
chunkSize = 1;
|
|
28
|
+
client;
|
|
29
|
+
constructor(deps) {
|
|
30
|
+
super(deps);
|
|
31
|
+
this.client = deps.client;
|
|
32
|
+
}
|
|
33
|
+
async plan(input) {
|
|
34
|
+
const id = String(input.share_id);
|
|
35
|
+
const snap = await this.client.getShareLink(id);
|
|
36
|
+
if (!snap.ok) {
|
|
37
|
+
throw new Error(`failed to read share link ${id}: ${snap.error.code} — ${snap.error.message}`);
|
|
38
|
+
}
|
|
39
|
+
const before = {
|
|
40
|
+
id: snap.snapshot.id,
|
|
41
|
+
title: snap.snapshot.title,
|
|
42
|
+
share_url: snap.snapshot.share_url,
|
|
43
|
+
expiration: snap.snapshot.expiration,
|
|
44
|
+
password_protected: snap.snapshot.password_protected,
|
|
45
|
+
revoked: false,
|
|
46
|
+
};
|
|
47
|
+
const after = { ...before, revoked: true };
|
|
48
|
+
const change = {
|
|
49
|
+
id,
|
|
50
|
+
operation: 'delete',
|
|
51
|
+
before,
|
|
52
|
+
after,
|
|
53
|
+
};
|
|
54
|
+
const riskFlags = [];
|
|
55
|
+
riskFlags.push({
|
|
56
|
+
code: 'irreversible',
|
|
57
|
+
severity: 'warning',
|
|
58
|
+
message: 'Revoke is irreversible: once executed, the share URL stops working immediately and recipients lose access.',
|
|
59
|
+
count: 1,
|
|
60
|
+
});
|
|
61
|
+
return { changes: [change], riskFlags };
|
|
62
|
+
}
|
|
63
|
+
apply = async (change) => {
|
|
64
|
+
const result = await this.client.revokeShareLink(change.id);
|
|
65
|
+
if (!result.ok) {
|
|
66
|
+
return { ok: false, error: result.error };
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
ok: true,
|
|
70
|
+
result: { share_id: change.id, revoked: true },
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function buildRevokeShareLinkTool(deps) {
|
|
75
|
+
return new RevokeShareLinkTool(deps);
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=revoke-share-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke-share-link.js","sourceRoot":"","sources":["../../src/tools/revoke-share-link.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { RawFacetCount } from '../../typesense.js';
|
|
2
|
+
import type { CompactAssetHit, SearchFacets, SearchNextStepHint, VerboseAssetHit } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Project raw Typesense facet counts into the structured `SearchFacets`
|
|
5
|
+
* block. Unknown facet fields are dropped on the floor — we only surface
|
|
6
|
+
* the ones the spec explicitly enumerates.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildSearchFacets(rawFacets: ReadonlyArray<RawFacetCount>, hits: ReadonlyArray<CompactAssetHit | VerboseAssetHit>, topN?: number): SearchFacets;
|
|
9
|
+
interface HintGeneratorContext {
|
|
10
|
+
found: number;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
/** Has at least one tag been returned? Used to avoid a hint when no tags exist. */
|
|
13
|
+
hasTags: boolean;
|
|
14
|
+
/** Number of hits where `tags` is empty/missing. */
|
|
15
|
+
untaggedCount: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate structured next-step hints for a `search_assets` response.
|
|
19
|
+
* Hints are emitted only when there is something *useful* to suggest —
|
|
20
|
+
* empty arrays mean "no obvious next step." Consumers can chain these
|
|
21
|
+
* into multi-tool LLM workflows without re-interpreting search results.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildAssetSearchNextSteps(ctx: HintGeneratorContext): SearchNextStepHint[];
|
|
24
|
+
/**
|
|
25
|
+
* Next-step hints for `search_collections` — currently lighter than the
|
|
26
|
+
* asset side because the dam_collections index has fewer signals to act
|
|
27
|
+
* on. Surfaces a single hint when results are empty so the LLM can fall
|
|
28
|
+
* back to `list_collections`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildCollectionSearchNextSteps(found: number): SearchNextStepHint[];
|
|
31
|
+
/** Count untagged hits in a verbose projection. Compact projection has no tags column. */
|
|
32
|
+
export declare function countUntagged(hits: ReadonlyArray<CompactAssetHit | VerboseAssetHit>): number;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=facets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facets.d.ts","sourceRoot":"","sources":["../../../src/tools/search/facets.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,eAAe,EAEf,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,EACvC,IAAI,EAAE,aAAa,CAAC,eAAe,GAAG,eAAe,CAAC,EACtD,IAAI,SAAK,GACR,YAAY,CAkCd;AAqCD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,oBAAoB,GACxB,kBAAkB,EAAE,CA8BtB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,MAAM,GACZ,kBAAkB,EAAE,CAWtB;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAC3B,IAAI,EAAE,aAAa,CAAC,eAAe,GAAG,eAAe,CAAC,GACrD,MAAM,CAUR"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// ── Facets + Next-step hints generator ───────────────────────────────
|
|
2
|
+
// Shapes the raw Typesense `facet_counts` array into the structured
|
|
3
|
+
// `SearchFacets` block declared in `./types.ts`, and produces a list of
|
|
4
|
+
// machine-readable `next_step_hints` based on what the search returned.
|
|
5
|
+
//
|
|
6
|
+
// Both generators are pure — given the same inputs they emit the same
|
|
7
|
+
// outputs, which makes them trivial to unit-test without touching
|
|
8
|
+
// Typesense.
|
|
9
|
+
/**
|
|
10
|
+
* Project raw Typesense facet counts into the structured `SearchFacets`
|
|
11
|
+
* block. Unknown facet fields are dropped on the floor — we only surface
|
|
12
|
+
* the ones the spec explicitly enumerates.
|
|
13
|
+
*/
|
|
14
|
+
export function buildSearchFacets(rawFacets, hits, topN = 10) {
|
|
15
|
+
const facets = {
|
|
16
|
+
tags: [],
|
|
17
|
+
file_type: [],
|
|
18
|
+
date_histogram: [],
|
|
19
|
+
score_distribution: [],
|
|
20
|
+
};
|
|
21
|
+
for (const f of rawFacets) {
|
|
22
|
+
const counts = f.counts.slice(0, topN).map((c) => ({
|
|
23
|
+
value: c.value,
|
|
24
|
+
count: c.count,
|
|
25
|
+
}));
|
|
26
|
+
if (f.field_name === 'tags')
|
|
27
|
+
facets.tags = counts;
|
|
28
|
+
else if (f.field_name === 'file_type')
|
|
29
|
+
facets.file_type = counts;
|
|
30
|
+
else if (f.field_name === 'modified_at') {
|
|
31
|
+
facets.date_histogram = bucketDateFacets(counts);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Score distribution — Typesense doesn't surface this as a facet, so we
|
|
35
|
+
// synthesise it from the hit-side (each hit's `_text_match` would need
|
|
36
|
+
// to be passed down for a true distribution). Keeping it empty here is
|
|
37
|
+
// intentional; richer scoring lives in the verbose-projection path
|
|
38
|
+
// when we hydrate via `view-detail`.
|
|
39
|
+
if (hits.length === 0) {
|
|
40
|
+
facets.score_distribution = [];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
facets.score_distribution = [
|
|
44
|
+
{ value: 'returned', count: hits.length },
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
return facets;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Bucket raw `modified_at` facet values (already strings of unix-seconds)
|
|
51
|
+
* into the four canonical buckets: 30d, 90d, 365d, older.
|
|
52
|
+
*/
|
|
53
|
+
function bucketDateFacets(counts) {
|
|
54
|
+
const now = Math.floor(Date.now() / 1000);
|
|
55
|
+
const day = 86_400;
|
|
56
|
+
const buckets = {
|
|
57
|
+
'30d': 0,
|
|
58
|
+
'90d': 0,
|
|
59
|
+
'365d': 0,
|
|
60
|
+
older: 0,
|
|
61
|
+
};
|
|
62
|
+
for (const c of counts) {
|
|
63
|
+
const ts = Number(c.value);
|
|
64
|
+
if (!Number.isFinite(ts)) {
|
|
65
|
+
buckets.older += c.count;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const ageDays = (now - ts) / day;
|
|
69
|
+
if (ageDays <= 30)
|
|
70
|
+
buckets['30d'] += c.count;
|
|
71
|
+
else if (ageDays <= 90)
|
|
72
|
+
buckets['90d'] += c.count;
|
|
73
|
+
else if (ageDays <= 365)
|
|
74
|
+
buckets['365d'] += c.count;
|
|
75
|
+
else
|
|
76
|
+
buckets.older += c.count;
|
|
77
|
+
}
|
|
78
|
+
return [
|
|
79
|
+
{ value: '30d', count: buckets['30d'] },
|
|
80
|
+
{ value: '90d', count: buckets['90d'] },
|
|
81
|
+
{ value: '365d', count: buckets['365d'] },
|
|
82
|
+
{ value: 'older', count: buckets.older },
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Generate structured next-step hints for a `search_assets` response.
|
|
87
|
+
* Hints are emitted only when there is something *useful* to suggest —
|
|
88
|
+
* empty arrays mean "no obvious next step." Consumers can chain these
|
|
89
|
+
* into multi-tool LLM workflows without re-interpreting search results.
|
|
90
|
+
*/
|
|
91
|
+
export function buildAssetSearchNextSteps(ctx) {
|
|
92
|
+
const hints = [];
|
|
93
|
+
if (ctx.untaggedCount > 0) {
|
|
94
|
+
hints.push({
|
|
95
|
+
tool: 'audit_tagging_hygiene',
|
|
96
|
+
reason_code: 'untagged_assets_found',
|
|
97
|
+
reason: `${ctx.untaggedCount} hit(s) have no tags — consider running the tagging-hygiene audit.`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (ctx.truncated) {
|
|
101
|
+
hints.push({
|
|
102
|
+
tool: 'search_assets',
|
|
103
|
+
reason_code: 'response_truncated',
|
|
104
|
+
reason: 'Result page was hard-capped to stay under the response budget. Use the returned next_cursor to continue.',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (ctx.found > 1000) {
|
|
108
|
+
hints.push({
|
|
109
|
+
tool: 'search_assets',
|
|
110
|
+
reason_code: 'large_result_set',
|
|
111
|
+
reason: 'Result set is large; consider narrowing with tag/file_type/date filters before bulk operations.',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return hints;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Next-step hints for `search_collections` — currently lighter than the
|
|
118
|
+
* asset side because the dam_collections index has fewer signals to act
|
|
119
|
+
* on. Surfaces a single hint when results are empty so the LLM can fall
|
|
120
|
+
* back to `list_collections`.
|
|
121
|
+
*/
|
|
122
|
+
export function buildCollectionSearchNextSteps(found) {
|
|
123
|
+
if (found === 0) {
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
tool: 'list_collections',
|
|
127
|
+
reason_code: 'empty_result',
|
|
128
|
+
reason: 'No matches found — list all collections in the workspace as a fallback.',
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
/** Count untagged hits in a verbose projection. Compact projection has no tags column. */
|
|
135
|
+
export function countUntagged(hits) {
|
|
136
|
+
let n = 0;
|
|
137
|
+
for (const h of hits) {
|
|
138
|
+
if (!('tags' in h) || h.tags === null || h.tags === undefined) {
|
|
139
|
+
n += 1;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (Array.isArray(h.tags) && h.tags.length === 0)
|
|
143
|
+
n += 1;
|
|
144
|
+
}
|
|
145
|
+
return n;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=facets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facets.js","sourceRoot":"","sources":["../../../src/tools/search/facets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SearchAssetFilters, Visibility } from './types.js';
|
|
2
|
+
/** Convert a `Visibility` enum value to the numeric Typesense column. */
|
|
3
|
+
export declare function visibilityToNumber(v: Visibility): 0 | 1;
|
|
4
|
+
/**
|
|
5
|
+
* Coerce a date bound (ISO-8601 string or unix-second integer) to a unix
|
|
6
|
+
* timestamp in seconds. Returns null if the input is unparseable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function toUnixSeconds(bound: number | string): number | null;
|
|
9
|
+
/**
|
|
10
|
+
* Build the `filter_by` clauses for the asset filters. Returns an array of
|
|
11
|
+
* clause strings (each already wrapped in parens where needed) — the
|
|
12
|
+
* caller joins them with ` && ` and prepends the workspace clause via the
|
|
13
|
+
* wrapper.
|
|
14
|
+
*
|
|
15
|
+
* Ordering and grammar match the Admin-Frontend
|
|
16
|
+
* `mixins/search-common-functions.js` builders. See
|
|
17
|
+
* `docs/typesense-filter-schema.md` for the full citation set.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildAssetFilterClauses(filters: SearchAssetFilters | undefined): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Escape a value for use inside a `filter_by` clause. Typesense supports
|
|
22
|
+
* backtick-quoted strings to handle special characters; for the asset
|
|
23
|
+
* filter surface (tag names, file types, IDs) we keep escaping minimal —
|
|
24
|
+
* if the value contains `,`, `]`, ``` ` ```, or whitespace we wrap in
|
|
25
|
+
* backticks. Plain identifiers pass through.
|
|
26
|
+
*/
|
|
27
|
+
export declare function escapeFilterValue(value: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Join filter clauses with ` && `. Empty array → empty string.
|
|
30
|
+
* Exposed for tests so they can validate the output as a plain string.
|
|
31
|
+
*/
|
|
32
|
+
export declare function joinFilterClauses(clauses: ReadonlyArray<string>): string;
|
|
33
|
+
//# sourceMappingURL=filter-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-builder.d.ts","sourceRoot":"","sources":["../../../src/tools/search/filter-builder.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEjE,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,GAAG,CAAC,CAGvD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CASnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACtC,MAAM,EAAE,CAsDV;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAExE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// ── Typesense filter_by builder ──────────────────────────────────────
|
|
2
|
+
// Translates the typed `SearchAssetFilters` envelope into the literal
|
|
3
|
+
// `filter_by` string Typesense expects. Clause grammar is documented in
|
|
4
|
+
// `docs/typesense-filter-schema.md`.
|
|
5
|
+
/** Convert a `Visibility` enum value to the numeric Typesense column. */
|
|
6
|
+
export function visibilityToNumber(v) {
|
|
7
|
+
if (v === 'public' || v === 0)
|
|
8
|
+
return 0;
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Coerce a date bound (ISO-8601 string or unix-second integer) to a unix
|
|
13
|
+
* timestamp in seconds. Returns null if the input is unparseable.
|
|
14
|
+
*/
|
|
15
|
+
export function toUnixSeconds(bound) {
|
|
16
|
+
if (typeof bound === 'number') {
|
|
17
|
+
if (!Number.isFinite(bound) || bound < 0)
|
|
18
|
+
return null;
|
|
19
|
+
return Math.floor(bound);
|
|
20
|
+
}
|
|
21
|
+
// ISO-8601 or any Date.parse-recognised string
|
|
22
|
+
const ms = Date.parse(bound);
|
|
23
|
+
if (Number.isNaN(ms))
|
|
24
|
+
return null;
|
|
25
|
+
return Math.floor(ms / 1000);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build the `filter_by` clauses for the asset filters. Returns an array of
|
|
29
|
+
* clause strings (each already wrapped in parens where needed) — the
|
|
30
|
+
* caller joins them with ` && ` and prepends the workspace clause via the
|
|
31
|
+
* wrapper.
|
|
32
|
+
*
|
|
33
|
+
* Ordering and grammar match the Admin-Frontend
|
|
34
|
+
* `mixins/search-common-functions.js` builders. See
|
|
35
|
+
* `docs/typesense-filter-schema.md` for the full citation set.
|
|
36
|
+
*/
|
|
37
|
+
export function buildAssetFilterClauses(filters) {
|
|
38
|
+
if (filters === undefined)
|
|
39
|
+
return [];
|
|
40
|
+
const clauses = [];
|
|
41
|
+
if (filters.tags !== undefined && filters.tags.length > 0) {
|
|
42
|
+
// Use the `tags:=[a,b,c]` array shorthand which Typesense interprets
|
|
43
|
+
// as include-any-of. Avoids the backslash-escape used by the frontend
|
|
44
|
+
// for exact match — semantically equivalent for non-special tag names.
|
|
45
|
+
const list = filters.tags
|
|
46
|
+
.map((t) => escapeFilterValue(t))
|
|
47
|
+
.join(',');
|
|
48
|
+
clauses.push(`tags:=[${list}]`);
|
|
49
|
+
}
|
|
50
|
+
if (filters.file_type !== undefined && filters.file_type.length > 0) {
|
|
51
|
+
const list = filters.file_type
|
|
52
|
+
.map((t) => escapeFilterValue(t))
|
|
53
|
+
.join(',');
|
|
54
|
+
clauses.push(`file_type:=[${list}]`);
|
|
55
|
+
}
|
|
56
|
+
if (filters.visibility !== undefined) {
|
|
57
|
+
clauses.push(`visibility:=${visibilityToNumber(filters.visibility)}`);
|
|
58
|
+
}
|
|
59
|
+
if (filters.collection_ids !== undefined && filters.collection_ids.length > 0) {
|
|
60
|
+
const list = filters.collection_ids
|
|
61
|
+
.map((id) => escapeFilterValue(String(id)))
|
|
62
|
+
.join(',');
|
|
63
|
+
clauses.push(`collection_ids:=[${list}]`);
|
|
64
|
+
}
|
|
65
|
+
if (filters.category_id !== undefined) {
|
|
66
|
+
clauses.push(`category_id:=${escapeFilterValue(String(filters.category_id))}`);
|
|
67
|
+
}
|
|
68
|
+
if (filters.created_after !== undefined) {
|
|
69
|
+
const ts = toUnixSeconds(filters.created_after);
|
|
70
|
+
if (ts !== null)
|
|
71
|
+
clauses.push(`created_at:>=${ts}`);
|
|
72
|
+
}
|
|
73
|
+
if (filters.created_before !== undefined) {
|
|
74
|
+
const ts = toUnixSeconds(filters.created_before);
|
|
75
|
+
if (ts !== null)
|
|
76
|
+
clauses.push(`created_at:<=${ts}`);
|
|
77
|
+
}
|
|
78
|
+
if (filters.modified_after !== undefined) {
|
|
79
|
+
const ts = toUnixSeconds(filters.modified_after);
|
|
80
|
+
if (ts !== null)
|
|
81
|
+
clauses.push(`modified_at:>=${ts}`);
|
|
82
|
+
}
|
|
83
|
+
if (filters.modified_before !== undefined) {
|
|
84
|
+
const ts = toUnixSeconds(filters.modified_before);
|
|
85
|
+
if (ts !== null)
|
|
86
|
+
clauses.push(`modified_at:<=${ts}`);
|
|
87
|
+
}
|
|
88
|
+
return clauses;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Escape a value for use inside a `filter_by` clause. Typesense supports
|
|
92
|
+
* backtick-quoted strings to handle special characters; for the asset
|
|
93
|
+
* filter surface (tag names, file types, IDs) we keep escaping minimal —
|
|
94
|
+
* if the value contains `,`, `]`, ``` ` ```, or whitespace we wrap in
|
|
95
|
+
* backticks. Plain identifiers pass through.
|
|
96
|
+
*/
|
|
97
|
+
export function escapeFilterValue(value) {
|
|
98
|
+
if (/[\s,\]`\\]/.test(value)) {
|
|
99
|
+
const escaped = value.replace(/`/g, '\\`');
|
|
100
|
+
return '`' + escaped + '`';
|
|
101
|
+
}
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Join filter clauses with ` && `. Empty array → empty string.
|
|
106
|
+
* Exposed for tests so they can validate the output as a plain string.
|
|
107
|
+
*/
|
|
108
|
+
export function joinFilterClauses(clauses) {
|
|
109
|
+
return clauses.filter((c) => c.length > 0).join(' && ');
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=filter-builder.js.map
|