Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ https://github.com/user-attachments/assets/8b1b8ef2-9fba-4951-bc9a-beaed4f6aff6
- [GeoJSON Preview tool (Beta)](#geojson-preview-tool-beta)
- [Coordinate Conversion tool](#coordinate-conversion-tool)
- [Bounding Box tool](#bounding-box-tool)
- [compare_styles_tool](#compare_styles_tool)
- [Style Optimization tool](#style-optimization-tool)
- [Resources](#resources)
- [Observability \& Tracing](#observability--tracing)
Expand Down Expand Up @@ -624,6 +625,53 @@ An array of four numbers representing the bounding box: `[minX, minY, maxX, maxY
- "Calculate the bounding box of this GeoJSON file" (then upload a .geojson file)
- "What's the bounding box for the coordinates in the uploaded parks.geojson file?"

#### compare_styles_tool

Compares two Mapbox styles and reports structural differences, including changes to layers, sources, and properties. This offline comparison tool performs deep object comparison without requiring API access.

**Parameters:**

- `styleA` (string or object, required): First Mapbox style to compare (JSON string or style object)
- `styleB` (string or object, required): Second Mapbox style to compare (JSON string or style object)
- `ignoreMetadata` (boolean, optional): If true, ignores metadata fields (id, owner, created, modified, draft, visibility) when comparing

**Comparison features:**

- Deep recursive comparison of nested structures
- Layer comparison by ID (not array position)
- Detailed diff reporting with JSON paths
- Identifies additions, removals, and modifications
- Optional metadata filtering

**Returns:**

```json
{
"identical": false,
"differences": [
{
"path": "layers.water.paint.fill-color",
"type": "modified",
"valueA": "#a0c8f0",
"valueB": "#b0d0ff",
"description": "Modified property at layers.water.paint.fill-color"
}
],
"summary": {
"totalDifferences": 1,
"added": 0,
"removed": 0,
"modified": 1
}
}
```

**Example prompts:**

- "Compare these two Mapbox styles and show me the differences"
- "What changed between my old style and new style?"
- "Compare styles ignoring metadata fields"

#### Style Optimization tool

Optimizes Mapbox styles by removing redundancies, simplifying expressions, and reducing file size.
Expand Down
19 changes: 19 additions & 0 deletions src/tools/compare-styles-tool/CompareStylesTool.input.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.

import { z } from 'zod';

export const CompareStylesInputSchema = z.object({
styleA: z
.union([z.string(), z.record(z.unknown())])
.describe('First Mapbox style (JSON string or style object)'),
styleB: z
.union([z.string(), z.record(z.unknown())])
.describe('Second Mapbox style (JSON string or style object)'),
ignoreMetadata: z
.boolean()
.optional()
.describe('Ignore metadata fields like id, owner, created, modified')
});

export type CompareStylesInput = z.infer<typeof CompareStylesInputSchema>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) Mapbox, Inc.
// Licensed under the MIT License.

import { z } from 'zod';

const DifferenceSchema = z.object({
path: z.string().describe('JSON path to the difference'),
type: z.enum(['added', 'removed', 'modified']).describe('Type of difference'),
valueA: z.unknown().optional().describe('Value in style A (if exists)'),
valueB: z.unknown().optional().describe('Value in style B (if exists)'),
description: z.string().optional().describe('Human-readable description')
});

export const CompareStylesOutputSchema = z.object({
identical: z.boolean().describe('Whether the styles are identical'),
differences: z.array(DifferenceSchema).describe('List of differences found'),
summary: z
.object({
totalDifferences: z.number().describe('Total number of differences'),
added: z.number().describe('Number of additions in style B'),
removed: z.number().describe('Number of removals from style A'),
modified: z.number().describe('Number of modifications')
})
.describe('Summary of differences')
});

export type CompareStylesOutput = z.infer<typeof CompareStylesOutputSchema>;
export type Difference = z.infer<typeof DifferenceSchema>;
Loading