Release v0.1.3

This commit is contained in:
winlifes
2026-05-11 05:30:48 -07:00
parent a903f7f0af
commit 69ab5710f6
9 changed files with 169 additions and 21 deletions
+28
View File
@@ -157,6 +157,32 @@ function selectAsset(uuid) {
return { selected: true, uuid };
}
function selectNode(uuid) {
if (!global.Editor || !Editor.Selection || typeof Editor.Selection.select !== 'function') {
throw new Error('Editor.Selection.select is unavailable in this Cocos environment.');
}
Editor.Selection.clear('node');
Editor.Selection.select('node', uuid);
return { selected: true, uuid };
}
function clearSelection(type) {
if (!global.Editor || !Editor.Selection || typeof Editor.Selection.clear !== 'function') {
throw new Error('Editor.Selection.clear is unavailable in this Cocos environment.');
}
const normalized = String(type || 'all').trim().toLowerCase();
if (normalized === 'asset' || normalized === 'node') {
Editor.Selection.clear(normalized);
return { cleared: true, type: normalized };
}
Editor.Selection.clear('asset');
Editor.Selection.clear('node');
return { cleared: true, type: 'all' };
}
function getCurrentSelection() {
if (!global.Editor || !Editor.Selection || typeof Editor.Selection.getSelected !== 'function') {
throw new Error('Editor.Selection API is unavailable in this Cocos environment.');
@@ -170,6 +196,7 @@ function getCurrentSelection() {
}
module.exports = {
clearSelection,
deleteAsset,
getCurrentSelection,
listAssets,
@@ -179,4 +206,5 @@ module.exports = {
queryAssetMeta,
queryAssetUrl,
selectAsset,
selectNode,
};
+7
View File
@@ -9,6 +9,7 @@ const DEFAULTS = {
toolProfile: 'core',
autostart: true,
maxInteractionLogEntries: 50,
lastClientTargetId: 'claude_code',
};
function getProjectPath() {
@@ -60,6 +61,11 @@ function normalizeProfile(value) {
return String(value || DEFAULTS.toolProfile).toLowerCase() === 'full' ? 'full' : 'core';
}
function normalizeClientTargetId(value) {
const normalized = String(value || '').trim();
return normalized || DEFAULTS.lastClientTargetId;
}
function loadConfig() {
const projectPath = getProjectPath();
const configPath = path.join(projectPath, 'funplay-cocos-mcp.config.json');
@@ -75,6 +81,7 @@ function loadConfig() {
maxInteractionLogEntries: Number.isInteger(fileConfig.maxInteractionLogEntries)
? Math.max(10, Math.min(500, fileConfig.maxInteractionLogEntries))
: DEFAULTS.maxInteractionLogEntries,
lastClientTargetId: normalizeClientTargetId(fileConfig.lastClientTargetId),
configPath,
configError: fileConfig.__error || '',
};
+85 -2
View File
@@ -3,6 +3,7 @@
const fs = require('fs');
const path = require('path');
const {
clearSelection,
deleteAsset,
getCurrentSelection,
listAssets,
@@ -11,6 +12,7 @@ const {
queryAssetInfo,
queryAssetMeta,
selectAsset,
selectNode,
} = require('./assets');
const { runScriptDiagnostics } = require('./diagnostics');
const { listWindows, sendKeyCombo, sendKeyPress, sendMouseClick, sendMouseDrag } = require('./input');
@@ -121,7 +123,7 @@ async function refreshAssets(projectPath, targetPath) {
return 'File written outside assets directory; no asset-db refresh was needed.';
}
function createToolRegistry({ getRuntimeContext, interactionLog, sceneBridge, editorExecutor }) {
function createToolRegistry({ getRuntimeContext, getStatus, interactionLog, sceneBridge, editorExecutor }) {
const tools = [
{
name: 'execute_javascript',
@@ -180,6 +182,87 @@ function createToolRegistry({ getRuntimeContext, interactionLog, sceneBridge, ed
return await editorExecutor({ code: args.code, args: args.args || {} });
},
},
{
name: 'get_editor_state',
profile: 'core',
description: '[specialist] Return a structured editor-state snapshot including project info, runtime server status, current selection, and visible Electron windows. Prefer this when you want one compact editor summary.',
inputSchema: createSchema({}, []),
handler: async () => {
const runtimeContext = getRuntimeContext();
const status = typeof getStatus === 'function' ? getStatus() : null;
let scene = null;
try {
const sceneInfo = await sceneBridge.call('getSceneInfo', { maxDepth: 1, includeComponents: false });
scene = sceneInfo
? {
sceneName: sceneInfo.sceneName,
uuid: sceneInfo.uuid,
childCount: sceneInfo.childCount,
}
: null;
} catch (error) {
scene = { error: error.message };
}
let windows = [];
try {
windows = listWindows();
} catch (error) {
windows = [{ error: error.message }];
}
return {
extensionName: runtimeContext.extensionName,
version: runtimeContext.version,
projectName: runtimeContext.projectName,
projectPath: runtimeContext.projectPath,
cocosVersion: runtimeContext.cocosVersion,
toolProfile: runtimeContext.config ? runtimeContext.config.toolProfile : 'core',
status,
selection: getCurrentSelection(),
scene,
windows,
};
},
},
{
name: 'get_selection',
profile: 'core',
description: '[specialist] Return the current editor selection in a compact structured form. Prefer this when selection state matters for the next action.',
inputSchema: createSchema({}, []),
handler: async () => getCurrentSelection(),
},
{
name: 'set_selection',
profile: 'core',
description: '[specialist] Set or clear the current editor selection for an asset or node. Use this when downstream editor workflows depend on selection state.',
inputSchema: createSchema(
{
type: { type: 'string', description: 'Selection target type: asset, node, or clear.' },
target: { type: 'string', description: 'Asset uuid/path/db url, or node uuid when type=node.' },
clearMode: { type: 'string', description: 'When type=clear, choose asset, node, or all.' },
},
['type']
),
handler: async (args) => {
const type = String(args.type || '').trim().toLowerCase();
if (type === 'clear') {
return clearSelection(args.clearMode || 'all');
}
if (type === 'asset') {
const info = await queryAssetInfo(args.target);
return selectAsset(info.uuid || args.target);
}
if (type === 'node') {
const target = String(args.target || '').trim();
if (!target) {
throw new Error('target is required when type=node.');
}
return selectNode(target);
}
throw new Error(`Unknown selection type '${args.type}'. Expected asset, node, or clear.`);
},
},
{
name: 'get_scene_info',
profile: 'core',
@@ -441,7 +524,7 @@ function createToolRegistry({ getRuntimeContext, interactionLog, sceneBridge, ed
{
name: 'get_editor_selection',
profile: 'full',
description: '[core] Return the current node and asset selection in the Cocos editor.',
description: '[compat] Return the current node and asset selection in the Cocos editor. Prefer get_selection as the primary structured selection read tool.',
inputSchema: createSchema({}, []),
handler: async () => getCurrentSelection(),
},