@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,13 @@
|
|
|
1
|
+
export type { ChangeRecord, DryRunPlan, DryRunPreview, DryRunResponse, ExecuteResult, ItemLedgerEntry, PreviewRow, ProgressEvent, RiskFlag, RiskSeverity, } from './types.js';
|
|
2
|
+
export { ChangeRecordSchema, DryRunPreviewSchema, ExecuteResultSchema, ItemLedgerEntrySchema, PreviewRowSchema, ProgressEventSchema, RiskFlagSchema, RiskSeveritySchema, dryRunPlanSchema, } from './types.js';
|
|
3
|
+
export { renderDiff, DEFAULT_MAX_PREVIEW_ROWS } from './diff-renderer.js';
|
|
4
|
+
export type { DiffRow, RenderDiffOptions, RenderDiffResult } from './diff-renderer.js';
|
|
5
|
+
export { buildSummary, computeAggregates, detectOverwriteRisk } from './summary.js';
|
|
6
|
+
export type { BuildSummaryArgs, SummaryResult, DetectOverwriteRiskOptions, OverwriteRiskResult } from './summary.js';
|
|
7
|
+
export { batchExecute, DEFAULT_CHUNK_SIZE, MAX_CHUNK_SIZE, } from './batch-executor.js';
|
|
8
|
+
export type { ApplyFn, ApplyResult, BatchExecuteOptions, BatchExecuteResult, } from './batch-executor.js';
|
|
9
|
+
export { withDryRun } from './with-dry-run.js';
|
|
10
|
+
export type { DryRunHandler, DryRunHandlerInput, PlanResult, WithDryRunConfig, } from './with-dry-run.js';
|
|
11
|
+
export { MutatingTool } from './mutating-tool.js';
|
|
12
|
+
export type { MutatingToolDeps } from './mutating-tool.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/conventions/dry-run/index.ts"],"names":[],"mappings":"AAIA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,UAAU,EACV,aAAa,EACb,QAAQ,EACR,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAErH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,OAAO,EACP,WAAW,EACX,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// ── Dry-Run Framework — Public Barrel ────────────────────────────────
|
|
2
|
+
// Single import surface for downstream tools. Anything not exported here is
|
|
3
|
+
// considered internal and may change without a major version bump.
|
|
4
|
+
export { ChangeRecordSchema, DryRunPreviewSchema, ExecuteResultSchema, ItemLedgerEntrySchema, PreviewRowSchema, ProgressEventSchema, RiskFlagSchema, RiskSeveritySchema, dryRunPlanSchema, } from './types.js';
|
|
5
|
+
export { renderDiff, DEFAULT_MAX_PREVIEW_ROWS } from './diff-renderer.js';
|
|
6
|
+
export { buildSummary, computeAggregates, detectOverwriteRisk } from './summary.js';
|
|
7
|
+
export { batchExecute, DEFAULT_CHUNK_SIZE, MAX_CHUNK_SIZE, } from './batch-executor.js';
|
|
8
|
+
export { withDryRun } from './with-dry-run.js';
|
|
9
|
+
export { MutatingTool } from './mutating-tool.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/conventions/dry-run/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,mEAAmE;AAcnE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGpF,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { EphemeralStateStore } from '../state-store.js';
|
|
2
|
+
import type { ApplyFn } from './batch-executor.js';
|
|
3
|
+
import type { PlanResult, DryRunHandler } from './with-dry-run.js';
|
|
4
|
+
import type { DryRunPlan } from './types.js';
|
|
5
|
+
export interface MutatingToolDeps<TInput> {
|
|
6
|
+
/** HMAC secret used to sign confirmation tokens. */
|
|
7
|
+
secret: string;
|
|
8
|
+
/** Ephemeral plan store (in-memory for stdio, Redis for HTTP). */
|
|
9
|
+
store: EphemeralStateStore<DryRunPlan<TInput>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Base class for every mutating MCP tool. Concrete subclasses provide the
|
|
13
|
+
* tool name and implement `plan()` (pure) plus `apply()` (per-item mutator).
|
|
14
|
+
* The framework guarantees:
|
|
15
|
+
* 1. No mutation can happen without a fresh, signed confirmation token.
|
|
16
|
+
* 2. Tokens are single-use (atomic get-and-delete on execute).
|
|
17
|
+
* 3. Failed items surface as `McpToolError` entries in the result ledger.
|
|
18
|
+
*
|
|
19
|
+
* To enforce that NO write code path bypasses the wrapper, this class is the
|
|
20
|
+
* only public way to construct a mutating handler — the type system makes
|
|
21
|
+
* `withDryRun()` direct usage discouraged via the `@internal` JSDoc marker
|
|
22
|
+
* and discouraged-but-not-blocked at the public surface; subclassing is the
|
|
23
|
+
* canonical pattern.
|
|
24
|
+
*/
|
|
25
|
+
export declare abstract class MutatingTool<TInput, TItemResult = unknown> {
|
|
26
|
+
protected readonly deps: MutatingToolDeps<TInput>;
|
|
27
|
+
/** Stable tool identifier (snake_case verb_noun). */
|
|
28
|
+
abstract readonly name: string;
|
|
29
|
+
/** Optional batch chunk size override. */
|
|
30
|
+
protected readonly chunkSize?: number;
|
|
31
|
+
/** Optional preview row cap override. */
|
|
32
|
+
protected readonly maxPreviewRows?: number;
|
|
33
|
+
/** Optional confirmation TTL override. */
|
|
34
|
+
protected readonly confirmationTtlMs?: number;
|
|
35
|
+
protected constructor(deps: MutatingToolDeps<TInput>);
|
|
36
|
+
/**
|
|
37
|
+
* Pure plan function. Must NOT perform writes. Returns the change list,
|
|
38
|
+
* optional risk flags, and optional tool-specific aggregates.
|
|
39
|
+
*/
|
|
40
|
+
protected abstract plan(input: TInput): Promise<PlanResult> | PlanResult;
|
|
41
|
+
/**
|
|
42
|
+
* Per-item executor invoked by the batch runner during the execute phase.
|
|
43
|
+
* Receives a single `ChangeRecord` and returns success or a typed error.
|
|
44
|
+
*/
|
|
45
|
+
protected abstract apply: ApplyFn<TItemResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Build the dry-run-enforced handler. This is the ONLY way to obtain a
|
|
48
|
+
* callable for a mutating tool — it is final on purpose.
|
|
49
|
+
*/
|
|
50
|
+
buildHandler(): DryRunHandler<TInput, TItemResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Convenience adapter that stamps the response with `schema_version` and
|
|
53
|
+
* wraps the result in the standard `structuredContent` shape used by every
|
|
54
|
+
* tool in this server.
|
|
55
|
+
*/
|
|
56
|
+
buildMcpHandler(): (args: {
|
|
57
|
+
input: TInput;
|
|
58
|
+
confirmation_token?: string;
|
|
59
|
+
}) => Promise<{
|
|
60
|
+
structuredContent: Record<string, unknown>;
|
|
61
|
+
isError?: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=mutating-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutating-tool.d.ts","sourceRoot":"","sources":["../../../src/conventions/dry-run/mutating-tool.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,gBAAgB,CAAC,MAAM;IACtC,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;;;GAaG;AACH,8BAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAWxC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC;IAVvE,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,0CAA0C;IAC1C,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACtC,yCAAyC;IACzC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAC3C,0CAA0C;IAC1C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE9C,SAAS,aAAgC,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC;IAEvE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU;IAExE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/C;;;OAGG;IACI,YAAY,IAAI,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC;IAgBzD;;;;OAIG;IACI,eAAe,IAAI,CACxB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,KACjD,OAAO,CAAC;QAAE,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CA0BhF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// ── Abstract MutatingTool Base Class ─────────────────────────────────
|
|
2
|
+
// The single sanctioned path for any tool that performs writes. Subclasses
|
|
3
|
+
// implement `plan()` and `apply()`; the base class is the only thing that
|
|
4
|
+
// constructs a handler, and the only handler it builds routes through
|
|
5
|
+
// `withDryRun`. There is no public escape hatch: the handler factory is
|
|
6
|
+
// `final` (TypeScript enforces this via the abstract methods + private
|
|
7
|
+
// constructor wrapper).
|
|
8
|
+
import { addSchemaVersion } from '../schema-version.js';
|
|
9
|
+
import { withDryRun } from './with-dry-run.js';
|
|
10
|
+
/**
|
|
11
|
+
* Base class for every mutating MCP tool. Concrete subclasses provide the
|
|
12
|
+
* tool name and implement `plan()` (pure) plus `apply()` (per-item mutator).
|
|
13
|
+
* The framework guarantees:
|
|
14
|
+
* 1. No mutation can happen without a fresh, signed confirmation token.
|
|
15
|
+
* 2. Tokens are single-use (atomic get-and-delete on execute).
|
|
16
|
+
* 3. Failed items surface as `McpToolError` entries in the result ledger.
|
|
17
|
+
*
|
|
18
|
+
* To enforce that NO write code path bypasses the wrapper, this class is the
|
|
19
|
+
* only public way to construct a mutating handler — the type system makes
|
|
20
|
+
* `withDryRun()` direct usage discouraged via the `@internal` JSDoc marker
|
|
21
|
+
* and discouraged-but-not-blocked at the public surface; subclassing is the
|
|
22
|
+
* canonical pattern.
|
|
23
|
+
*/
|
|
24
|
+
export class MutatingTool {
|
|
25
|
+
deps;
|
|
26
|
+
/** Optional batch chunk size override. */
|
|
27
|
+
chunkSize;
|
|
28
|
+
/** Optional preview row cap override. */
|
|
29
|
+
maxPreviewRows;
|
|
30
|
+
/** Optional confirmation TTL override. */
|
|
31
|
+
confirmationTtlMs;
|
|
32
|
+
constructor(deps) {
|
|
33
|
+
this.deps = deps;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the dry-run-enforced handler. This is the ONLY way to obtain a
|
|
37
|
+
* callable for a mutating tool — it is final on purpose.
|
|
38
|
+
*/
|
|
39
|
+
buildHandler() {
|
|
40
|
+
const config = {
|
|
41
|
+
tool: this.name,
|
|
42
|
+
secret: this.deps.secret,
|
|
43
|
+
store: this.deps.store,
|
|
44
|
+
plan: (input) => this.plan(input),
|
|
45
|
+
apply: (change) => this.apply(change),
|
|
46
|
+
};
|
|
47
|
+
if (this.chunkSize !== undefined)
|
|
48
|
+
config.chunkSize = this.chunkSize;
|
|
49
|
+
if (this.maxPreviewRows !== undefined)
|
|
50
|
+
config.maxPreviewRows = this.maxPreviewRows;
|
|
51
|
+
if (this.confirmationTtlMs !== undefined) {
|
|
52
|
+
config.confirmationTtlMs = this.confirmationTtlMs;
|
|
53
|
+
}
|
|
54
|
+
return withDryRun(config);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convenience adapter that stamps the response with `schema_version` and
|
|
58
|
+
* wraps the result in the standard `structuredContent` shape used by every
|
|
59
|
+
* tool in this server.
|
|
60
|
+
*/
|
|
61
|
+
buildMcpHandler() {
|
|
62
|
+
const handler = this.buildHandler();
|
|
63
|
+
return async (args) => {
|
|
64
|
+
const result = await handler(args);
|
|
65
|
+
if (!result.ok) {
|
|
66
|
+
return {
|
|
67
|
+
isError: true,
|
|
68
|
+
structuredContent: addSchemaVersion({
|
|
69
|
+
error: result.error,
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (result.phase === 'plan') {
|
|
74
|
+
return {
|
|
75
|
+
structuredContent: addSchemaVersion({
|
|
76
|
+
...result.response,
|
|
77
|
+
}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
structuredContent: addSchemaVersion({
|
|
82
|
+
...result.response,
|
|
83
|
+
}),
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=mutating-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutating-tool.js","sourceRoot":"","sources":["../../../src/conventions/dry-run/mutating-tool.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,wBAAwB;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAIxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAU/C;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAgB,YAAY;IAWS;IAPzC,0CAA0C;IACvB,SAAS,CAAU;IACtC,yCAAyC;IACtB,cAAc,CAAU;IAC3C,0CAA0C;IACvB,iBAAiB,CAAU;IAE9C,YAAyC,IAA8B;QAA9B,SAAI,GAAJ,IAAI,CAA0B;IAAG,CAAC;IAc3E;;;OAGG;IACI,YAAY;QACjB,MAAM,MAAM,GAA0D;YACpE,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YACxB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;YACtB,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;SACtC,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACpE,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS;YAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QACnF,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACpD,CAAC;QACD,OAAO,UAAU,CAAsB,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACI,eAAe;QAGpB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;YACpB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,iBAAiB,EAAE,gBAAgB,CAAC;wBAClC,KAAK,EAAE,MAAM,CAAC,KAAK;qBACpB,CAAC;iBACH,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;gBAC5B,OAAO;oBACL,iBAAiB,EAAE,gBAAgB,CAAC;wBAClC,GAAG,MAAM,CAAC,QAAQ;qBACnB,CAAC;iBACH,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,iBAAiB,EAAE,gBAAgB,CAAC;oBAClC,GAAG,MAAM,CAAC,QAAQ;iBACnB,CAAC;aACH,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { ChangeRecord, RiskFlag, RiskSeverity } from './types.js';
|
|
2
|
+
export interface BuildSummaryArgs {
|
|
3
|
+
tool: string;
|
|
4
|
+
changes: ChangeRecord[];
|
|
5
|
+
riskFlags: ReadonlyArray<RiskFlag>;
|
|
6
|
+
aggregates: Record<string, number>;
|
|
7
|
+
}
|
|
8
|
+
export interface SummaryResult {
|
|
9
|
+
summary: string;
|
|
10
|
+
aggregates: Record<string, number>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compute aggregate counts from a change list. Always returns the keys
|
|
14
|
+
* `total`, `creates`, `updates`, `deletes` so callers get a stable shape.
|
|
15
|
+
* Tool-specific aggregates can be merged on top via `extra`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeAggregates(changes: ChangeRecord[], extra?: Record<string, number>): Record<string, number>;
|
|
18
|
+
/**
|
|
19
|
+
* Build the deterministic summary string. Format:
|
|
20
|
+
*
|
|
21
|
+
* `<tool>: will <verb> N records (C creates, U updates, D deletes). [risk: ...]`
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildSummary(args: BuildSummaryArgs): SummaryResult;
|
|
24
|
+
export interface DetectOverwriteRiskOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Severity to use for the surfaced flag when overwrites are detected.
|
|
27
|
+
* Defaults to `'warning'`; tools that consider any overwrite catastrophic
|
|
28
|
+
* (e.g. `bulk_set_tags`) can pass `'critical'`.
|
|
29
|
+
*/
|
|
30
|
+
severity?: RiskSeverity;
|
|
31
|
+
/** Override flag code. Defaults to `'overwrite_existing_values'`. */
|
|
32
|
+
code?: string;
|
|
33
|
+
/** Override flag message. The framework appends `(N)` count automatically. */
|
|
34
|
+
message?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Only consider these field names. When omitted, every key on `before`/
|
|
37
|
+
* `after` is examined. Use this to scope the check to a single field
|
|
38
|
+
* (e.g. `['tags']`) on a record that carries other side-info.
|
|
39
|
+
*/
|
|
40
|
+
fields?: ReadonlyArray<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Predicate used to decide whether a value qualifies as "existing" (and
|
|
43
|
+
* therefore overwriteable). Defaults to: not `null`, not `undefined`, and
|
|
44
|
+
* not the empty string. Override for richer types (e.g. arrays).
|
|
45
|
+
*/
|
|
46
|
+
isExistingValue?: (value: unknown) => boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface OverwriteRiskResult {
|
|
49
|
+
/** Number of distinct change records where at least one field is being overwritten. */
|
|
50
|
+
records: number;
|
|
51
|
+
/** Total number of (record, field) pairs being overwritten. */
|
|
52
|
+
fields: number;
|
|
53
|
+
/** Risk flag suitable for surfacing on the preview, or null when nothing is at risk. */
|
|
54
|
+
flag: RiskFlag | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Walk a list of change records and report how many distinct records would
|
|
58
|
+
* have a non-empty existing value clobbered by the proposed `after` value.
|
|
59
|
+
*
|
|
60
|
+
* Deterministic: runs entirely off the plan, no I/O. Designed to be called
|
|
61
|
+
* from a tool's `plan()` so the resulting flag is included in the preview's
|
|
62
|
+
* `risk_flags` array via the standard pipeline — no fork of summary.ts
|
|
63
|
+
* required.
|
|
64
|
+
*/
|
|
65
|
+
export declare function detectOverwriteRisk(changes: ReadonlyArray<ChangeRecord>, opts?: DetectOverwriteRiskOptions): OverwriteRiskResult;
|
|
66
|
+
//# sourceMappingURL=summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../src/conventions/dry-run/summary.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EAAE,EACvB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,aAAa,CAiClE;AA+BD,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,wFAAwF;IACxF,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,EACpC,IAAI,GAAE,0BAA+B,GACpC,mBAAmB,CA4CrB"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// ── Deterministic Human Summary Generator ────────────────────────────
|
|
2
|
+
// Renders a fixed-template human-readable summary from plan aggregates and
|
|
3
|
+
// risk flags. Templating is purely string interpolation — no LLM call. The
|
|
4
|
+
// same plan always produces the same summary string.
|
|
5
|
+
//
|
|
6
|
+
// Also exports `detectOverwriteRisk()` — a generic, deterministic walk over
|
|
7
|
+
// change records that surfaces aggregate overwrite-risk flags ("this will
|
|
8
|
+
// overwrite existing values on N assets / M fields") so individual tools
|
|
9
|
+
// don't have to reinvent the analysis. Runs purely on the plan; no I/O.
|
|
10
|
+
/**
|
|
11
|
+
* Compute aggregate counts from a change list. Always returns the keys
|
|
12
|
+
* `total`, `creates`, `updates`, `deletes` so callers get a stable shape.
|
|
13
|
+
* Tool-specific aggregates can be merged on top via `extra`.
|
|
14
|
+
*/
|
|
15
|
+
export function computeAggregates(changes, extra = {}) {
|
|
16
|
+
let creates = 0;
|
|
17
|
+
let updates = 0;
|
|
18
|
+
let deletes = 0;
|
|
19
|
+
for (const change of changes) {
|
|
20
|
+
if (change.operation === 'create')
|
|
21
|
+
creates++;
|
|
22
|
+
else if (change.operation === 'update')
|
|
23
|
+
updates++;
|
|
24
|
+
else if (change.operation === 'delete')
|
|
25
|
+
deletes++;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
total: changes.length,
|
|
29
|
+
creates,
|
|
30
|
+
updates,
|
|
31
|
+
deletes,
|
|
32
|
+
...extra,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the deterministic summary string. Format:
|
|
37
|
+
*
|
|
38
|
+
* `<tool>: will <verb> N records (C creates, U updates, D deletes). [risk: ...]`
|
|
39
|
+
*/
|
|
40
|
+
export function buildSummary(args) {
|
|
41
|
+
const { tool, changes, riskFlags, aggregates } = args;
|
|
42
|
+
const total = aggregates['total'] ?? changes.length;
|
|
43
|
+
const creates = aggregates['creates'] ?? 0;
|
|
44
|
+
const updates = aggregates['updates'] ?? 0;
|
|
45
|
+
const deletes = aggregates['deletes'] ?? 0;
|
|
46
|
+
const verb = pickVerb({ creates, updates, deletes });
|
|
47
|
+
const breakdown = [
|
|
48
|
+
`${creates} create${creates === 1 ? '' : 's'}`,
|
|
49
|
+
`${updates} update${updates === 1 ? '' : 's'}`,
|
|
50
|
+
`${deletes} delete${deletes === 1 ? '' : 's'}`,
|
|
51
|
+
].join(', ');
|
|
52
|
+
const base = `${tool}: will ${verb} ${total} record${total === 1 ? '' : 's'} (${breakdown}).`;
|
|
53
|
+
const sortedFlags = [...riskFlags].sort(severityCompare);
|
|
54
|
+
if (sortedFlags.length === 0) {
|
|
55
|
+
return { summary: base, aggregates };
|
|
56
|
+
}
|
|
57
|
+
const riskSegment = sortedFlags
|
|
58
|
+
.map((flag) => {
|
|
59
|
+
const countSuffix = typeof flag.count === 'number' ? ` (${flag.count})` : '';
|
|
60
|
+
return `[${flag.severity}] ${flag.message}${countSuffix}`;
|
|
61
|
+
})
|
|
62
|
+
.join('; ');
|
|
63
|
+
return {
|
|
64
|
+
summary: `${base} ${riskSegment}`,
|
|
65
|
+
aggregates,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function pickVerb(args) {
|
|
69
|
+
const { creates, updates, deletes } = args;
|
|
70
|
+
const nonZero = [
|
|
71
|
+
creates > 0 ? 'create' : null,
|
|
72
|
+
updates > 0 ? 'update' : null,
|
|
73
|
+
deletes > 0 ? 'delete' : null,
|
|
74
|
+
].filter((v) => v !== null);
|
|
75
|
+
if (nonZero.length === 0)
|
|
76
|
+
return 'modify';
|
|
77
|
+
if (nonZero.length === 1) {
|
|
78
|
+
const [verb] = nonZero;
|
|
79
|
+
return verb ?? 'modify';
|
|
80
|
+
}
|
|
81
|
+
return 'modify';
|
|
82
|
+
}
|
|
83
|
+
const SEVERITY_ORDER = {
|
|
84
|
+
critical: 0,
|
|
85
|
+
warning: 1,
|
|
86
|
+
info: 2,
|
|
87
|
+
};
|
|
88
|
+
function severityCompare(a, b) {
|
|
89
|
+
const sevDiff = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity];
|
|
90
|
+
if (sevDiff !== 0)
|
|
91
|
+
return sevDiff;
|
|
92
|
+
return a.code.localeCompare(b.code);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Walk a list of change records and report how many distinct records would
|
|
96
|
+
* have a non-empty existing value clobbered by the proposed `after` value.
|
|
97
|
+
*
|
|
98
|
+
* Deterministic: runs entirely off the plan, no I/O. Designed to be called
|
|
99
|
+
* from a tool's `plan()` so the resulting flag is included in the preview's
|
|
100
|
+
* `risk_flags` array via the standard pipeline — no fork of summary.ts
|
|
101
|
+
* required.
|
|
102
|
+
*/
|
|
103
|
+
export function detectOverwriteRisk(changes, opts = {}) {
|
|
104
|
+
const isExisting = opts.isExistingValue ?? defaultIsExistingValue;
|
|
105
|
+
const fieldFilter = opts.fields !== undefined ? new Set(opts.fields) : null;
|
|
106
|
+
let records = 0;
|
|
107
|
+
let fields = 0;
|
|
108
|
+
for (const change of changes) {
|
|
109
|
+
if (change.operation !== 'update')
|
|
110
|
+
continue;
|
|
111
|
+
const before = change.before ?? {};
|
|
112
|
+
const after = change.after ?? {};
|
|
113
|
+
const keys = new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
114
|
+
let recordHasOverwrite = false;
|
|
115
|
+
for (const key of keys) {
|
|
116
|
+
if (fieldFilter !== null && !fieldFilter.has(key))
|
|
117
|
+
continue;
|
|
118
|
+
const beforeVal = before[key];
|
|
119
|
+
const afterVal = after[key];
|
|
120
|
+
if (!isExisting(beforeVal))
|
|
121
|
+
continue;
|
|
122
|
+
if (deepEqualValue(beforeVal, afterVal))
|
|
123
|
+
continue;
|
|
124
|
+
// For the "overwrite" semantic, we only count when the after value
|
|
125
|
+
// is materially different and the before value was non-empty.
|
|
126
|
+
fields++;
|
|
127
|
+
recordHasOverwrite = true;
|
|
128
|
+
}
|
|
129
|
+
if (recordHasOverwrite)
|
|
130
|
+
records++;
|
|
131
|
+
}
|
|
132
|
+
if (records === 0) {
|
|
133
|
+
return { records: 0, fields: 0, flag: null };
|
|
134
|
+
}
|
|
135
|
+
const severity = opts.severity ?? 'warning';
|
|
136
|
+
const code = opts.code ?? 'overwrite_existing_values';
|
|
137
|
+
const message = opts.message ??
|
|
138
|
+
`will overwrite existing values on ${records} asset${records === 1 ? '' : 's'} (${fields} field${fields === 1 ? '' : 's'})`;
|
|
139
|
+
return {
|
|
140
|
+
records,
|
|
141
|
+
fields,
|
|
142
|
+
flag: { code, severity, message, count: records },
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function defaultIsExistingValue(value) {
|
|
146
|
+
if (value === null || value === undefined)
|
|
147
|
+
return false;
|
|
148
|
+
if (typeof value === 'string')
|
|
149
|
+
return value !== '';
|
|
150
|
+
if (Array.isArray(value))
|
|
151
|
+
return value.length > 0;
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
function deepEqualValue(a, b) {
|
|
155
|
+
if (a === b)
|
|
156
|
+
return true;
|
|
157
|
+
if (a === null || b === null)
|
|
158
|
+
return false;
|
|
159
|
+
if (typeof a !== typeof b)
|
|
160
|
+
return false;
|
|
161
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
162
|
+
if (a.length !== b.length)
|
|
163
|
+
return false;
|
|
164
|
+
for (let i = 0; i < a.length; i++) {
|
|
165
|
+
if (!deepEqualValue(a[i], b[i]))
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
if (typeof a === 'object' && typeof b === 'object') {
|
|
171
|
+
const ao = a;
|
|
172
|
+
const bo = b;
|
|
173
|
+
const ak = Object.keys(ao);
|
|
174
|
+
const bk = Object.keys(bo);
|
|
175
|
+
if (ak.length !== bk.length)
|
|
176
|
+
return false;
|
|
177
|
+
for (const key of ak) {
|
|
178
|
+
if (!deepEqualValue(ao[key], bo[key]))
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/conventions/dry-run/summary.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2EAA2E;AAC3E,2EAA2E;AAC3E,qDAAqD;AACrD,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,yEAAyE;AACzE,wEAAwE;AAgBxE;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAuB,EACvB,QAAgC,EAAE;IAElC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;aACxC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;aAC7C,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;IACpD,CAAC;IACD,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,OAAO;QACP,OAAO;QACP,OAAO;QACP,GAAG,KAAK;KACT,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAsB;IACjD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC;IACpD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG;QAChB,GAAG,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;QAC9C,GAAG,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;QAC9C,GAAG,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE;KAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,IAAI,GAAG,GAAG,IAAI,UAAU,IAAI,IAAI,KAAK,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC;IAE9F,MAAM,WAAW,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACzD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,WAAW,GAAG,WAAW;SAC5B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;IAC5D,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;QACL,OAAO,EAAE,GAAG,IAAI,IAAI,WAAW,EAAE;QACjC,UAAU;KACX,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAA2D;IAC3E,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG;QACd,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;QAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;QAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;KAC9B,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACzC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;QACvB,OAAO,IAAI,IAAI,QAAQ,CAAC;IAC1B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,cAAc,GAAyC;IAC3D,QAAQ,EAAE,CAAC;IACX,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,CAAC;CACR,CAAC;AAEF,SAAS,eAAe,CAAC,CAAW,EAAE,CAAW;IAC/C,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAClC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAsCD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAoC,EACpC,OAAmC,EAAE;IAErC,MAAM,UAAU,GACd,IAAI,CAAC,eAAe,IAAI,sBAAsB,CAAC;IACjD,MAAM,WAAW,GACf,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE1D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ;YAAE,SAAS;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9E,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,SAAS;YACrC,IAAI,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC;gBAAE,SAAS;YAClD,mEAAmE;YACnE,8DAA8D;YAC9D,MAAM,EAAE,CAAC;YACT,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,kBAAkB;YAAE,OAAO,EAAE,CAAC;IACpC,CAAC;IAED,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,2BAA2B,CAAC;IACtD,MAAM,OAAO,GACX,IAAI,CAAC,OAAO;QACZ,qCAAqC,OAAO,SAAS,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAE9H,OAAO;QACL,OAAO;QACP,MAAM;QACN,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;KAClD,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,KAAK,EAAE,CAAC;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,CAAU,EAAE,CAAU;IAC5C,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,CAA4B,CAAC;QACxC,MAAM,EAAE,GAAG,CAA4B,CAAC;QACxC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC;YACrB,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|