Патчи к code mode и доки по его настройке
This commit is contained in:
@@ -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.)
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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');
|
||||
Reference in New Issue
Block a user