mirror of
https://github.com/penpot/penpot.git
synced 2026-07-22 14:08:03 +00:00
📚 Add .penpot format docs and inspector tool (#10674)
* 📚 Add comprehensive documentation for .penpot file format (v3) Create user-facing documentation for the .penpot binfile format to help developers and power users understand and inspect the ZIP+JSON structure. - Add technical specification with complete schema reference for all JSON files (manifest, file metadata, pages, shapes, library assets, storage objects, plugin data) - Add user-friendly overview explaining the format structure, inspection methods, and version history - Update export-import-files.njk to clarify current format is not deprecated and note that v2 was never released - Add cross-links between documentation pages - Include source code references to authoritative malli schemas AI-assisted-by: qwen3.7-plus * 📎 Add playwright dependency to the root package.json * 📚 Add browser based .penpot file inspector to docs Add a client-side, no-build inspector for .penpot (v3) files. The tool runs entirely in the browser: JSZip is loaded lazily from a CDN, the file is never uploaded. It provides a collapsible file tree, syntax- highlighted JSON viewer with search, image previews, a summary panel with file/shape/storage counts, shape summary cards with color swatches, and clickable UUID cross-references with backlinks. The inspector is added at docs/technical-guide/developer/data-model/penpot-file-inspector.njk and linked from the format spec and the user-facing format page. AI-assisted-by: minimax-m3 * 📚 Use full page width and 2-column layout for inspector The inspector previously sat inside the docs site's 42rem content column, which forced a stacked layout and wasted the wide viewport. - Hide the docs page-navigation sidebar on this page via :has() - Use a 2-column CSS grid: file tree (280px, sticky) on the left, content (flex: 1) on the right - Restore the directory tree as a permanent left-rail navigation (it was removed when the picker was first introduced, then added back as a collapsible panel; a sticky rail is a better fit now that horizontal space is plentiful) - Remove the tree toggle button — the tree is always visible - Collapses to 1 column on viewports below 900px AI-assisted-by: minimax-m3 * 💄 Indent nested JSON values in inspector The JSON tree view in the inspector was rendering all properties at the same indent level, making it hard to see which values were nested inside objects or arrays. Root-level properties and deeply nested ones looked identical. Add padding-left and a subtle vertical guide line to .jchildren so each nesting level is visually distinct. Bump the toggle column to 1.2em and add a touch of vertical padding to .jrow for breathing room. AI-assisted-by: minimax-m3
This commit is contained in:
parent
766368567e
commit
4c7863d6c8
628
docs/technical-guide/developer/data-model/penpot-file-format.md
Normal file
628
docs/technical-guide/developer/data-model/penpot-file-format.md
Normal file
@ -0,0 +1,628 @@
|
||||
---
|
||||
title: 3.02.01. Penpot file format (.penpot)
|
||||
desc: Complete technical specification for the .penpot file format, including structure, schemas, and inspection methods.
|
||||
---
|
||||
|
||||
# Penpot File Format (.penpot)
|
||||
|
||||
The `.penpot` file format is Penpot's native export format for design files. It's a ZIP archive containing JSON metadata and binary assets, designed to be open, inspectable, and efficient.
|
||||
|
||||
## Overview
|
||||
|
||||
The `.penpot` format (version 3) uses a ZIP container with JSON files for metadata and binary files for media assets. This approach provides several advantages:
|
||||
|
||||
- **Open and inspectable**: All metadata is human-readable JSON
|
||||
- **Efficient**: ZIP compression reduces file size
|
||||
- **Interoperable**: Standard formats enable third-party tooling
|
||||
- **Versioned**: Clear versioning system for format and data evolution
|
||||
|
||||
## Version History
|
||||
|
||||
| Version | Description | Status |
|
||||
|---------|-------------|--------|
|
||||
| v1 | Custom binary format | Deprecated |
|
||||
| v2 | SQLite-based format | Never released (internal only) |
|
||||
| v3 | ZIP + JSON format | **Current** |
|
||||
|
||||
## File Structure
|
||||
|
||||
A `.penpot` file contains the following structure:
|
||||
|
||||
```
|
||||
pencil.penpot (ZIP archive)
|
||||
├── manifest.json # Root metadata
|
||||
├── files/
|
||||
│ ├── {file-id}.json # File metadata
|
||||
│ └── {file-id}/
|
||||
│ ├── pages/
|
||||
│ │ ├── {page-id}.json # Page metadata
|
||||
│ │ └── {page-id}/
|
||||
│ │ └── {shape-id}.json # Individual shapes
|
||||
│ ├── media/
|
||||
│ │ └── {media-id}.json # Media references
|
||||
│ ├── colors/
|
||||
│ │ └── {color-id}.json # Library colors
|
||||
│ ├── components/
|
||||
│ │ └── {component-id}.json # Library components
|
||||
│ ├── typographies/
|
||||
│ │ └── {typography-id}.json # Library typographies
|
||||
│ ├── tokens.json # Design tokens library
|
||||
│ └── thumbnails/
|
||||
│ └── {tag}/{page-id}/{frame-id}.json # Thumbnail metadata
|
||||
└── objects/
|
||||
├── {uuid}.json # Storage object metadata
|
||||
└── {uuid}.{ext} # Binary media files (png, jpg, etc.)
|
||||
```
|
||||
|
||||
## Manifest Specification
|
||||
|
||||
The `manifest.json` file is the root of the archive and contains metadata about the export.
|
||||
|
||||
### Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"type": "penpot/export-files",
|
||||
"generatedBy": "penpot/2.12.0",
|
||||
"refer": "penpot",
|
||||
"files": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"name": "File Name",
|
||||
"features": ["feature1", "feature2"]
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
|
||||
### Fields
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `version` | integer | Yes | Format version (currently `1`) |
|
||||
| `type` | string | Yes | Must be `"penpot/export-files"` |
|
||||
| `generatedBy` | string | No | Penpot version that created the file |
|
||||
| `refer` | string | No | Source system (typically `"penpot"`) |
|
||||
| `files` | array | Yes | List of files in the archive |
|
||||
| `files[].id` | UUID | Yes | File identifier |
|
||||
| `files[].name` | string | Yes | File name |
|
||||
| `files[].features` | array | Yes | Set of feature flags |
|
||||
| `relations` | array | No | Library relationships `[file-id, library-id]` |
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "penpot/export-files",
|
||||
"version": 1,
|
||||
"generatedBy": "penpot/2.12.0-RC1-99-g40c27591f",
|
||||
"refer": "penpot",
|
||||
"files": [
|
||||
{
|
||||
"id": "73b59a94-3ea3-8189-8007-3d36adc8c3e3",
|
||||
"name": "Pencil | Penpot Design System",
|
||||
"features": [
|
||||
"fdata/path-data",
|
||||
"design-tokens/v1",
|
||||
"variants/v1",
|
||||
"layout/grid",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type"
|
||||
]
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
|
||||
## File Metadata
|
||||
|
||||
Each file has a JSON file at `files/{file-id}.json` containing the file's metadata.
|
||||
|
||||
### Schema
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | File identifier |
|
||||
| `name` | string | Yes | File name |
|
||||
| `revn` | integer | Yes | Revision number |
|
||||
| `vern` | integer | No | Version number |
|
||||
| `createdAt` | timestamp | Yes | Creation timestamp |
|
||||
| `modifiedAt` | timestamp | Yes | Last modification timestamp |
|
||||
| `deletedAt` | timestamp | No | Deletion timestamp (if soft-deleted) |
|
||||
| `projectId` | UUID | No | Project identifier |
|
||||
| `teamId` | UUID | No | Team identifier |
|
||||
| `isShared` | boolean | No | Whether file is a shared library |
|
||||
| `hasMediaTrimmed` | boolean | No | Whether media has been trimmed |
|
||||
| `features` | array | Yes | Set of enabled feature flags |
|
||||
| `migrations` | array | No | List of applied data migrations |
|
||||
| `options` | object | No | File-level options |
|
||||
|
||||
### Features
|
||||
|
||||
The `features` field is a set of strings indicating which features are enabled in the file. Common features include:
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| `fdata/path-data` | Path data format |
|
||||
| `fdata/shape-data-type` | Shape data type system |
|
||||
| `design-tokens/v1` | Design tokens support |
|
||||
| `variants/v1` | Component variants |
|
||||
| `layout/grid` | Grid layout system |
|
||||
| `components/v2` | Component system v2 |
|
||||
| `plugins/runtime` | Plugin runtime support |
|
||||
|
||||
### Migrations
|
||||
|
||||
The `migrations` field lists all data migrations applied to the file. This ensures backward compatibility when the data model evolves.
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "73b59a94-3ea3-8189-8007-3d36adc8c3e3",
|
||||
"name": "Pencil | Penpot Design System",
|
||||
"revn": 28425,
|
||||
"vern": 0,
|
||||
"createdAt": "2025-12-10T10:24:18.686066Z",
|
||||
"modifiedAt": "2025-12-10T12:13:49.799076Z",
|
||||
"teamId": "b62e1aa4-d9a7-8147-8005-2813bed4056e",
|
||||
"projectId": "f23add0e-6b77-8069-8005-41b48b93a5da",
|
||||
"isShared": true,
|
||||
"features": [
|
||||
"fdata/path-data",
|
||||
"design-tokens/v1",
|
||||
"variants/v1",
|
||||
"layout/grid",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type"
|
||||
],
|
||||
"migrations": [
|
||||
"legacy-2",
|
||||
"legacy-3",
|
||||
"0001-remove-tokens-from-groups",
|
||||
"0002-normalize-bool-content-v2"
|
||||
],
|
||||
"options": {
|
||||
"componentsV2": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Pages and Shapes
|
||||
|
||||
### Page Structure
|
||||
|
||||
Each page is stored at `files/{file-id}/pages/{page-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Page identifier |
|
||||
| `name` | string | Yes | Page name |
|
||||
| `index` | integer | No | Page order in the file |
|
||||
| `options` | object | No | Page options (guides, etc.) |
|
||||
| `background` | string | No | Background color (hex) |
|
||||
| `flows` | object | No | Prototype flows |
|
||||
| `guides` | object | No | Ruler guides |
|
||||
|
||||
### Shapes
|
||||
|
||||
Individual shapes are stored at `files/{file-id}/pages/{page-id}/{shape-id}.json`.
|
||||
|
||||
#### Shape Types
|
||||
|
||||
Penpot supports 9 shape types:
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `frame` | Container frame (artboard) |
|
||||
| `group` | Group of shapes |
|
||||
| `rect` | Rectangle |
|
||||
| `circle` | Circle/Ellipse |
|
||||
| `path` | Vector path |
|
||||
| `text` | Text shape |
|
||||
| `image` | Image |
|
||||
| `bool` | Boolean operation |
|
||||
| `svg-raw` | Raw SVG element |
|
||||
|
||||
#### Base Shape Attributes
|
||||
|
||||
All shapes share these base attributes:
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Shape identifier |
|
||||
| `name` | string | Yes | Shape name |
|
||||
| `type` | string | Yes | Shape type (see above) |
|
||||
| `selrect` | object | Yes | Selection rectangle `{x, y, width, height}` |
|
||||
| `points` | array | Yes | Array of points `[{x, y}, ...]` |
|
||||
| `transform` | array | Yes | 2D transformation matrix |
|
||||
| `transformInverse` | array | Yes | Inverse transformation matrix |
|
||||
| `parentId` | UUID | Yes | Parent shape identifier |
|
||||
| `frameId` | UUID | Yes | Containing frame identifier |
|
||||
|
||||
#### Geometry Attributes
|
||||
|
||||
Shapes with geometry (frame, rect, circle, image, svg-raw, text):
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `x` | number | Yes | X position |
|
||||
| `y` | number | Yes | Y position |
|
||||
| `width` | number | Yes | Width |
|
||||
| `height` | number | Yes | Height |
|
||||
|
||||
#### Generic Attributes
|
||||
|
||||
Optional attributes available on all shapes:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `fills` | array | Fill styles |
|
||||
| `strokes` | array | Stroke styles |
|
||||
| `opacity` | number | Opacity (0-1) |
|
||||
| `blendMode` | string | Blend mode |
|
||||
| `shadow` | array | Shadow effects |
|
||||
| `blur` | object | Blur effect |
|
||||
| `constraintsH` | string | Horizontal constraint |
|
||||
| `constraintsV` | string | Vertical constraint |
|
||||
| `r1`, `r2`, `r3`, `r4` | number | Border radius corners |
|
||||
| `blocked` | boolean | Shape is locked |
|
||||
| `hidden` | boolean | Shape is hidden |
|
||||
| `collapsed` | boolean | Shape is collapsed |
|
||||
| `componentId` | UUID | Component reference |
|
||||
| `componentFile` | UUID | Component library file |
|
||||
| `shapeRef` | UUID | Shape reference for components |
|
||||
| `touched` | array | Modified component properties |
|
||||
| `interactions` | array | Prototype interactions |
|
||||
| `exports` | array | Export settings |
|
||||
| `grids` | array | Grid configurations |
|
||||
| `appliedTokens` | object | Applied design tokens |
|
||||
| `pluginData` | object | Plugin-specific data |
|
||||
|
||||
#### Type-Specific Attributes
|
||||
|
||||
**Frame**
|
||||
- `shapes`: array of child shape UUIDs
|
||||
- `showContent`: boolean
|
||||
- `hideInViewer`: boolean
|
||||
|
||||
**Group**
|
||||
- `shapes`: array of child shape UUIDs
|
||||
|
||||
**Bool**
|
||||
- `shapes`: array of child shape UUIDs
|
||||
- `boolType`: string (`union`, `difference`, `exclude`, `intersection`)
|
||||
- `content`: path data
|
||||
|
||||
**Path**
|
||||
- `content`: path data (SVG path commands)
|
||||
|
||||
**Text**
|
||||
- `content`: text content with formatting
|
||||
- `positionData`: glyph position data
|
||||
|
||||
**Image**
|
||||
- `metadata`: object with `width`, `height`, `mtype`, `id`
|
||||
|
||||
### Example Shape
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "260aea33-4e55-808c-8007-3d4f2efe4230",
|
||||
"name": "Rectangle",
|
||||
"type": "rect",
|
||||
"x": 100,
|
||||
"y": 100,
|
||||
"width": 200,
|
||||
"height": 150,
|
||||
"selrect": {
|
||||
"x": 100,
|
||||
"y": 100,
|
||||
"width": 200,
|
||||
"height": 150
|
||||
},
|
||||
"points": [
|
||||
{"x": 100, "y": 100},
|
||||
{"x": 300, "y": 100},
|
||||
{"x": 300, "y": 250},
|
||||
{"x": 100, "y": 250}
|
||||
],
|
||||
"transform": [1, 0, 0, 1, 0, 0],
|
||||
"transformInverse": [1, 0, 0, 1, 0, 0],
|
||||
"parentId": "00000000-0000-0000-0000-000000000000",
|
||||
"frameId": "00000000-0000-0000-0000-000000000001",
|
||||
"fills": [
|
||||
{
|
||||
"color": "#FF5733",
|
||||
"opacity": 1
|
||||
}
|
||||
],
|
||||
"r1": 8,
|
||||
"r2": 8,
|
||||
"r3": 8,
|
||||
"r4": 8
|
||||
}
|
||||
```
|
||||
|
||||
## Library Assets
|
||||
|
||||
### Colors
|
||||
|
||||
Stored at `files/{file-id}/colors/{color-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Color identifier |
|
||||
| `name` | string | Yes | Color name |
|
||||
| `path` | string | No | Path in the library tree |
|
||||
| `opacity` | number | No | Opacity (0-1) |
|
||||
| `color` | string | Conditional | Hex color (for plain colors) |
|
||||
| `gradient` | object | Conditional | Gradient definition |
|
||||
| `image` | object | Conditional | Image fill definition |
|
||||
|
||||
#### Plain Color Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "abc123...",
|
||||
"name": "Primary Blue",
|
||||
"path": "Brand/Primary",
|
||||
"color": "#0066CC",
|
||||
"opacity": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### Gradient Color Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "def456...",
|
||||
"name": "Sunset Gradient",
|
||||
"gradient": {
|
||||
"type": "linear",
|
||||
"startX": 0,
|
||||
"startY": 0,
|
||||
"endX": 1,
|
||||
"endY": 1,
|
||||
"stops": [
|
||||
{"color": "#FF6B6B", "offset": 0, "opacity": 1},
|
||||
{"color": "#4ECDC4", "offset": 1, "opacity": 1}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
Stored at `files/{file-id}/components/{component-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Component identifier |
|
||||
| `name` | string | Yes | Component name |
|
||||
| `path` | string | Yes | Path in the library tree |
|
||||
| `mainInstanceId` | UUID | Yes | Root shape of main instance |
|
||||
| `mainInstancePage` | UUID | Yes | Page containing main instance |
|
||||
| `modifiedAt` | timestamp | No | Last modification |
|
||||
| `objects` | object | No | Captured shapes (if deleted) |
|
||||
|
||||
### Typographies
|
||||
|
||||
Stored at `files/{file-id}/typographies/{typography-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Typography identifier |
|
||||
| `name` | string | Yes | Typography name |
|
||||
| `fontId` | string | Yes | Font identifier |
|
||||
| `fontFamily` | string | Yes | Font family name |
|
||||
| `fontVariantId` | string | Yes | Font variant |
|
||||
| `fontSize` | string | Yes | Font size |
|
||||
| `fontWeight` | string | Yes | Font weight |
|
||||
| `fontStyle` | string | Yes | Font style |
|
||||
| `lineHeight` | string | Yes | Line height |
|
||||
| `letterSpacing` | string | Yes | Letter spacing |
|
||||
| `textTransform` | string | Yes | Text transform |
|
||||
|
||||
### Design Tokens
|
||||
|
||||
Stored at `files/{file-id}/tokens.json`.
|
||||
|
||||
The tokens library contains:
|
||||
|
||||
- **Sets**: Collections of tokens organized hierarchically
|
||||
- **Themes**: Named combinations of token sets
|
||||
- **Active Themes**: Currently applied themes
|
||||
|
||||
#### Token Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"sets": {
|
||||
"core": {
|
||||
"id": "uuid",
|
||||
"name": "Core",
|
||||
"tokens": {
|
||||
"color": {
|
||||
"primary": {
|
||||
"id": "uuid",
|
||||
"name": "primary",
|
||||
"type": "color",
|
||||
"value": "#0066CC"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"themes": {
|
||||
"light": {
|
||||
"id": "uuid",
|
||||
"name": "Light",
|
||||
"sets": ["core"]
|
||||
}
|
||||
},
|
||||
"activeThemes": ["light"]
|
||||
}
|
||||
```
|
||||
|
||||
## Media and Storage Objects
|
||||
|
||||
### Storage Objects
|
||||
|
||||
Binary assets (images, fonts, etc.) are stored in the `objects/` directory.
|
||||
|
||||
Each storage object has:
|
||||
- `objects/{uuid}.json` - Metadata
|
||||
- `objects/{uuid}.{ext}` - Binary content (png, jpg, svg, etc.)
|
||||
|
||||
#### Metadata Schema
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Storage object identifier |
|
||||
| `size` | integer | Yes | File size in bytes |
|
||||
| `contentType` | string | Yes | MIME type |
|
||||
| `bucket` | string | Yes | Storage bucket |
|
||||
| `hash` | string | No | Content hash (blake2b) |
|
||||
|
||||
#### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "0039433d-adc8-430d-b2c3-d884dea6e050",
|
||||
"size": 575,
|
||||
"contentType": "image/png",
|
||||
"bucket": "file-media-object",
|
||||
"hash": "blake2b:77d447db38eb5daf31acb7344a504cacc6b79aa11855a00501d9475c595053d0"
|
||||
}
|
||||
```
|
||||
|
||||
### Media References
|
||||
|
||||
File media references are stored at `files/{file-id}/media/{media-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `id` | UUID | Yes | Media identifier |
|
||||
| `name` | string | Yes | File name |
|
||||
| `width` | integer | Yes | Image width |
|
||||
| `height` | integer | Yes | Image height |
|
||||
| `mtype` | string | Yes | MIME type |
|
||||
| `mediaId` | UUID | Yes | Reference to storage object |
|
||||
| `thumbnaillId` | UUID | No | Reference to thumbnail |
|
||||
| `isLocal` | boolean | No | Whether media is local to file |
|
||||
|
||||
### Thumbnails
|
||||
|
||||
Page thumbnails are stored at `files/{file-id}/thumbnails/{tag}/{page-id}/{frame-id}.json`.
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `fileId` | UUID | Yes | File identifier |
|
||||
| `pageId` | UUID | Yes | Page identifier |
|
||||
| `frameId` | UUID | Yes | Frame identifier |
|
||||
| `tag` | string | Yes | Thumbnail tag |
|
||||
| `mediaId` | UUID | Yes | Reference to storage object |
|
||||
|
||||
## Plugin Data
|
||||
|
||||
Plugins can store custom data on files, pages, shapes, components, colors, and typographies using the `pluginData` field.
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"pluginData": {
|
||||
"plugin-id": {
|
||||
"key1": "value1",
|
||||
"key2": "value2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The plugin ID is a keyword (e.g., `"my-plugin"`), and the values are string key-value pairs.
|
||||
|
||||
## Inspecting a .penpot File
|
||||
|
||||
### List Contents
|
||||
|
||||
```bash
|
||||
unzip -l design.penpot
|
||||
```
|
||||
|
||||
### Extract and View
|
||||
|
||||
```bash
|
||||
# Extract to temporary directory
|
||||
unzip design.penpot -d /tmp/penpot-inspect
|
||||
|
||||
# View manifest
|
||||
cat /tmp/penpot-inspect/manifest.json | jq .
|
||||
|
||||
# List all files
|
||||
find /tmp/penpot-inspect -name "*.json" | head -20
|
||||
|
||||
# View a specific shape
|
||||
cat /tmp/penpot-inspect/files/*/pages/*/*.json | jq .
|
||||
```
|
||||
|
||||
### Browser-Based Inspector
|
||||
|
||||
For an interactive way to explore a `.penpot` file, try the [**Penpot file inspector**](/technical-guide/developer/data-model/penpot-file-inspector/). It runs entirely in your browser, displays a collapsible file tree, syntax-highlighted JSON, image previews, and clickable cross-references between shapes, components, colors, and media.
|
||||
|
||||
### Quick Inspection Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Inspect .penpot file structure
|
||||
|
||||
FILE=$1
|
||||
TMPDIR=$(mktemp -d)
|
||||
|
||||
unzip -q "$FILE" -d "$TMPDIR"
|
||||
|
||||
echo "=== Manifest ==="
|
||||
cat "$TMPDIR/manifest.json" | jq '{type, version, files: [.files[] | {id, name}]}'
|
||||
|
||||
echo -e "\n=== Files ==="
|
||||
for f in "$TMPDIR"/files/*.json; do
|
||||
echo "- $(jq -r '.name' "$f")"
|
||||
done
|
||||
|
||||
echo -e "\n=== Pages ==="
|
||||
for f in "$TMPDIR"/files/*/pages/*.json; do
|
||||
echo "- $(jq -r '.name' "$f")"
|
||||
done
|
||||
|
||||
echo -e "\n=== Storage Objects ==="
|
||||
ls -lh "$TMPDIR"/objects/*.{png,jpg,svg} 2>/dev/null | wc -l
|
||||
echo "media files"
|
||||
|
||||
rm -rf "$TMPDIR"
|
||||
```
|
||||
|
||||
## Cross-References
|
||||
|
||||
- [Penpot file inspector](/technical-guide/developer/data-model/penpot-file-inspector/) - Browser-based interactive inspector
|
||||
- [Data Model](/technical-guide/developer/data-model/) - Conceptual data model
|
||||
- [Data Guide](/technical-guide/developer/data-guide/) - Working with data structures
|
||||
- [Export/Import Files](/user-guide/export-import/export-import-files/) - User guide for exporting and importing
|
||||
|
||||
## Source Code References
|
||||
|
||||
The authoritative schema definitions are in the Penpot source code:
|
||||
|
||||
- **Manifest**: `backend/src/app/binfile/v3.clj` (schema:manifest)
|
||||
- **File**: `common/src/app/common/types/file.cljc` (schema:file)
|
||||
- **Page**: `common/src/app/common/types/page.cljc` (schema:page)
|
||||
- **Shape**: `common/src/app/common/types/shape.cljc` (schema:shape)
|
||||
- **Component**: `common/src/app/common/types/component.cljc` (schema:component)
|
||||
- **Color**: `common/src/app/common/types/color.cljc` (schema:library-color)
|
||||
- **Typography**: `common/src/app/common/types/typography.cljc` (schema:typography)
|
||||
- **Tokens**: `common/src/app/common/types/tokens_lib.cljc` (schema:tokens-lib)
|
||||
- **Plugin Data**: `common/src/app/common/types/plugins.cljc` (schema:plugin-data)
|
||||
- **Features**: `common/src/app/common/features.cljc` (schema:features)
|
||||
1401
docs/technical-guide/developer/data-model/penpot-file-inspector.njk
Normal file
1401
docs/technical-guide/developer/data-model/penpot-file-inspector.njk
Normal file
File diff suppressed because it is too large
Load Diff
@ -48,21 +48,22 @@ desc: Learn how to import and export files in Penpot, the free, open-source desi
|
||||
<figure><img src="/img/import-export/import-selection.webp" alt="Import penpot file" /></figure>
|
||||
|
||||
<h2 id="penpot-formats">Penpot file format</h2>
|
||||
<p>Penpot export to a unique format that streamline the import and export of files and assets by being more efficient and interoperable.</p>
|
||||
<p>Penpot exports to a unique format that streamlines the import and export of files and assets by being more efficient and interoperable.</p>
|
||||
<p>Unlike other design tools, <strong>Penpot's format is built on standard languages</strong>. The exported file is essentially a ZIP archive containing binary assets (such as bitmap and vector images) alongside a readable JSON structure. By avoiding proprietary formats, Penpot empowers users with autonomy from specific tools while enabling seamless third-party integrations.</p>
|
||||
<p>For a detailed look at what's inside a .penpot file, see <a href="/user-guide/export-import/penpot-file-format/">The .penpot file format</a>. Developers can also check the <a href="/technical-guide/developer/data-model/penpot-file-format/">technical specification</a>.</p>
|
||||
|
||||
<h3>Deprecated Penpot file formats</h3>
|
||||
<p class="advice">These formats can only be exported from version 2.3 or earlier versions, but can be imported to any Penpot version.</p>
|
||||
<p>There are two different deprecated Penpot file formats in which you can import/export Penpot files. A standard one and a binary one. You always have the chance to use both for any file.</p>
|
||||
<h4>[Deprecated] Penpot file (.penpot).</h4>
|
||||
<h4>[Deprecated] Binary file (.penpot) — v1</h4>
|
||||
<p>The fast one. Binary Penpot specific.</p>
|
||||
<ul>
|
||||
<li>✅ Highly efficient in terms of memory and transfer time when exporting and importing.</li>
|
||||
<li>❌ It can be opened only in Penpot.</li>
|
||||
<li>❌ Not transparent, code difficult to explore.</li>
|
||||
</ul>
|
||||
<h4>[Deprecated] Standard file (.zip).</h4>
|
||||
<p>The open one. A compressed file that includes SVG and JSON.</p>
|
||||
<h4>[Deprecated] Standard file (.zip) — v2 (never released)</h4>
|
||||
<p>The open one. A compressed file that includes SVG and JSON. This format was developed but never released to users.</p>
|
||||
<ul>
|
||||
<li>✅ Allows the file to be opened by other softwares (still, for those cases export to SVG seems to be the common practice).</li>
|
||||
<li>✅ Allows some automations and integrations.</li>
|
||||
|
||||
@ -13,7 +13,13 @@ desc: Begin with the Penpot user guide! Get quickstarts, shortcuts, and tutorial
|
||||
<p>How to export and import your Penpot files</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<li>
|
||||
<a href="/user-guide/export-import/penpot-file-format/">
|
||||
<h2>The .penpot file format →</h2>
|
||||
<p>Understand what's inside a .penpot file and how to inspect it</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/user-guide/export-import/exporting-layers/">
|
||||
<h2>Exporting layers →</h2>
|
||||
<p>How to export elements from your design into different file formats</p>
|
||||
|
||||
155
docs/user-guide/export-import/penpot-file-format.njk
Normal file
155
docs/user-guide/export-import/penpot-file-format.njk
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
title: The .penpot file format
|
||||
order: 2
|
||||
desc: Understand the .penpot file format, what's inside, and how to inspect your design files.
|
||||
---
|
||||
|
||||
<h1 id="penpot-file-format">The .penpot file format</h1>
|
||||
<p class="main-paragraph">Penpot's native file format is designed to be open, inspectable, and efficient. Unlike proprietary formats, you can always look inside a .penpot file to understand your design data.</p>
|
||||
|
||||
<h2 id="what-is-penpot-format">What is a .penpot file?</h2>
|
||||
|
||||
<p>A <code class="language-text">.penpot</code> file is a <strong>ZIP archive</strong> containing:</p>
|
||||
<ul>
|
||||
<li><strong>JSON metadata</strong> — human-readable descriptions of your pages, shapes, colors, components, and more</li>
|
||||
<li><strong>Binary media files</strong> — images, fonts, and other assets used in your design</li>
|
||||
</ul>
|
||||
|
||||
<p>This means your design data is never locked in a proprietary format. You can always unzip a .penpot file and read the JSON to understand what's inside.</p>
|
||||
|
||||
<h2 id="whats-inside">What's inside a .penpot file?</h2>
|
||||
|
||||
<p>When you unzip a .penpot file, you'll find this structure:</p>
|
||||
|
||||
<figure>
|
||||
<pre class="language-text"><code>your-design.penpot (ZIP archive)
|
||||
├── manifest.json ← Table of contents
|
||||
├── files/ ← Your design data
|
||||
│ ├── file-metadata.json
|
||||
│ └── file-data/
|
||||
│ ├── pages/ ← Each page of your design
|
||||
│ ├── colors/ ← Library colors
|
||||
│ ├── components/ ← Library components
|
||||
│ ├── typographies/ ← Library typographies
|
||||
│ ├── tokens.json ← Design tokens
|
||||
│ └── media/ ← Media references
|
||||
└── objects/ ← Images and binary assets</code></pre>
|
||||
</figure>
|
||||
|
||||
<h3>manifest.json</h3>
|
||||
<p>The manifest is the table of contents. It tells you:</p>
|
||||
<ul>
|
||||
<li>Which version of the format is used</li>
|
||||
<li>Which Penpot version created the file</li>
|
||||
<li>What files are included</li>
|
||||
<li>What features are enabled</li>
|
||||
</ul>
|
||||
|
||||
<h3>File data</h3>
|
||||
<p>The <code class="language-text">files/</code> directory contains all your design data organized by type:</p>
|
||||
<ul>
|
||||
<li><strong>Pages</strong> — Each page is split into individual shape files for efficiency</li>
|
||||
<li><strong>Colors</strong> — Your color library with hex values, gradients, or image fills</li>
|
||||
<li><strong>Components</strong> — Reusable component definitions</li>
|
||||
<li><strong>Typographies</strong> — Text style definitions</li>
|
||||
<li><strong>Tokens</strong> — Design tokens organized in sets and themes</li>
|
||||
<li><strong>Media</strong> — References to images and other assets</li>
|
||||
</ul>
|
||||
|
||||
<h3>Objects</h3>
|
||||
<p>The <code class="language-text">objects/</code> directory contains the actual binary files (PNG, JPG, SVG) referenced by your design. Each object has a JSON metadata file alongside the binary file.</p>
|
||||
|
||||
<h2 id="how-to-inspect">How to inspect a .penpot file</h2>
|
||||
|
||||
<p>Since .penpot files are just ZIP archives, you can inspect them with standard tools.</p>
|
||||
|
||||
<h3>On macOS or Linux</h3>
|
||||
|
||||
<p><strong>1. List the contents without extracting:</strong></p>
|
||||
<pre class="language-bash"><code>unzip -l your-design.penpot</code></pre>
|
||||
|
||||
<p><strong>2. Extract to a temporary folder:</strong></p>
|
||||
<pre class="language-bash"><code>unzip your-design.penpot -d /tmp/penpot-inspect</code></pre>
|
||||
|
||||
<p><strong>3. View the manifest:</strong></p>
|
||||
<pre class="language-bash"><code>cat /tmp/penpot-inspect/manifest.json | jq .</code></pre>
|
||||
|
||||
<p><strong>4. Browse the structure:</strong></p>
|
||||
<pre class="language-bash"><code>tree /tmp/penpot-inspect</code></pre>
|
||||
|
||||
<p><strong>5. View a specific shape:</strong></p>
|
||||
<pre class="language-bash"><code>cat /tmp/penpot-inspect/files/*/pages/*/*.json | jq .</code></pre>
|
||||
|
||||
<h3>On Windows</h3>
|
||||
|
||||
<p><strong>1. Right-click the .penpot file</strong> and select "Extract All..." or use 7-Zip.</p>
|
||||
|
||||
<p><strong>2. Browse the extracted folder</strong> to see the structure.</p>
|
||||
|
||||
<p><strong>3. Open any JSON file</strong> with a text editor or use a JSON viewer tool.</p>
|
||||
|
||||
<h3>Using AI tools</h3>
|
||||
|
||||
<p>You can use the <a href="/mcp/">Penpot MCP server</a> to inspect .penpot files with AI assistance. The MCP server can read and analyze your design files, making it easy to understand complex designs or automate tasks.</p>
|
||||
|
||||
<h2 id="versioning">Format versions</h2>
|
||||
|
||||
<p>The .penpot format has evolved over time:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Version</th>
|
||||
<th>Description</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>v3</strong></td>
|
||||
<td>ZIP + JSON format (current)</td>
|
||||
<td>✅ Current</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>v1</td>
|
||||
<td>Custom binary format</td>
|
||||
<td>⚠️ Deprecated</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="advice">All current Penpot versions export in v3 format. Old v1 files can still be imported, but new exports will use v3.</p>
|
||||
|
||||
<h3>Version numbers inside the file</h3>
|
||||
|
||||
<p>Inside a .penpot file, you'll see two different version numbers:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Format version</strong> (in <code class="language-text">manifest.json</code>) — Tracks changes to the ZIP structure itself. Currently <code class="language-text">1</code>.</li>
|
||||
<li><strong>Data version</strong> (in each file's JSON) — Tracks changes to the data model. This number increases as Penpot evolves.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Feature flags</h3>
|
||||
|
||||
<p>Files also include a list of <strong>feature flags</strong> that indicate which capabilities are used. For example:</p>
|
||||
|
||||
<ul>
|
||||
<li><code class="language-text">design-tokens/v1</code> — Uses design tokens</li>
|
||||
<li><code class="language-text">components/v2</code> — Uses the v2 component system</li>
|
||||
<li><code class="language-text">variants/v1</code> — Uses component variants</li>
|
||||
<li><code class="language-text">layout/grid</code> — Uses grid layouts</li>
|
||||
</ul>
|
||||
|
||||
<p>These flags help Penpot know what features need to be supported when importing the file.</p>
|
||||
|
||||
<h2 id="for-developers">For developers</h2>
|
||||
|
||||
<p>If you're building tools or integrations that work with .penpot files, the <a href="/technical-guide/developer/data-model/penpot-file-format/">complete technical specification</a> provides detailed schema definitions for every JSON file in the archive.</p>
|
||||
|
||||
<p>Key resources:</p>
|
||||
<ul>
|
||||
<li><a href="/technical-guide/developer/data-model/penpot-file-format/">Technical specification</a> — Complete schema reference</li>
|
||||
<li><a href="/technical-guide/developer/data-model/penpot-file-inspector/">File inspector</a> — Browser-based tool to interactively explore a .penpot file</li>
|
||||
<li><a href="/mcp/">MCP Server</a> — AI-powered file inspection and manipulation</li>
|
||||
<li><a href="/technical-guide/developer/data-model/">Data model</a> — Conceptual overview of Penpot's data structures</li>
|
||||
</ul>
|
||||
@ -4,7 +4,7 @@
|
||||
"license": "MPL-2.0",
|
||||
"author": "Kaleidos INC Sucursal en España SL",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@11.10.0+sha512.0b7f8b98060031904c017e3a41eb187a16d40eeb829b95c4f8cb03681761fc4ab53dd219115b9b447f4dce1a05a214764461e7d3703392a9f32f9511ce8c86c8",
|
||||
"packageManager": "pnpm@11.12.0+sha512.820a6fbd0d9f04c226638002aead1e45340a9139dd5dc077c1d83ef44aa2481c8eb6637b4c9aa696a3c7e35ba818e49cf27213e5f2b91138d09b7a3e26e898ba",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/penpot/penpot"
|
||||
@ -16,10 +16,12 @@
|
||||
"fmt": "./scripts/fmt"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/mcp": "^0.0.76",
|
||||
"@playwright/test": "^1.61.1",
|
||||
"@types/node": "^26.0.1",
|
||||
"esbuild": "^0.28.1",
|
||||
"mdts": "^0.20.3",
|
||||
"nrepl-client": "^0.3.0",
|
||||
"opencode-ai": "^1.17.11"
|
||||
"playwright": "^1.61.1"
|
||||
}
|
||||
}
|
||||
|
||||
195
pnpm-lock.yaml
generated
195
pnpm-lock.yaml
generated
@ -8,6 +8,12 @@ importers:
|
||||
|
||||
.:
|
||||
devDependencies:
|
||||
'@playwright/mcp':
|
||||
specifier: ^0.0.76
|
||||
version: 0.0.76
|
||||
'@playwright/test':
|
||||
specifier: ^1.61.1
|
||||
version: 1.61.1
|
||||
'@types/node':
|
||||
specifier: ^26.0.1
|
||||
version: 26.0.1
|
||||
@ -20,9 +26,9 @@ importers:
|
||||
nrepl-client:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0
|
||||
opencode-ai:
|
||||
specifier: ^1.17.11
|
||||
version: 1.17.11
|
||||
playwright:
|
||||
specifier: ^1.61.1
|
||||
version: 1.61.1
|
||||
|
||||
packages:
|
||||
|
||||
@ -188,6 +194,16 @@ packages:
|
||||
'@kwsites/promise-deferred@1.1.1':
|
||||
resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
|
||||
|
||||
'@playwright/mcp@0.0.76':
|
||||
resolution: {integrity: sha512-ICcW6wAV+HoNEco19eni+JTVylCIIedruWkrRl2Rsv/qcGhBZLT/c0I1VounjIjSVSupw3pHmcr3CNCikTHTBQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@playwright/test@1.61.1':
|
||||
resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@simple-git/args-pathspec@1.0.3':
|
||||
resolution: {integrity: sha512-ngJMaHlsWDTfjyq9F3VIQ8b7NXbBLq5j9i5bJ6XLYtD6qlDXT7fdKY2KscWWUF8t18xx052Y/PUO1K1TRc9yKA==}
|
||||
|
||||
@ -365,6 +381,11 @@ packages:
|
||||
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
@ -545,75 +566,6 @@ packages:
|
||||
resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
opencode-ai@1.17.11:
|
||||
resolution: {integrity: sha512-a4331YhfsIiDSve0YRP2eNdlY1iDqhzw979Ky66XWiKDA8jeykfsqGUDAmKYKjS3hLV8U8+krFBuMFVO7p5ptQ==}
|
||||
cpu: [arm64, x64]
|
||||
os: [darwin, linux, win32]
|
||||
hasBin: true
|
||||
|
||||
opencode-darwin-arm64@1.17.11:
|
||||
resolution: {integrity: sha512-WpBokL8RL8BvdPKzJhQlLbVigz4jT0uESDWgwLcsU2JAP8hOWc/bMgzf87C7VtJlcjUY9ao60UzbPlsUffb/0g==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
opencode-darwin-x64-baseline@1.17.11:
|
||||
resolution: {integrity: sha512-hay37M7ALa4/4RrtJDggnOOCL226+cgQQQ0KiBFWNMDhygtwBszQnZmNxWxZtoRNIr3sIIS8JNsuBfhG4OwXYg==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
opencode-darwin-x64@1.17.11:
|
||||
resolution: {integrity: sha512-ZxQzLT92FT96Y8ahpHZiejD+m7vQYhAfskfzMwc0baDjkctEXy6UkZT5gY5jTDl+Bb74xgmKYJK6Lz20luhOXA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
opencode-linux-arm64-musl@1.17.11:
|
||||
resolution: {integrity: sha512-haM+NZ/CC14VdHSi81pRlYDbLvu3sXAQF8HH1t7yi0YpH3wLibq0Ms8prM0809Sza+30pyUIxH6aoYghnr2Juw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
opencode-linux-arm64@1.17.11:
|
||||
resolution: {integrity: sha512-CN3LSlqSrC1LbYHXZs21B8hIB951ebCRowwC+p4SDwPPUKknRzGYi5V7FjXAp8xq5hx27/QGgmGjfauv6RbAiA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
opencode-linux-x64-baseline-musl@1.17.11:
|
||||
resolution: {integrity: sha512-AR3soQ1kYquD+QHaNDcWhHxd6lT8yUZJ2jsnls+7oOTisQWUspi5TpFD5FL4Et1MMtoJx63CAySDTzUpRXUO9Q==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
opencode-linux-x64-baseline@1.17.11:
|
||||
resolution: {integrity: sha512-y0sibv7zg0KDLD7hdMCLe4+YYP6t5PQmqTV88KR7jWIU7qvl1hyuIAI84QLCt+7DACpNsFsUfofu6Hib051jZw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
opencode-linux-x64-musl@1.17.11:
|
||||
resolution: {integrity: sha512-cl2SMRa1c6dJMxvs5BQMy7Q2LVBwGXbLHpjc0OaeMkdORwdBfwCXfW1GNA61pNR4mMHMKrbFEV6dETqCDuIaWQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
opencode-linux-x64@1.17.11:
|
||||
resolution: {integrity: sha512-at2oODO6N4yMTlvtKOFECVDvj4Nz3iFygmSKyoVdokgpMhYt6l9ta63pEp1jAaTxLpjQGbCzpRYbY/QqRAeB9Q==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
opencode-windows-arm64@1.17.11:
|
||||
resolution: {integrity: sha512-pWOT/Ml4e3S12BQTmw8i+CsQ7QF0kI6Z//9z/N60gLW1U5afVYQpHkT1pT5RVjysPVHP8G4TN7Rbyi8m+fapCQ==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
opencode-windows-x64-baseline@1.17.11:
|
||||
resolution: {integrity: sha512-RkJX3S77bzFZOHyQsqBqkI567hGHiTGU2TTIkBphYvRNxCQy+ZDjn3QAh+h7zyCHfieeWRKA96kl9ycKaJGO4A==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
opencode-windows-x64@1.17.11:
|
||||
resolution: {integrity: sha512-4ON++fPbRVhLpYvy6j0RolFstU1OncbqZ4FLFeAkC4L6CNO06kHEwmwRfEVcGo+zFpug/ljdW2T0W+sYBw20SA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
parseurl@1.3.3:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@ -635,6 +587,26 @@ packages:
|
||||
plantuml@0.0.2:
|
||||
resolution: {integrity: sha512-3YzQJUO1Yg+mDckTm3Ht5Q8bmtN8g3M9LD8fXqiqHDW3vzUpHrUe9lxVY6AT1I50w7FdOned0hhJno4JBIku2g==}
|
||||
|
||||
playwright-core@1.61.0-alpha-1781023400000:
|
||||
resolution: {integrity: sha512-UdtUd9qnCO0zvb8p3OvOZpelY6mA40mTb3NmWGuMtrD+hqqWuorWCPlSGwj7jw/LEB9AxvYLHTL1CJi2flvksg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright-core@1.61.1:
|
||||
resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.61.0-alpha-1781023400000:
|
||||
resolution: {integrity: sha512-8TRUG3IvwaAhuVm6k3C5vB7CwC5Fxq76DCCxOgPr6r1dpTedDwxlmdOBUkSZ0zxfxP14jcuPxi86/Trq4eA03w==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.61.1:
|
||||
resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
powershell-utils@0.1.0:
|
||||
resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==}
|
||||
engines: {node: '>=20'}
|
||||
@ -864,6 +836,15 @@ snapshots:
|
||||
|
||||
'@kwsites/promise-deferred@1.1.1': {}
|
||||
|
||||
'@playwright/mcp@0.0.76':
|
||||
dependencies:
|
||||
playwright: 1.61.0-alpha-1781023400000
|
||||
playwright-core: 1.61.0-alpha-1781023400000
|
||||
|
||||
'@playwright/test@1.61.1':
|
||||
dependencies:
|
||||
playwright: 1.61.1
|
||||
|
||||
'@simple-git/args-pathspec@1.0.3': {}
|
||||
|
||||
'@simple-git/argv-parser@1.1.1':
|
||||
@ -1079,6 +1060,9 @@ snapshots:
|
||||
|
||||
fresh@2.0.0: {}
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
@ -1263,57 +1247,6 @@ snapshots:
|
||||
powershell-utils: 0.1.0
|
||||
wsl-utils: 0.3.1
|
||||
|
||||
opencode-ai@1.17.11:
|
||||
optionalDependencies:
|
||||
opencode-darwin-arm64: 1.17.11
|
||||
opencode-darwin-x64: 1.17.11
|
||||
opencode-darwin-x64-baseline: 1.17.11
|
||||
opencode-linux-arm64: 1.17.11
|
||||
opencode-linux-arm64-musl: 1.17.11
|
||||
opencode-linux-x64: 1.17.11
|
||||
opencode-linux-x64-baseline: 1.17.11
|
||||
opencode-linux-x64-baseline-musl: 1.17.11
|
||||
opencode-linux-x64-musl: 1.17.11
|
||||
opencode-windows-arm64: 1.17.11
|
||||
opencode-windows-x64: 1.17.11
|
||||
opencode-windows-x64-baseline: 1.17.11
|
||||
|
||||
opencode-darwin-arm64@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-darwin-x64-baseline@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-darwin-x64@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-arm64-musl@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-arm64@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-x64-baseline-musl@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-x64-baseline@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-x64-musl@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-linux-x64@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-windows-arm64@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-windows-x64-baseline@1.17.11:
|
||||
optional: true
|
||||
|
||||
opencode-windows-x64@1.17.11:
|
||||
optional: true
|
||||
|
||||
parseurl@1.3.3: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
@ -1332,6 +1265,22 @@ snapshots:
|
||||
execa: 4.1.0
|
||||
get-stream: 5.2.0
|
||||
|
||||
playwright-core@1.61.0-alpha-1781023400000: {}
|
||||
|
||||
playwright-core@1.61.1: {}
|
||||
|
||||
playwright@1.61.0-alpha-1781023400000:
|
||||
dependencies:
|
||||
playwright-core: 1.61.0-alpha-1781023400000
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
playwright@1.61.1:
|
||||
dependencies:
|
||||
playwright-core: 1.61.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
powershell-utils@0.1.0: {}
|
||||
|
||||
proxy-addr@2.0.7:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user