@mearl/native-host 2.22.5 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -962,7 +962,7 @@ except BaseException as error:
962
962
  "message": "返回值无法 JSON 序列化: " + _error_message(serialization_error),
963
963
  })
964
964
  sys.exit(1)
965
- `}});import{randomUUID}from"node:crypto";import{linkSync as linkSync2,mkdirSync as mkdirSync4,readFileSync as readFileSync7,rmSync as rmSync5,writeFileSync as writeFileSync4}from"node:fs";import{join as join8}from"node:path";function localPluginExecutionHost(){let directory=pluginDirectory(),hostId=hostIds.get(directory);if(!hostId){mkdirSync4(directory,{recursive:!0,mode:448});let file=join8(directory,".execution-host-id"),proposed=randomUUID(),temporary=`${file}.${proposed}.tmp`;try{writeFileSync4(temporary,proposed,{flag:"wx",mode:384}),linkSync2(temporary,file)}catch(error){if(error.code!=="EEXIST")throw error}finally{rmSync5(temporary,{force:!0})}if(hostId=readFileSync7(file,"utf8").trim(),!UUID.test(hostId))throw new Error("Invalid plugin execution host identity");hostIds.set(directory,hostId)}return Object.freeze({hostId,epoch})}function createPluginInvocationIdentity(plugin,source,parent){return Object.freeze({invocationId:randomUUID(),host:parent?.host??localPluginExecutionHost(),plugin,source,...parent?{parentInvocationId:parent.invocationId}:{}})}var epoch,hostIds,UUID,init_pluginExecution=__esm({"../client/src/plugins/runtime/pluginExecution.ts"(){"use strict";init_pluginRegistry();epoch=randomUUID(),hostIds=new Map,UUID=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i}});import{execFile}from"node:child_process";var init_pluginProcessTree=__esm({"../client/src/plugins/runtime/pluginProcessTree.ts"(){"use strict";init_dist()}});import{fork as fork2}from"node:child_process";var init_pluginExecutor=__esm({"../client/src/plugins/runtime/pluginExecutor.ts"(){"use strict";init_runtimePaths();init_pluginRegistry();init_pluginSource();init_pluginExecution();init_pluginExecutorProtocol();init_pluginProcessTree();init_dist()}});import{tmpdir}from"node:os";import{join as join9}from"node:path";var init_pluginHostPaths=__esm({"../client/src/plugins/runtime/pluginHostPaths.ts"(){"use strict";init_pluginRegistry()}});var init_plugin_tasks=__esm({"../client/src/generated/plugin-tasks.ts"(){"use strict"}});var MAX_MESSAGE_BYTES,init_pluginTaskWire=__esm({"../client/src/plugins/pluginTaskWire.ts"(){"use strict";MAX_MESSAGE_BYTES=96*1024*1024}});import{spawn as spawn5}from"node:child_process";import{closeSync as closeSync5,mkdirSync as mkdirSync5,openSync as openSync5}from"node:fs";import{createConnection}from"node:net";var init_pluginHostConnection=__esm({"../client/src/plugins/clients/pluginHostConnection.ts"(){"use strict";init_runtimePaths();init_dist();init_pluginHostPaths();init_plugin_tasks();init_pluginTaskWire();init_pluginExecutorProtocol()}});import{open,mkdir,rename,rm,stat}from"node:fs/promises";import path2 from"node:path";var CHUNK_BYTES,init_artifacts=__esm({"../client/src/artifacts.ts"(){"use strict";CHUNK_BYTES=256*1024}});var init_dist2=__esm({"../cloud/cloud-types/dist/index.js"(){"use strict"}});var OBSERVED_PAGE_ACTIONS,init_actionTimeouts=__esm({"../client/src/actionTimeouts.ts"(){"use strict";init_browser_action_protocol();OBSERVED_PAGE_ACTIONS=new Set(PAGE_ACT_ACTIONS)}});var init_protocol=__esm({"../provider/dist/protocol.js"(){"use strict"}});var init_types=__esm({"../provider/dist/types.js"(){"use strict";init_protocol()}});var PROVIDER_ACTIONS,providerActionSet,init_provider_actions=__esm({"../provider/dist/generated/provider-actions.js"(){"use strict";PROVIDER_ACTIONS=["tab_checkpoint","capture_checkpoint","get_requests","get_logs","get_events","set_mock","get_mocks","set_rule","get_rules","send_request","send_mtop_request","browser_release","page_screenshot","tab_open","tab_close","tab_list","tab_group","page_click","page_drag","page_type","page_scroll","page_hover","page_eval","page_runtime","page_inspect","page_snapshot","page_press","page_wait","page_navigate","page_upload","page_frames","set_device_emulation","set_app_profile","set_timezone","get_cookie","set_cookie","request_domain_permission","run_actions","page_download"],providerActionSet=new Set(PROVIDER_ACTIONS)}});var init_provider_runtime=__esm({"../provider/dist/provider-runtime.js"(){"use strict";init_types();init_provider_actions()}});import{existsSync as existsSync4,readFileSync as readFileSync8,renameSync as renameSync5,rmSync as rmSync6,statSync as statSync6,writeFileSync as writeFileSync5}from"node:fs";import{isAbsolute as isAbsolute4,join as join10,relative as relative3,resolve as resolve4,sep as sep2}from"node:path";var init_registry2=__esm({"../provider/dist/registry.js"(){"use strict";init_dist();init_types();init_provider_runtime();init_protocol()}});import{spawn as spawn6}from"node:child_process";import{tmpdir as tmpdir2}from"node:os";import{join as join11}from"node:path";var init_control_host=__esm({"../provider/dist/control-host.js"(){"use strict";init_protocol();init_dist()}});var init_host=__esm({"../provider/dist/host.js"(){"use strict";init_registry2();init_control_host()}});import net from"node:net";import{chmodSync,rmSync as rmSync7}from"node:fs";import{dirname as dirname5}from"node:path";var MAX_REQUEST_BYTES,init_server=__esm({"../provider/dist/server.js"(){"use strict";init_dist();init_provider_actions();init_provider_runtime();init_registry2();init_types();init_protocol();MAX_REQUEST_BYTES=16*1024*1024}});var init_dist3=__esm({"../provider/dist/index.js"(){"use strict";init_types();init_protocol();init_provider_actions();init_registry2();init_provider_runtime();init_server()}});import{spawn as spawn7}from"node:child_process";import{closeSync as closeSync6,existsSync as existsSync5,mkdirSync as mkdirSync6,openSync as openSync6}from"node:fs";import{join as join12}from"node:path";var init_launcher=__esm({"../provider/dist/launcher.js"(){"use strict";init_dist();init_registry2();init_protocol()}});var init_runtime=__esm({"../provider/dist/runtime.js"(){"use strict";init_launcher();init_registry2();init_provider_runtime()}});import fs2 from"node:fs";var init_fileRefs=__esm({"../client/src/fileRefs.ts"(){"use strict"}});import fs3 from"node:fs";import os from"node:os";import path3 from"node:path";var BROWSERS_DIR,init_browserRegistry=__esm({"../client/src/browserRegistry.ts"(){"use strict";BROWSERS_DIR=path3.join(os.homedir(),".mearl","browsers")}});import net2 from"node:net";import fs4 from"node:fs";import os2 from"node:os";import path4 from"node:path";var MAX_SOCKET_BUFFER_SIZE,SOCKET_PATH,SESSION_OPTION,init_socket=__esm({"../client/src/socket.ts"(){"use strict";init_runtimePaths();init_host();init_dist3();init_runtime();init_fileRefs();init_browserRegistry();init_actionTimeouts();init_browser_action_protocol();MAX_SOCKET_BUFFER_SIZE=64*1024*1024,SOCKET_PATH=process.platform==="win32"?"\\\\.\\pipe\\mearl-agent":path4.join(os2.tmpdir(),"mearl-agent.sock"),SESSION_OPTION=Symbol("control-session")}});import{existsSync as existsSync6,readFileSync as readFileSync9}from"node:fs";import{homedir as homedir3}from"node:os";import{join as join13}from"node:path";var MEARL_CONFIG_DIR,init_unifiedConfig=__esm({"../client/src/unifiedConfig.ts"(){"use strict";MEARL_CONFIG_DIR=join13(homedir3(),".mearl")}});import WebSocket from"ws";var init_unified=__esm({"../client/src/unified.ts"(){"use strict";init_pageEvalArguments();init_artifacts();init_dist2();init_actionTimeouts();init_browser_action_protocol();init_socket();init_unifiedConfig()}});var init_pluginTasks=__esm({"../client/src/plugins/clients/pluginTasks.ts"(){"use strict";init_pluginHostConnection();init_dist();init_pluginHostPaths();init_unified();init_plugin_tasks();init_pluginExecutorProtocol()}});import{closeSync as closeSync7,fsyncSync,mkdirSync as mkdirSync7,openSync as openSync7,renameSync as renameSync6,rmSync as rmSync8,writeFileSync as writeFileSync6}from"node:fs";import{dirname as dirname6}from"node:path";var init_pluginHostFiles=__esm({"../client/src/plugins/runtime/pluginHostFiles.ts"(){"use strict"}});import{closeSync as closeSync8,openSync as openSync8,opendirSync,readFileSync as readFileSync10,readSync as readSync2,readdirSync as readdirSync5,rmSync as rmSync9,statSync as statSync7}from"node:fs";import{join as join14}from"node:path";var PLUGIN_TASK_RESULT_CHUNK_BYTES,MAX_EVENT_BYTES,MAX_RESULT_BYTES,RETENTION_MS,init_pluginTaskStore=__esm({"../client/src/plugins/runtime/pluginTaskStore.ts"(){"use strict";init_plugin_tasks();init_pluginHostFiles();init_pluginHostPaths();init_dist();PLUGIN_TASK_RESULT_CHUNK_BYTES=192*1024,MAX_EVENT_BYTES=512*1024,MAX_RESULT_BYTES=64*1024*1024,RETENTION_MS=10080*60*1e3}});import{rmSync as rmSync10}from"node:fs";var init_pluginRuntimeCleanup=__esm({"../client/src/plugins/runtime/pluginRuntimeCleanup.ts"(){"use strict";init_dist();init_pluginHostPaths();init_pluginRegistry();init_pluginTasks();init_pluginTaskStore()}});var init_pluginPages=__esm({"../client/src/plugins/clients/pluginPages.ts"(){"use strict";init_unified()}});var init_pluginState=__esm({"../client/src/plugins/clients/pluginState.ts"(){"use strict";init_pluginHostConnection()}});var init_pluginModels=__esm({"../client/src/plugins/clients/pluginModels.ts"(){"use strict";init_pluginTasks()}});import{readFileSync as readFileSync11}from"node:fs";import{dirname as dirname7,extname as extname2,resolve as resolve5}from"node:path";import{pathToFileURL}from"node:url";function readPluginVersion(entry){try{let manifest=skillManifestPath(resolve5(dirname7(entry),".."));return manifest?readFileSync11(manifest,"utf8").match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1]?.split(/\r?\n/).find(line=>/^version:\s*/.test(line))?.match(/^version:\s*["']?([^"'#\s]+)["']?\s*$/)?.[1]:void 0}catch{return}}function isObject2(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isPluginInvocation(value){return isObject2(value)&&typeof value.command=="string"&&isObject2(value.input)}function normalizePluginProgress(progress){if(typeof progress=="string"){if(!progress)throw new Error("app.progress 需要非空消息");return progress}if(!isObject2(progress)||typeof progress.message!="string"||!progress.message)throw new Error("app.progress 需要非空消息");if(progress.data!==void 0&&!isObject2(progress.data))throw new Error("app.progress data 必须是对象");let data;if(progress.data)try{let serialized=JSON.stringify(progress.data),parsed=serialized===void 0?void 0:JSON.parse(serialized);if(!isObject2(parsed))throw new Error("invalid object");data=Object.freeze(parsed)}catch{throw new Error("app.progress data 必须是可 JSON 序列化的对象")}return Object.freeze({message:progress.message,...data?{data}:{}})}function missingPluginEntryMessage(entry,pluginName){let name=pluginName??"<name>";return["插件入口已失效","",`插件:${name}`,`入口:${entry}`,"",`卸载命令:npx @mearl/setup plugin uninstall ${name}`].join(`
965
+ `}});import{randomUUID}from"node:crypto";import{linkSync as linkSync2,mkdirSync as mkdirSync4,readFileSync as readFileSync7,rmSync as rmSync5,writeFileSync as writeFileSync4}from"node:fs";import{join as join8}from"node:path";function localPluginExecutionHost(){let directory=pluginDirectory(),hostId=hostIds.get(directory);if(!hostId){mkdirSync4(directory,{recursive:!0,mode:448});let file=join8(directory,".execution-host-id"),proposed=randomUUID(),temporary=`${file}.${proposed}.tmp`;try{writeFileSync4(temporary,proposed,{flag:"wx",mode:384}),linkSync2(temporary,file)}catch(error){if(error.code!=="EEXIST")throw error}finally{rmSync5(temporary,{force:!0})}if(hostId=readFileSync7(file,"utf8").trim(),!UUID.test(hostId))throw new Error("Invalid plugin execution host identity");hostIds.set(directory,hostId)}return Object.freeze({hostId,epoch})}function createPluginInvocationIdentity(plugin,source,parent){return Object.freeze({invocationId:randomUUID(),host:parent?.host??localPluginExecutionHost(),plugin,source,...parent?{parentInvocationId:parent.invocationId}:{}})}var epoch,hostIds,UUID,init_pluginExecution=__esm({"../client/src/plugins/runtime/pluginExecution.ts"(){"use strict";init_pluginRegistry();epoch=randomUUID(),hostIds=new Map,UUID=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i}});import{execFile}from"node:child_process";var init_pluginProcessTree=__esm({"../client/src/plugins/runtime/pluginProcessTree.ts"(){"use strict";init_dist()}});import{fork as fork2}from"node:child_process";var init_pluginExecutor=__esm({"../client/src/plugins/runtime/pluginExecutor.ts"(){"use strict";init_runtimePaths();init_pluginRegistry();init_pluginSource();init_pluginExecution();init_pluginExecutorProtocol();init_pluginProcessTree();init_dist()}});import{tmpdir}from"node:os";import{join as join9}from"node:path";var init_pluginHostPaths=__esm({"../client/src/plugins/runtime/pluginHostPaths.ts"(){"use strict";init_pluginRegistry()}});var init_plugin_tasks=__esm({"../client/src/generated/plugin-tasks.ts"(){"use strict"}});var MAX_MESSAGE_BYTES,init_pluginTaskWire=__esm({"../client/src/plugins/pluginTaskWire.ts"(){"use strict";MAX_MESSAGE_BYTES=96*1024*1024}});import{spawn as spawn5}from"node:child_process";import{closeSync as closeSync5,mkdirSync as mkdirSync5,openSync as openSync5}from"node:fs";import{createConnection}from"node:net";var init_pluginHostConnection=__esm({"../client/src/plugins/clients/pluginHostConnection.ts"(){"use strict";init_runtimePaths();init_dist();init_pluginHostPaths();init_plugin_tasks();init_pluginTaskWire();init_pluginExecutorProtocol()}});import{open,mkdir,rename,rm,stat}from"node:fs/promises";import path2 from"node:path";var CHUNK_BYTES,init_artifacts=__esm({"../client/src/artifacts.ts"(){"use strict";CHUNK_BYTES=256*1024}});var init_dist2=__esm({"../cloud/cloud-types/dist/index.js"(){"use strict"}});var OBSERVED_PAGE_ACTIONS,init_actionTimeouts=__esm({"../client/src/actionTimeouts.ts"(){"use strict";init_browser_action_protocol();OBSERVED_PAGE_ACTIONS=new Set(PAGE_ACT_ACTIONS)}});var init_protocol=__esm({"../provider/dist/protocol.js"(){"use strict"}});var init_types=__esm({"../provider/dist/types.js"(){"use strict";init_protocol()}});var PROVIDER_ACTIONS,providerActionSet,init_provider_actions=__esm({"../provider/dist/generated/provider-actions.js"(){"use strict";PROVIDER_ACTIONS=["tab_checkpoint","capture_checkpoint","get_requests","get_logs","get_events","set_mock","get_mocks","set_rule","get_rules","send_request","send_mtop_request","browser_release","page_screenshot","tab_open","tab_close","tab_list","tab_group","page_click","page_drag","page_type","page_scroll","page_hover","page_eval","page_runtime","page_inspect","page_snapshot","page_press","page_wait","page_navigate","page_upload","page_frames","set_device_emulation","set_app_profile","set_timezone","get_cookie","set_cookie","request_domain_permission","run_actions","page_download"],providerActionSet=new Set(PROVIDER_ACTIONS)}});var init_provider_runtime=__esm({"../provider/dist/provider-runtime.js"(){"use strict";init_types();init_provider_actions()}});import{existsSync as existsSync4,readFileSync as readFileSync8,renameSync as renameSync5,rmSync as rmSync6,statSync as statSync6,writeFileSync as writeFileSync5}from"node:fs";import{isAbsolute as isAbsolute4,join as join10,relative as relative3,resolve as resolve4,sep as sep2}from"node:path";var init_registry2=__esm({"../provider/dist/registry.js"(){"use strict";init_dist();init_types();init_provider_runtime();init_protocol()}});import{spawn as spawn6}from"node:child_process";import{tmpdir as tmpdir2}from"node:os";import{join as join11}from"node:path";var init_control_host=__esm({"../provider/dist/control-host.js"(){"use strict";init_protocol();init_dist()}});var init_host=__esm({"../provider/dist/host.js"(){"use strict";init_registry2();init_control_host()}});import net from"node:net";import{chmodSync,rmSync as rmSync7}from"node:fs";import{dirname as dirname5}from"node:path";var MAX_REQUEST_BYTES,init_server=__esm({"../provider/dist/server.js"(){"use strict";init_dist();init_provider_actions();init_provider_runtime();init_registry2();init_types();init_protocol();MAX_REQUEST_BYTES=16*1024*1024}});var init_dist3=__esm({"../provider/dist/index.js"(){"use strict";init_types();init_protocol();init_provider_actions();init_registry2();init_provider_runtime();init_server()}});import{spawn as spawn7}from"node:child_process";import{closeSync as closeSync6,existsSync as existsSync5,mkdirSync as mkdirSync6,openSync as openSync6}from"node:fs";import{join as join12}from"node:path";var init_launcher=__esm({"../provider/dist/launcher.js"(){"use strict";init_dist();init_registry2();init_protocol()}});var init_runtime=__esm({"../provider/dist/runtime.js"(){"use strict";init_launcher();init_registry2();init_provider_runtime()}});import fs2 from"node:fs";var init_fileRefs=__esm({"../client/src/fileRefs.ts"(){"use strict"}});import fs3 from"node:fs";import os from"node:os";import path3 from"node:path";var BROWSERS_DIR,init_browserRegistry=__esm({"../client/src/browserRegistry.ts"(){"use strict";BROWSERS_DIR=path3.join(os.homedir(),".mearl","browsers")}});import net2 from"node:net";import fs4 from"node:fs";import os2 from"node:os";import path4 from"node:path";var MAX_SOCKET_BUFFER_SIZE,SOCKET_PATH,SESSION_OPTION,init_socket=__esm({"../client/src/socket.ts"(){"use strict";init_runtimePaths();init_host();init_dist3();init_runtime();init_fileRefs();init_browserRegistry();init_actionTimeouts();init_browser_action_protocol();MAX_SOCKET_BUFFER_SIZE=64*1024*1024,SOCKET_PATH=process.platform==="win32"?"\\\\.\\pipe\\mearl-agent":path4.join(os2.tmpdir(),"mearl-agent.sock"),SESSION_OPTION=Symbol("control-session")}});import{existsSync as existsSync6,readFileSync as readFileSync9}from"node:fs";import{homedir as homedir3}from"node:os";import{join as join13}from"node:path";var MEARL_CONFIG_DIR,init_unifiedConfig=__esm({"../client/src/unifiedConfig.ts"(){"use strict";MEARL_CONFIG_DIR=join13(homedir3(),".mearl")}});import WebSocket from"ws";var init_unified=__esm({"../client/src/unified.ts"(){"use strict";init_pageEvalArguments();init_artifacts();init_dist2();init_actionTimeouts();init_browser_action_protocol();init_socket();init_unifiedConfig()}});var init_pluginTasks=__esm({"../client/src/plugins/clients/pluginTasks.ts"(){"use strict";init_pluginHostConnection();init_dist();init_pluginHostPaths();init_unified();init_plugin_tasks();init_pluginExecutorProtocol()}});import{closeSync as closeSync7,fsyncSync,mkdirSync as mkdirSync7,openSync as openSync7,renameSync as renameSync6,rmSync as rmSync8,writeFileSync as writeFileSync6}from"node:fs";import{dirname as dirname6}from"node:path";var init_pluginHostFiles=__esm({"../client/src/plugins/runtime/pluginHostFiles.ts"(){"use strict"}});import{closeSync as closeSync8,openSync as openSync8,opendirSync,readFileSync as readFileSync10,readSync as readSync2,readdirSync as readdirSync5,rmSync as rmSync9,statSync as statSync7}from"node:fs";import{join as join14}from"node:path";var PLUGIN_TASK_RESULT_CHUNK_BYTES,MAX_EVENT_BYTES,MAX_RESULT_BYTES,RETENTION_MS,init_pluginTaskStore=__esm({"../client/src/plugins/runtime/pluginTaskStore.ts"(){"use strict";init_plugin_tasks();init_pluginHostFiles();init_pluginHostPaths();init_dist();PLUGIN_TASK_RESULT_CHUNK_BYTES=192*1024,MAX_EVENT_BYTES=512*1024,MAX_RESULT_BYTES=64*1024*1024,RETENTION_MS=10080*60*1e3}});import{rmSync as rmSync10}from"node:fs";var init_pluginRuntimeCleanup=__esm({"../client/src/plugins/runtime/pluginRuntimeCleanup.ts"(){"use strict";init_dist();init_pluginHostPaths();init_pluginRegistry();init_pluginTasks();init_pluginTaskStore()}});var init_pluginPages=__esm({"../client/src/plugins/clients/pluginPages.ts"(){"use strict";init_unified()}});var init_pluginState=__esm({"../client/src/plugins/clients/pluginState.ts"(){"use strict";init_pluginHostConnection()}});var init_pluginModels=__esm({"../client/src/plugins/clients/pluginModels.ts"(){"use strict";init_pluginTasks()}});import{readFileSync as readFileSync11}from"node:fs";import{dirname as dirname7,extname as extname2,resolve as resolve5}from"node:path";import{pathToFileURL}from"node:url";function readPluginVersion(entry){try{let manifest=skillManifestPath(resolve5(dirname7(entry),".."));return manifest?readFileSync11(manifest,"utf8").match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1]?.split(/\r?\n/).find(line=>/^version:\s*/.test(line))?.match(/^version:\s*["']?([^"'#\s]+)["']?\s*$/)?.[1]:void 0}catch{return}}function isObject2(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function isPluginInvocation(value){return isObject2(value)&&typeof value.command=="string"&&isObject2(value.input)}function normalizePluginProgress(progress){if(typeof progress=="string"){if(!progress)throw new Error("app.progress 需要非空消息");return progress}if(!isObject2(progress)||typeof progress.message!="string"||!progress.message)throw new Error("app.progress 需要非空消息");if(progress.data!==void 0&&!isObject2(progress.data))throw new Error("app.progress data 必须是对象");let data;if(progress.data)try{let serialized=JSON.stringify(progress.data),parsed=serialized===void 0?void 0:JSON.parse(serialized);if(!isObject2(parsed))throw new Error("invalid object");data=Object.freeze(parsed)}catch{throw new Error("app.progress data 必须是可 JSON 序列化的对象")}return Object.freeze({message:progress.message,...data?{data}:{}})}function missingPluginEntryMessage(entry,pluginName){let name=pluginName??"<name>";return["插件入口已失效","",`插件:${name}`,`入口:${entry}`,"",`卸载命令:npx @mearl/setup@2 plugin uninstall ${name}`].join(`
966
966
  `)}async function loadPlugin(entry,context,pluginName){let entryVersion;try{entryVersion=pluginFileVersion(entry)}catch{throw new PluginError("PLUGIN_ENTRY_MISSING",missingPluginEntryMessage(entry,pluginName))}let commands=new Map,recoveries=new Map,migrations=new Map,executing=!1,checkpointDeclaration,invocationGeneration=0,registering=!0,name,description,toolbox,pageRuntime,stateStorage,taskRecovery,appProfiles,profileSources,registerCommand=(signature,handler,description2="",examples=[],toolboxOnly=!1,runtimeOnly=!1)=>{if(!registering)throw new Error("命令只能在入口注册阶段声明");let[name2,...args]=signature.trim().split(/\s+/);if(!/^[a-z][a-z0-9-]*$/.test(name2)||commands.has(name2)||typeof handler!="function"||!Array.isArray(examples)||examples.some(example=>typeof example!="string"||!example.trim()))throw new Error(`无效或重复的命令: ${signature}`);let command=new Command(name2).description(description2);for(let argument of args){if(!/^(?:<[a-zA-Z][\w-]*(?:\.\.\.)?>|\[[a-zA-Z][\w-]*(?:\.\.\.)?\])$/.test(argument))throw new Error(`无效的位置参数: ${argument}`);command.argument(argument)}let names=command.registeredArguments.map(argument=>argument.name());if(new Set(names).size!==names.length)throw new Error(`参数名称重复: ${signature}`);commands.set(name2,{command,signature,handler,examples:[...examples],toolboxOnly,runtimeOnly})},app=Object.freeze({options:Object.freeze({...context.options}),command:(signature,handler,description2="",examples=[])=>registerCommand(signature,handler,description2,examples),runtimeCommand:(signature,handler,description2="",examples=[])=>registerCommand(signature,handler,description2,examples,!1,!0),recoveryCommand(command,handler){if(!registering||!/^[a-z][a-z0-9-]*$/.test(command)||typeof handler!="function"||recoveries.has(command))throw new Error("Invalid or duplicate recovery command");recoveries.set(command,handler)},checkpointMigration(command,handler){if(!registering||!/^[a-z][a-z0-9-]*$/.test(command)||typeof handler!="function"||migrations.has(command))throw new Error("Invalid or duplicate checkpoint migration");migrations.set(command,(input,commandContext)=>handler(input,commandContext))},checkpoint(data,expectedSequence){if(!executing||!context.invocation?.taskId)throw new PluginError("PLUGIN_TASK_REQUIRED","Checkpoints require a managed task");return context.signal?.throwIfAborted(),context.invoke("plugin_task_checkpoint",{plugin:pluginName??name,data,expectedSequence,expectedDeclaration:checkpointDeclaration})},state(collection,operation,input={}){if(!executing)throw new Error("app.state is only available during command execution");if(context.signal?.throwIfAborted(),!stateStorage||!Object.hasOwn(stateStorage.collections,collection))throw new PluginError("PLUGIN_STATE_NOT_DECLARED","Plugin state collection is not declared");return context.invoke("plugin_state",{...input,plugin:pluginName??name,collection,operation,expectedDeclaration:pluginStateSignature(stateStorage.collections[collection])})},model(request,options={}){if(!executing)throw new Error("app.model is only available during command execution");context.signal?.throwIfAborted();let generation=invocationGeneration,observing=()=>executing&&generation===invocationGeneration&&!context.signal?.aborted;if(context.runModel)return context.runModel(pluginName??name,request,{signal:context.signal,onProgress:progress=>{observing()&&(context.progress(progress),options.onProgress?.(progress))}});let payload={plugin:pluginName??name,operation:"run",request};return options.onProgress?context.invoke("plugin_model",payload,{},progress=>{observing()&&options.onProgress?.(progress)}):context.invoke("plugin_model",payload)},page(operation,input={}){if(!executing)throw new Error("app.page is only available during command execution");return context.signal?.throwIfAborted(),context.invoke("plugin_page",{...input,plugin:pluginName??name,operation})},toolboxCommand:(signature,handler,description2="",examples=[])=>registerCommand(signature,handler,description2,examples,!0),invoke(action,payload={},options={}){if(!executing)throw new Error("app.invoke 只能在命令执行期间调用");return context.signal?.throwIfAborted(),context.invoke(action,payload,options)},progress(progress){if(!executing)throw new Error("app.progress 只能在命令执行期间调用");context.progress(normalizePluginProgress(progress))}});try{if(extname2(entry).toLowerCase()===".py"){let descriptor=await describePythonPlugin(entry,app.options);name=descriptor.name,description=descriptor.description,toolbox=normalizePluginToolboxContribution(descriptor.toolbox),pageRuntime=normalizePluginPageRuntime(descriptor.pageRuntime),stateStorage=normalizePluginState(descriptor.stateStorage),taskRecovery=normalizePluginTaskRecovery(descriptor.taskRecovery),{appProfiles,profileSources}=loadPluginAppProfiles(entry,descriptor.appProfiles);for(let command of descriptor.commands){let commandName=command.signature.trim().split(/\s+/)[0];if(command.migrationOnly){app.checkpointMigration(commandName,(input,commandContext)=>runPythonPluginCommand(entry,commandName,input,app,commandContext,"migration",descriptor));continue}if(command.recoveryOnly){app.recoveryCommand(commandName,(input,commandContext)=>runPythonPluginCommand(entry,commandName,input,app,commandContext,!0,descriptor));continue}(command.runtimeOnly?app.runtimeCommand:command.toolboxOnly?app.toolboxCommand:app.command)(command.signature,(input,commandContext)=>runPythonPluginCommand(entry,commandName,input,app,commandContext,!1,descriptor,command.runtimeOnly),command.description)}}else{let moduleUrl=pathToFileURL(entry);moduleUrl.searchParams.set("mearl-version",entryVersion);let module=await import(moduleUrl.href);if(module.name!==void 0&&typeof module.name!="string")throw new Error("入口的 name 导出必须为字符串");if(name=module.name,module.description!==void 0&&typeof module.description!="string")throw new Error("入口的 description 导出必须为字符串");if(description=module.description,toolbox=normalizePluginToolboxContribution(module.toolbox),pageRuntime=normalizePluginPageRuntime(module.pageRuntime),stateStorage=normalizePluginState(module.stateStorage),taskRecovery=normalizePluginTaskRecovery(module.taskRecovery),{appProfiles,profileSources}=loadPluginAppProfiles(entry,module.appProfiles),module.default!==void 0&&typeof module.default!="function")throw new Error("入口必须默认导出 register(app) 函数");if(typeof module.default=="function")await module.default(app);else if(!appProfiles)throw new Error("入口必须默认导出 register(app) 函数")}if(commands.size===0&&!appProfiles)throw new Error("入口未注册任何命令");for(let command of Object.keys(taskRecovery?.commands??{}))if(!commands.has(command)||commands.get(command)?.runtimeOnly||commands.get(command)?.toolboxOnly||!recoveries.has(command))throw new Error(`Recovery requires a command and recoveryCommand: ${command}`);for(let command of recoveries.keys())if(!Object.hasOwn(taskRecovery?.commands??{},command))throw new Error(`Undeclared recovery command: ${command}`);for(let[command,definition]of Object.entries(taskRecovery?.commands??{}))if(!!definition.migrateFrom?.length!==migrations.has(command))throw new Error(`Checkpoint migrations require a declaration and checkpointMigration: ${command}`);for(let command of migrations.keys())if(!Object.hasOwn(taskRecovery?.commands??{},command))throw new Error(`Undeclared checkpoint migration: ${command}`);let runtimeCommands=new Set(Object.values(pageRuntime?.events??{}).map(event=>event.command));pageRuntime?.initialize&&runtimeCommands.add(pageRuntime.initialize);for(let[name2,command]of commands)if(command.runtimeOnly&&!runtimeCommands.has(name2))throw new Error(`runtimeCommand is not declared in pageRuntime.events: ${name2}`);for(let name2 of runtimeCommands)if(!commands.has(name2)||commands.get(name2)?.toolboxOnly)throw new Error(`Invalid page runtime command: ${name2}`);let toolboxCommands=toolbox?.page.commands??[];for(let[name2,command]of commands)if(command.toolboxOnly&&!toolboxCommands.includes(name2))throw new Error(`toolboxCommand 未声明在 toolbox.page.commands 中: ${name2}`);for(let command of toolboxCommands)if(!commands.has(command))throw new Error(`toolbox 命令未注册: ${command}`)}catch(error){throw new PluginError("PLUGIN_LOAD_FAILED",`${entry}: ${error instanceof Error?error.message:String(error)}`)}finally{registering=!1}let find=(name2,toolboxPage=!1)=>{let command=commands.get(name2);if(!command)throw new PluginError("PLUGIN_COMMAND_NOT_FOUND",`未知子命令: ${name2}`);if(toolboxPage==="runtime"){if(!(pageRuntime?.initialize===name2||Object.values(pageRuntime?.events??{}).some(event=>event.command===name2))||command.toolboxOnly)throw new PluginError("PLUGIN_COMMAND_NOT_ALLOWED","Page runtime command is not declared")}else{if(command.runtimeOnly)throw new PluginError("PLUGIN_COMMAND_RUNTIME_ONLY",`命令仅供页面运行时调用: ${name2}`);if(toolboxPage){if(!toolbox?.page.commands.includes(name2))throw new PluginError("PLUGIN_COMMAND_NOT_ALLOWED",`工具页面不允许调用命令: ${name2}`)}else if(command.toolboxOnly)throw new PluginError("PLUGIN_COMMAND_TOOLBOX_ONLY",`命令仅供工具页面调用: ${name2}`)}return command},publicCommands=()=>[...commands.values()].filter(command=>!command.toolboxOnly&&!command.runtimeOnly),run2=async(positionals,payload,namedInput={},toolboxPage=!1)=>{if(payload!==void 0&&positionals.length>0)throw new PluginError("PLUGIN_INVALID_INPUT","位置参数调用与 --payload 调用不能混用");if(payload!==void 0&&Object.keys(namedInput).length>0)throw new PluginError("PLUGIN_INVALID_INPUT","插件业务选项与 --payload 调用不能混用");if(payload!==void 0&&(!isObject2(payload)||typeof payload.command!="string"||!isObject2(payload.input)))throw new PluginError("PLUGIN_INVALID_INPUT",'--payload 必须为 {"command":"...","input":{...}}');let envelope=payload,commandName=envelope?.command??positionals[0]??"",hidden=toolboxPage==="recovery"||toolboxPage==="migration",selected=find(commandName,hidden?!1:toolboxPage),command=selected.command,handler=toolboxPage==="recovery"?recoveries.get(commandName):toolboxPage==="migration"?migrations.get(commandName):selected.handler;if(!handler||toolboxPage==="recovery"&&!context.invocation?.recovery)throw new PluginError("PLUGIN_TASK_RECOVERY_UNAVAILABLE","Recovery handler requires a managed recovery attempt");if(toolboxPage==="recovery"&&context.invocation?.recovery?.declarationHash!==pluginRecoverySignature(taskRecovery.commands[commandName]))throw new PluginError("PLUGIN_RECOVERY_DECLARATION_CHANGED","Recovery declaration differs from the admitted format");let positionalInput=envelope?{...envelope.input}:Object.fromEntries(command.registeredArguments.map((argument,index)=>[argument.name(),argument.variadic?positionals.slice(index+1):positionals[index+1]]).filter(([,value])=>value!==void 0));for(let name2 of Object.keys(namedInput))if(Object.hasOwn(positionalInput,name2))throw new PluginError("PLUGIN_INVALID_INPUT",`参数不能重复传入: ${name2}`);let input={...positionalInput,...namedInput};if(!envelope&&!command.registeredArguments.some(argument=>argument.variadic)&&positionals.length-1>command.registeredArguments.length)throw new PluginError("PLUGIN_INVALID_INPUT","位置参数过多");for(let argument of hidden?[]:command.registeredArguments){let value=Object.hasOwn(input,argument.name())?input[argument.name()]:void 0;if(argument.required&&(value==null||value===""||Array.isArray(value)&&value.length===0))throw new PluginError("PLUGIN_INVALID_INPUT",`缺少必填参数: ${argument.name()}`);if(argument.variadic&&value!==void 0&&!Array.isArray(value))throw new PluginError("PLUGIN_INVALID_INPUT",`${argument.name()} 必须为数组`)}if(executing)throw new PluginError("PLUGIN_BUSY","同一命令实例不能并发执行");let signal=context.signal??new AbortController().signal;signal.throwIfAborted();let identity=context.invocation??createPluginInvocationIdentity(pluginName??name??"unregistered",context.source??"sdk",context.parentInvocation),generation=++invocationGeneration,assertActive=()=>{if(!executing||generation!==invocationGeneration)throw new PluginError("PLUGIN_INVOCATION_ENDED","命令调用已结束");signal.throwIfAborted()},commandContext=Object.freeze({identity,signal,...identity.recovery?{recovery:structuredClone(identity.recovery)}:{},checkpoint:(data,expectedSequence)=>(assertActive(),app.checkpoint(data,expectedSequence)),...identity.page?{page:Object.freeze({send:(message,options={})=>(assertActive(),app.page("send",{instanceId:identity.page.instanceId,message,...options.timeoutSec!==void 0?{timeoutSec:options.timeoutSec}:{}})),get:()=>(assertActive(),app.page("get",{instanceId:identity.page.instanceId}))})}:{},invoke:(action,payload2,options)=>(assertActive(),app.invoke(action,payload2,options)),state:(collection,operation,input2)=>(assertActive(),app.state(collection,operation,{...identity.page?{instanceId:identity.page.instanceId}:{},...input2})),model:(request,options)=>(assertActive(),app.model(request,options)),progress:progress=>{assertActive(),app.progress(progress)}});checkpointDeclaration=taskRecovery&&Object.hasOwn(taskRecovery.commands,commandName)?pluginRecoverySignature(taskRecovery.commands[commandName]):void 0,executing=!0,context.onInvocation?.(identity);try{return await handler(input,commandContext)}finally{executing=!1,checkpointDeclaration=void 0,context.onInvocation?.(void 0)}};return{name,description,toolbox,pageRuntime,stateStorage,taskRecovery,appProfiles,profileSources,version:readPluginVersion(entry),commandHelp(namespace){return publicCommands().map(({command,signature})=>` ${namespace} ${signature} ${command.description()}`).join(`
967
967
  `)},help(namespace,name2){let selected=name2?[find(name2)]:publicCommands();if(!selected.length){let location=toolbox?`请在 Mearl ${toolbox.displayMode==="popup"?"Popup":"工具箱"} 中打开「${toolbox.title}」使用。`:"此插件未提供公开 CLI 命令。";return`${namespace} 未提供 CLI 命令。
968
968
  ${location}`}let examples=selected.flatMap(({examples:examples2})=>examples2);return["用法:",...selected.map(({command,signature})=>` ${namespace} ${signature} ${command.description()}`),...examples.length?["","示例:",...examples.map(example=>` ${namespace} ${example}`)]:[]].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearl/native-host",
3
- "version": "2.22.5",
3
+ "version": "2.23.0",
4
4
  "description": "Native Messaging Host for Mearl — bridges Chrome Extension and local socket server",
5
5
  "type": "module",
6
6
  "engines": {
@@ -45,13 +45,13 @@
45
45
  "@types/ws": "^8.18.1",
46
46
  "esbuild": "^0.25.2",
47
47
  "typescript": "^5.8.3",
48
- "@mearl/browser-core": "2.22.5",
49
- "@mearl/app-profiles": "2.22.5",
50
- "@mearl/provider": "2.22.5",
51
- "@mearl/daemon-core": "2.22.5",
52
- "@mearl/setup": "2.22.5",
53
- "@mearl/client": "2.22.5",
54
- "@mearl/agent-runtime": "2.22.5"
48
+ "@mearl/app-profiles": "2.23.0",
49
+ "@mearl/client": "2.23.0",
50
+ "@mearl/daemon-core": "2.23.0",
51
+ "@mearl/browser-core": "2.23.0",
52
+ "@mearl/provider": "2.23.0",
53
+ "@mearl/agent-runtime": "2.23.0",
54
+ "@mearl/setup": "2.23.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "rm -rf dist/ && node build.mjs",