Патчи к code mode и доки по его настройке

This commit is contained in:
ftc
2026-09-13 10:03:08 +03:00
parent 55959b6e7f
commit 7e3498bd7b
6 changed files with 1402 additions and 3 deletions
+102
View File
@@ -0,0 +1,102 @@
# Code Mode setup
The `cocos-code-mode` extension (in [extensions/cocos-code-mode](../extensions/cocos-code-mode))
runs an HTTP server inside the Cocos Creator editor and exposes scene, asset and
inspector operations as [UTCP](https://www.utcp.io/) tools. That is how the editor
is driven from outside the UI — see [CODE_MODE_TOOLS.md](CODE_MODE_TOOLS.md) for
the tool reference.
## Prerequisites
- Cocos Creator 3.8.8 must be **running with this project open**. The tool server
lives inside the editor process; if the editor is closed, there are no tools.
- The extension registers itself in `~/.utcp_config.json` on startup.
## The port changes on every editor restart
The server binds to `127.0.0.1` on an OS-assigned port, and rewrites
`~/.utcp_config.json` each time. Always read the config file rather than
remembering a port:
```bash
cat ~/.utcp_config.json
```
## Running a tool chain
Pass the config path via `UTCP_CONFIG_FILE`. The script body runs as an async
function; tool calls look synchronous and `return` gives back the result.
```bash
UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli run <<'EOF'
const tree = CocosEditor.nodeGetTree({});
return { name: tree.name, children: (tree.children || []).map(c => c.name) };
EOF
```
Discover tools by task instead of guessing names:
```bash
UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli search "add a sprite to a node"
```
## Working discipline
The tools are built around **discover, then act**:
1. `nodeGetTree` / `assetGetTree` — find the thing.
2. `inspectorGetInstanceDefinition` — get its real TypeScript class.
3. `inspectorSetInstanceProperties` — set properties by confirmed name.
`inspectorSetInstanceProperties` states it outright: if a property path or type
has not been confirmed via an `inspectorGet*` call, do not call a setter. Property
names differ from the engine docs often enough that guessing corrupts scenes.
Batch reads and writes into one `run` script — each `npx` invocation re-registers
the manual, which costs a few seconds.
## Regenerating the tool reference
After updating the extension:
```bash
curl -s "$(node -p "require(require('os').homedir()+'/.utcp_config.json').manual_call_templates[0].url")" -o manual.json
node docs/scripts/gen-tool-reference.js manual.json docs/CODE_MODE_TOOLS.md
```
## Known issue: `sharp` / libvips conflict on Windows
**Symptom.** The editor logs `The plug-in main process failed to load` with either
`Could not load the "sharp" module using the win32-x64 runtime` or
`TypeError: Cannot read properties of undefined (reading 'output')` at
`node_modules/sharp/lib/utility.js`. No `~/.utcp_config.json` appears and no tools
are reachable.
**Cause.** Two things stacked:
1. The released extension zip was packaged on macOS, so its bundled `sharp` ships
only `darwin-arm64` binaries.
2. More fundamentally, Cocos Creator already has its own `sharp` **0.32.6**
(libvips 8.14) resident in the same process. On Windows a second libvips cannot
be loaded beside the first, so the extension's `sharp` 0.34.x binds against the
editor's older DLL. That DLL has no JPEG 2000 support, `format.jp2k` comes back
undefined, and the module throws while initialising — taking the whole plugin
with it.
**Fix.** [asset-tools.js](../extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js)
now loads `sharp` lazily, prefers the editor's own resident build under
`process.resourcesPath/app.asar.unpacked/node_modules/sharp`, and tolerates it
being unavailable. `sharp` is only a fast path for `assetGetPreview`, which
already had a renderer-based fallback, so a missing image library no longer stops
the tool server from starting.
That file is tracked by git, so the fix survives — but **re-importing the extension
from a release zip will overwrite it.** If the extension is ever re-imported,
re-apply the patch and, on Windows, also install the matching native binaries:
```bash
cd extensions/cocos-code-mode && npm install --no-save --os=win32 --cpu=x64 --include=optional sharp@0.34.5
```
(`extensions/cocos-code-mode/node_modules` is gitignored, so that install does not
survive a clean checkout either.)
+485
View File
@@ -0,0 +1,485 @@
# Code Mode tool reference (`CocosEditor`)
Generated from the live UTCP manual served by the `cocos-code-mode` extension
(UTCP 1.0.1, 24 tools). Regenerate with the command in
[CODE_MODE_SETUP.md](CODE_MODE_SETUP.md) whenever the extension is updated.
All tools are called as `CocosEditor.<name>({ ... })` inside a `utcp run` script.
Calls look synchronous — the host bridges the async work, so no `await` is needed.
## Conventions
Nodes, components and assets are passed around as UUID handles:
```ts
interface IInstanceReference { id: string; type?: string; } // e.g. { id: "a1b2…", type: "cc.Sprite" }
```
Work **discover, then act**: get the tree, get the type definition, then set properties by name.
Never guess property names — `inspectorGetInstanceDefinition` returns the real TypeScript class.
## Scene graph
### `nodeGetTree`
Get the hierarchy tree of specific node or scene root if no reference is provided. Children have recursive structure.
```ts
CocosEditor.nodeGetTree(args: {
reference?: {
id: string;
type?: string;
};
}): {
path?: string;
reference: {
id: string;
type?: string;
};
name: string;
active: boolean;
components: {
id: string;
type?: string;
}[];
children: Record<string, unknown>[];
}
```
### `nodeGetAtPath`
Get nodes at specific path in the scene hierarchy. Usually returns one node, but can return multiple nodes with the same name.
```ts
CocosEditor.nodeGetAtPath(args: {
hierarchyPath: string; // Path to the node in the scene hierarchy"
}): {
references?: {
id: string;
type?: string;
}[];
}
```
### `nodeCreate`
Create a new node in the scene. If no parent is specified, root node is used. Returns reference to the new node.
```ts
CocosEditor.nodeCreate(args: {
name: string;
parentReference?: {
id: string;
type?: string;
};
assetReference?: {
id: string;
type?: string;
};
unwrapPrefab?: boolean; // default: false
}): {
reference: {
id: string;
type?: string;
};
}
```
### `nodeCreatePrimitive`
Create a new node with predefined primitive geometry MeshRenderer. If no parent is specified, root node is used. Returns reference to the new node.
```ts
CocosEditor.nodeCreatePrimitive(args: {
name: string;
primitiveType: "Capsule" | "Cone" | "Cube" | "Cylinder" | "Plane" | "Quad" | "Sphere" | "Torus";
parentReference?: {
id: string;
type?: string;
};
}): {
reference: {
id: string;
type?: string;
};
}
```
### `nodeOperate`
Perform operation on referenced node, including prefab operations.
```ts
CocosEditor.nodeOperate(args: {
operation: "move" | "copy" | "delete" | "create_prefab" | "revert_prefab" | "apply_prefab" | "unwrap_prefab" | "unwrap_prefab_completely" | "open_prefab";
reference: {
id: string;
type?: string;
};
newParentReference?: {
id: string;
type?: string;
};
newPrefabPath?: string; // For create_prefab: target db:// path
siblingIndex?: integer; // For move/copy: target index in parent children array
}): {
success?: boolean;
createdPrefabAssetReference?: {
id: string;
type?: string;
};
updatedNodeReference?: {
id: string;
type?: string;
};
copiedNodeReference?: {
id: string;
type?: string;
};
}
```
## Components
### `nodeComponentsGet`
Get components of specific type on a node. If componentType is not provided, returns all components on the node.
```ts
CocosEditor.nodeComponentsGet(args: {
reference: {
id: string;
type?: string;
};
componentType?: string;
}): {
references: {
id: string;
type?: string;
}[];
}
```
### `nodeComponentAdd`
Add a component to a referenced node, returns reference to the new component
```ts
CocosEditor.nodeComponentAdd(args: {
reference: {
id: string;
type?: string;
};
componentType: string;
}): {
reference: {
id: string;
type?: string;
};
}
```
### `nodeComponentRemove`
Remove referenced component from node it is attached to.
```ts
CocosEditor.nodeComponentRemove(args: {
reference: {
id: string;
type?: string;
};
}): {
success: boolean;
error?: string;
}
```
### `nodeGetAvailableComponentTypes`
Get list of globally available component types (class names) at the moment.
```ts
CocosEditor.nodeGetAvailableComponentTypes(args: {
includeInternal: boolean; // Whether to include internal engine components. — default: false
filter?: string; // Optional filter string to match component types or categories (case-insensitive substring match).
}): {
componentTypes: string[];
}
```
## Inspector (types & properties)
### `inspectorGetInstanceDefinition`
Generates TypeScript definition based on properties and descriptions of instance (Node, Component, Asset).
```ts
CocosEditor.inspectorGetInstanceDefinition(args: {
reference: {
id: string;
type?: string;
};
}): {
definition: string;
}
```
### `inspectorGetSettingsDefinition`
Generates TypeScript definition for specific settings.
```ts
CocosEditor.inspectorGetSettingsDefinition(args: {
settingsType: "CommonTypes" | "CurrentSceneGlobals" | "ProjectSettings";
}): {
definition: string;
}
```
### `inspectorGetInstanceProperties`
Gets plain object of properties, with no serialization info for any instance (scene node, component, asset).
```ts
CocosEditor.inspectorGetInstanceProperties(args: {
reference: {
id: string;
type?: string;
};
}): {
dump: Record<string, unknown>;
}
```
### `inspectorGetSettingsProperties`
Gets plain object of properties for the specific settings.
```ts
CocosEditor.inspectorGetSettingsProperties(args: {
settingsType: "CurrentSceneGlobals" | "ProjectSettings";
}): {
dump: Record<string, unknown>;
}
```
### `inspectorSetInstanceProperties`
Sets a property on instance of Node, Component or Asset. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter.
```ts
CocosEditor.inspectorSetInstanceProperties(args: {
reference: {
id: string;
type?: string;
};
propertyPaths: string[]; // Plain paths to the properties (e.g., ['position.x', 'rotation.y']). Don't support code execution. Arrays are reached by indexes. (e.g. 'sharedMaterials.0')
values: array,object,string,number,boolean,null[];
}): {
success: boolean;
error?: string;
}
```
### `inspectorSetSettingsProperties`
Sets a property on the specific settings. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter.
```ts
CocosEditor.inspectorSetSettingsProperties(args: {
settingsType: "CurrentSceneGlobals" | "ProjectSettings";
propertyPath: string; // Plain path to the property (e.g., 'ambient.skyLightingColor.r'). Don't support code execution.
value: array,object,string,number,boolean,null;
}): {
success: boolean;
error?: string;
}
```
## Assets
### `assetGetTree`
Get the asset and subAsset hierarchy tree. Children have recursive structure.
```ts
CocosEditor.assetGetTree(args: {
reference?: {
id: string;
type?: string;
};
assetPath?: string; // Root path to start from
}): {
filesystemPath?: string;
reference: {
id: string;
type?: string;
};
name: string;
children: Record<string, unknown>[];
}
```
### `assetGetAtPath`
Get asset reference by given local path and name, including extension. Can be used for subassets too. Returns reference to the asset.
```ts
CocosEditor.assetGetAtPath(args: {
assetPath: string;
}): {
reference: {
id: string;
type?: string;
};
}
```
### `assetCreate`
Create empty asset or folder of given type. Automatically handles folders creation along the path. Returns reference to the new asset.
```ts
CocosEditor.assetCreate(args: {
assetPath: string;
preset: "folder" | "material" | "effect" | "scene" | "prefab" | "typescript" | "animation-clip" | "render-texture" | "physics-material" | "animation-graph" | "animation-graph-variant" | "animation-mask" | "auto-atlas" | "effect-header" | "label-atlas" | "terrain"; // Preset type for the new asset
options?: {
overwrite?: boolean;
rename?: boolean;
}; // Additional options for the operation
}): {
reference: {
id: string;
type?: string;
};
}
```
### `assetImport`
Import an external file as an asset into the project. Path must end with the extension. Returns reference to the new asset.
```ts
CocosEditor.assetImport(args: {
sourceFilesystemPath: string; // Source filesystem path of the file to import
targetAssetPath: string; // Target path in the asset database
imageType?: "raw" | "texture" | "normal-map" | "sprite-frame" | "texture-cube"; // For image files, specify how to import them
options?: {
overwrite?: boolean;
rename?: boolean;
}; // Additional options for the operation
}): {
reference: {
id: string;
type?: string;
};
}
```
### `assetOperate`
Perform operations on assets (move, copy, delete, open). Returns reference to the affected asset (for delete/open returns the source asset reference).
```ts
CocosEditor.assetOperate(args: {
operation: "move" | "copy" | "delete" | "open" | "refresh" | "reimport";
reference: {
id: string;
type?: string;
};
targetAssetPath?: string; // Target path (for move/copy/import)
options?: {
overwrite?: boolean;
rename?: boolean;
}; // Additional options for the operation
}): {
reference: {
id: string;
type?: string;
};
}
```
### `assetGetPreview`
Returns preview image of the asset (Prefab, Image, Model or Material is supported). IMPORTANT: To visualize the image, you must return the result of this function DIRECTLY as the final value of your code, do NOT wrap it in an object.
```ts
CocosEditor.assetGetPreview(args: {
reference: {
id: string;
type?: string;
};
imageSize?: number; // Size of the preview image (square) — default: 512
jpegQuality?: integer; // JPEG Quality of the preview image — default: 80
transparentColor?: {
r: integer;
g: integer;
b: integer;
}; // Background color for transparent images in RGB format
}): {
type: string;
data: string;
mimeType: string;
}
```
## Editor
### `editorOperate`
Common editor operations for scene and prefab view, game preview controls and asset database refresh
```ts
CocosEditor.editorOperate(args: {
operation: "save_scene_or_prefab" | "close_scene_or_prefab" | "play_preview" | "pause" | "step" | "stop" | "refresh";
}): {
success: boolean;
error?: string;
}
```
### `editorGetLogs`
Get last N editor log entries
```ts
CocosEditor.editorGetLogs(args: {
count: number; // Number of log entries to retrieve — default: 10
showStack?: boolean; // Return full stack trace for each log entry
order: "newest-to-oldest" | "oldest-to-newest"; // Order of logs — default: "newest-to-oldest"
}): {
logLines: string[];
}
```
### `editorGetScenePreview`
Returns preview image of scene view. IMPORTANT: To visualize the image, you must return the result of this function DIRECTLY as the final value of your code, do NOT wrap it in an object.
```ts
CocosEditor.editorGetScenePreview(args: {
imageSize?: {
width?: number; // default: 512
height?: number; // default: 512
};
jpegQuality?: integer; // default: 80
cameraPosition: {
x: number;
y: number;
z: number;
}; // Camera world position
targetPosition: {
x: number;
y: number;
z: number;
}; // Point the camera looks at
orthographic?: boolean; // Whether to use orthographic projection — default: false
orthographicSize?: number; // Orthographic size (only applies if orthographic is true) — default: 10
}): {
type: string;
data: string;
mimeType: string;
}
```
+101
View File
@@ -0,0 +1,101 @@
const fs = require('fs');
const manual = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'));
function render(schema, indent) {
if (!schema) return 'unknown';
const pad = ' '.repeat(indent);
const padIn = ' '.repeat(indent + 1);
if (schema.enum) return schema.enum.map(v => JSON.stringify(v)).join(' | ');
switch (schema.type) {
case 'array':
return render(schema.items, indent) + '[]';
case 'object': {
if (!schema.properties) return 'Record<string, unknown>';
const req = schema.required || [];
const lines = Object.entries(schema.properties).map(([k, v]) => {
const opt = req.includes(k) ? '' : '?';
let line = `${padIn}${k}${opt}: ${render(v, indent + 1)};`;
const notes = [];
if (v.description) notes.push(v.description);
if (v.default !== undefined) notes.push(`default: ${JSON.stringify(v.default)}`);
if (notes.length) line += ` // ${notes.join(' — ')}`;
return line;
});
return `{\n${lines.join('\n')}\n${pad}}`;
}
case undefined:
return 'unknown';
default:
return schema.type;
}
}
const groups = [
['Scene graph', ['nodeGetTree', 'nodeGetAtPath', 'nodeCreate', 'nodeCreatePrimitive', 'nodeOperate']],
['Components', ['nodeComponentsGet', 'nodeComponentAdd', 'nodeComponentRemove', 'nodeGetAvailableComponentTypes']],
['Inspector (types & properties)', ['inspectorGetInstanceDefinition', 'inspectorGetSettingsDefinition', 'inspectorGetInstanceProperties', 'inspectorGetSettingsProperties', 'inspectorSetInstanceProperties', 'inspectorSetSettingsProperties']],
['Assets', ['assetGetTree', 'assetGetAtPath', 'assetCreate', 'assetImport', 'assetOperate', 'assetGetPreview']],
['Editor', ['editorOperate', 'editorGetLogs', 'editorGetScenePreview']],
];
const byName = new Map(manual.tools.map(t => [t.name, t]));
const out = [];
out.push('# Code Mode tool reference (`CocosEditor`)');
out.push('');
out.push('Generated from the live UTCP manual served by the `cocos-code-mode` extension');
out.push(`(UTCP ${manual.utcp_version}, ${manual.tools.length} tools). Regenerate with the command in`);
out.push('[CODE_MODE_SETUP.md](CODE_MODE_SETUP.md) whenever the extension is updated.');
out.push('');
out.push('All tools are called as `CocosEditor.<name>({ ... })` inside a `utcp run` script.');
out.push('Calls look synchronous — the host bridges the async work, so no `await` is needed.');
out.push('');
out.push('## Conventions');
out.push('');
out.push('Nodes, components and assets are passed around as UUID handles:');
out.push('');
out.push('```ts');
out.push('interface IInstanceReference { id: string; type?: string; } // e.g. { id: "a1b2…", type: "cc.Sprite" }');
out.push('```');
out.push('');
out.push('Work **discover, then act**: get the tree, get the type definition, then set properties by name.');
out.push('Never guess property names — `inspectorGetInstanceDefinition` returns the real TypeScript class.');
out.push('');
const seen = new Set();
for (const [title, names] of groups) {
out.push(`## ${title}`);
out.push('');
for (const name of names) {
const t = byName.get(name);
if (!t) continue;
seen.add(name);
out.push(`### \`${name}\``);
out.push('');
out.push(t.description);
out.push('');
out.push('```ts');
out.push(`CocosEditor.${name}(args: ${render(t.inputs, 0)}): ${render(t.outputs, 0)}`);
out.push('```');
out.push('');
}
}
const rest = manual.tools.filter(t => !seen.has(t.name));
if (rest.length) {
out.push('## Other');
out.push('');
for (const t of rest) {
out.push(`### \`${t.name}\``);
out.push('');
out.push(t.description);
out.push('');
out.push('```ts');
out.push(`CocosEditor.${t.name}(args: ${render(t.inputs, 0)}): ${render(t.outputs, 0)}`);
out.push('```');
out.push('');
}
}
fs.writeFileSync(process.argv[3], out.join('\n'));
console.log('wrote', process.argv[3], out.length, 'lines');
+31 -3
View File
@@ -44,7 +44,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetTools = void 0; exports.AssetTools = void 0;
const package_json_1 = __importDefault(require("../../../package.json")); const package_json_1 = __importDefault(require("../../../package.json"));
const sharp_1 = __importDefault(require("sharp")); let sharp_1;
/**
* Cocos Creator keeps its own sharp (0.32.6) resident in this process. On
* Windows a second libvips cannot be loaded beside it, so the copy bundled with
* this extension binds against the editor's older DLL and throws while loading.
* Prefer the editor's build, fall back to the bundled one, and tolerate neither
* being usable - asset previews fall back to the renderer-based path.
*/
function getSharp() {
if (sharp_1 !== undefined)
return sharp_1;
const { join } = require('path');
const candidates = [];
if (process.resourcesPath)
candidates.push(join(process.resourcesPath, 'app.asar.unpacked', 'node_modules', 'sharp'));
candidates.push('sharp');
for (const candidate of candidates) {
try {
sharp_1 = require(candidate);
return sharp_1;
}
catch (e) {
console.warn(`[cocos-code-mode] sharp not loadable from ${candidate}: ${e.message}`);
}
}
sharp_1 = null;
return sharp_1;
}
const fs_extra_1 = __importDefault(require("fs-extra")); const fs_extra_1 = __importDefault(require("fs-extra"));
const decorators_1 = require("../decorators"); const decorators_1 = require("../decorators");
const schemas_1 = require("../schemas"); const schemas_1 = require("../schemas");
@@ -333,9 +360,10 @@ class AssetTools {
sourcePath = fileInfo.file; sourcePath = fileInfo.file;
} }
} }
if (sourcePath && fs_extra_1.default.existsSync(sourcePath)) { const sharp = sourcePath ? getSharp() : null;
if (sharp && fs_extra_1.default.existsSync(sourcePath)) {
try { try {
const image = (0, sharp_1.default)(sourcePath); const image = sharp(sourcePath);
const metadata = await image.metadata(); const metadata = await image.metadata();
const requestedSize = args.imageSize || 512; const requestedSize = args.imageSize || 512;
let processed = image; let processed = image;
+679
View File
@@ -0,0 +1,679 @@
{
"name": "fool-cardgame",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "fool-cardgame",
"dependencies": {
"@utcp/code-mode": "^1.2.13",
"sharp": "^0.35.4"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.11.3",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
"integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@img/colour": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
"integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz",
"integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.3.3"
}
},
"node_modules/@img/sharp-darwin-x64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz",
"integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.3.3"
}
},
"node_modules/@img/sharp-freebsd-wasm32": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz",
"integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==",
"license": "Apache-2.0",
"optional": true,
"os": [
"freebsd"
],
"dependencies": {
"@img/sharp-wasm32": "0.35.4"
},
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz",
"integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz",
"integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz",
"integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==",
"cpu": [
"arm"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz",
"integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-ppc64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz",
"integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==",
"cpu": [
"ppc64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-riscv64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz",
"integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==",
"cpu": [
"riscv64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz",
"integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==",
"cpu": [
"s390x"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz",
"integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz",
"integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz",
"integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz",
"integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==",
"cpu": [
"arm"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.3.3"
}
},
"node_modules/@img/sharp-linux-arm64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz",
"integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.3.3"
}
},
"node_modules/@img/sharp-linux-ppc64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz",
"integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==",
"cpu": [
"ppc64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-ppc64": "1.3.3"
}
},
"node_modules/@img/sharp-linux-riscv64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz",
"integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==",
"cpu": [
"riscv64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-riscv64": "1.3.3"
}
},
"node_modules/@img/sharp-linux-s390x": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz",
"integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==",
"cpu": [
"s390x"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-s390x": "1.3.3"
}
},
"node_modules/@img/sharp-linux-x64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz",
"integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.3.3"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz",
"integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-arm64": "1.3.3"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz",
"integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linuxmusl-x64": "1.3.3"
}
},
"node_modules/@img/sharp-wasm32": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz",
"integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==",
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
"@emnapi/runtime": "^1.11.3"
},
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-webcontainers-wasm32": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz",
"integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==",
"cpu": [
"wasm32"
],
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"@img/sharp-wasm32": "0.35.4"
},
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-arm64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz",
"integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz",
"integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==",
"cpu": [
"ia32"
],
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz",
"integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@utcp/code-mode": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/@utcp/code-mode/-/code-mode-1.2.13.tgz",
"integrity": "sha512-HbDjHdOos/b5ZuU0hezvn8cJy6KUJ/NXxFlnb+iTRX6X30t9c2DxWJfJtz9EsSOVYBrN7Bh72e/S47MOPmK9bg==",
"license": "MPL-2.0",
"engines": {
"node": ">=18.0.0"
},
"peerDependencies": {
"@utcp/sdk": "^1.1.0",
"isolated-vm": "^6.0.0"
},
"peerDependenciesMeta": {
"isolated-vm": {
"optional": false
}
}
},
"node_modules/@utcp/sdk": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@utcp/sdk/-/sdk-1.1.2.tgz",
"integrity": "sha512-YOBhcOK5kbD27d3emuXNAb8gBb8nH2kr7BuqjrvmSGyUi9379jzusYeTuZDsAxyy5da9VZPnfC/cNCpTVkEtUw==",
"license": "MPL-2.0",
"peer": true,
"dependencies": {
"dotenv": "^17.2.1",
"zod": "^3.23.8"
}
},
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
}
},
"node_modules/dotenv": {
"version": "17.4.2",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
"integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/isolated-vm": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-6.2.0.tgz",
"integrity": "sha512-UuSlxSHWt2QuJ5WvBhzlIJx2VVZN/a44SqBbEZFKNdvuSyhOvhmyDo8SQ+njVbhnh/njoL/aW0bUTiFYlpweGQ==",
"hasInstallScript": true,
"license": "ISC",
"peer": true,
"dependencies": {
"node-gyp-build": "^4.8.4"
},
"engines": {
"node": ">=22.0.0"
}
},
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"license": "MIT",
"peer": true,
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/semver": {
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/sharp": {
"version": "0.35.4",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz",
"integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==",
"license": "Apache-2.0",
"dependencies": {
"@img/colour": "^1.1.0",
"detect-libc": "^2.1.2",
"semver": "^7.8.5"
},
"engines": {
"node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-darwin-arm64": "0.35.4",
"@img/sharp-darwin-x64": "0.35.4",
"@img/sharp-freebsd-wasm32": "0.35.4",
"@img/sharp-libvips-darwin-arm64": "1.3.3",
"@img/sharp-libvips-darwin-x64": "1.3.3",
"@img/sharp-libvips-linux-arm": "1.3.3",
"@img/sharp-libvips-linux-arm64": "1.3.3",
"@img/sharp-libvips-linux-ppc64": "1.3.3",
"@img/sharp-libvips-linux-riscv64": "1.3.3",
"@img/sharp-libvips-linux-s390x": "1.3.3",
"@img/sharp-libvips-linux-x64": "1.3.3",
"@img/sharp-libvips-linuxmusl-arm64": "1.3.3",
"@img/sharp-libvips-linuxmusl-x64": "1.3.3",
"@img/sharp-linux-arm": "0.35.4",
"@img/sharp-linux-arm64": "0.35.4",
"@img/sharp-linux-ppc64": "0.35.4",
"@img/sharp-linux-riscv64": "0.35.4",
"@img/sharp-linux-s390x": "0.35.4",
"@img/sharp-linux-x64": "0.35.4",
"@img/sharp-linuxmusl-arm64": "0.35.4",
"@img/sharp-linuxmusl-x64": "0.35.4",
"@img/sharp-webcontainers-wasm32": "0.35.4",
"@img/sharp-win32-arm64": "0.35.4",
"@img/sharp-win32-ia32": "0.35.4",
"@img/sharp-win32-x64": "0.35.4"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
}
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD",
"optional": true
},
"node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}
+4
View File
@@ -3,5 +3,9 @@
"uuid": "2d8862c1-33e6-4159-bb31-fc590692a1e5", "uuid": "2d8862c1-33e6-4159-bb31-fc590692a1e5",
"creator": { "creator": {
"version": "3.8.8" "version": "3.8.8"
},
"dependencies": {
"@utcp/code-mode": "^1.2.13",
"sharp": "^0.35.4"
} }
} }