[{"data":1,"prerenderedAt":761},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fdevelopment\u002Fquick-start\u002Ffaq":199,"\u002Fdocs\u002Fdevelopment\u002Fquick-start\u002Ffaq-surround":756},[4,9,41,111,116,132],{"title":5,"path":6,"stem":7,"icon":8},"准备","\u002Fdocs\u002Fpreparation","1.docs\u002F1.preparation","i-lucide-rocket",{"title":10,"icon":11,"path":12,"stem":13,"children":14,"page":40},"用户手册","i-lucide-book-open","\u002Fdocs\u002Fgetting-started","1.docs\u002F2.getting-started",[15,20,25,30,35],{"title":16,"path":17,"stem":18,"icon":19},"认识 UDhold","\u002Fdocs\u002Fgetting-started\u002Fwhat-is-udhold","1.docs\u002F2.getting-started\u002F1.what-is-udhold","i-lucide-info",{"title":21,"path":22,"stem":23,"icon":24},"核心概念","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","1.docs\u002F2.getting-started\u002F2.core-concepts","i-lucide-lightbulb",{"title":26,"path":27,"stem":28,"icon":29},"主面板布局","\u002Fdocs\u002Fgetting-started\u002Fmain-interface","1.docs\u002F2.getting-started\u002F3.main-interface","i-lucide-monitor",{"title":31,"path":32,"stem":33,"icon":34},"快速上手 5 分钟","\u002Fdocs\u002Fgetting-started\u002Fquick-tour","1.docs\u002F2.getting-started\u002F4.quick-tour","i-lucide-zap",{"title":36,"path":37,"stem":38,"icon":39},"常用快捷键","\u002Fdocs\u002Fgetting-started\u002Fshortcut-keys","1.docs\u002F2.getting-started\u002F5.shortcut-keys","i-lucide-keyboard",false,{"title":42,"path":43,"stem":44,"children":45,"icon":110},"核心功能","\u002Fdocs\u002Ffeatures","1.docs\u002F3.features\u002F1.index",[46,49,53,58,63,67,71,76,81,86,91,96,101,106],{"title":47,"path":43,"stem":44,"icon":48},"功能总览","i-lucide-layout-grid",{"title":50,"path":51,"stem":52,"icon":39},"快捷键","\u002Fdocs\u002Ffeatures\u002Fshortcuts","1.docs\u002F3.features\u002F10.shortcuts",{"title":54,"path":55,"stem":56,"icon":57},"AI 模型","\u002Fdocs\u002Ffeatures\u002Fai-models","1.docs\u002F3.features\u002F16.ai-models","i-lucide-bot",{"title":59,"path":60,"stem":61,"icon":62},"AI 助手","\u002Fdocs\u002Ffeatures\u002Fai-helper","1.docs\u002F3.features\u002F17.ai-helper","i-lucide-bot-message-square",{"title":64,"path":65,"stem":66,"icon":19},"关于","\u002Fdocs\u002Ffeatures\u002Fabout","1.docs\u002F3.features\u002F19.about",{"title":68,"path":69,"stem":70,"icon":29},"系统命令","\u002Fdocs\u002Ffeatures\u002Fsystem","1.docs\u002F3.features\u002F2.system",{"title":72,"path":73,"stem":74,"icon":75},"调试日志","\u002Fdocs\u002Ffeatures\u002Fdebug","1.docs\u002F3.features\u002F20.debug","i-lucide-terminal",{"title":77,"path":78,"stem":79,"icon":80},"通用设置","\u002Fdocs\u002Ffeatures\u002Fsettings","1.docs\u002F3.features\u002F21.settings","i-mdi-cog-outline",{"title":82,"path":83,"stem":84,"icon":85},"文件资源管理器","\u002Fdocs\u002Ffeatures\u002Ffiles","1.docs\u002F3.features\u002F3.files","i-lucide-folder-tree",{"title":87,"path":88,"stem":89,"icon":90},"文件树","\u002Fdocs\u002Ffeatures\u002Ffiles-tree","1.docs\u002F3.features\u002F4.files-tree","i-lucide-list-tree",{"title":92,"path":93,"stem":94,"icon":95},"文件预览","\u002Fdocs\u002Ffeatures\u002Fpreview","1.docs\u002F3.features\u002F5.preview","i-lucide-eye",{"title":97,"path":98,"stem":99,"icon":100},"本地启动","\u002Fdocs\u002Ffeatures\u002Flocal-launch","1.docs\u002F3.features\u002F6.local-launch","i-lucide-app-window",{"title":102,"path":103,"stem":104,"icon":105},"插件中心","\u002Fdocs\u002Ffeatures\u002Fplugins","1.docs\u002F3.features\u002F7.plugins","i-lucide-puzzle",{"title":107,"path":108,"stem":109,"icon":8},"快速启动","\u002Fdocs\u002Ffeatures\u002Fquick-start","1.docs\u002F3.features\u002F8.quick-start","i-lucide-star",{"title":112,"path":113,"stem":114,"icon":115},"主题","\u002Fdocs\u002Fthemes","1.docs\u002F4.themes","i-lucide-palette",{"title":117,"icon":118,"path":119,"stem":120,"children":121,"page":40},"相关协议","i-lucide-scroll","\u002Fdocs\u002Flegal","1.docs\u002F5.legal",[122,127],{"title":123,"path":124,"stem":125,"icon":126},"用户须知","\u002Fdocs\u002Flegal\u002Fuser-notice","1.docs\u002F5.legal\u002F1.user-notice","i-lucide-file-text",{"title":128,"path":129,"stem":130,"icon":131},"隐私协议","\u002Fdocs\u002Flegal\u002Fprivacy","1.docs\u002F5.legal\u002F2.privacy","i-lucide-shield-check",{"title":133,"icon":134,"path":135,"stem":136,"children":137,"page":40},"开发指南","i-lucide-code","\u002Fdocs\u002Fdevelopment","1.docs\u002F6.development",[138,156,190],{"title":139,"icon":8,"path":140,"stem":141,"children":142,"page":40},"快速开始","\u002Fdocs\u002Fdevelopment\u002Fquick-start","1.docs\u002F6.development\u002F1.quick-start",[143,147,151],{"title":144,"path":145,"stem":146,"icon":19},"介绍","\u002Fdocs\u002Fdevelopment\u002Fquick-start\u002Fintroduction","1.docs\u002F6.development\u002F1.quick-start\u002F1.introduction",{"title":148,"path":149,"stem":150,"icon":34},"快速上手","\u002Fdocs\u002Fdevelopment\u002Fquick-start\u002Fgetting-started","1.docs\u002F6.development\u002F1.quick-start\u002F2.getting-started",{"title":152,"path":153,"stem":154,"icon":155},"常见问题","\u002Fdocs\u002Fdevelopment\u002Fquick-start\u002Ffaq","1.docs\u002F6.development\u002F1.quick-start\u002F3.faq","i-lucide-circle-help",{"title":157,"icon":115,"path":158,"stem":159,"children":160,"page":40},"设计系统","\u002Fdocs\u002Fdevelopment\u002Fdesign-system","1.docs\u002F6.development\u002F2.design-system",[161,166,171,176,181,186],{"title":162,"path":163,"stem":164,"icon":165},"设计令牌","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Ftokens","1.docs\u002F6.development\u002F2.design-system\u002F1.tokens","i-lucide-pipette",{"title":167,"path":168,"stem":169,"icon":170},"主题与明暗模式","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Ftheming","1.docs\u002F6.development\u002F2.design-system\u002F2.theming","i-lucide-sun-moon",{"title":172,"path":173,"stem":174,"icon":175},"基础样式类","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Fbase-styles","1.docs\u002F6.development\u002F2.design-system\u002F3.base-styles","i-lucide-layout-template",{"title":177,"path":178,"stem":179,"icon":180},"图标体系","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Ficons","1.docs\u002F6.development\u002F2.design-system\u002F4.icons","i-lucide-shapes",{"title":182,"path":183,"stem":184,"icon":185},"通用组件","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Fcomponents","1.docs\u002F6.development\u002F2.design-system\u002F5.components","i-lucide-component",{"title":187,"path":188,"stem":189,"icon":48},"场景组件","\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Fscene-components","1.docs\u002F6.development\u002F2.design-system\u002F6.scene-components",{"title":191,"icon":57,"path":192,"stem":193,"children":194,"page":40},"AI","\u002Fdocs\u002Fdevelopment\u002Fai","1.docs\u002F6.development\u002F3.ai",[195],{"title":196,"path":197,"stem":198,"icon":126},"LLMs.txt","\u002Fdocs\u002Fdevelopment\u002Fai\u002Fllms-txt","1.docs\u002F6.development\u002F3.ai\u002F1.llms-txt",{"id":200,"title":152,"body":201,"description":749,"extension":750,"meta":751,"navigation":752,"path":153,"rawbody":753,"seo":754,"stem":154,"__hash__":755},"docs\u002F1.docs\u002F6.development\u002F1.quick-start\u002F3.faq.md",{"type":202,"value":203,"toc":718},"minimark",[204,214,218,223,236,275,279,296,300,314,318,336,340,347,350,354,360,406,410,428,432,447,451,462,465,469,495,499,505,550,555,559,581,585,603,606,610,623,665,669,672,676,689,693,696,700],[205,206,207,208,213],"p",{},"按「开发调试 \u002F 权限与调用 \u002F 界面与主题 \u002F 打包与发布」四类整理。没找到答案的问题，欢迎通过",[209,210,212],"a",{"href":211},"\u002Fabout","关于页面","的联系方式反馈。",[215,216,217],"h2",{"id":217},"开发调试",[219,220,222],"h3",{"id":221},"改了代码宿主里看到的还是旧界面","改了代码，宿主里看到的还是旧界面？",[205,224,225,226,230,231,235],{},"九成是 dev server 的问题。宿主只在 dev server ",[227,228,229],"strong",{},"可达","时才直连它，探测失败会静默回退加载本地 ",[232,233,234],"code",{},"dist"," 产物：",[237,238,239,255,262,265],"ol",{},[240,241,242,243,246,247,250,251,254],"li",{},"确认 ",[232,244,245],{},"pnpm dev"," 在跑，且端口与 ",[232,248,249],{},"development.main"," 一致（建议 vite 配 ",[232,252,253],{},"strictPort: true","，防止 vite 端口被占后自己换端口）。",[240,256,257,258,261],{},"在浏览器里直接开 ",[232,259,260],{},"http:\u002F\u002Flocalhost:\u003C端口>"," 验证页面本身能访问。",[240,263,264],{},"确认插件在「插件开发者」里处于运行调试登记态（宿主重启后登记失效，重新点一次「运行调试」）。",[240,266,267,268,270,271,274],{},"如果确实在加载旧 ",[232,269,234],{},"，重新 ",[232,272,273],{},"pnpm build"," 更新产物。",[219,276,278],{"id":277},"developmentmain-可以填局域网地址方便真机调试吗","development.main 可以填局域网地址方便真机调试吗？",[205,280,281,282,284,285,288,289,288,292,295],{},"不行。出于安全考虑，",[232,283,249],{}," 只允许 ",[232,286,287],{},"localhost"," \u002F ",[232,290,291],{},"127.0.0.1",[232,293,294],{},"[::1]"," 的 http(s) 地址，宿主会拒绝登记远程页面。",[219,297,299],{"id":298},"怎么在插件里打印日志排查","怎么在插件里打印日志排查？",[205,301,302,303,306,307,310,311,313],{},"普通 ",[232,304,305],{},"console.log"," 在 WebView 开发者工具里看（调试态宿主可右键插件页面打开 DevTools）；需要留痕的日志走宿主日志域 ",[232,308,309],{},"udhold.log","，可在宿主的",[209,312,72],{"href":73},"面板统一查看。",[219,315,317],{"id":316},"插件页面一打开就白屏","插件页面一打开就白屏？",[205,319,320,321,324,325,328,329,331,332,335],{},"常见原因：构建产物路径不对（vite 没配 ",[232,322,323],{},"base: '.\u002F'","，产物用了绝对路径 ",[232,326,327],{},"\u002Fassets\u002F...","，在宿主 asset 协议下 404）；或 ",[232,330,234],{}," 字段指错了入口文件。免构建插件则检查 ",[232,333,334],{},"index.html"," 是否在插件根目录。",[219,337,339],{"id":338},"dev-server-启动很慢宿主会不会超时","dev server 启动很慢，宿主会不会超时？",[205,341,342,343,346],{},"「运行调试」轮询端口就绪有 90 秒超时，覆盖正常 ",[232,344,345],{},"pnpm install"," + 启动的时间。首次安装依赖较慢属正常，后续热启动都在秒级。",[215,348,349],{"id":349},"权限与调用",[219,351,353],{"id":352},"调用-api-返回-code-403-permission_denied","调用 API 返回 code 403 \u002F PERMISSION_DENIED？",[205,355,356,359],{},[232,357,358],{},"permissions"," 没声明或写错了。对照排查：",[361,362,363,378,385,396],"ul",{},[240,364,365,366,369,370,373,374,377],{},"声明是",[227,367,368],{},"前缀匹配","：",[232,371,372],{},"files.list"," 精确放行一个方法，",[232,375,376],{},"files.*"," 放行整个域。",[240,379,380,381,384],{},"拼写以能力目录为准：方法路径必须与 API 文档一致（域.方法，如 ",[232,382,383],{},"ai.models.list","）。",[240,386,387,388,391,392,395],{},"改了 ",[232,389,390],{},"plugin.json"," 后要",[227,393,394],{},"重开插件","让新权限生效。",[240,397,398,399,288,402,405],{},"存储类（",[232,400,401],{},"db",[232,403,404],{},"dbStorage","）、路由、生命周期等基础能力免声明；文件、剪贴板历史、AI、登录态等敏感域必须声明。",[219,407,409],{"id":408},"调用其他插件routerpush-pluginrun被拒","调用其他插件（router.push \u002F plugin.run）被拒？",[205,411,412,413,415,416,419,420,423,424,427],{},"跨插件调用要在 ",[232,414,390],{}," 的 ",[232,417,418],{},"plugins"," 数组里登记目标插件名：",[232,421,422],{},"\"plugins\": [\"files\", \"calculator\"]","；声明 ",[232,425,426],{},"\"*\""," 放行全部（审核高风险，不推荐）。打开自己豁免白名单。",[219,429,431],{"id":430},"方法调用没有抛错但拿不到数据","方法调用没有抛错但拿不到数据？",[205,433,434,435,438,439,442,443,446],{},"宿主方法统一返回 ",[232,436,437],{},"IpcResult"," 信封，失败也是正常 resolve。要检查 ",[232,440,441],{},"res.code !== 0","（失败）与 ",[232,444,445],{},"res.success === false","（业务分歧，非错误）两个分支，不能只 try\u002Fcatch。",[219,448,450],{"id":449},"插件数据存在哪卸载会清掉吗","插件数据存在哪？卸载会清掉吗？",[205,452,453,454,457,458,461],{},"数据落在用户数据目录 ",[232,455,456],{},"plugin-storage\u002F\u003C插件名>\u002F"," 下，各插件自动隔离，互不可见。",[227,459,460],{},"卸载插件默认连数据一起清空","；用户在插件中心手动卸载时可选择保留。禁用则完全保留数据，随时恢复。",[215,463,464],{"id":464},"界面与主题",[219,466,468],{"id":467},"插件没有跟随宿主的明暗主题","插件没有跟随宿主的明暗主题？",[205,470,471,472,475,476,479,480,483,484,487,488,491,492,494],{},"工程型插件检查入口 ",[232,473,474],{},"main.ts"," 是否调用了 ",[232,477,478],{},"setupThemeSync()","（来自 ",[232,481,482],{},"@udhold\u002Fudhold-ui\u002Futils","），并确认引入了 ",[232,485,486],{},"@udhold\u002Fudhold-ui\u002Fstyles\u002Fglobal.css","。免构建插件没有这套工具，需要监听宿主事件 ",[232,489,490],{},"udhold.onThemeChange"," 手动切换样式。完整机制见",[209,493,167],{"href":168},"。",[219,496,498],{"id":497},"图标显示不出来i-z-xxx-类","图标显示不出来（i-z-xxx 类）？",[205,500,501,504],{},[232,502,503],{},"i-z-*"," 图标类来自插件自己的本地 SVG 图标集，检查：",[237,506,507,529,540],{},[240,508,509,512,513,516,517,520,521,524,525,528],{},[232,510,511],{},"uno.config.ts"," 配了 ",[232,514,515],{},"presetIcons"," 且用 ",[232,518,519],{},"FileSystemIconLoader"," 把 ",[232,522,523],{},"src\u002Fassets\u002Ficons"," 注册为 ",[232,526,527],{},"z"," 集合；",[240,530,531,532,535,536,539],{},"SVG 文件名与类名一致（",[232,533,534],{},"i-z-back"," 对应 ",[232,537,538],{},"back.svg","）；",[240,541,542,543,546,547,549],{},"使用 ",[232,544,545],{},"DetailPanel"," 组件的插件，图标集里必须有 ",[232,548,538],{},"（组件内部依赖它）。",[205,551,552,553,494],{},"配置方法见",[209,554,177],{"href":178},[219,556,558],{"id":557},"message-消息弹不出来","Message 消息弹不出来？",[205,560,561,564,565,568,569,572,573,576,577,580],{},[232,562,563],{},"Message"," 与 ",[232,566,567],{},"ConfirmDialog"," 是「挂载一次、全局调用」的组件，确认根组件模板里挂了 ",[232,570,571],{},"\u003CMessage :items=\"messageState\" ... \u002F>","（",[232,574,575],{},"useMessage()"," 返回的状态要接上），否则 ",[232,578,579],{},"message.success(...)"," 不会有任何显示。",[219,582,584],{"id":583},"用-react-原生-js-能开发吗","用 React \u002F 原生 JS 能开发吗？",[205,586,587,588,591,592,572,595,598,599,602],{},"可以。插件就是 Web 页面，框架不限（官方的 JSON Tools 就是 React 工程）。注意 ",[232,589,590],{},"@udhold\u002Fudhold-ui"," 的 Vue 组件不能直接用于 React，但其",[227,593,594],{},"设计令牌与全局样式",[232,596,597],{},"global.css","）和工具函数（",[232,600,601],{},"setupThemeSync"," 等）是框架无关的，照常引入即可。",[215,604,605],{"id":605},"打包与发布",[219,607,609],{"id":608},"打包后的插件缺文件-样式丢了","打包后的插件缺文件 \u002F 样式丢了？",[205,611,612,613,415,615,618,619,622],{},"打包严格按 ",[232,614,390],{},[232,616,617],{},"build"," 字段收录：",[232,620,621],{},"[\"dist\"]"," 就只有 dist 目录。检查：",[361,624,625,631,655],{},[240,626,627,628,630],{},"是否先执行了 ",[232,629,273],{},"（打的是当时的旧 dist）；",[240,632,633,634,564,636,639,640,642,643,646,647,650,651,654],{},"插件根目录的 ",[232,635,390],{},[232,637,638],{},"logo.png"," 由打包器固定收进包根，无需进 ",[232,641,617],{}," 数组；",[232,644,645],{},"src\u002F"," 里引用的其他静态资源要随构建一起进 dist（放 ",[232,648,649],{},"src\u002Fassets"," 或 Vite ",[232,652,653],{},"public\u002F"," 均可）；",[240,656,657,658,661,662,664],{},"需要额外收录 ",[232,659,660],{},"services[].entry"," 等根目录文件时，把它们加进 ",[232,663,617],{}," 数组。",[219,666,668],{"id":667},"上传市场后在哪里看审核状态","上传市场后在哪里看审核状态？",[205,670,671],{},"在「插件开发者」的发布相关页面可以查看已上传版本与审核状态；审核未通过会附原因（多数是权限声明与实际功能不符）。",[219,673,675],{"id":674},"用户怎么收到新版本","用户怎么收到新版本？",[205,677,678,679,415,681,684,685,688],{},"改 ",[232,680,390],{},[232,682,683],{},"version","（semver，比较大小决定是否更新）→ 构建打包 → 上传市场。已安装用户",[227,686,687],{},"打开插件时","宿主自动检查更新并静默完成安装，无需用户操作。",[219,690,692],{"id":691},"能不能先小范围发给别人测试","能不能先小范围发给别人测试？",[205,694,695],{},"可以，不走市场：打包 zip 直接发给对方，在插件中心「本地安装」导入即可。市场发布时也可以先选「测试」状态灰度，验证无误再转「正式」。",[219,697,699],{"id":698},"想让插件开机自启怎么做","想让插件开机自启怎么做？",[205,701,702,703,705,706,709,710,713,714,717],{},"两种方式：纯后台场景在 ",[232,704,390],{}," 声明 ",[232,707,708],{},"\"startup\": \"background\"","（宿主启动完成后拉起无头实例，启动形式由插件自己编排）；带服务进程的插件把服务的 ",[232,711,712],{},"startup"," 设为 ",[232,715,716],{},"\"host\"","（随宿主启动，不创建界面）。",{"title":719,"searchDepth":720,"depth":720,"links":721},"",2,[722,730,736,742],{"id":217,"depth":720,"text":217,"children":723},[724,726,727,728,729],{"id":221,"depth":725,"text":222},3,{"id":277,"depth":725,"text":278},{"id":298,"depth":725,"text":299},{"id":316,"depth":725,"text":317},{"id":338,"depth":725,"text":339},{"id":349,"depth":720,"text":349,"children":731},[732,733,734,735],{"id":352,"depth":725,"text":353},{"id":408,"depth":725,"text":409},{"id":430,"depth":725,"text":431},{"id":449,"depth":725,"text":450},{"id":464,"depth":720,"text":464,"children":737},[738,739,740,741],{"id":467,"depth":725,"text":468},{"id":497,"depth":725,"text":498},{"id":557,"depth":725,"text":558},{"id":583,"depth":725,"text":584},{"id":605,"depth":720,"text":605,"children":743},[744,745,746,747,748],{"id":608,"depth":725,"text":609},{"id":667,"depth":725,"text":668},{"id":674,"depth":725,"text":675},{"id":691,"depth":725,"text":692},{"id":698,"depth":725,"text":699},"插件开发中高频问题的排查手册：调试不生效、权限被拒、主题不跟随、打包缺文件等。","md",{},{"icon":155},"---\ntitle: 常见问题\ndescription: 插件开发中高频问题的排查手册：调试不生效、权限被拒、主题不跟随、打包缺文件等。\nnavigation:\n  icon: i-lucide-circle-help\n---\n\n按「开发调试 \u002F 权限与调用 \u002F 界面与主题 \u002F 打包与发布」四类整理。没找到答案的问题，欢迎通过[关于页面](\u002Fabout)的联系方式反馈。\n\n## 开发调试\n\n### 改了代码，宿主里看到的还是旧界面？\n\n九成是 dev server 的问题。宿主只在 dev server **可达**时才直连它，探测失败会静默回退加载本地 `dist` 产物：\n\n1. 确认 `pnpm dev` 在跑，且端口与 `development.main` 一致（建议 vite 配 `strictPort: true`，防止 vite 端口被占后自己换端口）。\n2. 在浏览器里直接开 `http:\u002F\u002Flocalhost:\u003C端口>` 验证页面本身能访问。\n3. 确认插件在「插件开发者」里处于运行调试登记态（宿主重启后登记失效，重新点一次「运行调试」）。\n4. 如果确实在加载旧 `dist`，重新 `pnpm build` 更新产物。\n\n### development.main 可以填局域网地址方便真机调试吗？\n\n不行。出于安全考虑，`development.main` 只允许 `localhost` \u002F `127.0.0.1` \u002F `[::1]` 的 http(s) 地址，宿主会拒绝登记远程页面。\n\n### 怎么在插件里打印日志排查？\n\n普通 `console.log` 在 WebView 开发者工具里看（调试态宿主可右键插件页面打开 DevTools）；需要留痕的日志走宿主日志域 `udhold.log`，可在宿主的[调试日志](\u002Fdocs\u002Ffeatures\u002Fdebug)面板统一查看。\n\n### 插件页面一打开就白屏？\n\n常见原因：构建产物路径不对（vite 没配 `base: '.\u002F'`，产物用了绝对路径 `\u002Fassets\u002F...`，在宿主 asset 协议下 404）；或 `dist` 字段指错了入口文件。免构建插件则检查 `index.html` 是否在插件根目录。\n\n### dev server 启动很慢，宿主会不会超时？\n\n「运行调试」轮询端口就绪有 90 秒超时，覆盖正常 `pnpm install` + 启动的时间。首次安装依赖较慢属正常，后续热启动都在秒级。\n\n## 权限与调用\n\n### 调用 API 返回 code 403 \u002F PERMISSION_DENIED？\n\n`permissions` 没声明或写错了。对照排查：\n\n- 声明是**前缀匹配**：`files.list` 精确放行一个方法，`files.*` 放行整个域。\n- 拼写以能力目录为准：方法路径必须与 API 文档一致（域.方法，如 `ai.models.list`）。\n- 改了 `plugin.json` 后要**重开插件**让新权限生效。\n- 存储类（`db` \u002F `dbStorage`）、路由、生命周期等基础能力免声明；文件、剪贴板历史、AI、登录态等敏感域必须声明。\n\n### 调用其他插件（router.push \u002F plugin.run）被拒？\n\n跨插件调用要在 `plugin.json` 的 `plugins` 数组里登记目标插件名：`\"plugins\": [\"files\", \"calculator\"]`；声明 `\"*\"` 放行全部（审核高风险，不推荐）。打开自己豁免白名单。\n\n### 方法调用没有抛错但拿不到数据？\n\n宿主方法统一返回 `IpcResult` 信封，失败也是正常 resolve。要检查 `res.code !== 0`（失败）与 `res.success === false`（业务分歧，非错误）两个分支，不能只 try\u002Fcatch。\n\n### 插件数据存在哪？卸载会清掉吗？\n\n数据落在用户数据目录 `plugin-storage\u002F\u003C插件名>\u002F` 下，各插件自动隔离，互不可见。**卸载插件默认连数据一起清空**；用户在插件中心手动卸载时可选择保留。禁用则完全保留数据，随时恢复。\n\n## 界面与主题\n\n### 插件没有跟随宿主的明暗主题？\n\n工程型插件检查入口 `main.ts` 是否调用了 `setupThemeSync()`（来自 `@udhold\u002Fudhold-ui\u002Futils`），并确认引入了 `@udhold\u002Fudhold-ui\u002Fstyles\u002Fglobal.css`。免构建插件没有这套工具，需要监听宿主事件 `udhold.onThemeChange` 手动切换样式。完整机制见[主题与明暗模式](\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Ftheming)。\n\n### 图标显示不出来（i-z-xxx 类）？\n\n`i-z-*` 图标类来自插件自己的本地 SVG 图标集，检查：\n\n1. `uno.config.ts` 配了 `presetIcons` 且用 `FileSystemIconLoader` 把 `src\u002Fassets\u002Ficons` 注册为 `z` 集合；\n2. SVG 文件名与类名一致（`i-z-back` 对应 `back.svg`）；\n3. 使用 `DetailPanel` 组件的插件，图标集里必须有 `back.svg`（组件内部依赖它）。\n\n配置方法见[图标体系](\u002Fdocs\u002Fdevelopment\u002Fdesign-system\u002Ficons)。\n\n### Message 消息弹不出来？\n\n`Message` 与 `ConfirmDialog` 是「挂载一次、全局调用」的组件，确认根组件模板里挂了 `\u003CMessage :items=\"messageState\" ... \u002F>`（`useMessage()` 返回的状态要接上），否则 `message.success(...)` 不会有任何显示。\n\n### 用 React \u002F 原生 JS 能开发吗？\n\n可以。插件就是 Web 页面，框架不限（官方的 JSON Tools 就是 React 工程）。注意 `@udhold\u002Fudhold-ui` 的 Vue 组件不能直接用于 React，但其**设计令牌与全局样式**（`global.css`）和工具函数（`setupThemeSync` 等）是框架无关的，照常引入即可。\n\n## 打包与发布\n\n### 打包后的插件缺文件 \u002F 样式丢了？\n\n打包严格按 `plugin.json` 的 `build` 字段收录：`[\"dist\"]` 就只有 dist 目录。检查：\n\n- 是否先执行了 `pnpm build`（打的是当时的旧 dist）；\n- 插件根目录的 `plugin.json` 与 `logo.png` 由打包器固定收进包根，无需进 `build` 数组；`src\u002F` 里引用的其他静态资源要随构建一起进 dist（放 `src\u002Fassets` 或 Vite `public\u002F` 均可）；\n- 需要额外收录 `services[].entry` 等根目录文件时，把它们加进 `build` 数组。\n\n### 上传市场后在哪里看审核状态？\n\n在「插件开发者」的发布相关页面可以查看已上传版本与审核状态；审核未通过会附原因（多数是权限声明与实际功能不符）。\n\n### 用户怎么收到新版本？\n\n改 `plugin.json` 的 `version`（semver，比较大小决定是否更新）→ 构建打包 → 上传市场。已安装用户**打开插件时**宿主自动检查更新并静默完成安装，无需用户操作。\n\n### 能不能先小范围发给别人测试？\n\n可以，不走市场：打包 zip 直接发给对方，在插件中心「本地安装」导入即可。市场发布时也可以先选「测试」状态灰度，验证无误再转「正式」。\n\n### 想让插件开机自启怎么做？\n\n两种方式：纯后台场景在 `plugin.json` 声明 `\"startup\": \"background\"`（宿主启动完成后拉起无头实例，启动形式由插件自己编排）；带服务进程的插件把服务的 `startup` 设为 `\"host\"`（随宿主启动，不创建界面）。\n",{"title":152,"description":749},"M_PXtnBW0m7QT3ClmN3oFAVFJNsfViMoAd8-prbbkzc",[757,759],{"title":148,"path":149,"stem":150,"description":758,"icon":34},"从环境准备到发布市场的完整实操：创建工程、运行调试、调用宿主能力、打包发布。",{"title":162,"path":163,"stem":164,"description":760,"icon":165},"UDhold 设计系统的颜色、字体、圆角、阴影与动效变量参考，插件界面与宿主保持一致视觉的基础。",1793010253443]