Optimized the root .gitignore to exclude virtual environments, node modules, and temp folders to ensure clean and lightweight version tracking. Co-authored-by: Cursor <cursoragent@cursor.com>
420 lines
419 KiB
JavaScript
420 lines
419 KiB
JavaScript
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/index.js","assets/chunks/index2.js","assets/chunks/vendor-common.js","assets/chunks/vendor-react.js","assets/chunks/_commonjsHelpers.js","assets/chunks/preload-helper.js","assets/chunks/_commonjs-dynamic-modules.js"])))=>i.map(i=>d[i]);
|
||
import{j as e,r,R as be,d as ql}from"./chunks/vendor-react.js?v=1775123024591";import{a as In,G as Zl,b as Xo,c as fe,B as te,D as Js,d as Qs,e as mn,f as Xs,F as Dt,g as At,I as Ps,h as Ea,L as io,T as Yo,i as Ta,j as Un,u as Rr,k as vt,l as Et,m as Tt,n as It,A as Jl}from"./chunks/AppDialogProvider.js?v=1775123024591";import{aH as Ql,aI as gt,aJ as Xl,aK as La,aL as ei,aM as ti,aN as H,aO as si,aP as ni,aQ as ai,aR as Yl,aS as ri,aT as oi,aU as ii,aV as li,aW as Fn,aX as ci,aY as di,aZ as ui,a_ as mi,a$ as ec,b0 as tc,b1 as en,b2 as ss,b3 as hi,b4 as sc,b5 as pi,b6 as nc,b7 as ac,b8 as ns,b9 as Ia,ba as as,bb as _n,bc as hn,bd as fi,be as rc,bf as xi,bg as oc,bh as ic,bi as gi,bj as yi,bk as lc,bl as bi,bm as wi,bn as ji,bo as cc,bp as Ni,bq as vi,br as Si,bs as dn,bt as ta,bu as dc,bv as pn,bw as un,bx as Ln,by as _s,bz as Ci,bA as Ma,bB as ki,bC as Ei,bD as uc,bE as Ti,bF as mc,bG as Ii,bH as hc,bI as Pi,bJ as pc,bK as Di,bL as fc,bM as Ai,bN as Ri,bO as xc,bP as gc,bQ as $i,bR as yc,bS as bc,bT as Oi,bU as wc,bV as jc,bW as Nc,bX as _i,bY as Li,bZ as vc,b_ as Mi,b$ as Ui,c0 as Sc,c1 as Fi,c2 as Pa,c3 as Xa,c4 as Ds,c5 as Cc,c6 as lo,c7 as kc,c8 as Ec,c9 as gr,ca as Tc,cb as Ic,cc as Pc,cd as zi,ce as Bi,cf as Dc,cg as Ac,ch as Wi,ci as Rc,cj as $c,ck as co,cl as Oc,cm as _c,cn as Lc,co as Mc,cp as pa,cq as uo,cr as Uc,cs as Fc,ct as zc,cu as Tn,cv as Bc,cw as rn,cx as Wc,cy as mo,cz as Gc,cA as Kc,cB as Vc,cC as Sa,cD as fa,cE as Ya,cF as Hc,cG as ho,cH as po,cI as Gi,cJ as qc,cK as Zc,cL as Jc,cM as Qc,cN as Ki,cO as Xc,cP as Yc}from"./chunks/vendor-common.js?v=1775123024591";import{I as Ua,a as Fa,b as $r,c as Or,d as sa,e as _r,f as na,g as yr,h as Vi}from"./chunks/vendor-assistant.js?v=1775123024591";import{S as fo,y as er,Q as ed}from"./chunks/vendor-antd.js?v=1775123024591";import{G as Hi}from"./chunks/use-feedback-bridge.js?v=1775123024591";import{P as td}from"./chunks/vendor-export.js?v=1775123024591";import{_ as sd}from"./chunks/preload-helper.js?v=1775123024591";import"./chunks/_commonjsHelpers.js?v=1775123024591";import"./chunks/_commonjs-dynamic-modules.js?v=1775123024591";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))a(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&a(l)}).observe(document,{childList:!0,subtree:!0});function n(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function a(o){if(o.ep)return;o.ep=!0;const i=n(o);fetch(o.href,i)}})();const nd=({...t})=>e.jsx(Ql,{className:"toaster group",icons:{success:e.jsx(ti,{className:"size-4"}),info:e.jsx(ei,{className:"size-4"}),warning:e.jsx(La,{className:"size-4"}),error:e.jsx(Xl,{className:"size-4"}),loading:e.jsx(gt,{className:"size-4 animate-spin"})},style:{"--normal-bg":"hsl(var(--popover))","--normal-text":"hsl(var(--popover-foreground))","--normal-border":"hsl(var(--border))","--border-radius":"var(--radius)"},...t}),ad="axhub-admin-active-tab",xo="axhub-make-dark-mode",$n="axhub-make-welcome-dismissed",go="axhub:assistant-panel-width",Ca="axhub:open-assistant-url",rd="./skills/project-guide/SKILL.md",yo=["我是新人,请先阅读项目引导技能文档,带我熟悉 Axhub Make:",rd].join(`
|
||
`),od=1,id="2026-03-28",ld=[{id:"brainstorming",title:"Brainstorming",titleZh:"头脑风暴",description:"用于快速发散想法、明确文档主题与结构方向。",defaultSelected:!0,localPaths:["/skills/third-party/brainstorming/SKILL.md"],references:["obra/superpowers@brainstorming"],category:"研究与探索"},{id:"deep-research",title:"Deep Research",titleZh:"深度研究",description:"用于系统化收集证据、形成深入研究材料。",defaultSelected:!1,localPaths:["/skills/third-party/deep-research/SKILL.md"],references:["199-biotechnologies/claude-deep-research-skill@deep-research"],category:"研究与探索"},{id:"anything-to-notebooklm",title:"Anything to NotebookLM",titleZh:"资料转 NotebookLM",description:"将原始素材整理为适合 NotebookLM 使用的输入结构。",defaultSelected:!1,localPaths:["/skills/third-party/anything-to-notebooklm/SKILL.md"],references:["joeseesun/anything-to-notebooklm@anything-to-notebooklm"],category:"研究与探索"},{id:"prd",title:"PRD",titleZh:"产品需求文档",description:"用于生成或完善 PRD 结构与内容。",defaultSelected:!1,localPaths:["/skills/third-party/prd/SKILL.md"],references:["https://skills.sh/github/awesome-copilot/prd"],category:"产品与需求"},{id:"product-requirements",title:"Product Requirements",titleZh:"产品需求",description:"用于整理产品目标、范围与需求细节。",defaultSelected:!1,localPaths:["/skills/third-party/product-requirements/SKILL.md"],references:["https://skills.sh/cexll/myclaude/product-requirements"],category:"产品与需求"},{id:"research",title:"Research",titleZh:"研究分析",description:"用于进行主题研究、资料筛选与结果归纳。",defaultSelected:!1,localPaths:["/skills/third-party/research/SKILL.md"],references:["https://skills.sh/tavily-ai/skills/research"],category:"研究与探索"},{id:"user-story-writing",title:"User Story Writing",titleZh:"用户故事编写",description:"用于编写清晰可执行的用户故事。",defaultSelected:!1,localPaths:["/skills/third-party/user-story-writing/SKILL.md"],references:["https://skills.sh/aj-geddes/useful-ai-prompts/user-story-writing"],category:"产品与需求"}],cd={version:od,generatedAt:id,skills:ld},dd=3,ud="2026-03-28",md=[{id:"project-guide",titleZh:"项目引导",titleEn:"Project Guide",description:"不知道从何开始或需要获得开发建议时,执行该技能。AI 会为你评估当前项目状态,并推荐最佳的下一步操作与平台使用技巧。",localPath:"/skills/project-guide",skillMdPath:"/skills/project-guide/SKILL.md",slashCommand:"/project-guide",category:"项目管理"},{id:"create-workflow",titleZh:"创建内容",titleEn:"Unified Create",description:"想创建任何新内容(如原型、组件、主题或文档)时执行此技能。AI 会引导你完成规范的创建流程,无需手动记忆繁杂的规则。",localPath:"/skills/create-workflow",skillMdPath:"/skills/create-workflow/SKILL.md",slashCommand:"/create-workflow",category:"日常工作流"},{id:"design-review",titleZh:"设计 Review",titleEn:"Design Review",description:"界面开发完成后,想检查是否符合项目 UI 规范时执行此技能。AI 会帮你找出违规样式并提供修改建议,或帮你将新设计沉淀为主题。",localPath:"/skills/design-review",skillMdPath:"/skills/design-review/SKILL.md",slashCommand:"/design-review",category:"日常工作流"},{id:"project-memory",titleZh:"项目整理",titleEn:"Project Memory",description:"想整理项目积累的经验时执行此技能。AI 会把近期的代码变更、零散信息和新增逻辑沉淀至说明文档中,以保持项目资产井井有条。",localPath:"/skills/project-memory",skillMdPath:"/skills/project-memory/SKILL.md",slashCommand:"/project-memory",category:"日常工作流"},{id:"work-summary",titleZh:"工作总结",titleEn:"Work Summary",description:"日常报告编写利器。随时执行该技能来回顾近期的成果,AI 会自动追踪你的代码变更,直接为你生成一份清晰的日报或工作总结。",localPath:"/skills/work-summary",skillMdPath:"/skills/work-summary/SKILL.md",slashCommand:"/work-summary",category:"日常工作流"},{id:"skills-management",titleZh:"技能管理",titleEn:"Skills Management",description:"管理和维护当前项目的技能库。当你想为团队添加新的自定义技能、修改现有描述或恢复官方默认技能时,执行此技能。",localPath:"/skills/skills-management",skillMdPath:"/skills/skills-management/SKILL.md",slashCommand:"/skills-management",category:"项目管理"}],hd={version:dd,generatedAt:ud,skills:md},pd=1,fd="2026-03-28",xd=[{id:"frontend-design",title:"Landing & Marketing",titleEn:"Landing & Marketing",titleZh:"C端展示与落地页",description:"使用场景:需要打造高辨识度视觉风格的页面/落地页/展示型界面时;强调创意审美、版式与动效表达,避免模板化“AI 味”。",localPaths:["/skills/third-party/frontend-design/SKILL.md"],sourcePageUrl:"https://skills.sh/anthropics/skills/frontend-design",sourceRepoUrl:"https://github.com/anthropics/skills",sourcePath:"skills/frontend-design",license:null,category:"设计与体验"},{id:"interface-design",title:"Admin & SaaS Interface",titleEn:"Admin & SaaS Interface",titleZh:"B端后台与SaaS",description:"使用场景:后台、SaaS、工具类产品的交互界面设计(仪表盘/设置页/数据界面);强调信息架构与可用性,不用于营销落地页。",localPaths:["/skills/third-party/interface-design/SKILL.md"],sourcePageUrl:"https://skills.sh/dammyjay93/interface-design/interface-design",sourceRepoUrl:"https://github.com/Dammyjay93/interface-design",sourcePath:".claude/skills/interface-design",license:null,category:"设计与体验"},{id:"ui-ux-pro-max",title:"UI/UX Pro Max",titleEn:"UI/UX Pro Max",titleZh:"UI/UX 专家指南",description:"使用场景:需要快速选型和评审 UI/UX 方案时(色板、字体、图表、无障碍、响应式、性能);更偏规则库与优化清单,而非单一风格生成。",localPaths:["/skills/ui-ux-pro-max/SKILL.md"],sourcePageUrl:"https://skills.sh/nextlevelbuilder/ui-ux-pro-max-skill/ui-ux-pro-max",sourceRepoUrl:"https://github.com/nextlevelbuilder/ui-ux-pro-max-skill",sourcePath:".claude/skills/ui-ux-pro-max",license:null,category:"设计与体验"},{id:"implement-design",title:"figma-implement-design",titleEn:"figma-implement-design",titleZh:"Figma 设计实现还原",description:"使用场景:拿到 Figma 链接或选中节点后,基于 Figma MCP 进行 1:1 设计还原并输出可落地代码。",localPaths:["/skills/third-party/implement-design/SKILL.md"],sourcePageUrl:"https://skills.sh/figma/mcp-server-guide/implement-design",sourceRepoUrl:"https://github.com/figma/mcp-server-guide",sourcePath:"skills/implement-design",license:null,category:"开发与实现"},{id:"baoyu-image-gen",title:"Baoyu Image Gen",titleEn:"Baoyu Image Gen",titleZh:"宝玉图像生成",description:"使用场景:批量生成视觉素材(插画、封面、背景图等)而非页面结构;支持 OpenAI/Google/DashScope、多比例与参考图生成。",localPaths:["/skills/third-party/baoyu-image-gen/SKILL.md"],sourcePageUrl:"https://skills.sh/jimliu/baoyu-skills/baoyu-image-gen",sourceRepoUrl:"https://github.com/jimliu/baoyu-skills",sourcePath:"skills/baoyu-image-gen",license:null,category:"设计与体验"},{id:"shadcn-ui",title:"shadcn/ui",titleEn:"shadcn/ui",titleZh:"shadcn 组件体系",description:"使用场景:React + Tailwind 项目搭建/扩展 shadcn/ui 组件体系;侧重可访问性、表单模式、主题变量与组件工程化复用。",localPaths:["/skills/third-party/shadcn-ui/SKILL.md"],sourcePageUrl:"https://skills.sh/giuseppe-trisciuoglio/developer-kit/shadcn-ui",sourceRepoUrl:"https://github.com/giuseppe-trisciuoglio/developer-kit",sourcePath:"plugins/developer-kit-typescript/skills/shadcn-ui",license:null,category:"开发与实现"},{id:"ant-design",title:"Ant Design",titleEn:"Ant Design",titleZh:"Ant Design 企业后台",description:"使用场景:企业后台/管理系统采用 antd 6 + Pro + X 时的组件选型与架构决策;强调 token 主题、SSR、CRUD 与 AI 聊天 UI 模式。",localPaths:["/skills/third-party/ant-design/SKILL.md"],sourcePageUrl:"https://skills.sh/ant-design/antd-skill/ant-design",sourceRepoUrl:"https://github.com/ant-design/antd-skill",sourcePath:"skills/ant-design",license:null,category:"开发与实现"},{id:"stitch-skills",title:"Stitch Skills",titleEn:"Stitch Skills",titleZh:"Stitch 主流程编排",description:"使用场景:以 spec.md 驱动 Stitch 设计并确认后再生成代码;统一编排 design-md、stitch-loop、react-components,避免跳过设计 gate。",localPaths:["/skills/third-party/stitch-skills/stitch-main-workflow/SKILL.md"],sourcePageUrl:"https://github.com/google-labs-code/stitch-skills",sourceRepoUrl:"https://github.com/google-labs-code/stitch-skills",sourcePaths:["skills/design-md","skills/react-components","skills/stitch-loop"],license:"Apache-2.0",category:"开发与实现"},{id:"gemini-cli-uiux",title:"Gemini CLI UI/UX",titleEn:"Gemini CLI UI/UX",titleZh:"Gemini 设计",description:"AI 直接调用 Gemini CLI 进行 UI/UX 设计与落地",localPaths:["/skills/gemini-cli-uiux/SKILL.md"],activeTabs:["prototypes"],license:null,category:"开发与实现"},{id:"design-bid-proposals",title:"Design Bid Proposals",titleEn:"Design Bid Proposals",titleZh:"设计比稿三案",description:"使用场景:在原型或组件新建时默认生成 A 稳健型、B 平衡型、C 突破型三案;严格在 3–6 个未锁死维度上拉开差异,并输出差异对比表与推荐方向。",localPaths:["/skills/design-bid-proposals/SKILL.md"],license:null,category:"设计与体验"},{id:"pencil-sync-after-prototype-workflow",title:"Pencil Sync After Prototype Workflow",titleEn:"Pencil Sync After Prototype Workflow",titleZh:"原型后置 Pencil 同步",description:"使用场景:先完成 spec.md 与 index.tsx 原型实现,再 1:1 回建 Pencil,并要求后续代码、规格与 .pen 强同步。",localPaths:["/skills/pencil-sync-after-prototype-workflow/SKILL.md"],activeTabs:["prototypes"],license:null,category:"开发与实现"},{id:"taste-skill",title:"Design Taste",titleEn:"Design Taste",titleZh:"高品质前端设计",description:"使用场景:打造高品质、去 AI 味的前端界面;通过设计方差、动效强度、视觉密度三个维度精确控制输出风格,内置反 AI 模板化规则与高端设计灵感库。",localPaths:["/skills/third-party/taste-skill/SKILL.md"],sourceRepoUrl:"https://github.com/Leonxlnx/taste-skill",sourcePath:"taste-skill",license:null,category:"设计与体验"}],gd={version:pd,generatedAt:fd,skills:xd},yd=1,bd="2026-03-28",wd=[{id:"tailwind-design-system",title:"Tailwind Design System",titleZh:"Tailwind 设计系统",description:"用于基于 Tailwind CSS v4 设计和落地可扩展主题系统,覆盖 token、变量、组件模式与响应式规范。",defaultSelected:!0,localPaths:["/skills/third-party/tailwind-design-system/SKILL.md"],category:"开发与实现"},{id:"theme-factory",title:"Theme Factory",titleZh:"主题工厂",description:"用于快速构建和应用视觉主题方案,包含颜色体系与字体搭配参考,适合主题风格探索与定稿。",defaultSelected:!1,localPaths:["/skills/third-party/theme-factory/SKILL.md"],category:"设计与体验"},{id:"ui-ux-pro-max",title:"UI/UX Pro Max",titleZh:"UI/UX 专家指南",description:"用于补充 UI/UX 规则库与评审清单,覆盖可访问性、色板、排版、交互、响应式与性能优化建议。",defaultSelected:!1,localPaths:["/skills/ui-ux-pro-max/SKILL.md"],category:"设计与体验"},{id:"ui-design-brain",title:"UI Design Brain",titleZh:"UI 设计大脑",description:"用于基于 60+ 真实组件模式与界面最佳实践来辅助主题和界面风格设计,减少通用 AI 模板感。",defaultSelected:!1,localPaths:["/skills/third-party/ui-design-brain/SKILL.md"],sourceRepoUrl:"https://github.com/carmahhawwari/ui-design-brain",sourcePath:".",license:"MIT",category:"设计与体验"},{id:"gemini-cli-uiux",title:"Gemini CLI UI/UX",titleZh:"Gemini 设计",description:"AI 直接调用 Gemini CLI 进行 UI/UX 设计与落地",defaultSelected:!1,localPaths:["/skills/gemini-cli-uiux/SKILL.md"],category:"设计与体验"}],jd={version:yd,generatedAt:bd,skills:wd},za=Object.assign({"../../../../axhub-make/.axhub/make/skills/doc-skills-manifest.default.json?v=1775123024591":cd,"../../../../axhub-make/.axhub/make/skills/install-skills-manifest.default.json?v=1775123024591":hd,"../../../../axhub-make/.axhub/make/skills/skills-manifest.default.json?v=1775123024591":gd,"../../../../axhub-make/.axhub/make/skills/theme-skills-manifest.default.json?v=1775123024591":jd});function bo(t){var s;return((s=t.split("?")[0])==null?void 0:s.split("#")[0])||t}function Ba(t,s){const n=`${s}.json`,a=`${s}.default.json`,o=Object.entries(t).find(([l])=>bo(l).endsWith(`/${n}`));if(o)return o[1];const i=Object.entries(t).find(([l])=>bo(l).endsWith(`/${a}`));if(i)return i[1];throw new Error(`Missing skill manifest: ${n} or ${a}`)}const qi=Ba(za,"doc-skills-manifest"),Nd=Ba(za,"install-skills-manifest"),Lr=Ba(za,"skills-manifest"),Zi=Ba(za,"theme-skills-manifest"),br="skills",vd=`/${br}/`;function aa(t){if(typeof t!="string"||t.includes("\0"))return null;const s=t.trim();if(!s||s.includes(":"))return null;const n=s.replace(/\\+/g,"/"),o=(n.startsWith("/")?n:`/${n}`).split("/").filter(Boolean);if(o.length<2||o[0]!==br)return null;const i=[br];for(let c=1;c<o.length;c+=1){const d=o[c];if(d==="..")return null;d!=="."&&i.push(d)}if(i.length<2)return null;const l=`/${i.join("/")}`;return l.startsWith(vd)?l:null}const wo=Lr;function Sd(t){const{itemType:s}=t;return`**系统交互要求**:
|
||
- 首次回复必须严格使用以下模板,并等待用户补充信息/确认;确认前不要生成任何文件、代码或文档
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,准备创建${s}。
|
||
|
||
请详细描述您的需求:
|
||
\`\`\``}function Cd(){return` - 文件结构、依赖引用、样式规范、导出规范
|
||
- ⚠️ **验收标准**:完成后必须对照此文档检查实现`}function kd(){return`
|
||
|
||
**核心流程**:收到用户需求 → 阅读规范 → 设计 → 生成 spec.md + index.tsx
|
||
|
||
**📋 必读规范文档**:
|
||
1. **\`/rules/design-guide.md\`** ⭐️ 设计流程(必须先完成)
|
||
- 资料收集、业务场景识别、数据源查找、内容规划、视觉设计
|
||
|
||
2. **\`/rules/development-standards.md\`**
|
||
${Cd()}
|
||
|
||
3. **\`/docs/templates/spec-template.md\`**
|
||
- spec.md 文档模板,使用此模板生成规格文档`}function tr(t){const{title:s,selected:n,available:a,toLine:o}=t;return n.length===0?"":`
|
||
|
||
${s}${n.map(i=>{const l=a.find(c=>c.name===i);return`
|
||
${o(i,l)}`}).join("")}`}function Ed(t,s=[]){const n=new Set(t.map(l=>String(l||"").trim()).filter(Boolean)),a=new Set,o=[],i=Array.isArray(wo.skills)?wo.skills:[];for(const l of i)if(n.has(l.id)&&Array.isArray(l.localPaths))for(const c of l.localPaths){const d=aa(c);d&&(a.has(d)||(a.add(d),o.push(d)))}for(const l of s){const c=aa(l);c&&(a.has(c)||(a.add(c),o.push(c)))}return o.length===0?"":`
|
||
|
||
**使用项目技能**:
|
||
${o.map(l=>`- \`${l}\``).join(`
|
||
`)}`}function Td(t,s){const n=`\`/src/themes/${t}/DESIGN.md\``,a=`\`/src/themes/${t}/designToken.json\``,o=`\`/src/themes/${t}/globals.css\``,i=`\`/src/themes/${t}/index.tsx\``;if([s==null?void 0:s.hasDesignSpec,s==null?void 0:s.hasDesignToken,s==null?void 0:s.hasGlobals,s==null?void 0:s.hasIndexTsx].some(c=>typeof c=="boolean")){const c=[];return s!=null&&s.hasDesignSpec&&c.push(` - ${n}`),s!=null&&s.hasDesignToken&&c.push(` - ${a}`),s!=null&&s.hasGlobals&&c.push(` - ${o}`),s!=null&&s.hasIndexTsx&&c.push(` - ${i}`),c}return[` - ${n}(如果存在)`,` - ${a}(如果存在)`,` - ${o}(如果存在)`,` - ${i}(如果存在)`]}function Id(t,s=[],n=[],a=[],o=[],i=[],l=[],c=[]){const w=t==="components"?"组件":"原型",j=`**系统指令**:你将作为UI/UX 设计架构师 × 前端工程师(复合型),创建一个${w}`,$=Sd({itemType:w}),v=kd(),D=tr({title:"**📚 参考文档**:",selected:n,available:a,toLine:(y,P)=>`- **\`/docs/${y}\`** - ${(P==null?void 0:P.displayName)||y}`}),u=tr({title:"**🎨 主题配置**:",selected:o,available:i,toLine:(y,P)=>{const R=Td(y,P);return R.length?`- ${(P==null?void 0:P.displayName)||y}
|
||
${R.join(`
|
||
`)}`:`- ${(P==null?void 0:P.displayName)||y}`}}),C=tr({title:"**📊 参考数据**:",selected:l,available:c,toLine:(y,P)=>`- **\`/src/database/${y}\`** - ${(P==null?void 0:P.displayName)||y}`}),K=Ed(s);return`${j}
|
||
|
||
⚠️ **重要提示**:请务必完整阅读以下所有规范文档和参考资料,不要偷懒!这些文档包含了关键的开发规范和最佳实践。
|
||
${K}${v}${u}${D}${C}
|
||
|
||
${$}`}(Lr.skills??[]).map(t=>({id:String(t.id??t.key??t.name??t.title??"").trim(),title:String(t.titleEn??t.title??t.name??t.titleZh??t.titleCn??"").trim(),titleZh:String(t.titleZh??t.titleCn??"").trim()||void 0,titleEn:String(t.titleEn??t.title??t.name??"").trim()||void 0,description:String(t.description??""),localPaths:Array.isArray(t.localPaths)?t.localPaths:[]}));function Pd(t,s){const[n,a]=r.useState(!1),[o,i]=r.useState([]),[l,c]=r.useState([]),[d,w]=r.useState([]),[j,$]=r.useState([]),[v,D]=r.useState([]),[u,C]=r.useState([]),[K,y]=r.useState([]),[P,R]=r.useState(!1);return r.useEffect(()=>{if(!P)return;(async()=>{try{const re=await fetch("/api/docs");if(re.ok){const B=await re.json();$(B)}}catch(re){console.error("Failed to load docs:",re)}})()},[P]),r.useEffect(()=>{if(!P)return;(async()=>{try{const re=await fetch("/api/themes");if(re.ok){const B=await re.json();c(B)}}catch(re){console.error("Failed to load themes:",re)}})()},[P]),r.useEffect(()=>{if(!P)return;(async()=>{try{const re=await fetch("/api/data/tables");if(re.ok){const xe=(await re.json()).map(ie=>({name:`${ie.fileName}.json`,displayName:ie.tableName}));C(xe)}}catch(re){console.error("Failed to load data assets:",re)}})()},[P]),r.useEffect(()=>{n&&(y([]),R(!0))},[n]),{createDialogVisible:n,selectedThemes:o,availableThemes:l,selectedDocs:d,availableDocs:j,selectedDataAssets:v,availableDataAssets:u,selectedSkills:K,setCreateDialogVisible:a,setSelectedThemes:i,setSelectedDocs:w,setSelectedDataAssets:D,setSelectedSkills:y,buildPrompt:async()=>Id(t,K,d,j,o,l,v,u),clearCreateDialogState:()=>{a(!1),w([]),i([]),D([]),y([]),R(!1),$([]),c([]),C([])},handleCreateCancel:()=>{a(!1),w([]),i([]),D([]),y([]),R(!1),$([]),c([]),C([])}}}async function Dd(t){const s=await fetch("/api/prompt/execute",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"自动执行失败");if(!(n!=null&&n.url)||typeof n.url!="string")throw new Error("自动执行返回地址无效");return{...n,url:In(n.url)}}const Pt={async deleteItem(t){const s=await fetch("/api/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){const n=await s.json();throw new Error(n.error||"删除失败")}return s.json()},async getWsClients(){const t=await fetch("/api/ws/clients");return t.ok?(await t.json()).clients||[]:[]},async sendWsMessage(t){const s=await fetch("/api/ws/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!s.ok){const n=await s.text();throw new Error(n||"发送失败")}return s.json()},async fetchCode(t){const s=await fetch(t);if(!s.ok)throw new Error(`获取构建代码失败,请让 AI 修复: ${s.statusText}`);return s.text()},async fetchHackCss(t,s){const n=`${window.location.origin}/${t}/${s}/hack.css`;try{const a=await fetch(n);if(a.ok)return await a.text()}catch(a){console.warn("fetch hack.css failed",a)}return""},async fetchSpecMd(t,s){const n=`${window.location.origin}/${t}/${s}/spec.md`;try{const a=await fetch(n);if(a.ok)return await a.text()}catch(a){console.warn("Error fetching spec.md",a)}return""},async reviewCode(t,s={}){const n=await fetch("/api/code-review",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t,enforceComponentExportName:s.enforceComponentExportName===!0})});if(!n.ok){const a=await n.json();throw new Error(a.error||"代码检查失败")}return n.json()},async getAxureApiPreview(t){const s=await fetch("/api/axure-api-preview",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})}),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"加载 Axure API 预览失败");return n},async probeExportMake(t){const s=await fetch(`/api/export-make?path=${encodeURIComponent(t)}&probe=1`),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"加载 .fig 导出状态失败");return n},async getExportMakePrompt(t){const s=await fetch(`/api/export-make?path=${encodeURIComponent(t)}&prompt=1`),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"加载 .fig 导出 Prompt 失败");return n},async executePrompt(t){const s={scene:t.scene,client:t.client,prompt:t.prompt};return Dd(s)},async getConfig(){const t=await fetch("/api/config");if(!t.ok)throw new Error("加载配置失败");return t.json()},async getAssistantRuntime(t){const s=(t==null?void 0:t.autoStart)===!1?"?autoStart=false":"",n=await fetch(`/api/assistant/runtime${s}`);if(!n.ok)throw new Error("加载助手运行时配置失败");return n.json()},async bootstrapAssistant(t){const s=await fetch("/api/assistant/bootstrap",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"启动 Axhub Genie 失败");return n},async openIDE(t){const s=await fetch("/api/ide/open",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),n=await s.json();if(!s.ok)throw new Error((n==null?void 0:n.error)||"打开 IDE 失败");return n}},Ad=["genieApiBaseUrl","apiBaseUrl","genieIntegrationChannel","integrationChannel","genieTargetClientId","integrationClientId","cwd","workdir","provider","tool","targetPath","context","editorIntegrationWs","editorApiBaseUrl","editorIntegrationChannel","editorClientId","editorSessionId","editorPageUrl"];function jo(t){for(const s of Ad)t.searchParams.delete(s)}function Rd(t){return String(t||"").trim().replace(/^\/+/,"").replace(/\/+$/,"").replace(/\/{2,}/g,"/")}function $d(t){return Rd(t).split("/").filter(Boolean).map(s=>encodeURIComponent(s)).join("/")}function wr(t,s,n){var i;if(!t)return null;const a=s==="demo"?t.demoUrl:t.specUrl,o=new URL(a,window.location.origin);if(s==="demo"){const l=$d(((i=n==null?void 0:n.selectedSubPage)==null?void 0:i.path)||"");if(l){const c=o.pathname.replace(/\/+$/,"");o.pathname=`${c}/${l}`}}return o}function Od(t,s,n,a){const o=wr(t,s,{selectedSubPage:s==="demo"?a==null?void 0:a.selectedSubPage:null});if(!o)return"";const i=String((t==null?void 0:t.displayName)||"").trim(),l=a==null?void 0:a.integrationWs,c=a==null?void 0:a.genieBridge,d=!!(l!=null&&l.enabled&&String(l.channel).trim()&&String(l.clientId||"").trim()),w=String((c==null?void 0:c.projectPath)||"").trim();if(i?o.searchParams.set("axhubDisplayName",i):o.searchParams.delete("axhubDisplayName"),s==="demo"&&n==="webEditorV2"){if(o.searchParams.set("editor","webEditorV2"),d){o.searchParams.set("editorIntegrationWs","1"),o.searchParams.set("editorIntegrationChannel",String(l==null?void 0:l.channel).trim()),o.searchParams.set("editorClientId",String((l==null?void 0:l.clientId)||"").trim());const j=String((l==null?void 0:l.apiBaseUrl)||"").trim();j?o.searchParams.set("editorApiBaseUrl",j):o.searchParams.delete("editorApiBaseUrl");const $=String((l==null?void 0:l.sessionId)||"").trim();$?o.searchParams.set("editorSessionId",$):o.searchParams.delete("editorSessionId")}else o.searchParams.delete("editorIntegrationWs"),o.searchParams.delete("editorApiBaseUrl"),o.searchParams.delete("editorIntegrationChannel"),o.searchParams.delete("editorClientId"),o.searchParams.delete("editorSessionId");w?o.searchParams.set("cwd",w):o.searchParams.delete("cwd")}else s==="spec"&&n==="specAnnotation"?(jo(o),o.searchParams.set("editor","specAnnotation"),o.searchParams.set("specEdit","1")):(jo(o),o.searchParams.delete("editor"),o.searchParams.delete("specEdit"));return a!=null&&a.width&&Number.isFinite(a.width)?o.searchParams.set("width",String(Math.round(a.width))):o.searchParams.delete("width"),o.toString()}function Pn(t,s){const n=t;if(n.filePath){const o=n.filePath.indexOf("src/");if(o>=0){let i=n.filePath.substring(o);return i=i.replace(/\/index\.(t|j)sx?$/i,""),i}return n.filePath}return`${s==="prototypes"?"src/prototypes":"src/components"}/${t.name}`}const _d="AXHUB_WEB_EDITOR_GENIE_REQUEST",Ji=["workspacePaths","relatedFiles","extraContext"];function ws(t){return typeof t=="string"?t.trim():""}function Zt(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Qi(t){const s=[],n=new Set;for(const a of t){const o=ws(a);!o||n.has(o)||(n.add(o),s.push(o))}return s}function Ld(t){return Array.isArray(t)?Qi(t):[]}function sr(t){const n=t.replace(/\\/g,"/").split("/").filter(Boolean);return n[n.length-1]||t}function Md(t){const s=ws(t);if(s==="claude"||s==="cursor"||s==="codex"||s==="gemini"||s==="opencode")return s}function Ud(t){if(!Zt(t))return null;const s=ws(t.tag),n=ws(t.selector),a=ws(t.label);return!s||!n||!a?null:{tag:s,selector:n,label:a}}function Fd(t){if(!Array.isArray(t))return[];const s=[],n=new Set;for(const a of t){const o=Ud(a);if(!o)continue;const i=`${o.tag}::${o.selector}::${o.label}`;n.has(i)||(n.add(i),s.push(o))}return s}function No(t){if(!Zt(t))return{};const s={};for(const n of Ji){const a=Ld(t[n]);a.length>0&&(s[n]=a)}return s}function Xi(t,s){const n=No(t),a=No(s),o={};for(const i of Ji){const l=Qi([...n[i]??[],...a[i]??[]]);l.length>0&&(o[i]=l)}return o}function jr(t,s){if(!Zt(t)&&!s)return;const n=Zt(t)?{...t}:{},a=Xi(Zt(n.promptContext)?n.promptContext:n,s);return Object.keys(a).length>0&&(n.promptContext={...Zt(n.promptContext)?n.promptContext:{},...a}),Object.keys(n).length>0?n:void 0}function zd(t,s){const n=jr(t),a=jr(s),o=Xi(Zt(n)?Zt(n.promptContext)?n.promptContext:n:void 0,Zt(a)?Zt(a.promptContext)?a.promptContext:a:void 0),i={...n??{},...a??{}};return Object.keys(o).length>0&&(i.promptContext={...Zt(n==null?void 0:n.promptContext)?n.promptContext:{},...Zt(a==null?void 0:a.promptContext)?a.promptContext:{},...o}),Object.keys(i).length>0?i:void 0}function Bd(t){if(!t||typeof t!="object")return!1;const s=t;if(s.type!==_d||!s.payload||typeof s.payload!="object")return!1;const n=s.payload;return typeof n.preferCurrentSession=="boolean"&&typeof n.mode=="string"}function bs(t,s={}){const n=ws(s.path),a=ws(s.displayName);if(typeof t=="string"){const l=ws(t)||n;return{path:l,displayName:a||sr(l)}}if(!Zt(t))return{path:n,displayName:a||sr(n)};const o=ws(t.path)||n,i=ws(t.displayName)||a||sr(o);return{path:o,displayName:i}}function Nr(t){return bs(t).path}function Mr(t,s={}){if(!Zt(t))return null;const n=bs(t.currentFile,{...bs(s.fallbackCurrentFile)});return{version:"1",systemContext:typeof t.systemContext=="string"?t.systemContext:"",currentFile:n,selectedElements:Fd(t.selectedElements),extensions:jr(t.extensions,s.promptContext)}}function nr(t,s){return!t&&!s?null:t?s?{version:"1",systemContext:s.systemContext||t.systemContext,currentFile:bs(s.currentFile,bs(t.currentFile)),selectedElements:s.selectedElements.length>0?s.selectedElements:t.selectedElements,extensions:zd(t.extensions,s.extensions)}:t:s??null}function Wd(t,s={}){if(!Zt(t))return null;const n=ws(t.mode);return n!=="selection_context"&&n!=="save"||typeof t.preferCurrentSession!="boolean"?null:{mode:n,provider:Md(t.provider),prompt:typeof t.prompt=="string"?t.prompt:void 0,targetPath:ws(t.targetPath)||void 0,preferCurrentSession:t.preferCurrentSession,context:t.context?Mr(t.context,{fallbackCurrentFile:s.fallbackCurrentFile,promptContext:s.promptContext})??void 0:void 0}}function Gd(t,s){const n=String(t||"").trim(),a=String(s||"").trim();return!!(n&&a&&n!==a)}function Kd(t){return{...t,currentFile:bs(t.currentFile),selectedElements:[]}}function vr(t){return Nr(t.currentFile)}function Vd(t){const s=r.useRef(null),[n,a]=r.useState(!1),o=r.useRef(!1);r.useEffect(()=>{a(!1)},[t]),r.useEffect(()=>{o.current=n},[n]);const i=r.useCallback(()=>{try{return new URL(t).origin}catch{return"*"}},[t]),l=r.useCallback((j,$="replace")=>{const v=s.current;if(!v||!v.contentWindow)return!1;const D={type:"update_context",mode:$,context:{version:j.version,systemContext:j.systemContext,currentFile:j.currentFile,selectedElements:j.selectedElements,extensions:j.extensions}};return v.contentWindow.postMessage(D,i()),!0},[i]),c=r.useCallback((j,$)=>{const v=s.current;if(!v||!v.contentWindow)return!1;const D={type:"update_prompt",prompt:j,autoSend:$};return v.contentWindow.postMessage(D,i()),!0},[i]),d=r.useCallback((j,$="replace")=>{l(j,$),$==="replace"&&(window.setTimeout(()=>l(j,$),160),window.setTimeout(()=>l(j,$),520))},[l]),w=r.useCallback(async(j=8e3)=>{var v;const $=Date.now();for(;Date.now()-$<j;){if((v=s.current)!=null&&v.contentWindow&&o.current)return!0;await new Promise(D=>setTimeout(D,120))}return!1},[]);return{iframeRef:s,iframeLoaded:n,setIframeLoaded:a,syncContext:l,syncContextWithRetry:d,syncPrompt:c,waitForReady:w}}const ar="__axhub_assistant_runtime_page_store__";function Hd(){return{runtime:null,initialized:!1,initialProbePromise:null,requests:{},listeners:new Set}}function Ys(){const t=globalThis;return t[ar]||(t[ar]=Hd()),t[ar]}function qd(t){Ys().listeners.forEach(n=>{n(t)})}function Ur(t){const s=Ys();s.runtime=t,t&&(s.initialized=!0),qd(t)}function Zd(t){const s=Ys();return s.listeners.add(t),()=>{s.listeners.delete(t)}}function Jd(t){return(t==null?void 0:t.autoStart)===!1?"probe":"auto-start"}async function Yi(t){const s=Ys(),n=Jd(t),a=s.requests[n];if(a)return a;const o=(async()=>{const i=await Pt.getAssistantRuntime({autoStart:(t==null?void 0:t.autoStart)??!0});return Ur(i),i})().finally(()=>{const i=Ys();i.requests[n]===o&&delete i.requests[n]});return s.requests[n]=o,o}async function Qd(t){const s=Ys();return s.initialized&&s.runtime?s.runtime:s.runtime?(s.initialized=!0,s.runtime):(s.initialProbePromise||(s.initialProbePromise=Yi({autoStart:!1}).catch(()=>(Ur(t),t)).finally(()=>{const n=Ys();n.initialized=!0,n.initialProbePromise=null})),s.initialProbePromise)}function Xd({defaultRuntime:t}){const s=r.useRef(t),[n,a]=r.useState(()=>Ys().runtime),[o,i]=r.useState(!1);r.useEffect(()=>{s.current=t},[t]);const l=r.useCallback(d=>{Ur(d)},[]),c=r.useCallback(async d=>Yi({autoStart:(d==null?void 0:d.autoStart)??!1}),[]);return r.useEffect(()=>{let d=!1;const w=Zd(j=>{d||a(j)});return Qd(s.current).then(j=>{d||a(j)}),()=>{d=!0,w()}},[]),{runtime:n,setRuntime:l,checking:o,setChecking:i,refreshRuntime:c}}function Yd(t,s){const n=Array.isArray(t)?t:[],a=Array.isArray(s)?s:[],o=[...n],i=new Set(o.map(l=>String((l==null?void 0:l.selector)||"").trim()).filter(Boolean));for(const l of a){const c=String((l==null?void 0:l.selector)||"").trim();!c||i.has(c)||(o.push(l),i.add(c))}return o}function eu(t){const s=Array.isArray(t)?t:[],n=[],a=new Set;for(const o of s){const i=String((o==null?void 0:o.tag)||"").trim(),l=String((o==null?void 0:o.selector)||"").trim(),c=String((o==null?void 0:o.label)||"").trim();if(!i||!l||!c)continue;const d=`${i}::${l}::${c}`;a.has(d)||(a.add(d),n.push({tag:i,selector:l,label:c}))}return n}const tu=3e3,vo=5e3,su=5,nu=1500,au=3,el="Genie 页面未在线,请先打开对应 Genie 页面。",tl="Genie 连接配置不完整。",So="Genie 连接未建立,请稍后重试。";function rr(t){const s=Math.random().toString(36).slice(2,10);return`${t}_${Date.now().toString(36)}_${s}`}function Co(t,s){return typeof t!="number"||!Number.isFinite(t)||t<=0?s:Math.max(100,Math.round(t))}function ko(t){return!!t&&typeof t=="object"}function ru(t,s){const n=t.payload;if(!n||typeof n!="object")return!1;const a=n.frontend;return ko(a)?typeof a.connected=="boolean"?a.connected:Array.isArray(a.clients)?a.clients.some(o=>ko(o)&&o.clientId===s):!1:!1}function ou(t,s){if(t==="FRONTEND_NOT_ONLINE")return el;const n=typeof s=="string"?s.trim():"";return n||(typeof t=="string"&&t.trim()?`Genie 集成失败:${t.trim()}`:"Genie 集成失败,请稍后重试。")}function iu(t,s){const n=String(t??"").trim();if(!n)throw new Error(tl);const a=new URL(n);a.protocol=a.protocol==="https:"?"wss:":"ws:",a.pathname=`${a.pathname.replace(/\/+$/,"")}/agent/ws`;const o=String(s??"").trim();return o?a.searchParams.set("apiKey",o):a.searchParams.delete("apiKey"),a.toString()}function lu(t){let s=!1,n=!1,a=null,o=null,i=null,l=null,c=null,d=null,w=0,j=0;const $=new Map;function v(k){var N;n!==k&&(n=k,(N=t.onAvailabilityChange)==null||N.call(t,k))}function D(){return String(t.apiBaseUrl).trim().length>0&&String(t.integrationChannel).trim().length>0&&String(t.targetClientId).trim().length>0&&String(t.externalClientId).trim().length>0}function u(){l!==null&&(window.clearTimeout(l),l=null)}function C(){c!==null&&(window.clearTimeout(c),c=null)}function K(){d!==null&&(window.clearTimeout(d),d=null)}function y(k){const N=$.get(k);N&&(window.clearTimeout(N.timeoutId),$.delete(k))}function P(k,N,U){const A=$.get(k);A&&(window.clearTimeout(A.timeoutId),$.delete(k),U==="FRONTEND_NOT_ONLINE"&&v(!1),A.reject(new Error(N)))}function R(k){const N=$.get(k);N&&(window.clearTimeout(N.timeoutId),$.delete(k),N.resolve())}function L(k){for(const[N,U]of $.entries())window.clearTimeout(U.timeoutId),U.reject(new Error(k)),$.delete(N)}function F(k,N){return new Promise((U,A)=>{const q=window.setTimeout(()=>{$.delete(k),A(new Error("等待 Genie 响应超时,请稍后重试。"))},N);$.set(k,{resolve:U,reject:A,timeoutId:q})})}function x(k){if(!a||a.readyState!==WebSocket.OPEN)throw new Error(So);a.send(JSON.stringify(k))}function V(){!s||!D()||d!==null||w>=su||(w+=1,d=window.setTimeout(()=>{d=null,z()},tu))}function re(){j=0,C()}function B(){!s||!D()||c!==null||!a||a.readyState!==WebSocket.OPEN||j>=au||(j+=1,c=window.setTimeout(()=>{c=null,se()},nu))}function xe(k){a===k&&(a=null,o=null,i=null,u(),C(),v(!1),L("Genie 连接已断开,请稍后重试。"),V())}function ie(k){let N=null;try{N=JSON.parse(k.data)}catch{return}if(N!=null&&N.type){if(N.type==="integration.connected"){w=0,re(),N.requestId===o&&t.probeOnStart!==!1&&se();return}if(N.type==="integration.pong"){if(N.requestId!==i)return;i=null,u();const U=ru(N,t.targetClientId);v(U),U?re():B();return}if(N.type==="integration.presence"){const U=N.payload;if(!U||U.channel!==t.integrationChannel||U.clientId!==t.targetClientId)return;U.event==="frontend-online"?(re(),v(!0)):U.event==="frontend-offline"&&v(!1);return}if(N.type==="integration.ack"&&N.requestId){R(N.requestId);return}if(N.type==="integration.error"){const U=N.payload,A=ou(U==null?void 0:U.code,U==null?void 0:U.message);N.requestId===i&&(i=null,u(),v(!1),B()),N.requestId&&P(N.requestId,A,U==null?void 0:U.code)}}}function z(){if(!s||!D()||a)return;let k;try{k=new WebSocket(iu(t.apiBaseUrl,t.apiKey))}catch{v(!1),V();return}a=k,k.onopen=()=>{if(a===k){K(),w=0,o=rr("genie_connect");try{x({type:"integration.connect",requestId:o,payload:{role:"external-client",channel:t.integrationChannel,clientId:t.externalClientId,capabilities:["presence.query","context.push"]}})}catch{k.close()}}},k.onmessage=ie,k.onerror=()=>{v(!1)},k.onclose=()=>{xe(k)}}async function se(){if(!s||!D())return;const k=rr("genie_probe"),N=Co(t.probeTimeoutMs,vo);i=k,u();try{x({type:"integration.ping",requestId:k,payload:{channel:t.integrationChannel,targetClientId:t.targetClientId}})}catch{i=null,v(!1),B();return}l=window.setTimeout(()=>{i===k&&(i=null,v(!1),B())},N)}async function W(k,N="replace"){if(!D())throw new Error(tl);if(!n)throw new Error(el);if(!a||a.readyState!==WebSocket.OPEN)throw new Error(So);const U=rr("genie_context"),A=F(U,Co(t.probeTimeoutMs,vo));try{x({type:"integration.context.update",requestId:U,payload:{channel:t.integrationChannel,targetClientId:t.targetClientId,mode:N,context:k}})}catch(q){throw y(U),q}await A}function S(){s=!1,K(),u(),C(),i=null,o=null,w=0,j=0,L("Genie bridge 已停止。");const k=a;a=null,k&&(k.onopen=null,k.onmessage=null,k.onerror=null,k.onclose=null,k.close()),v(!1)}function Y(){if(s){(t.probeOnStart??!0)&&(a==null?void 0:a.readyState)===WebSocket.OPEN&&se();return}s=!0,v(!1),w=0,j=0,C(),!(!D()||typeof window>"u"||typeof WebSocket>"u")&&z()}return{start:Y,stop:S,isAvailable(){return n},updateContext:W}}const cu={claude:"genie:claude",codex:"genie:codex",gemini:"genie:gemini",opencode:"genie:opencode"},sl=new Set(["genie:claude","genie:codex","genie:gemini","genie:opencode"]),nl=new Set(["local:cursor","local:qoder"]);function Da(t){if(t==null||typeof t!="string")return null;const s=t.trim().toLowerCase();return s?sl.has(s)||nl.has(s)?s:cu[s]||null:null}function al(t){return typeof t=="string"&&sl.has(t)}function rl(t){return typeof t=="string"&&nl.has(t)}function Fr(t){if(!al(t))return null;const s=t.split(":")[1];return s==="claude"||s==="codex"||s==="gemini"||s==="opencode"?s:null}function du(t){const s=new URL("cursor://anysphere.cursor-deeplink/prompt");return s.searchParams.set("text",t),s.toString()}function uu(t){const s=new URL("qoder://aicoding.aicoding-deeplink/chat");return s.searchParams.set("text",t),s.searchParams.set("mode","agent"),s.toString()}function Sr(t,s){if(!s)throw new Error("Prompt 不能为空");if(t==="local:cursor")return du(s);if(t==="local:qoder")return uu(s);throw new Error("不支持的本地编辑器类型")}function Eo(t,s){try{const a=sessionStorage.getItem(t);if(a)return a}catch{}const n=`${s}-${Math.random().toString(36).slice(2,10)}`;try{sessionStorage.setItem(t,n)}catch{}return n}function mu({messageApi:t,modal:s,preferredPromptClient:n,activeTab:a,viewMode:o,currentSpecDocKey:i,selectedItem:l}){const c="[assistant-runtime-ui]",d="http://localhost:32123",w=/mac/i.test(navigator.platform)?"sudo npm install -g @axhub/genie":"npm install -g @axhub/genie",j=320,$=320,v=640,D={webBaseUrl:d,apiBaseUrl:`${d}/api`,projectPath:"",source:"default",health:{status:"runtime_unreachable",message:"助手运行时不可用,请先启动 Axhub Genie。",checkedAt:new Date().toISOString(),commandSource:"default",hints:{installGlobal:w,start:"axhub-genie",status:"axhub-genie status"}}},u=r.useMemo(()=>Fr(n),[n]),[C,K]=r.useState(!1),[y,P]=r.useState(!1),[R,L]=r.useState(()=>{const ue=localStorage.getItem(go),ne=ue?Number(ue):Number.NaN;return Number.isFinite(ne)&&ne>=$?Math.min(ne,v):j}),[F,x]=r.useState(null),[V,re]=r.useState(null),B=r.useRef(null),xe=r.useRef(""),ie=r.useRef(!1),z=r.useRef(""),se=r.useRef(Eo("__axhub_make_host_client_id__","make-host")),W=r.useRef(Eo("__axhub_make_editor_client_id__","make-editor")),{runtime:S,setRuntime:Y,checking:k,setChecking:N,refreshRuntime:U}=Xd({defaultRuntime:D}),A=r.useMemo(()=>{const ue=((S==null?void 0:S.webBaseUrl)||d).replace(/\/+$/g,""),ne=new URL(`${ue}/`),me=(S==null?void 0:S.projectPath)||"";return me&&ne.searchParams.set("cwd",me),u&&ne.searchParams.set("provider",u),In(ne.toString(),window.location.origin)},[S,u]),q=F||A,{iframeRef:pe,iframeLoaded:Ne,setIframeLoaded:Ce,syncContext:Ie,syncContextWithRetry:ve,syncPrompt:Ue,waitForReady:Fe}=Vd(q);r.useEffect(()=>{localStorage.setItem(go,String(Math.round(R)))},[R]);const Oe=r.useCallback((ue,ne)=>{try{const me=new URL(In(ue,window.location.origin));return me.searchParams.set("context",JSON.stringify(ne)),me.toString()}catch(me){return console.warn("Failed to serialize assistant context into URL:",me),In(ue,window.location.origin)}},[]),We=r.useCallback(()=>{var ue;(ue=B.current)==null||ue.stop(),B.current=null,xe.current=""},[]),E=r.useCallback(ue=>{ie.current=!0;const ne=String((ue==null?void 0:ue.apiBaseUrl)||(S==null?void 0:S.apiBaseUrl)||D.apiBaseUrl).trim();if(!ne||B.current&&xe.current===ne)return;We();const me=lu({apiBaseUrl:ne,integrationChannel:Xo,targetClientId:Zl,externalClientId:se.current,probeOnStart:!0});me.start(),B.current=me,xe.current=ne},[S==null?void 0:S.apiBaseUrl,We,D.apiBaseUrl]);r.useEffect(()=>{ie.current&&E(S)},[S,E]),r.useEffect(()=>()=>{We()},[We]);const ce=r.useMemo(()=>{const ue=l?Pn(l,a):null,ne=i==="prd"?"prd":"spec",je=ue?o==="spec"?`${ue}/${ne==="prd"?"prd.md":"spec.md"}`:`${ue}/index.tsx`:null,De=(l==null?void 0:l.displayName)||"",ge={version:"1",systemContext:"",currentFile:bs(je,{displayName:De}),selectedElements:[],extensions:{source:"axhub-runtime",projectPath:(S==null?void 0:S.projectPath)||"",provider:u,viewMode:o,activeTab:a,currentSpecDocKey:ne,selectedItem:l?{name:l.name,displayName:l.displayName,demoUrl:l.demoUrl,specUrl:l.specUrl}:null,paths:{itemSourcePath:ue,currentFilePath:je,currentFileDirectory:ue},updatedAt:new Date().toISOString()}};return V?nr(ge,V)??ge:ge},[a,V,S==null?void 0:S.projectPath,i,u,l,o]),Pe=r.useCallback((ue,ne)=>{const me=(ne==null?void 0:ne.viewMode)??"demo",je=(ne==null?void 0:ne.activeTab)??a,De=(ne==null?void 0:ne.specDocKey)==="prd"?"prd":"spec",ge=Pn(ue,je),Ze=me==="spec"?`${ge}/${De==="prd"?"prd.md":"spec.md"}`:`${ge}/index.tsx`,dt={version:"1",systemContext:"",currentFile:bs(Ze,{displayName:ue.displayName||ue.name}),selectedElements:[],extensions:{source:"axhub-runtime",projectPath:(S==null?void 0:S.projectPath)||"",provider:u,viewMode:me,activeTab:je,currentSpecDocKey:De,selectedItem:{name:ue.name,displayName:ue.displayName,demoUrl:ue.demoUrl,specUrl:ue.specUrl},paths:{itemSourcePath:ge,currentFilePath:Ze,currentFileDirectory:ge},updatedAt:new Date().toISOString()}},St=ne==null?void 0:ne.externalContext;return St?nr(dt,St)??dt:dt},[a,S==null?void 0:S.projectPath,u]);r.useEffect(()=>{var je;const ue=vr(ce),ne=z.current;if(z.current=ue,!Gd(ne,ue)||(re(De=>{if(!De)return De;const ge=bs(ce.currentFile);return Nr(De.currentFile)===ge.path&&De.selectedElements.length===0?De:{...De,currentFile:ge,selectedElements:[]}}),!ie.current))return;const me=Kd(ce);(je=B.current)==null||je.updateContext(me,"replace").catch(()=>{})},[ce]),r.useEffect(()=>{!C||!Ne||Ie(ce,"replace")},[ce,Ne,C,Ie]);const Ee=r.useCallback((ue,ne)=>{const me=ue||A;let je=me;try{const De=new URL(In(me,window.location.origin)),ge=(S==null?void 0:S.projectPath)||"";!De.searchParams.get("cwd")&&ge&&De.searchParams.set("cwd",ge),!De.searchParams.get("provider")&&u&&De.searchParams.set("provider",u),ne&&!De.searchParams.get("targetPath")&&De.searchParams.set("targetPath",ne),De.searchParams.get("context")?je=De.toString():je=Oe(De.toString(),ce)}catch{je=Oe(me,ce)}return In(je,window.location.origin)},[ce,A,S==null?void 0:S.projectPath,Oe,u]),Te=r.useCallback((ue,ne)=>{const me=Ee(ue,ne);P(!0),K(!0),Ce(!1),x(me)},[Ee,Ce]),Ye=r.useCallback((ue,ne)=>{const me=Ee(ue,ne);window.open(me,"_blank","noopener,noreferrer")},[Ee]),nt=r.useCallback((ue,ne,me,je,De="iframe")=>{const ge=ue.health.hints,Ze=String(ge.installGlobal||w).trim()||w;s.confirm({title:"Axhub Genie 未就绪",content:e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"whitespace-pre-line text-sm leading-6 text-muted-foreground",children:ue.health.message}),e.jsx("div",{className:"rounded-2xl border border-border/70 bg-muted/70 px-4 py-3 font-mono text-[13px] leading-6 text-foreground shadow-sm",children:Ze}),e.jsx("div",{className:"text-xs leading-5 text-muted-foreground",children:"先在终端执行这一条命令,完成后再回来打开 Genie。"})]}),okText:"复制命令",cancelText:"稍后再说",onOk:async()=>{try{await navigator.clipboard.writeText(Ze),t.success("npx 命令已复制")}catch{t.warning("复制命令失败,请手动复制")}}}),ne==="event"&&t.warning("Genie 未就绪,已回退为安装引导。")},[t,s,w]),Me=r.useCallback(async ue=>{if(ue.health.status!=="runtime_unreachable")return ue;let ne=ue;const me=5,je=700;for(let De=0;De<me;De+=1){await new Promise(ge=>setTimeout(ge,je));try{const ge=await U();if(ne=ge,Y(ge),ge.health.status==="ready"||ge.health.status==="missing_cli"||ge.health.status==="needs_update"||ge.health.status==="cli_error")return ge}catch(ge){console.warn(`${c} runtime poll failed`,ge);break}}return ne},[U]),b=r.useCallback(async(ue,ne,me,je="iframe")=>{if(k)return!1;N(!0);const De=t.loading("正在启动并检测 Axhub Genie...",0);console.info(`${c} begin runtime check`,{trigger:ue,openTarget:je,targetUrl:ne||null,targetPath:me||null});try{const ge=await Pt.getAssistantRuntime();Y(ge),console.info(`${c} runtime response`,{status:ge.health.status,message:ge.health.message,source:ge.source,commandSource:ge.health.commandSource,webBaseUrl:ge.webBaseUrl,apiBaseUrl:ge.apiBaseUrl});const Ze=await Me(ge);if(Ze.health.status==="ready")return E(Ze),je==="window"?Ye(ne,me):Te(ne,me),!0;console.warn(`${c} runtime not ready`,{status:Ze.health.status,message:Ze.health.message,hints:Ze.health.hints}),nt(Ze,ue,ne,me,je)}catch(ge){const Ze=S||D;Y(Ze),console.error(`${c} runtime check failed`,ge),t.error((ge==null?void 0:ge.message)||"检测 Axhub Genie 状态失败"),nt(Ze,ue,ne,me,je)}finally{De(),N(!1)}return!1},[k,S,E,t,Ye,Te,N,nt,Me,D]),he=r.useCallback(async ue=>{var wt,Je;const ne=Wd(ue,{fallbackCurrentFile:ce.currentFile});if(!ne){t.warning("收到无效的 Genie 请求");return}const me=((wt=ne.targetPath)==null?void 0:wt.trim())||void 0,je=ne.context,De=String(ne.prompt||"").trim(),ge=ne.mode==="selection_context",Ze=(()=>{if(!je)return V;const tt=Mr(V??ce,{fallbackCurrentFile:ce.currentFile})??{version:"1",systemContext:"",currentFile:bs(ce.currentFile),selectedElements:[],extensions:{}},st=Yd(tt.selectedElements,je.selectedElements);return nr(tt,{version:"1",systemContext:je.systemContext||tt.systemContext,currentFile:bs(je.currentFile,bs(tt.currentFile)),selectedElements:eu(st),extensions:{...tt.extensions||{},...je.extensions||{}}})})();Ze&&re(Ze);let dt=C&&Ne&&!!((Je=pe.current)!=null&&Je.contentWindow),St=!1;if(!dt){const tt=ge?je:Ze,st=tt?Oe(A,tt):void 0;if(!await b("event",st,me))return;if(St=!!tt,dt=await Fe(8e3),!dt){t.warning("助手面板尚未加载完成,请稍后再试。");return}}if(Ze){const tt=ge?"append":"replace",st=ge?je:Ze;st&&!(ge&&St)&&ve(st,tt)}if(ge)return;if(!De){t.warning("缺少发送内容");return}Ue(De,!0)||t.error("发送失败:无法写入助手输入框")},[ce,V,Ne,pe,A,C,Oe,b,t,ve,Ue,Fe]),ke=r.useCallback(()=>{if(C){K(!1),P(!1),Ce(!1),x(null),ie.current=!1,We();return}if(y){K(!0);return}b("button")},[y,C,b,Ce,We]);r.useEffect(()=>{const ue=ne=>{const me=ne,je=me.detail,De=je==null?void 0:je.url;!De||typeof De!="string"||(b("event",De,je==null?void 0:je.targetPath),me.preventDefault())};return window.addEventListener(Ca,ue),()=>{window.removeEventListener(Ca,ue)}},[b]);const T=r.useCallback((ue,ne)=>{try{const me=new CustomEvent(Ca,{detail:{url:ue,...ne?{targetPath:ne}:{}},cancelable:!0});return!window.dispatchEvent(me)}catch{return!1}},[]),Z=r.useCallback(()=>{var ue;re(ne=>ne&&{...ne,selectedElements:[]}),C&&Ne&&((ue=pe.current)!=null&&ue.contentWindow)&&ve({version:ce.version,systemContext:ce.systemContext,currentFile:ce.currentFile,selectedElements:[],extensions:ce.extensions},"replace")},[ce,Ne,pe,C,ve]),de=r.useCallback(()=>{try{const ue=new URL(A);ue.searchParams.set("context",JSON.stringify({version:"1"})),b("button",ue.toString(),void 0,"window")}catch{b("button",A,void 0,"window")}},[A,b]),J=r.useCallback(ue=>{const ne=Pe(ue,{viewMode:"demo",activeTab:"prototypes",specDocKey:"spec"}),me=Nr(ne.currentFile),je=Oe(A,ne);try{const De=new URL(je);De.searchParams.set("targetPath",me),b("button",De.toString(),void 0,"window")}catch{b("button",je,me,"window")}},[A,Pe,Oe,b]),Ae=r.useCallback(async()=>{const ue=((S==null?void 0:S.projectPath)||"").trim();if(!ue){t.warning("当前未获取到项目目录");return}try{await navigator.clipboard.writeText(ue),t.success("项目目录已复制")}catch(ne){console.error("Failed to copy project path: ",ne),t.error("复制失败")}},[S==null?void 0:S.projectPath,t]),ze=r.useCallback(()=>{Ce(!0)},[Ce]);return{assistantVisible:C,assistantPanelMounted:y,assistantPanelWidth:R,setAssistantPanelWidth:L,assistantPanelMinWidth:$,assistantPanelMaxWidth:v,assistantIframeRef:pe,assistantIframeSrc:q,handleAssistantIframeLoad:ze,assistantContextV1:ce,assistantProjectPath:(S==null?void 0:S.projectPath)||"",assistantApiBaseUrl:((S==null?void 0:S.apiBaseUrl)||D.apiBaseUrl).trim(),assistantWebEditorClientId:W.current,handleToggleAssistant:ke,handleWebEditorGenieRequest:he,clearAssistantSelectedElementsOnExit:Z,tryOpenByAssistantIframe:T,handleOpenAssistantInNewWindowNoContext:de,handleOpenAssistantWithItemContext:J,handleCopyProjectDirectory:Ae}}async function an(t,s){if(!t.ok){const n=await t.json().catch(()=>({}));throw new Error((n==null?void 0:n.error)||s)}return t.json()}const kt={async getProjectTitle(){const t=await fetch("/api/prototype-admin/project-title");return((await an(t,"加载项目标题失败")).title||"").trim()||"未命名项目"},async updateProjectTitle(t){const s=await fetch("/api/prototype-admin/project-title",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:t})});return an(s,"保存项目标题失败")},async getSidebarTree(t){const s=await fetch(`/api/prototype-admin/sidebar-tree?tab=${encodeURIComponent(t)}`);return an(s,"加载侧边栏树失败")},async saveSidebarTree(t,s){const n=await fetch(`/api/prototype-admin/sidebar-tree?tab=${encodeURIComponent(t)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({tree:s})});return an(n,"保存侧边栏树失败")},async createSidebarFolder(t){const s=await fetch(`/api/prototype-admin/sidebar-tree/folder?tab=${encodeURIComponent(t)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});return an(s,"新建文件夹失败")},async getResourceOrder(t){const s=await fetch(`/api/prototype-admin/resource-order?type=${encodeURIComponent(t)}`);return an(s,"加载资源排序失败")},async saveResourceOrder(t,s){const n=await fetch(`/api/prototype-admin/resource-order?type=${encodeURIComponent(t)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({order:s})});return an(n,"保存资源排序失败")}},hu="subpage-group:";function Cr(t,s){return{id:`item:${t}:${s.name}`,kind:"item",title:s.displayName||s.name,itemKey:`${t}/${s.name}`}}function pu(t){return`folder:${t}:${Math.random().toString(36).slice(2,8)}`}function To(t,s){return s.map(n=>Cr(t,n))}function Vs(t,s,n){const a=new Map(n.map(d=>[`${t}/${d.name}`,d])),o=new Set,i=d=>{const w=[];return d.forEach(j=>{var D;if(j.kind==="folder"){const u=i(Array.isArray(j.children)?j.children:[]);if((D=j.id)!=null&&D.startsWith(hu)){w.push(...u);return}w.push({...j,id:j.id||pu(t),title:j.title||"未命名文件夹",kind:"folder",children:u});return}const $=j.itemKey||"";if(!$||!a.has($))return;const v=a.get($);o.add($),w.push(Cr(t,v))}),w},l=i(s);return[...n.filter(d=>!o.has(`${t}/${d.name}`)).map(d=>Cr(t,d)),...l]}const Hs="src/docs",On="src/docs/templates";function ol(t){return String(t||"").trim().replace(/\\/g,"/").replace(/^\/+/,"").replace(/\/+/g,"/")}function il(t){let s=ol(t);return!s||s==="api/docs"?"":s.startsWith("api/docs/templates/")?s.slice(19):s.startsWith("api/docs/")?s.slice(9):s==="docs"?"":s.startsWith("docs/templates/")?s.slice(15):s.startsWith("docs/")?s.slice(5):s===On?"":s.startsWith(`${On}/`)?s.slice(`${On}/`.length):s===Hs?"":s.startsWith(`${Hs}/`)?s.slice(`${Hs}/`.length):s}function zr(t,s){const n=il(s);return n?t==="template"&&n.startsWith("templates/")?n.slice(10):n:""}function Is(t,s){const n=ol(s);if(!n)return t==="template"?On:Hs;if(n===Hs||n===On||n.startsWith(`${Hs}/`))return n;if(n==="docs"||n.startsWith("docs/"))return n?`src/${n}`:Hs;if(n==="api/docs"||n.startsWith("api/docs/"))return Is(t,il(n));const a=zr(t,n),o=t==="template"?On:Hs;return a?`${o}/${a}`:o}const fu={width:500,height:300},Io="/api/axure-bridge",ll="需先安装并打开 3743 及以上版本的 Axure",Po={desktop:{width:1920,height:1080},mobile:{width:390,height:846},tablet:{width:768,height:1098}};function xu(t){if(typeof window<"u"&&"requestIdleCallback"in window){const n=window.requestIdleCallback(()=>{t()});return()=>window.cancelIdleCallback(n)}const s=globalThis.setTimeout(t,0);return()=>globalThis.clearTimeout(s)}function Do(t){return t==="1"||t==="true"}function gu(t){const s=`${$n}:`;for(let n=0;n<t.length;n+=1){const a=t.key(n);if(a!=null&&a.startsWith(s))return!0}return!1}function or(t,s){const n=String(t||"").trim();if(n)return`${$n}:${n}`;const a=String(s||"").trim();if(a)return`${$n}:name:${a}`;const o=typeof window>"u"?"unknown-origin":window.location.origin;return`${$n}:origin:${o}`}function Ao(t){const s=localStorage.getItem(t);if(s!==null)return Do(s);const n=localStorage.getItem($n);return n!==null&&!gu(localStorage)?(localStorage.setItem(t,n),localStorage.removeItem($n),Do(n)):!1}function yu(t,s){localStorage.setItem(t,"1")}function bu(t){return t==="document"?"docs":t==="canvas"?"canvas":t==="assets"?"components":"prototypes"}function xa(){return{enabled:!1,dirty:!1,saving:!1,quickEditMode:"annotation"}}function qs(t){return String(t||"").trim().replace(/\.[^./\\]+$/u,"")}function wu(t){const s=String(t||"").trim().replace(/\\/g,"/"),n=s.split("/");return n[n.length-1]||s}function Ro(t){return qs(wu(t))==="project-overview"}function ir(t){return qs(t)==="spec-template"}function cl(t){const s=zr("doc",String((t==null?void 0:t.name)||"").trim()),n=qs(s);return{name:s,displayName:n||s,jsUrl:"",demoUrl:"",specUrl:"",filePath:Is("doc",s)}}function $o(t){return Array.isArray(t)?t.map(s=>cl(s)).filter(s=>!!s.name):[]}function ln(t){const s=zr("template",String((t==null?void 0:t.name)||"").trim()),n=qs(s);return{name:s,displayName:n||s,jsUrl:"",demoUrl:"",specUrl:"",filePath:Is("template",s)}}function ju(t){return{name:t.name,displayName:t.displayName,jsUrl:"",demoUrl:"",specUrl:""}}function Nu(t){return t.map(s=>ju(s))}function vu(t,s,n,a){let o=!1;const i=l=>l.map(c=>c.kind==="folder"?{...c,children:Array.isArray(c.children)?i(c.children):c.children}:c.itemKey!==s?c:(o=!0,{...c,itemKey:n,title:a||c.title}));return{nextTree:i(t),replaced:o}}function ga(t,s,n){const a=[],o=new Set;return t.forEach(i=>{const l=i===s?n:i;!l||o.has(l)||(o.add(l),a.push(l))}),a}function Ls(t,s,n){if(!Array.isArray(t)||t.length<=1)return t;const a=new Map;return s.forEach((o,i)=>{a.set(o,i)}),[...t].sort((o,i)=>{const l=a.get(n(o)),c=a.get(n(i));return l!==void 0&&c!==void 0?l-c:l!==void 0?-1:c!==void 0?1:n(o).localeCompare(n(i))})}function Su(t,s){return t==="components"?fu:Po[s]??Po.desktop}function ds(t){return typeof t=="string"?t.trim():""}function Oo(t){var i,l;const s=[],n=ds(t==null?void 0:t.message),a=ds((i=t==null?void 0:t.cause)==null?void 0:i.message),o=ds(t==null?void 0:t.code)||ds((l=t==null?void 0:t.cause)==null?void 0:l.code);return n&&s.push(n),a&&a!==n&&s.push(`cause=${a}`),o&&s.push(`code=${o}`),s.join(";")||"未知错误"}async function _o(t){let s="";try{s=(await t.text()).trim()}catch{s=""}if(!s)return{body:null,text:""};try{return{body:JSON.parse(s),text:s}}catch{return{body:null,text:s}}}function ya(t,s,n){const a=ds(s==null?void 0:s.error)||ds(s==null?void 0:s.message)||ds(n)||t,o=[],i=ds(s==null?void 0:s.details),l=ds(s==null?void 0:s.causeMessage),c=ds(s==null?void 0:s.code),d=ds(s==null?void 0:s.route),w=ds(s==null?void 0:s.bridgeUrl),j=typeof(s==null?void 0:s.payloadBytes)=="number"?s.payloadBytes:null;return i&&i!==a&&o.push(i),l&&l!==i&&l!==a&&o.push(`cause=${l}`),c&&o.push(`code=${c}`),d&&o.push(`route=${d}`),w&&o.push(`bridge=${w}`),j!==null&&o.push(`payload=${j}B`),o.length===0?a:`${a}(${o.join(";")})`}function Cu(t){const s=ds(t);return s?s.includes("ECONNREFUSED")||s.includes("localhost:32767")||s.includes("/api/axure-bridge/available")||s.includes("/available")||s.includes("Axure Bridge")?ll:s.includes("导出超时")?"复制到 Axure 超时,请重试":s.startsWith("复制到 Axure 失败:")?"复制到 Axure 失败,请查看控制台":s:"复制到 Axure 失败,请查看控制台"}function ku({messageApi:t}){const[s,n]=r.useState(!0),[a,o]=r.useState({components:[],prototypes:[]}),[i,l]=r.useState([]),[c,d]=r.useState([]),[w,j]=r.useState([]),[$,v]=r.useState([]),[D,u]=r.useState([]),[C,K]=r.useState({themes:[],data:[],templates:[]}),[y,P]=r.useState({components:[],prototypes:[],docs:[],canvas:[]}),[R,L]=r.useState(!1),[F,x]=r.useState("未命名项目"),[V,re]=r.useState(""),B=r.useRef(new Set),xe=r.useRef(!1),ie=r.useCallback(async()=>{try{const N=await fetch("/api/entries.json");if(!N.ok)throw new Error("Failed to fetch data");const U=await N.json();o(U)}catch(N){t.error(`加载数据失败: ${N.message}`)}finally{n(!1)}},[t]),z=r.useCallback(async()=>{try{const[N,U,A,q,pe,Ne,Ce,Ie]=await Promise.all([fetch("/api/docs"),fetch("/api/canvas"),fetch("/api/themes"),fetch("/api/data/tables"),fetch("/api/docs/templates"),kt.getResourceOrder("themes").catch(()=>null),kt.getResourceOrder("data").catch(()=>null),kt.getResourceOrder("templates").catch(()=>null)]),ve=Array.isArray(Ne==null?void 0:Ne.order)?Ne.order:[],Ue=Array.isArray(Ce==null?void 0:Ce.order)?Ce.order:[],Fe=Array.isArray(Ie==null?void 0:Ie.order)?Ie.order:[];if(K({themes:ve,data:Ue,templates:Fe}),N.ok){const Oe=await N.json();l($o(Oe))}if(U.ok){const Oe=await U.json();d(Array.isArray(Oe)?Oe:[])}if(A.ok){const Oe=await A.json(),We=Array.isArray(Oe)?Oe:[];j(Ls(We,ve,E=>E.name))}if(q.ok){const Oe=await q.json(),We=Array.isArray(Oe)?Oe:[];v(Ls(We,Ue,E=>E.fileName))}if(pe.ok){const Oe=await pe.json(),We=Array.isArray(Oe)?Oe.map(E=>({name:String((E==null?void 0:E.name)||"").trim(),displayName:qs(String((E==null?void 0:E.name)||"").trim()),description:String((E==null?void 0:E.description)||"").trim()||void 0})).filter(E=>!!E.name):[];u(Ls(We,Fe,E=>E.name))}else u([])}catch(N){console.warn("Failed to load docs/themes/data/templates assets:",N),u([])}finally{L(!0)}},[]),se=r.useCallback(async()=>{const N=await fetch("/api/docs");if(!N.ok)throw new Error("Failed to fetch docs");const U=await N.json(),A=$o(U);return l(A),A},[]),W=r.useCallback(async()=>{const N=await fetch("/api/canvas");if(!N.ok)throw new Error("Failed to fetch canvas items");const U=await N.json(),A=Array.isArray(U)?U:[];return d(A),A},[]),S=r.useCallback(N=>N==="docs"?i:N==="components"?a.components:N==="canvas"?Nu(c):a.prototypes,[c,a.components,a.prototypes,i]),Y=r.useCallback(async(N,U)=>{if(!(U!=null&&U.force)&&B.current.has(N)||(N==="prototypes"||N==="components")&&s||(N==="docs"||N==="canvas")&&!R)return;const A=S(N);P(q=>({...q,[N]:q[N].length>0?q[N]:To(N,A)}));try{const q=await kt.getSidebarTree(N),pe=Vs(N,Array.isArray(q.tree)?q.tree:[],A);B.current.add(N),P(Ne=>({...Ne,[N]:pe}))}catch{B.current.add(N),P(q=>({...q,[N]:To(N,A)}))}},[S,s,R]);r.useEffect(()=>{ie()},[ie]),r.useEffect(()=>{let N=!1;return kt.getProjectTitle().then(U=>{N||x(U)}).catch(()=>{N||x("未命名项目")}),()=>{N=!0}},[]),r.useEffect(()=>{document.title=`${F||"未命名项目"} - Axhub Make`},[F]),r.useEffect(()=>{if(!xe.current)return xe.current=!0,xu(()=>{z()})},[z]),r.useEffect(()=>{P(N=>{let U=!1;const A={...N},q=["prototypes","components","docs","canvas"];for(const pe of q){if(!B.current.has(pe))continue;const Ne=Vs(pe,N[pe]||[],S(pe));Ne!==N[pe]&&(A[pe]=Ne,U=!0)}return U?A:N})},[S]);const k=r.useCallback(N=>{const U=bu(N);Y(U)},[Y]);return{loading:s,setLoading:n,data:a,setData:o,docsItems:i,setDocsItems:l,canvasItems:c,setCanvasItems:d,themes:w,setThemes:j,dataTables:$,setDataTables:v,templateAssets:D,setTemplateAssets:u,resourceOrders:C,setResourceOrders:K,sidebarTrees:y,setSidebarTrees:P,sidebarAssetsLoaded:R,setSidebarAssetsLoaded:L,projectTitle:F,setProjectTitle:x,searchText:V,setSearchText:re,loadedSidebarTreeTabsRef:B,sidebarAssetsRequestedRef:xe,loadData:ie,reloadSidebarAssets:z,reloadDocsItems:se,reloadCanvasItems:W,getSidebarTabItems:S,loadSidebarTree:Y,ensureSidebarTreeLoaded:k}}const Mn=[{value:"cursor",label:"Cursor"},{value:"trae",label:"TRAE"},{value:"vscode",label:"Visual Studio Code"},{value:"trae_cn",label:"TRAE CN"},{value:"windsurf",label:"Windsurf"},{value:"kiro",label:"Kiro"},{value:"qoder",label:"Qoder"},{value:"antigravity",label:"Antigravity"}],Eu=Mn.map(t=>t.value),Br={cursor:"Cursor",trae:"TRAE",vscode:"Visual Studio Code",trae_cn:"TRAE CN",windsurf:"Windsurf",kiro:"Kiro",qoder:"Qoder",antigravity:"Antigravity"},Tu=["vscode","cursor"],Iu=[/system cannot find the file/i,/cannot find the file specified/i,/系统找不到指定的文件/,/no such file or directory/i,/is not recognized as an internal or external command/i,/command not found/i,/enoent/i];function Pu(t,s,n){const a=typeof(t==null?void 0:t.message)=="string"?t.message.trim():"",o=s?Br[s]:"编辑器",i=`未检测到 ${o},请先安装后再试`,l=`打开${o}失败,请稍后重试`,c=a&&Iu.some(d=>d.test(a))?i:l;return n?`${c},已继续后续操作`:c}async function Aa({preferredIDE:t,targetPath:s}){if(!t)return!1;try{return await Pt.openIDE({ide:t,targetPath:s&&s.trim()?s.trim():void 0}),!0}catch(n){return console.error("Failed to auto open IDE:",n),H.warning(Pu(n,t,!!s)),!1}}function Du({messageApi:t,preferredIDE:s,selectedItem:n,activeTab:a,viewMode:o,currentSpecDocKey:i,currentMarkdownResource:l,selectedTheme:c,selectedDataTable:d}){const w=r.useCallback(async({filePath:y,copyText:P,fallbackPath:R,fallbackPaths:L,emptySelectionMessage:F})=>{const x=(y||"").trim();if(!x){t.warning(F);return}const V=[...Tu],re=t.loading("正在发送到 IDE...",0);try{P&&await navigator.clipboard.writeText(P);const B=await Aa({preferredIDE:s,targetPath:x}),xe=B?10:1;let ie=!1;for(let S=0;S<xe;S+=1){const Y=await Pt.sendWsMessage({type:"handshake",payload:"prototype-admin",targetClientTypes:V});if(Y!=null&&Y.sent){ie=!0;break}S<xe-1&&await new Promise(k=>setTimeout(k,500))}if(!ie){t.info("编辑器正在启动中,已复制文件标题,可稍后在编辑器中打开");return}const z=B?3:1;let se=!1;const W=Array.from(new Set([x,...L||[],R||""].map(S=>S.trim()).filter(Boolean)));for(let S=0;S<z;S+=1){for(const Y of W){const k=await Pt.sendWsMessage({type:"open-file",payload:Y,targetClientTypes:V});if(k!=null&&k.sent){se=!0;break}}if(se)break;S<z-1&&await new Promise(Y=>setTimeout(Y,300))}if(!se){t.warning("编辑器未连接,已复制了文件标题,可前往使用");return}t.success("已在编辑器中打开,并复制了文件标题,可前往编辑")}catch(B){t.error((B==null?void 0:B.message)||"发送失败")}finally{re()}},[t,s]),j=r.useCallback(async()=>{let y="",P="";if(n){const R=n;if(o==="spec"){const L=i==="prd"?"prd.md":"spec.md";y=`src/${a}/${n.name}/${L}`,P=`[${n.displayName} - ${L==="prd.md"?"PRD":"SPEC"}](${Pn(n,a)}/${L})`}else{if(R.filePath){const L=R.filePath.indexOf("src/");L>=0?y=R.filePath.substring(L):y=R.filePath}else y=`src/${a}/${n.name}/index.tsx`;P=`[${n.displayName}](${Pn(n,a)})`}}else{await w({emptySelectionMessage:"请先选择条目"});return}await w({filePath:y,copyText:P,emptySelectionMessage:"请先选择条目"})},[a,i,w,n,o]),$=r.useCallback(async(y,P)=>{const R=P??l.kind,L=y??l.item,F=R==="template"?"模板":"文档";if(!L){t.warning(`请先选择${F}`);return}const x=Is(R==="template"?"template":"doc",L.filePath||L.name),V=`[${L.displayName||L.name}](${x})`;await w({filePath:x,copyText:V,emptySelectionMessage:`请先选择${F}`})},[l.item,l.kind,t,w]),v=r.useCallback(async y=>{const P=y??c;if(!P){t.warning("请先选择主题");return}const R=`src/themes/${P.name}`,L=P.hasIndexTsx===!1?`${R}/designToken.json`:`${R}/index.tsx`,F=[`${R}/designToken.json`,`${R}/globals.css`,`${R}/README.md`,`${R}/DESIGN-SPEC.md`,R],x=`[${P.displayName}](src/themes/${P.name})`;await w({filePath:L,fallbackPaths:F,copyText:x,emptySelectionMessage:"请先选择主题"})},[t,w,c]),D=r.useCallback(async y=>{const P=y??c;if(!P){t.warning("请先选择主题");return}if(!P.hasDoc){t.warning("当前主题暂无规范文档");return}const R=`src/themes/${P.name}/README.md`,L=`src/themes/${P.name}/DESIGN-SPEC.md`,F=`[${P.displayName} 规范文档](${R})`;await w({filePath:R,fallbackPath:L,copyText:F,emptySelectionMessage:"请先选择主题"})},[t,w,c]),u=r.useCallback(async y=>{const P=y??d;if(!P){t.warning("请先选择数据表");return}const R=(P.fileName||"").trim(),L=/\.json$/i.test(R),F=L?R.replace(/\.json$/i,""):R,x=L?`src/database/${R}`:`src/database/${R}.json`,V=[`src/database/${F}.json`,`src/database/${F}`],re=`[${P.tableName}](${x})`;await w({filePath:x,fallbackPaths:V,copyText:re,emptySelectionMessage:"请先选择数据表"})},[t,w,d]),C=r.useCallback(async y=>Aa({preferredIDE:y||s}),[s]),K=r.useCallback(async y=>{let P="";if(o==="spec"){const R=i==="prd"?"prd.md":"spec.md";P=`[${y.displayName} - ${R==="prd.md"?"PRD":"SPEC"}](${Pn(y,a)}/${R})`}else P=`[${y.displayName}](${Pn(y,a)})`;if(!P){t.warning("无法获取路径");return}try{await navigator.clipboard.writeText(P),t.success("路径已复制")}catch(R){console.error("Failed to copy: ",R),t.error("复制失败")}},[a,i,t,o]);return{openFileInIDE:w,handleOpenIdeFile:j,handleOpenSelectedDocInIDE:$,handleOpenSelectedThemeInIDE:v,handleOpenSelectedThemeDocInIDE:D,handleOpenSelectedDataTableInIDE:u,handleOpenProjectInIDE:C,handleCopyItemPath:K}}const Au={"genie:claude":"ClaudeCode","genie:cursor":"Cursor CLI","genie:codex":"Codex","genie:gemini":"Gemini CLI","genie:opencode":"OpenCode","local:cursor":"Cursor","local:qoder":"Qoder"},Ru=["genie:claude","genie:codex","genie:gemini","genie:opencode"];function lr(t){return`ide:${t}`}function $u(t){return t==="local:cursor"?"cursor":"qoder"}function Ou(t){return typeof t=="string"&&t.startsWith("genie:")}function _u(t){return t==="local:cursor"||t==="local:qoder"}function Lu(t,s){const n={key:"copy",label:"复制 Prompt"},a=Ru.map(c=>({key:c,label:`用 ${Au[c]} 执行`})),o=Mn.map(c=>({key:lr(c.value),label:`在 ${Br[c.value]} 中执行`})),i=[{key:"automation",label:"自动化执行",actions:a},{key:"ide",label:"本地编辑器",actions:o}],l=(()=>{if(Ou(t)){const c=a.find(d=>d.key===t);if(c)return c}if(s)return o.find(c=>c.key===lr(s))??n;if(_u(t)){const c=$u(t);return o.find(d=>d.key===lr(c))??n}return n})();return{mainAction:l,copyAction:n,actionGroups:i,includeCopyInMenu:l.key!=="copy"}}const us=ec,ms=tc,Mu=be.forwardRef(({className:t,inset:s,children:n,...a},o)=>e.jsxs(si,{ref:o,className:fe("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",s&&"pl-8",t),...a,children:[n,e.jsx(ni,{className:"ml-auto h-4 w-4"})]}));Mu.displayName=si.displayName;const Uu=be.forwardRef(({className:t,...s},n)=>e.jsx(ai,{ref:n,className:fe("z-[2000] min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg",t),...s}));Uu.displayName=ai.displayName;const ts=be.forwardRef(({className:t,sideOffset:s=4,...n},a)=>e.jsx(Yl,{children:e.jsx(ri,{ref:a,sideOffset:s,className:fe("z-[2000] min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",t),...n})}));ts.displayName=ri.displayName;const Re=be.forwardRef(({className:t,inset:s,...n},a)=>e.jsx(oi,{ref:a,className:fe("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",s&&"pl-8",t),...n}));Re.displayName=oi.displayName;const Fu=be.forwardRef(({className:t,children:s,checked:n,...a},o)=>e.jsxs(ii,{ref:o,className:fe("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),checked:n,...a,children:[e.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(li,{children:e.jsx(Fn,{className:"h-4 w-4"})})}),s]}));Fu.displayName=ii.displayName;const zu=be.forwardRef(({className:t,children:s,...n},a)=>e.jsxs(ci,{ref:a,className:fe("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...n,children:[e.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(li,{children:e.jsx(di,{className:"h-2 w-2 fill-current"})})}),s]}));zu.displayName=ci.displayName;const ra=be.forwardRef(({className:t,inset:s,...n},a)=>e.jsx(ui,{ref:a,className:fe("px-2 py-1.5 text-sm font-semibold",s&&"pl-8",t),...n}));ra.displayName=ui.displayName;const Mt=be.forwardRef(({className:t,...s},n)=>e.jsx(mi,{ref:n,className:fe("-mx-1 my-1 h-px bg-border",t),...s}));Mt.displayName=mi.displayName;const Bu={"genie:claude":Vi,"genie:cursor":na,"genie:codex":yr,"genie:gemini":Ua,"genie:opencode":yr,"local:cursor":na,"local:qoder":Fa},Wu={cursor:na,trae:sa,vscode:_r,trae_cn:sa,windsurf:Or,kiro:$r,qoder:Fa,antigravity:Ua};function hs({preferredClient:t,scene:s,buildPrompt:n,disabled:a,type:o="primary",onAfterCopy:i,copySuccessMessage:l="Prompt 已复制到剪贴板",executeSuccessMessage:c="已打开新会话",fallbackMessage:d="自动执行失败,已回退为复制 Prompt",preferredIDE:w=null,getIdeTargetPath:j,block:$=!1,className:v,copyLabel:D="复制 Prompt",style:u}){const[C,K]=r.useState(!1),y=r.useRef(!1),P=W=>{if(typeof W!="string"||!W.startsWith("ide:"))return!1;const S=W.slice(4);return Eu.includes(S)},R=W=>W.slice(4),{mainAction:L,copyAction:F,actionGroups:x,includeCopyInMenu:V}=r.useMemo(()=>{const W=Lu(t,w);if(D==="复制 Prompt")return W;const S=Y=>Y.key!=="copy"?Y:{...Y,label:D};return{mainAction:S(W.mainAction),copyAction:S(W.copyAction),includeCopyInMenu:W.includeCopyInMenu,actionGroups:W.actionGroups.map(Y=>({...Y,actions:Y.actions.map(S)}))}},[t,w,D]),re=W=>{if(W==="copy")return e.jsx(ss,{className:"h-4 w-4"});if(P(W)){const Y=R(W),k=Wu[Y];return k?e.jsx(k,{size:16,color:"currentColor"}):e.jsx(hi,{className:"h-4 w-4"})}const S=Bu[W];if(S)return e.jsx(S,{size:16,color:"currentColor"})},B=(W,S)=>{try{const Y=new CustomEvent(Ca,{detail:{url:W,...S?{targetPath:S}:{}},cancelable:!0});return!window.dispatchEvent(Y)}catch{return!1}},xe=W=>{try{return window.open(W,"_blank","noopener,noreferrer")||(window.location.href=W),!0}catch{return!1}},ie=async W=>{var S,Y;if(!(C||y.current)){y.current=!0,K(!0);try{const k=await n();if(!k||!String(k).trim()){H.warning("没有可用的 Prompt");return}const N=W==="copy"?l:d;await navigator.clipboard.writeText(k);const U=(j==null?void 0:j())||void 0;if(W==="copy"){H.success(l),i==null||i();return}if(P(W)){const q=R(W),pe=Br[q];H.info(`已复制 Prompt,正尝试打开 ${pe} 编辑器`);const Ne=q==="cursor"?"local:cursor":q==="qoder"?"local:qoder":null;if(Ne){try{const Ie=Sr(Ne,k);xe(Ie)||H.success(N)}catch(Ie){Ie!=null&&Ie.message&&console.error("open deeplink failed:",Ie.message),H.success(N)}i==null||i();return}await Aa({preferredIDE:q,targetPath:U})||H.success(N),i==null||i();return}if(rl(W)){try{const q=Sr(W,k);xe(q)?H.success(c):H.success(N)}catch(q){q!=null&&q.message&&console.error("open deeplink failed:",q.message),H.success(N)}i==null||i();return}if(!al(W)){H.success(N),i==null||i();return}const A=Fr(W);if(!A){H.success(N),i==null||i();return}try{const q=await Pt.executePrompt({scene:s,client:A,prompt:k});B(q.url,U)||window.open(q.url,"_blank"),H.success(c),i==null||i()}catch(q){(S=q==null?void 0:q.message)!=null&&S.includes("Axhub Genie")||(Y=q==null?void 0:q.message)!=null&&Y.includes("@axhub/genie")?H.warning("Genie 未就绪,已回退为复制 Prompt。请先安装/启动 Axhub Genie。"):H.success(N),i==null||i(),q!=null&&q.message&&console.error("execute prompt failed:",q.message)}}catch(k){H.error((k==null?void 0:k.message)||"操作失败")}finally{y.current=!1,K(!1)}}},z=fe("inline-flex items-center",$?"w-full":"w-auto",v),se=o==="primary"?"brand":"outline";return e.jsxs(us,{modal:!1,children:[e.jsxs("div",{className:z,style:u,children:[e.jsxs(te,{variant:se,size:"sm",disabled:a||C,className:fe("rounded-r-none",$?"flex-1 min-w-0":""),onClick:()=>void ie(L.key),children:[C?e.jsx(gt,{className:"h-4 w-4 animate-spin"}):re(L.key),e.jsx("span",{className:"truncate",children:L.label})]}),e.jsx(ms,{asChild:!0,children:e.jsx(te,{variant:se,size:"sm",disabled:a||C,className:"rounded-l-none border-l border-white/20 px-2",children:e.jsx(en,{className:"h-3.5 w-3.5"})})})]}),e.jsxs(ts,{align:"end",side:"top",sideOffset:6,avoidCollisions:!1,className:"w-64",children:[x.map((W,S)=>e.jsxs(be.Fragment,{children:[e.jsx(ra,{children:W.label}),W.actions.map(Y=>e.jsxs(Re,{onClick:()=>void ie(Y.key),className:"gap-2",children:[re(Y.key),Y.label]},Y.key)),S<x.length-1?e.jsx(Mt,{}):null]},W.key)),V&&x.length>0?e.jsx(Mt,{}):null,V&&e.jsxs(Re,{onClick:()=>void ie(F.key),className:"gap-2",children:[re(F.key),F.label]})]})]})}function Gu(t){const s=new Set,n=[];for(const a of t){const o=String(a||"").trim();if(!o)continue;const i=o.startsWith("/")?o:`/${o}`;s.has(i)||(s.add(i),n.push(i))}return n}function Lo(t){const s=t.targetType,n=Gu(Array.isArray(t.docs)?t.docs:[]);if(s!=="prototypes")throw new Error(`Unsupported targetType: ${String(s)}`);return`**系统指令**:你将作为 UI/UX 设计架构师 × 前端工程师(复合型),协助用户「从 Pencil 导入并创建原型」(无需上传文件)。
|
||
|
||
${n.length>0?`**📋 参考文档(必须阅读)**:
|
||
${n.map(o=>`- \`${o}\``).join(`
|
||
`)}
|
||
`:""}
|
||
**关键约束(必须遵守)**:
|
||
1. 必须先通过 Pencil MCP 获取当前打开的 .pen 与 selection:
|
||
- 优先调用:\`mcp__pencil__get_editor_state\`
|
||
- 若不确定工具前缀/命名空间:先使用 MCP 的 \`list_tools\`(或等价能力)列出可用工具,找到 pencil 相关工具后再调用
|
||
- 若工具不可用/调用失败:立刻停止,并提示用户
|
||
- 打开 Pencil 桌面端并打开目标 .pen 文件
|
||
- 选中要导入的 Frame(可多选)
|
||
- 检查 MCP 配置(参考:\`/skills/mcp-installer/SKILL.md\`)
|
||
2. 构建候选 Frame 列表(“已有的 frame”):
|
||
- 若 selection 中包含 Frame:候选 = selection Frames
|
||
- 若 selection 为空或不是 Frame:使用 \`mcp__pencil__batch_get\` 在当前文件中搜索/列出 Frame 候选
|
||
- 对每个候选 Frame,至少输出:序号 / frameId / frameName / 尺寸(若可得)
|
||
- 若候选过多导致无法确认:要求用户回到 Pencil 先选中需要的 Frame,再重试读取
|
||
- 候选较少时(可选):用 \`mcp__pencil__get_screenshot\` 辅助用户辨认
|
||
3. 在用户确认导入范围与输出结构之前,禁止创建/修改任何文件、代码或文档。
|
||
|
||
**需要用户决定(不要推荐,列出选项并等待用户回答)**:
|
||
- 导入范围:全部 / 只导入部分(用序号或 frameId 指定)/ 回到 Pencil 重新选择后再读
|
||
- 输出结构(二选一):
|
||
A. 单原型多屏:生成 1 个 \`src/prototypes/<name>/\`,在 \`index.tsx\` 内提供轻量导航切换各 Frame 对应 Screen
|
||
B. 多原型批量:每个 Frame 生成 1 个 \`src/prototypes/<proto-name>/\`
|
||
- 命名规则:\`<name>\` / \`<proto-name>\` 如何从 Frame 名称派生(kebab-case),以及重名冲突处理
|
||
|
||
**目标输出(对每个生成的原型目录)**:
|
||
- \`src/prototypes/<name>/spec.md\`(必须记录 Pencil 来源信息:.pen 标识/路径若可得、导入的 frameId 列表、frameName 列表、Screen 到实现模块的映射)
|
||
- \`src/prototypes/<name>/index.tsx\`
|
||
- (可选)\`src/prototypes/<name>/style.css\`
|
||
|
||
**验收**:
|
||
- 单原型:\`node scripts/check-app-ready.mjs /prototypes/<name>\`
|
||
- 多原型:对每个生成的原型逐个运行 \`check-app-ready\`;如用户明确要求加速,可按用户指示减少验收次数
|
||
- READY 之前必须修复到通过
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,我将从 Pencil 导入并创建原型(无需上传)。
|
||
|
||
我会先通过 Pencil MCP 读取:
|
||
1) 当前打开的 .pen 文件
|
||
2) 当前选中的 Frame(或可用 Frame 列表)
|
||
|
||
请确认:
|
||
- Pencil 桌面端已打开目标 .pen 文件
|
||
- 已选中要导入的 Frame(可多选;也可以先不选,我会列候选给你选)
|
||
|
||
现在开始读取...
|
||
\`\`\``}const Wr=nc,Gr=ac,Wa=be.forwardRef(({className:t,align:s="center",sideOffset:n=6,container:a,...o},i)=>e.jsx(sc,{container:a??void 0,children:e.jsx(pi,{ref:i,align:s,sideOffset:n,className:fe("z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out",t),...o})}));Wa.displayName=pi.displayName;const Kr=be.forwardRef(({className:t,...s},n)=>e.jsx(ns,{ref:n,className:fe("flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",t),...s}));Kr.displayName=ns.displayName;const Vr=be.forwardRef(({className:t,...s},n)=>e.jsxs("div",{className:"flex items-center border-b px-3","cmdk-input-wrapper":"",children:[e.jsx(Ia,{className:"mr-2 h-4 w-4 shrink-0 opacity-50"}),e.jsx(ns.Input,{ref:n,className:fe("flex h-10 w-full rounded-md bg-transparent py-3 text-[14px] leading-5 outline-none placeholder:text-[14px] placeholder:leading-5 placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",t),...s})]}));Vr.displayName=ns.Input.displayName;const Hr=be.forwardRef(({className:t,onWheelCapture:s,...n},a)=>e.jsx(ns.List,{ref:a,className:fe("max-h-[300px] overflow-y-auto overflow-x-hidden overscroll-contain",t),onWheelCapture:o=>{o.stopPropagation(),s==null||s(o)},...n}));Hr.displayName=ns.List.displayName;const qr=be.forwardRef((t,s)=>e.jsx(ns.Empty,{ref:s,className:"py-6 text-center text-sm",...t}));qr.displayName=ns.Empty.displayName;const Ra=be.forwardRef(({className:t,...s},n)=>e.jsx(ns.Group,{ref:n,className:fe("overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",t),...s}));Ra.displayName=ns.Group.displayName;const Ku=be.forwardRef(({className:t,...s},n)=>e.jsx(ns.Separator,{ref:n,className:fe("-mx-1 h-px bg-border",t),...s}));Ku.displayName=ns.Separator.displayName;const Zr=be.forwardRef(({className:t,...s},n)=>e.jsx(ns.Item,{ref:n,className:fe("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",t),...s}));Zr.displayName=ns.Item.displayName;function Ms({options:t,value:s,onChange:n,placeholder:a="请选择",searchPlaceholder:o="搜索选项...",className:i,disabled:l,portalContainer:c}){const[d,w]=be.useState(!1),j=be.useMemo(()=>{const D=new Map(t.map(u=>[u.value,u]));return s.map(u=>D.get(u)).filter(u=>!!u)},[t,s]),$=D=>{if(s.includes(D)){n(s.filter(u=>u!==D));return}n([...s,D])},v=D=>{n(s.filter(u=>u!==D))};return e.jsxs(Wr,{open:d,onOpenChange:w,children:[e.jsx(Gr,{asChild:!0,children:e.jsxs(te,{type:"button",variant:"outline",role:"combobox","aria-expanded":d,className:fe("h-auto min-h-9 w-full justify-between px-3 py-1.5 text-left font-normal ring-1 ring-transparent focus-visible:ring-ring",i),disabled:l,children:[e.jsx("div",{className:"flex min-h-5 flex-1 flex-wrap items-center gap-1",children:j.length===0?e.jsx("span",{className:"text-sm text-muted-foreground",children:a}):j.map(D=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-sm text-foreground",children:[D.label,e.jsx("button",{type:"button",className:"inline-flex h-3.5 w-3.5 items-center justify-center rounded text-muted-foreground hover:text-foreground",onClick:u=>{u.preventDefault(),u.stopPropagation(),v(D.value)},"aria-label":`移除 ${D.label}`,children:e.jsx(as,{className:"h-3 w-3"})})]},D.value))}),e.jsx(en,{className:"ml-2 h-4 w-4 shrink-0 opacity-60"})]})}),e.jsx(Wa,{className:"w-[var(--radix-popover-trigger-width)] p-0",align:"start",container:c,children:e.jsxs(Kr,{children:[e.jsx(Vr,{placeholder:o}),e.jsxs(Hr,{children:[e.jsx(qr,{children:"暂无结果"}),e.jsx(Ra,{children:t.map(D=>{const u=s.includes(D.value);return e.jsxs(Zr,{value:D.value,disabled:D.disabled,onSelect:()=>$(D.value),className:"gap-2",children:[e.jsx("span",{className:fe("inline-flex h-4 w-4 items-center justify-center rounded border border-muted-foreground/40",u&&"border-foreground bg-foreground text-background"),children:u?e.jsx(Fn,{className:"h-3 w-3"}):null}),e.jsx("span",{className:"text-sm",children:D.label})]},D.value)})})]})]})})]})}function Jr({options:t,value:s,onChange:n,placeholder:a="请选择",searchPlaceholder:o="搜索选项...",className:i,disabled:l,columns:c=1,portalContainer:d,presentation:w="popover",dialogTitle:j="请选择"}){const[$,v]=be.useState(!1),D=be.useMemo(()=>{const L=new Map(t.map(F=>[F.value,F]));return s.map(F=>L.get(F)).filter(F=>!!F)},[t,s]),u=be.useMemo(()=>{const L={},F=[];return t.forEach(x=>{x.category?(L[x.category]||(L[x.category]=[]),L[x.category].push(x)):F.push(x)}),{groups:L,ungrouped:F}},[t]),C=L=>{if(s.includes(L)){n(s.filter(F=>F!==L));return}n([...s,L])},K=L=>{n(s.filter(F=>F!==L))},y=L=>{const F=s.includes(L.value);return e.jsx(Zr,{value:`${L.value} ${L.label} ${L.secondaryLabel??""}`.trim(),disabled:L.disabled,onSelect:()=>C(L.value),className:fe("h-full min-h-[96px] rounded-md border px-3.5 py-3",F?"border-foreground/40 bg-muted/50 text-foreground":"border-border","data-[selected=true]:bg-muted/70 data-[selected=true]:text-foreground"),children:e.jsxs("div",{className:"flex w-full items-start gap-2",children:[e.jsx("span",{className:fe("mt-0.5 inline-flex h-4 w-4 items-center justify-center rounded border border-muted-foreground/40",F&&"border-foreground bg-foreground text-background"),children:F?e.jsx(Fn,{className:"h-3 w-3"}):null}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"line-clamp-1 text-sm font-medium text-foreground",children:L.label}),L.secondaryLabel?e.jsx("div",{className:"mt-0.5 line-clamp-1 text-[11px] font-normal leading-4 text-muted-foreground/60",children:L.secondaryLabel}):null,L.description?e.jsx("div",{className:"mt-1 line-clamp-2 text-sm leading-5 text-muted-foreground",children:L.description}):null]})]})},L.value)},P=L=>e.jsxs(Kr,{className:"h-full min-h-0 justify-start",children:[e.jsx(Vr,{placeholder:o}),e.jsxs(Hr,{className:L,children:[e.jsx(qr,{children:"暂无结果"}),Object.entries(u.groups).map(([F,x])=>e.jsxs(Ra,{className:"p-2",children:[e.jsx("div",{className:"mb-2.5 px-1.5 text-xs font-semibold text-muted-foreground",children:F}),e.jsx("div",{className:fe("grid gap-3",c===2&&"grid-cols-2"),children:x.map(y)})]},F)),u.ungrouped.length>0&&e.jsx(Ra,{className:"p-2",children:e.jsx("div",{className:fe("grid gap-3",c===2&&"grid-cols-2"),children:u.ungrouped.map(y)})})]})]}),R=e.jsxs(te,{type:"button",variant:"outline",role:"combobox","aria-expanded":$,className:fe("h-auto min-h-9 w-full justify-between px-3 py-1.5 text-left font-normal ring-1 ring-transparent focus-visible:ring-ring",i),disabled:l,onClick:w==="dialog"?()=>v(!0):void 0,children:[e.jsx("div",{className:"flex min-h-5 flex-1 flex-wrap items-center gap-1",children:D.length===0?e.jsx("span",{className:"text-sm text-muted-foreground",children:a}):D.map(L=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded bg-muted px-2 py-0.5 text-sm text-foreground",children:[L.label,e.jsx("button",{type:"button",className:"inline-flex h-3.5 w-3.5 items-center justify-center rounded text-muted-foreground hover:text-foreground",onClick:F=>{F.preventDefault(),F.stopPropagation(),K(L.value)},"aria-label":`移除 ${L.label}`,children:e.jsx(as,{className:"h-3 w-3"})})]},L.value))}),e.jsx(en,{className:"ml-2 h-4 w-4 shrink-0 opacity-60"})]});return w==="dialog"?e.jsxs(e.Fragment,{children:[R,e.jsx(Js,{open:$,onOpenChange:v,children:e.jsxs(Qs,{className:"!top-6 sm:!top-8 !translate-y-0 !flex !flex-col h-[560px] max-h-[calc(100vh-3rem)] sm:max-h-[calc(100vh-4rem)] max-w-[780px] gap-0 overflow-hidden p-0 [&>button[aria-label='关闭']]:right-4 [&>button[aria-label='关闭']]:top-2.5 [&>button[aria-label='关闭']]:h-7 [&>button[aria-label='关闭']]:w-7",children:[e.jsx(mn,{className:"h-12 flex-row items-center border-b px-4 py-0 text-left !space-y-0",children:e.jsx(Xs,{asChild:!0,children:e.jsx("div",{className:"m-0 flex h-full items-center text-base font-semibold leading-none tracking-tight",children:j})})}),e.jsx("div",{className:"flex min-h-0 flex-1 flex-col px-4 pb-4 pt-2",children:P("max-h-none min-h-0 flex-1")})]})})]}):e.jsxs(Wr,{open:$,onOpenChange:v,children:[e.jsx(Gr,{asChild:!0,children:R}),e.jsx(Wa,{className:"w-[var(--radix-popover-trigger-width)] p-0",align:"start",container:d,children:P()})]})}function dl({title:t,description:s,accept:n,multiple:a=!1,disabled:o=!1,loading:i=!1,allowDrop:l=!0,className:c,browseLabel:d="选择文件",emptyIcon:w,selectedFiles:j=[],onFilesSelected:$,onClear:v,inputProps:D}){const u=r.useRef(null),[C,K]=r.useState(!1),y=r.useMemo(()=>j.slice(0,3),[j]),P=Math.max(j.length-y.length,0),R=()=>{var B;o||(B=u.current)==null||B.click()},L=B=>{const xe=Array.from(B.currentTarget.files??[]);xe.length>0&&$(xe),B.currentTarget.value=""},F=B=>{o||(B.key==="Enter"||B.key===" ")&&(B.preventDefault(),R())},x=B=>{o||!l||(B.preventDefault(),B.dataTransfer.dropEffect="copy",K(!0))},V=B=>{if(o||!l)return;B.preventDefault();const xe=B.relatedTarget;xe instanceof Node&&B.currentTarget.contains(xe)||K(!1)},re=B=>{if(o||!l)return;B.preventDefault(),K(!1);const xe=Array.from(B.dataTransfer.files??[]);xe.length>0&&$(xe)};return e.jsxs("div",{children:[e.jsxs("div",{role:"button",tabIndex:o?-1:0,onClick:R,onKeyDown:F,onDragOver:x,onDragEnter:x,onDragLeave:V,onDrop:re,className:fe("flex min-h-[150px] flex-col items-center justify-center gap-2 rounded-md border border-dashed border-border/70 bg-muted/10 p-6 text-center transition-colors",!o&&"cursor-pointer hover:bg-muted/30",C&&l&&"border-primary bg-primary/5",o&&"cursor-not-allowed opacity-60",c),"aria-disabled":o,children:[i?e.jsx(gt,{className:"h-7 w-7 animate-spin text-primary"}):w??e.jsx(_n,{className:"h-7 w-7 text-primary"}),e.jsx("div",{className:"text-sm font-medium",children:t}),s?e.jsx("div",{className:"max-w-md text-[12px] leading-4 text-muted-foreground",children:s}):null,e.jsx("div",{className:"mt-2 inline-flex items-center rounded-md border border-border/70 bg-background px-3 py-1.5 text-xs font-medium text-foreground shadow-sm",children:d}),l?null:e.jsx("div",{className:"text-[11px] text-muted-foreground",children:"当前模式仅支持点击选择"})]}),e.jsx("input",{ref:u,type:"file",accept:n,multiple:a,className:"hidden",onChange:L,disabled:o,...D}),j.length>0?e.jsx("div",{className:"mt-3 rounded-md border border-border/70 bg-muted/20 p-3",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"mb-2 text-xs font-medium text-foreground",children:["已选择 ",j.length," 个文件"]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[y.map(B=>e.jsxs("div",{className:"inline-flex max-w-full items-center gap-1.5 rounded-full bg-background px-2.5 py-1 text-xs text-muted-foreground shadow-sm",title:B.name,children:[e.jsx(hn,{className:"h-3.5 w-3.5 shrink-0"}),e.jsx("span",{className:"max-w-[220px] truncate",children:B.name})]},B.name)),P>0?e.jsxs("div",{className:"inline-flex items-center rounded-full bg-background px-2.5 py-1 text-xs text-muted-foreground shadow-sm",children:["+",P," 个文件"]}):null]})]}),v?e.jsx(te,{variant:"ghost",size:"icon-xs",onClick:B=>{B.stopPropagation(),v()},"aria-label":"清空已选择文件",children:e.jsx(as,{className:"h-3.5 w-3.5"})}):null]})}):null]})}function Vu(t){return t?typeof t=="string"?t.trim():t instanceof Error||typeof t=="object"&&"message"in t?String(t.message||"").trim():String(t).trim():""}function $a(t,s="上传失败,请稍后重试"){var o;const n=Vu(t);if(!n)return s;if(n==="请上传 ZIP 文件"||n==="当前来源不支持文件夹上传")return n;if(n.includes("local_axure 暂不支持文件夹上传"))return"当前来源暂不支持文件夹上传,请使用 ZIP 文件";if(n.includes("上传的文件为空"))return"上传失败,文件内容为空";if(n.includes("临时文件不存在"))return"上传失败,请重新选择文件后重试";if(n.includes("ENAMETOOLONG"))return"解压失败,压缩包内部路径过长,请缩短路径后重试";if(n.includes("MODULE_NOT_FOUND")||n.includes("Cannot find module")||n.includes("executeUserEntryPoint"))return"解压失败,运行环境异常,请重启应用后重试";if(n.includes("extract-zip")||n.includes("Zip not found")||n.includes("local-axure-extract failed"))return"解压失败,请确认 ZIP 文件完整且格式正确后重试";if(n.startsWith("解压失败:"))return"解压失败,请检查 ZIP 文件后重试";if(n.startsWith("预处理脚本执行失败:"))return"预处理失败,请检查导入内容后重试";const a=((o=n.split(/\r?\n/).find(Boolean))==null?void 0:o.trim())||"";return a&&a.length<=60&&!/[A-Za-z]:\\|node:internal|requireStack|at\s+\w+/i.test(a)?a:s}const zn=lc,Hu=rc,ul=be.forwardRef(({className:t,...s},n)=>e.jsx(fi,{className:fe("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...s,ref:n}));ul.displayName=fi.displayName;const qu=ic("fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",{variants:{side:{top:"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",bottom:"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",left:"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",right:"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"}},defaultVariants:{side:"right"}}),fn=be.forwardRef(({side:t="right",className:s,children:n,...a},o)=>e.jsxs(Hu,{children:[e.jsx(ul,{}),e.jsxs(xi,{ref:o,className:fe(qu({side:t}),s),...a,children:[n,e.jsxs(oc,{"data-sheet-close":"",className:"absolute right-4 top-4 inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",children:[e.jsx(as,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));fn.displayName=xi.displayName;const xn=({className:t,...s})=>e.jsx("div",{className:fe("flex flex-col space-y-2 text-center sm:text-left",t),...s});xn.displayName="SheetHeader";const Bn=({className:t,...s})=>e.jsx("div",{className:fe("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",t),...s});Bn.displayName="SheetFooter";const gn=be.forwardRef(({className:t,...s},n)=>e.jsx(gi,{ref:n,className:fe("m-0 text-lg font-semibold leading-none tracking-tight text-foreground",t),...s}));gn.displayName=gi.displayName;const Zu=be.forwardRef(({className:t,...s},n)=>e.jsx(yi,{ref:n,className:fe("m-0 text-sm text-muted-foreground",t),...s}));Zu.displayName=yi.displayName;const ca=cc,Wn=be.forwardRef(({className:t,...s},n)=>e.jsx(bi,{ref:n,className:fe("inline-flex h-9 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",t),...s}));Wn.displayName=bi.displayName;const Jt=be.forwardRef(({className:t,...s},n)=>e.jsx(wi,{ref:n,className:fe("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",t),...s}));Jt.displayName=wi.displayName;const Ju=be.forwardRef(({className:t,...s},n)=>e.jsx(ji,{ref:n,className:fe("mt-2 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",t),...s}));Ju.displayName=ji.displayName;const Ga=be.forwardRef(({className:t,...s},n)=>e.jsx(Ni,{ref:n,className:fe("inline-flex items-center gap-1",t),...s}));Ga.displayName=Ni.displayName;const Zs=be.forwardRef(({className:t,...s},n)=>e.jsx(vi,{ref:n,className:fe("inline-flex items-center justify-center rounded-md px-2 py-1.5 text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",t),...s}));Zs.displayName=vi.displayName;function Qu({visible:t,onClose:s,activeTab:n,selectedThemes:a,setSelectedThemes:o,availableThemes:i,selectedDocs:l,setSelectedDocs:c,availableDocs:d,selectedDataAssets:w,setSelectedDataAssets:j,availableDataAssets:$,preferredPromptClient:v,preferredIDE:D,buildCreatePrompt:u,onAfterCreatePromptAction:C,onUploadSuccess:K,selectedSkills:y,setSelectedSkills:P}){const[R,L]=r.useState(null),[F,x]=r.useState("create"),[V,re]=r.useState("make"),[B,xe]=r.useState("zip"),[ie,z]=r.useState(!1),[se,W]=r.useState(null),[S,Y]=r.useState([]),k=n==="components"?"新建组件":"新建原型",N=n==="components"?"导入组件":"导入原型",U=r.useMemo(()=>(Lr.skills??[]).reduce((ce,Pe)=>{const Ee=String(Pe.id??"").trim(),Te=String(Pe.titleZh??Pe.titleCn??"").trim(),Ye=String(Pe.titleEn??Pe.title??"").trim(),nt=Te||Ye;if(!Ee||!nt)return ce;const Me=Array.isArray(Pe.activeTabs)?Pe.activeTabs.map(he=>String(he||"").trim()).filter(Boolean):[];if(Me.length>0&&!Me.includes(n))return ce;const b={value:Ee,label:nt,secondaryLabel:Te&&Ye&&Te!==Ye?Ye:void 0,description:String(Pe.description??"").trim()||"适用于界面设计与前端实现相关的通用场景。",category:Pe.category};return ce.push(b),ce},[]),[n]);r.useEffect(()=>{t&&(x("create"),re("make"),xe("zip"),z(!1),W(null),Y([]))},[t]),r.useEffect(()=>{pe(V)&&B!=="zip"&&xe("zip")},[B,V]);const A=E=>["make","axhub"].includes(E),q=(E,ce)=>A(E)?!0:E==="google_stitch"?(ce==null?void 0:ce.requiresAi)!==!0:!1,pe=E=>E==="figma_make",Ne=E=>["axure_prototype","web_page"].includes(E),Ce=E=>E==="pencil",Ie=E=>Ne(E)||Ce(E),ve="/skills",Ue=r.useMemo(()=>{const E=[{key:"make",title:"Axbub Make",description:"支持自己或他人的 ZIP 包",docs:[`${ve}/local-axure-workflow/SKILL.md`],icon:e.jsx(dn,{className:"h-8 w-8 text-sky-500"})},{key:"axhub",title:"Axbub 扩展",description:"可导出任意网页(静态)",docs:[`${ve}/screenshot-page-workflow/SKILL.md`],icon:e.jsx(ta,{className:"h-8 w-8 text-violet-500"})},{key:"google_stitch",title:"Google Stitch",description:"AI 驱动的 UI 设计工具(静态)",docs:[`${ve}/screenshot-page-workflow/SKILL.md`],icon:e.jsx(dc,{className:"h-8 w-8 text-rose-500"})},{key:"figma_make",title:"Figma Make",description:"上传 Figma 原始导出的 ZIP 工程包",docs:[`${ve}/figma-make-project-converter/SKILL.md`],icon:e.jsx(ta,{className:"h-8 w-8 text-pink-500"})},{key:"v0",title:"V0 App",description:"在线应用生成平台",docs:[`${ve}/v0-project-converter/SKILL.md`],icon:e.jsx(_n,{className:"h-8 w-8 text-emerald-500"})},{key:"google_aistudio",title:"Google AIStudio",description:"在线应用生成平台",docs:[`${ve}/ai-studio-project-converter/SKILL.md`],icon:e.jsx(pn,{className:"h-8 w-8 text-amber-500"})},{key:"axure_prototype",title:"Axure 原型链接",description:"支持在线或本地预览的链接",docs:[`${ve}/axure-prototype-workflow/SKILL.md`,`${ve}/axure-prototype-workflow/prototype-restoration.md`],icon:e.jsx(un,{className:"h-8 w-8 text-sky-500"})},{key:"web_page",title:"网页链接",description:"支持任意网页链接",docs:[`${ve}/web-page-workflow/SKILL.md`,`${ve}/web-page-workflow/prototype-restoration.md`],icon:e.jsx(pn,{className:"h-8 w-8 text-cyan-500"})}];return n==="prototypes"&&E.push({key:"pencil",title:"Pencil 导入",description:"读取当前打开的 Pencil 文件",docs:[`${ve}/pencil-import-workflow/SKILL.md`,`${ve}/pencil-sync-after-prototype-workflow/SKILL.md`,`${ve}/mcp-installer/SKILL.md`],icon:e.jsx(Si,{className:"h-8 w-8 text-slate-500"})}),E},[n]),Fe=async E=>{var Pe;if(E.length===0)return;if(pe(V)&&B!=="zip"){H.error("当前来源仅支持 ZIP 上传");return}const ce=new FormData;if(ce.append("uploadType",V),ce.append("targetType",n),ce.append("uploadMode",B),B==="zip"){const Ee=E[0];if(!Ee.name.endsWith(".zip")){H.error("请上传 ZIP 文件");return}ce.append("file",Ee,Ee.name)}else{if(E.length===0){H.error(B==="folder"?"请选择文件夹":"请选择文件");return}if(B==="folder"){const Te=(((Pe=E[0])==null?void 0:Pe.webkitRelativePath)||"").split("/").filter(Boolean)[0];Te&&ce.append("folderName",Te)}E.forEach(Ee=>{ce.append("files",Ee,Ee.name);const Te=B==="folder"&&Ee.webkitRelativePath||Ee.name;ce.append("relativePaths",Te)})}Y(E),z(!0);try{const Ee=await fetch("/api/upload",{method:"POST",body:ce}),Te=await Ee.json();Ee.ok&&Te.success?(W(Te),q(V,Te)?(H.success(Te.message||"上传成功"),setTimeout(()=>{s(),K==null||K()},800)):H.success(Te.message||"页面已准备好,可继续交给 AI 完善")):(console.error("[CreateDialog] 上传失败:",{status:Ee.status,statusText:Ee.statusText,result:Te}),H.error($a(Te==null?void 0:Te.error,"上传失败,请稍后重试")))}catch(Ee){console.error("[CreateDialog] 上传异常详情:",Ee),H.error($a(Ee,"上传失败,请稍后重试"))}finally{z(!1)}},Oe=r.useCallback(()=>{const E=Ue.find(Ee=>Ee.key===V),ce=(E==null?void 0:E.docs)||[];if(Ce(V))return Lo({targetType:"prototypes",docs:ce});if(Ne(V)){const Ee=n==="components"?"组件":"原型",Te=V==="axure_prototype"?"Axure 原型链接":"网页链接";return`**系统指令**:你将作为UI/UX 设计架构师 × 前端工程师(复合型),协助用户「基于${Te}导入并创建一个${Ee}」。
|
||
|
||
**📋 参考技能文档(必须阅读)**:
|
||
${ce.map(Ye=>`- \`${Ye}\``).join(`
|
||
`)}
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,我将基于 ${Te} 导入并创建一个${Ee}。
|
||
|
||
请把链接发我(URL):
|
||
\`\`\``}if(!(se!=null&&se.prompt))throw new Error("没有可复制的 Prompt");let Pe=se.prompt;return ce.length>0&&(Pe+=`
|
||
|
||
📋 参考技能文档:
|
||
${ce.map(Ee=>`- \`${Ee}\``).join(`
|
||
`)}`),Pe},[n,Lo,Ne,Ce,Ue,se,V]),We=B==="folder"?{directory:"",webkitdirectory:""}:{};return e.jsx(zn,{open:t,onOpenChange:E=>!E&&s(),children:e.jsx(fn,{ref:L,side:"left",className:"flex w-full max-w-[620px] flex-col p-0 text-sm sm:max-w-[620px] [&>[data-sheet-close]]:hidden",children:e.jsxs(ca,{value:F,onValueChange:E=>{(E==="create"||E==="upload")&&x(E)},className:"flex h-full flex-col",children:[e.jsxs(xn,{className:"border-b px-5 py-3.5",children:[e.jsx(gn,{className:"sr-only",children:`${k} / ${N}`}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(Wn,{className:"grid h-8 w-full max-w-[280px] grid-cols-2 rounded-lg border border-border/70 bg-muted/50 p-0.5",children:[e.jsx(Jt,{value:"create",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:k}),e.jsx(Jt,{value:"upload",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:N})]}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md",onClick:s,"aria-label":"关闭",children:e.jsx(as,{className:"h-4 w-4"})})]})]}),e.jsx("div",{className:"flex-1 space-y-4 overflow-y-auto px-5 py-4.5",children:F==="create"?e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"rounded-md border border-border/60 bg-muted/30 px-3.5 py-2.5 text-[13px] leading-relaxed text-muted-foreground",children:"💡 你也可以直接与 AI 对话生成原型,以下选项可帮助生成更精准的提示词。"}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"从技能列表中选择,AI 会参考对应应用场景生成方案",tooltipClassName:"max-w-none w-fit whitespace-nowrap",children:"使用技能"}),e.jsx(Jr,{value:y,onChange:P,placeholder:"请选择技能(可多选)",searchPlaceholder:"搜索技能...",options:U,columns:2,portalContainer:R,presentation:"dialog",dialogTitle:"选择技能(可多选)"})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会根据所选主题生成原型,主题可在资产管理原型中进行管理",children:"主题"}),e.jsx(Ms,{value:a,onChange:o,placeholder:"自动",searchPlaceholder:"搜索主题...",options:i.map(E=>({value:E.name,label:E.displayName})),portalContainer:R})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会根据所选文档生成原型,文档可在资产管理原型中进行管理",children:"文档"}),e.jsx(Ms,{value:l,onChange:c,placeholder:"自动",searchPlaceholder:"搜索文档...",options:d.map(E=>({value:E.name,label:E.displayName})),portalContainer:R})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会根据所选数据生成原型,数据可在数据管理原型中进行管理",children:"数据"}),e.jsx(Ms,{value:w,onChange:j,placeholder:"自动",searchPlaceholder:"搜索数据...",options:$.map(E=>({value:E.name,label:E.displayName})),portalContainer:R})]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 gap-4",children:Ue.map(E=>{const ce=E.key===V;return e.jsxs("button",{type:"button",onClick:()=>{re(E.key),xe((pe(E.key),"zip")),W(null),Y([])},className:`flex items-center gap-2.5 rounded-md border p-3 text-left transition ${ce?"border-foreground/60 bg-muted/40":"border-border hover:bg-muted/30"}`,children:[e.jsx("div",{className:"flex-shrink-0 text-muted-foreground/80 [&_svg]:h-6 [&_svg]:w-6",children:E.icon}),e.jsxs("div",{className:"grid gap-1",children:[e.jsx("div",{className:"text-sm font-medium leading-none",children:E.title}),e.jsx("div",{className:"text-[12px] leading-4 text-muted-foreground line-clamp-2",children:E.description})]})]},E.key)})}),Ie(V)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:Ce(V)?"当前来源无需上传文件。请确保 Pencil 桌面端已打开目标 .pen 文件,点击底部按钮完成后续导入。":"当前来源无需上传文件。点击底部按钮开始对话,并将链接发送给 AI 即可。"}):e.jsxs("div",{className:"space-y-3 pt-2",children:[pe(V)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:"Figma Make 导入仅支持原始导出的 ZIP 工程包。请直接上传 Figma 导出的 ZIP,不要先手动解压、删改文件或重组目录。"}):e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium",children:"上传方式"}),e.jsxs(Ga,{type:"single",value:B,onValueChange:E=>{(E==="zip"||E==="folder")&&(xe(E),W(null),Y([]))},children:[e.jsx(Zs,{value:"zip",children:"ZIP"}),e.jsx(Zs,{value:"folder",children:"文件夹"})]})]}),e.jsx(dl,{title:pe(V)?"点击上传或拖拽 Figma 原始 ZIP 到此区域":B==="zip"?"点击上传或拖拽 ZIP 文件到此区域":"点击上传文件夹",description:pe(V)?"请上传 Figma Make 原始导出的 ZIP 工程包,系统会按官方项目结构直接处理。":B==="zip"?"建议优先使用 ZIP 上传,导入更稳定。":"请选择本地文件夹,系统会按原目录结构上传。",accept:pe(V)||B==="zip"?".zip":void 0,multiple:!pe(V)&&B==="folder",disabled:ie,loading:ie,allowDrop:pe(V)||B!=="folder",browseLabel:pe(V)||B==="zip"?"选择 ZIP 文件":"选择文件夹",selectedFiles:S,onFilesSelected:Fe,onClear:()=>{Y([]),W(null)},inputProps:pe(V)?void 0:We}),se!=null&&se.requiresAi?e.jsxs("div",{className:"rounded-md border border-emerald-200 bg-emerald-50/70 p-3 text-sm text-emerald-900",children:[e.jsx("div",{className:"font-medium",children:"页面已可预览"}),e.jsx("div",{className:"mt-1 leading-6 text-emerald-800",children:se.message||"当前可先查看页面结构与样式效果,部分细节还可继续完善。"}),se.hint?e.jsx("div",{className:"mt-1 text-[12px] leading-5 text-emerald-700",children:se.hint}):null]}):null]})]})}),e.jsxs(Bn,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:s,children:"取消"}),F==="create"?e.jsx(hs,{type:"primary",preferredClient:v,preferredIDE:D,scene:`create-${n}`,buildPrompt:()=>u(),onAfterCopy:C,copySuccessMessage:"复制成功,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt"}):Ie(V)||!q(V,se)?e.jsx(hs,{type:"primary",preferredClient:v,preferredIDE:D,scene:`upload-${V}-${n}`,buildPrompt:Oe,copySuccessMessage:"提示词已复制到剪贴板,请粘贴给 AI 继续完善",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",disabled:!Ie(V)&&!se}):null]})]})})})}function Xu({state:t,actions:s}){return e.jsx(Qu,{visible:t.visible,onClose:s.onClose,activeTab:t.activeTab,selectedDocs:t.selectedDocs,setSelectedDocs:s.setSelectedDocs,availableDocs:t.availableDocs,selectedThemes:t.selectedThemes,setSelectedThemes:s.setSelectedThemes,availableThemes:t.availableThemes,selectedDataAssets:t.selectedDataAssets,setSelectedDataAssets:s.setSelectedDataAssets,availableDataAssets:t.availableDataAssets,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE,buildCreatePrompt:s.buildCreatePrompt,onAfterCreatePromptAction:s.onAfterCreatePromptAction,onUploadSuccess:s.onUploadSuccess,selectedSkills:t.selectedSkills??[],setSelectedSkills:s.setSelectedSkills??(()=>{})})}const cr=[".md",".txt",".pdf",".docx",".pptx",".xlsx",".csv",".json",".html",".xml"];function dr(t){return t.slice(Math.max(0,t.lastIndexOf("."))).toLowerCase()}function Yu({visible:t,onClose:s,selectedSkillIds:n,setSelectedSkillIds:a,availableDocSkills:o,selectedDocs:i,setSelectedDocs:l,availableDocs:c,selectedDataAssets:d,setSelectedDataAssets:w,availableDataAssets:j,selectedTemplates:$,setSelectedTemplates:v,availableTemplates:D,selectedReferencePrototypes:u,setSelectedReferencePrototypes:C,availableReferencePrototypes:K,preferredPromptClient:y,preferredIDE:P,buildCreateDocPrompt:R,onAfterCreatePromptAction:L,onManualCreateSuccess:F,onImportSuccess:x}){const[V,re]=r.useState(null),[B,xe]=r.useState("ai"),[ie,z]=r.useState(""),[se,W]=r.useState(""),[S,Y]=r.useState(!1),[k,N]=r.useState({checking:!1,installed:!1,commandSource:"unavailable",version:"",installHints:[],error:""}),[U,A]=r.useState([]),[q,pe]=r.useState(!1),[Ne,Ce]=r.useState([]),[Ie,ve]=r.useState(""),Ue=r.useCallback(async()=>{N(b=>({...b,checking:!0,error:""}));try{const b=await fetch("/api/docs/import/markitdown-status"),he=await b.json().catch(()=>null);if(!b.ok)throw new Error((he==null?void 0:he.error)||"检测 markitdown 失败");N({checking:!1,installed:!!(he!=null&&he.installed),commandSource:String((he==null?void 0:he.commandSource)||"unavailable"),version:String((he==null?void 0:he.version)||""),installHints:Array.isArray(he==null?void 0:he.installHints)?he.installHints:[],error:String((he==null?void 0:he.error)||"")})}catch(b){N(he=>({...he,checking:!1,installed:!1,commandSource:"unavailable",version:"",error:(b==null?void 0:b.message)||"检测失败",installHints:he.installHints.length>0?he.installHints:["brew install python@3.11","python3.11 -m pip install -U 'markitdown[pdf,docx,pptx,xlsx]'"]}))}},[]);r.useEffect(()=>{t&&(xe("ai"),z(""),W(""),Y(!1),A([]),Ce([]),ve(""),pe(!1),Ue())},[Ue,t]);const Fe=r.useMemo(()=>o.map(b=>({value:b.id,label:b.titleZh||b.title,secondaryLabel:b.titleZh&&b.title&&b.titleZh!==b.title?b.title:void 0,description:String(b.description||"").trim()||"适用于文档内容生成与结构化整理场景。",category:b.category})),[o]),Oe=r.useMemo(()=>U.some(b=>dr(b.name)!==".md"),[U]),We=r.useMemo(()=>Ne.filter(b=>!b.success),[Ne]),E=r.useMemo(()=>!!(k.error||Ie||We.length>0),[We.length,Ie,k.error]),ce=U.length>0&&(k.installed||!Oe),Pe=r.useCallback(()=>{const b=(k.installHints.length>0?k.installHints:["python3 -m pip install -U 'markitdown[pdf,docx,pptx,xlsx]'"]).map(Z=>`- \`${Z}\``).join(`
|
||
`),he=U.length>0?U.map(Z=>{const de=dr(Z.name)||"unknown",J=Math.max(1,Math.round(Z.size/1024));return`- ${Z.name} (${de}, ${J} KB)`}).join(`
|
||
`):"- 当前未选择文件",ke=We.length>0?We.map(Z=>`- ${Z.originalName} [${Z.extension||"unknown"}]:${Z.error||"未知错误"}`).join(`
|
||
`):"- 暂无单文件失败明细",T=[k.commandSource||"unavailable",k.version].filter(Boolean).join(" · ")||"unavailable";return["请帮我排查 Axhub Runtime 中的文档导入 / markitdown 环境问题,并给出可直接复制执行的修复方案。","","请按下面要求回答:","- 先根据错误信息判断最可能的根因。","- 输出 macOS + zsh 环境下可直接执行的检查命令和修复命令。","- 优先给最小修复路径;如果有多种可能,请按“先检查 → 再修复”组织。","- 最后补充“修复后如何验证”的步骤。","","## 当前信息",`- markitdown 状态:${k.installed?"可用":"当前不可用"}`,`- 命令来源 / 版本:${T}`,`- 状态检测报错:${k.error||"无"}`,`- 最近一次导入报错:${Ie||"无"}`,"- 建议安装命令:",b,"- 当前待导入文件:",he,"- 最近一次失败明细:",ke,"","## 请按这个结构回复","1. 根因判断","2. 检查命令","3. 修复命令","4. 修复后验证步骤","5. 如果仍失败,还需要补充采集哪些信息"].join(`
|
||
`)},[We,U,Ie,k.commandSource,k.error,k.installHints,k.installed,k.version]),Ee=r.useCallback(async()=>{const b=ie.trim();if(!b){W("请输入文档名称");return}W(""),Y(!0);try{const he=await fetch("/api/docs/manual-create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:b})}),ke=await he.json().catch(()=>({}));if(!he.ok||!(ke!=null&&ke.success))throw new Error((ke==null?void 0:ke.error)||"创建失败");H.success(`文档「${ke.displayName||b}」创建成功`),await(F==null?void 0:F()),L()}catch(he){const ke=(he==null?void 0:he.message)||"创建失败";W(ke),H.error(ke)}finally{Y(!1)}},[ie,L,F]),Te=r.useCallback(b=>{if(!b||b.length===0)return;const he=new Set(U.map(de=>`${de.name}:${de.size}:${de.lastModified}`)),ke=[];let T=0,Z=0;Array.from(b).forEach(de=>{const J=dr(de.name);if(!cr.includes(J)){T+=1;return}if(!k.installed&&J!==".md"){Z+=1;return}const Ae=`${de.name}:${de.size}:${de.lastModified}`;he.has(Ae)||(he.add(Ae),ke.push(de))}),T>0&&H.warning(`已忽略 ${T} 个不支持的文件格式`),Z>0&&H.warning(`markitdown 当前不可用,已忽略 ${Z} 个非 .md 文件`),ke.length>0&&A(de=>[...de,...ke])},[U,k.installed]),Ye=r.useCallback(async()=>{if(!ce){H.warning("请选择可导入的文件");return}const b=new FormData;U.forEach(he=>{b.append("files",he,he.name)}),pe(!0),Ce([]),ve("");try{const he=await fetch("/api/docs/import",{method:"POST",body:b}),ke=await he.json().catch(()=>({})),T=Array.isArray(ke==null?void 0:ke.results)?ke.results:[];Ce(T);const Z=Number((ke==null?void 0:ke.successCount)||0),de=Number((ke==null?void 0:ke.failedCount)||0),J=T.find(ze=>!ze.success&&ze.error),Ae=String((ke==null?void 0:ke.error)||(ke==null?void 0:ke.markitdownError)||(J==null?void 0:J.error)||"").trim();if(!he.ok&&Z===0)throw new Error(Ae||"导入失败");if(Z>0&&await(x==null?void 0:x()),de===0){ve(""),H.success(`导入成功,共 ${Z} 个文档`),L();return}ve(Ae||`已导入 ${Z} 个文档,${de} 个失败`),H.warning(`已导入 ${Z} 个文档,${de} 个失败`)}catch(he){const ke=(he==null?void 0:he.message)||"导入失败";ve(ke),H.error(ke)}finally{pe(!1)}},[ce,U,L,x]),nt=r.useCallback(async b=>{try{await navigator.clipboard.writeText(b),H.success("安装命令已复制")}catch{H.error("复制安装命令失败")}},[]),Me=S||q;return e.jsx(zn,{open:t,onOpenChange:b=>!b&&s(),children:e.jsx(fn,{ref:re,side:"left",className:"flex w-full max-w-[620px] flex-col p-0 text-sm sm:max-w-[620px] [&>[data-sheet-close]]:hidden",children:e.jsxs(ca,{value:B,onValueChange:b=>{(b==="ai"||b==="manual"||b==="import")&&(xe(b),W(""))},className:"flex h-full flex-col",children:[e.jsxs(xn,{className:"border-b px-5 py-3.5",children:[e.jsx(gn,{className:"sr-only",children:"新建文档 / 导入文档"}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs(Wn,{className:"grid h-8 w-full max-w-[340px] grid-cols-3 rounded-lg border border-border/70 bg-muted/50 p-0.5",children:[e.jsx(Jt,{value:"ai",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"AI 新建"}),e.jsx(Jt,{value:"manual",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"手动新建"}),e.jsx(Jt,{value:"import",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"导入文档"})]}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md",onClick:s,"aria-label":"关闭",disabled:Me,children:e.jsx(as,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{className:"flex-1 space-y-4 overflow-y-auto px-5 py-4.5",children:[B==="manual"?e.jsxs(Dt,{children:[e.jsx(At,{hint:"输入文档名称后会在 src/docs 下直接创建 .md 文件",children:"文档名称"}),e.jsx(Ps,{value:ie,onChange:b=>{z(b.target.value),se&&W("")},placeholder:"例如:订单流程说明",autoFocus:!0,disabled:S,onKeyDown:b=>{b.key==="Enter"&&(b.preventDefault(),Ee())},"aria-invalid":!!se}),se?e.jsx(Ea,{className:"text-destructive",children:se}):e.jsx(Ea,{children:"将创建一个空白 Markdown 文档,后续可继续编辑内容。"})]}):null,B==="ai"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"rounded-md border border-border/60 bg-muted/30 px-3.5 py-2.5 text-[13px] leading-relaxed text-muted-foreground",children:"💡 你也可以直接与 AI 对话生成文档,以下选项可帮助生成更精准的提示词。"}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"从文档技能列表中选择,AI 会参考对应技能生成文档方案",tooltipClassName:"max-w-none w-fit whitespace-nowrap",children:"使用技能"}),e.jsx(Jr,{value:n,onChange:a,placeholder:"请选择技能(可多选)",searchPlaceholder:"搜索技能...",options:Fe,columns:2,portalContainer:V,presentation:"dialog",dialogTitle:"选择技能(可多选)"})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会参考所选文档补充上下文信息",children:"文档"}),e.jsx(Ms,{value:i,onChange:l,placeholder:"自动",searchPlaceholder:"搜索文档...",options:c.map(b=>({value:b.name,label:b.displayName})),portalContainer:V})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"选择参考原型后,AI 会读取原型源码与 spec 作为文档编写参考",children:"参考原型"}),e.jsx(Ms,{value:u,onChange:C,placeholder:"自动",searchPlaceholder:"搜索参考原型...",options:K.map(b=>({value:b.name,label:b.displayName})),portalContainer:V})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会参考所选数据辅助文档编写",children:"数据"}),e.jsx(Ms,{value:d,onChange:w,placeholder:"自动",searchPlaceholder:"搜索数据...",options:j.map(b=>({value:b.name,label:b.displayName})),portalContainer:V})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会参考所选模板组织文档结构与格式",children:"模板"}),e.jsx(Ms,{value:$,onChange:v,placeholder:"自动",searchPlaceholder:"搜索模板...",options:D.map(b=>({value:b.name,label:b.displayName})),portalContainer:V})]})]}):null,B==="import"?e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:`rounded-md border px-3 py-2.5 ${k.installed?"border-emerald-300/70 bg-emerald-50/30":"border-amber-300/70 bg-amber-50/30"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium",children:[k.installed?e.jsx(ti,{className:"h-4 w-4 text-emerald-600"}):e.jsx(La,{className:"h-4 w-4 text-amber-600"}),e.jsx("span",{children:k.installed?"markitdown 已可用":"markitdown 当前不可用"})]}),e.jsx(te,{type:"button",variant:"outline",size:"sm",className:"h-7",onClick:()=>void Ue(),disabled:k.checking||q,children:k.checking?e.jsxs(e.Fragment,{children:[e.jsx(gt,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"检测中"]}):e.jsxs(e.Fragment,{children:[e.jsx(Ln,{className:"mr-1.5 h-3.5 w-3.5"}),"重新检测"]})})]}),e.jsxs("div",{className:"mt-1 text-[12px] text-muted-foreground",children:["命令来源:",k.commandSource||"unavailable",k.version?` · ${k.version}`:""]}),k.error?e.jsx("div",{className:"mt-1 text-[12px] text-destructive",children:k.error}):null]}),k.installed?null:e.jsxs("div",{className:"rounded-md border border-dashed p-3",children:[e.jsx("div",{className:"mb-2 text-sm font-medium",children:"修复引导(修复后支持非 .md 文档导入)"}),e.jsx("div",{className:"space-y-2",children:(k.installHints.length>0?k.installHints:["python3 -m pip install -U 'markitdown[pdf,docx,pptx,xlsx]'"]).map(b=>e.jsxs("div",{className:"flex items-center gap-2 rounded-md border bg-muted/30 px-2 py-1.5",children:[e.jsx("code",{className:"flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-[12px]",children:b}),e.jsx(te,{type:"button",variant:"ghost",size:"icon-sm",className:"h-6 w-6",onClick:()=>void nt(b),children:e.jsx(ss,{className:"h-3.5 w-3.5"})})]},b))}),e.jsx("div",{className:"mt-2 text-[12px] text-muted-foreground",children:"当前仅允许导入 .md 文件,其它格式需先修复 markitdown 环境后使用。"})]}),E?e.jsxs("div",{className:"rounded-md border border-dashed p-3",children:[e.jsx("div",{className:"mb-1 text-sm font-medium",children:"让 AI 帮你修复"}),e.jsx("div",{className:"mb-3 text-[12px] text-muted-foreground",children:"会自动带上当前检测状态、报错信息、安装命令和失败文件明细,方便你的 AI 直接给出修复步骤。"}),e.jsx(hs,{type:"default",block:!0,preferredClient:y,preferredIDE:P,scene:"repair-doc-import",buildPrompt:Pe,copyLabel:"复制诊断 Prompt",copySuccessMessage:"诊断 Prompt 已复制,请发送给 AI 排查",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制诊断 Prompt"})]}):null,e.jsxs("label",{className:"flex min-h-[150px] cursor-pointer flex-col items-center justify-center gap-2 rounded-md border border-dashed p-6 text-center hover:bg-muted/40",onDragOver:b=>{b.preventDefault()},onDrop:b=>{b.preventDefault(),Te(b.dataTransfer.files)},children:[e.jsx(_n,{className:"h-7 w-7 text-primary"}),e.jsx("div",{className:"text-sm font-medium",children:"点击选择或拖拽文档文件"}),e.jsxs("div",{className:"text-[12px] leading-4 text-muted-foreground",children:["支持 ",cr.join(", "),",并统一导入为 .md"]}),e.jsx("input",{type:"file",multiple:!0,className:"hidden",accept:cr.join(","),onChange:b=>{Te(b.target.files),b.currentTarget.value=""},disabled:q})]}),U.length>0?e.jsxs("div",{className:"rounded-md border p-2.5",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm font-medium",children:["待导入文件(",U.length,")"]}),e.jsx(te,{type:"button",variant:"ghost",size:"sm",className:"h-7",onClick:()=>A([]),disabled:q,children:"清空"})]}),e.jsx("div",{className:"max-h-[160px] space-y-1.5 overflow-y-auto pr-1",children:U.map((b,he)=>e.jsxs("div",{className:"flex items-center gap-2 rounded border px-2 py-1.5",children:[e.jsx(hn,{className:"h-3.5 w-3.5 text-muted-foreground"}),e.jsx("span",{className:"flex-1 truncate text-[12px]",children:b.name}),e.jsx(te,{type:"button",variant:"ghost",size:"icon-sm",className:"h-6 w-6",onClick:()=>{A(ke=>ke.filter((T,Z)=>Z!==he))},disabled:q,children:e.jsx(_s,{className:"h-3.5 w-3.5"})})]},`${b.name}-${b.size}-${b.lastModified}-${he}`))})]}):null,Ne.length>0?e.jsxs("div",{className:"rounded-md border p-2.5",children:[e.jsx("div",{className:"mb-2 text-sm font-medium",children:"导入结果"}),e.jsx("div",{className:"max-h-[140px] space-y-1.5 overflow-y-auto pr-1",children:Ne.map((b,he)=>e.jsxs("div",{className:"rounded border px-2 py-1.5 text-[12px]",children:[e.jsxs("div",{className:"font-medium",children:[b.success?"成功":"失败"," · ",b.originalName]}),b.savedName?e.jsxs("div",{className:"text-muted-foreground",children:["输出:",b.savedName]}):null,b.error?e.jsx("div",{className:"text-destructive",children:b.error}):null]},`${b.originalName}-${he}`))})]}):null]}):null]}),e.jsxs(Bn,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:s,disabled:Me,children:"取消"}),B==="manual"?e.jsx(te,{variant:"brand",size:"sm",onClick:()=>void Ee(),disabled:S,children:S?e.jsxs(e.Fragment,{children:[e.jsx(gt,{className:"mr-2 h-4 w-4 animate-spin"}),"创建中..."]}):"创建"}):null,B==="ai"?e.jsx(hs,{type:"primary",preferredClient:y,preferredIDE:P,scene:"create-doc",buildPrompt:()=>R(),onAfterCopy:L,copySuccessMessage:"复制成功,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt"}):null,B==="import"?e.jsx(te,{variant:"brand",size:"sm",onClick:()=>void Ye(),disabled:q||!ce,children:q?e.jsxs(e.Fragment,{children:[e.jsx(gt,{className:"mr-2 h-4 w-4 animate-spin"}),"导入中..."]}):"导入文档"}):null]})]})})})}function em({state:t,actions:s}){return e.jsx(Yu,{visible:t.visible,onClose:s.onClose,selectedSkillIds:t.selectedSkillIds,setSelectedSkillIds:s.setSelectedSkillIds,availableDocSkills:t.availableDocSkills,selectedDocs:t.selectedDocs,setSelectedDocs:s.setSelectedDocs,availableDocs:t.availableDocs,selectedDataAssets:t.selectedDataAssets,setSelectedDataAssets:s.setSelectedDataAssets,availableDataAssets:t.availableDataAssets,selectedTemplates:t.selectedTemplates,setSelectedTemplates:s.setSelectedTemplates,availableTemplates:t.availableTemplates,selectedReferencePrototypes:t.selectedReferencePrototypes,setSelectedReferencePrototypes:s.setSelectedReferencePrototypes,availableReferencePrototypes:t.availableReferencePrototypes,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE,buildCreateDocPrompt:s.buildCreateDocPrompt,onAfterCreatePromptAction:s.onAfterCreatePromptAction,onManualCreateSuccess:s.onManualCreateSuccess,onImportSuccess:s.onImportSuccess})}const ml=Zi,tm=["/skills/axure-prototype-workflow/theme-generation.md","/skills/axure-prototype-workflow/doc-generation.md","/skills/axure-prototype-workflow/data-generation.md","/skills/web-page-workflow/theme-generation.md","/skills/web-page-workflow/doc-generation.md","/skills/web-page-workflow/data-generation.md"],sm={make_zip:["/skills/local-axure-workflow/SKILL.md"],local_axure:["/skills/local-axure-workflow/SKILL.md"],axure_prototype:["/skills/axure-prototype-workflow/SKILL.md","/skills/axure-prototype-workflow/asset-extraction.md"],web_page:["/skills/web-page-workflow/SKILL.md","/skills/web-page-workflow/asset-extraction.md"],screenshot:["/skills/screen-to-code/SKILL.md","/skills/screen-to-code/screenshot-collection.md"],v0:["/skills/v0-project-converter/SKILL.md"],google_aistudio:["/skills/ai-studio-project-converter/SKILL.md"],figma_make:["/skills/figma-make-project-converter/SKILL.md"],app_direct:[]};function Qr(t){const s=String(t||"").trim();return s?s.startsWith("/")?s:`/${s}`:""}function nm(t){const s=[],n=new Set;for(const a of t){const o=Qr(a);!o||n.has(o)||(n.add(o),s.push(o))}return s}function am(t){const s=new Set,n=t.matchAll(/`([^`\n]+)`/g);for(const a of n){const o=Qr(a[1]||"");o&&s.add(o)}return s}function ba(t){return t==="axure_prototype"||t==="web_page"}function Jn(t){return t==="app_direct"}function hl(t){return t==="app_direct"?[]:nm([...sm[t]||[],...tm])}function rm(t){const s=t==="axure_prototype"?"Axure 原型链接":"网页链接",n=hl(t);return`**系统指令**:你将作为UI/UX 设计架构师 × 前端工程师(复合型),协助用户「基于${s}导入并创建主题」。
|
||
|
||
**📋 参考文档(必须阅读)**:
|
||
${n.map(a=>`- \`${a}\``).join(`
|
||
`)}
|
||
|
||
**目标输出**:
|
||
- \`src/themes/<theme-key>/\`(主题 token、\`DESIGN.md\`、\`index.tsx\`)
|
||
- \`src/docs/\`(按需生成项目文档)
|
||
- \`src/database/\`(按需生成数据模型)
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,我将基于${s}导入并创建主题。
|
||
|
||
请把链接发我(URL):
|
||
\`\`\``}function om(t,s){const n=String(t||"").trim();if(!n)return"";const a=hl(s);if(a.length===0)return n;const o=am(n),i=a.filter(l=>!o.has(Qr(l)));return i.length===0?n:`${n}
|
||
|
||
📋 主题导入参考文档:
|
||
${i.map(l=>`- \`${l}\``).join(`
|
||
`)}`}function Mo(t){const{title:s,selected:n,available:a,toLine:o}=t;return n.length===0?"":`
|
||
|
||
${s}${n.map(i=>{const l=a.find(c=>c.name===i);return`
|
||
${o(i,l)}`}).join("")}`}function im(t){const s=new Set(t.map(c=>String(c||"").trim()).filter(Boolean));if(s.size===0)return"";const n=new Set,a=[],o=new Set,i=[];for(const c of ml.skills??[]){if(!s.has(c.id))continue;let d=!1;for(const w of c.localPaths??[]){const j=aa(String(w||"").trim());!j||n.has(j)||(n.add(j),a.push(j),d=!0)}if(!d)for(const w of c.references??[]){const j=String(w||"").trim();!j||o.has(j)||(o.add(j),i.push(j))}}return a.length===0&&i.length===0?"":`
|
||
|
||
**使用项目技能**:
|
||
${(a.length>0?a:i).map(c=>`- \`${c}\``).join(`
|
||
`)}`}function Uo(){const t=(ml.skills??[]).filter(s=>!!s.defaultSelected).map(s=>s.id).filter(Boolean);return t.length>0?t:["tailwind-design-system"]}function lm(t=[],s=[],n=[],a=[],o=[]){const i=im(t),l=Mo({title:"**📚 参考文档**:",selected:s,available:n,toLine:(d,w)=>`- **\`/docs/${d}\`** - ${(w==null?void 0:w.displayName)||d}`}),c=Mo({title:"**🖼️ 参考原型页面**:",selected:a,available:o,toLine:(d,w)=>`- **\`/src/prototypes/${d}/spec.md\`** - ${(w==null?void 0:w.displayName)||d}`});return`**系统指令**:你将作为UI/UX 设计架构师 × 前端工程师(复合型),协助用户「新建一个主题」。
|
||
|
||
⚠️ **重要提示**:请务必完整阅读以下规范和参考资料,先完成需求对齐,再进行任何文件写入。
|
||
|
||
${i}
|
||
|
||
**📋 必读规范文档**:
|
||
- **\`/rules/theme-generation-guide.md\`** ⭐️ 主题生成完整规范
|
||
|
||
**系统交互要求**:
|
||
- 收到本条系统指令后,必须先向用户回复一次,并等待用户补充信息/确认;确认前不要写入或修改文件
|
||
- 首次回复保持轻量友好,不要让用户有压力
|
||
- 告知:已准备好开始新建主题
|
||
${c?`
|
||
⚠️ **对于参考原型页面,请直接读取其源代码和 spec 及任何相关信息,此外如果你有能力截图,请结合页面截图界面来进行视觉风格分析,辅助生成主题。**
|
||
`:""}${l}${c}
|
||
|
||
**目标目录**:\`src/themes/<theme-key>/\`
|
||
**输出目标**:遵循规范生成主题文件(如 \`globals.css\` 或 \`designToken.json\`、\`index.tsx\`,必要时补充 \`DESIGN.md\`)
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,准备新建主题。
|
||
|
||
请先告诉我你的主题目标(品牌/业务场景/风格偏好/参考素材均可),
|
||
我会先给出建议的 theme-key 与交付文件清单,待你确认后再开始生成。
|
||
\`\`\``}function cm({visible:t,onClose:s,selectedSkillIds:n,setSelectedSkillIds:a,selectedDocs:o,setSelectedDocs:i,availableDocs:l,selectedReferencePages:c,setSelectedReferencePages:d,availableReferencePages:w,preferredPromptClient:j,preferredIDE:$,buildCreateThemePrompt:v,onAfterCreatePromptAction:D,onImportSuccess:u}){const[C,K]=r.useState(null),[y,P]=r.useState("ai"),[R,L]=r.useState("local_axure"),[F,x]=r.useState("zip"),[V,re]=r.useState(!1),[B,xe]=r.useState(null),ie=r.useMemo(()=>[{key:"local_axure",title:"本地 Axure ZIP",description:"扩展转后化导出的 zip",icon:e.jsx(ta,{className:"h-8 w-8 text-emerald-500"}),uploadModeSupport:"zip"},{key:"make_zip",title:"Make 导入 ZIP",description:"上传 Axhub Make 导出的 ZIP 包",icon:e.jsx(dn,{className:"h-8 w-8 text-sky-500"}),uploadModeSupport:"zip"},{key:"axure_prototype",title:"Axure 原型链接",description:"支持在线或本地预览的链接",icon:e.jsx(un,{className:"h-8 w-8 text-sky-500"}),uploadModeSupport:"none"},{key:"web_page",title:"网页链接",description:"支持任意网页链接",icon:e.jsx(pn,{className:"h-8 w-8 text-cyan-500"}),uploadModeSupport:"none"},{key:"screenshot",title:"截图导入",description:"支持多张截图",icon:e.jsx(Ci,{className:"h-8 w-8 text-violet-500"}),uploadModeSupport:"none"},{key:"figma_make",title:"Figma Make",description:"Figma 设计稿代码导出",icon:e.jsx(ta,{className:"h-8 w-8 text-pink-500"}),uploadModeSupport:"folder"},{key:"v0",title:"V0 App",description:"在线应用生成平台",icon:e.jsx(_n,{className:"h-8 w-8 text-emerald-500"}),uploadModeSupport:"folder"},{key:"google_aistudio",title:"Google AIStudio",description:"在线应用生成平台",icon:e.jsx(pn,{className:"h-8 w-8 text-amber-500"}),uploadModeSupport:"folder"},{key:"app_direct",title:"移动端 APP",description:"暂未开放",icon:e.jsx(Ma,{className:"h-8 w-8 text-muted-foreground/60"}),uploadModeSupport:"none"}],[]),se=r.useMemo(()=>ie.find(A=>A.key===R)||ie[0],[ie,R]).uploadModeSupport==="folder",W=r.useMemo(()=>(Zi.skills??[]).reduce((q,pe)=>{const Ne=String(pe.id??"").trim(),Ce=String(pe.titleZh??pe.titleCn??"").trim(),Ie=String(pe.titleEn??pe.title??"").trim(),ve=Ce||Ie;return!Ne||!ve||q.push({value:Ne,label:ve,secondaryLabel:Ce&&Ie&&Ce!==Ie?Ie:void 0,description:String(pe.description??"").trim()||"适用于主题方案生成与视觉规范设计场景。",category:pe.category}),q},[]),[]);r.useEffect(()=>{t&&(P("ai"),L("local_axure"),x("zip"),re(!1),xe(null))},[t]),r.useEffect(()=>{!se&&F==="folder"&&(x("zip"),xe(null))},[se,F]);const S=r.useCallback(async A=>{var Ie;if(!A||A.length===0||ba(R)||Jn(R))return;const q=Array.from(A),pe=R==="screenshot",Ne=R==="make_zip"?"local_axure":R,Ce=new FormData;if(pe)Ce.append("targetType","themes"),q.forEach(ve=>{Ce.append("files",ve,ve.name)});else if(Ce.append("uploadType",Ne),Ce.append("targetType","themes"),Ce.append("uploadMode",F),F==="zip"){const ve=q[0];if(!ve.name.toLowerCase().endsWith(".zip")){H.error("请上传 ZIP 文件");return}Ce.append("file",ve,ve.name)}else{if(!se){H.error("当前来源不支持文件夹上传");return}const Ue=(((Ie=q[0])==null?void 0:Ie.webkitRelativePath)||"").split("/").filter(Boolean)[0];Ue&&Ce.append("folderName",Ue),q.forEach(Fe=>{Ce.append("files",Fe,Fe.name);const Oe=Fe.webkitRelativePath||Fe.name;Ce.append("relativePaths",Oe)})}re(!0);try{const ve=pe?"/api/upload-screenshots":"/api/upload",Ue=await fetch(ve,{method:"POST",body:Ce}),Fe=await Ue.json().catch(()=>({}));if(!Ue.ok||!(Fe!=null&&Fe.success))throw console.error("[CreateThemeDialog] 主题导入上传失败:",{endpoint:ve,status:Ue.status,statusText:Ue.statusText,result:Fe}),new Error((Fe==null?void 0:Fe.error)||"上传失败");xe(Fe),H.success(Fe.message||"上传成功,请点击复制 Prompt")}catch(ve){console.error("[CreateThemeDialog] 主题导入异常详情:",ve),H.error($a(ve,"上传失败,请稍后重试"))}finally{re(!1)}},[R,se,F]),Y=r.useCallback(()=>{if(Jn(R))throw new Error("该导入来源暂未开放");if(ba(R))return rm(R);const A=String((B==null?void 0:B.prompt)||"").trim();if(!A)throw new Error("请先上传文件并生成导入结果");return om(A,R)},[R,B]),k=r.useCallback(async()=>{try{await(u==null?void 0:u())}finally{D()}},[D,u]),N=se&&F==="folder"?{directory:"",webkitdirectory:""}:{},U=Jn(R)||!ba(R)&&!B;return e.jsx(zn,{open:t,onOpenChange:A=>!A&&s(),children:e.jsx(fn,{ref:K,side:"left",className:"flex w-full max-w-[620px] flex-col p-0 text-sm sm:max-w-[620px] [&>[data-sheet-close]]:hidden",children:e.jsxs(ca,{value:y,onValueChange:A=>{(A==="ai"||A==="import")&&P(A)},className:"flex h-full flex-col",children:[e.jsxs(xn,{className:"border-b px-5 py-3.5",children:[e.jsx(gn,{className:"sr-only",children:"新建主题 / 导入主题"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(Wn,{className:"grid h-8 w-full max-w-[280px] grid-cols-2 rounded-lg border border-border/70 bg-muted/50 p-0.5",children:[e.jsx(Jt,{value:"ai",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"新建主题"}),e.jsx(Jt,{value:"import",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"导入主题"})]}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md",onClick:s,"aria-label":"关闭",disabled:V,children:e.jsx(as,{className:"h-4 w-4"})})]})]}),e.jsx("div",{className:"flex-1 space-y-4 overflow-y-auto px-5 py-4.5",children:y==="ai"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"rounded-md border border-border/60 bg-muted/30 px-3.5 py-2.5 text-[13px] leading-relaxed text-muted-foreground",children:"💡 你也可以直接与 AI 对话生成主题,以下选项可帮助生成更精准的提示词。"}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"从技能列表中选择,AI 会参考对应应用场景生成方案",tooltipClassName:"max-w-none w-fit whitespace-nowrap",children:"使用技能"}),e.jsx(Jr,{value:n,onChange:a,placeholder:"请选择技能(可多选)",searchPlaceholder:"搜索技能...",options:W,columns:2,portalContainer:C,presentation:"dialog",dialogTitle:"选择技能(可多选)"})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"AI 会根据所选文档生成主题,文档可在资产管理中进行管理",children:"文档"}),e.jsx(Ms,{value:o,onChange:i,placeholder:"自动",searchPlaceholder:"搜索文档...",options:l.map(A=>({value:A.name,label:A.displayName})),portalContainer:C})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"选择参考页面后,AI 会读取并在有能力时截图分析页面来辅助生成主题",children:"参考页面(多选)"}),e.jsx(Ms,{value:c??[],onChange:A=>d==null?void 0:d(A),placeholder:"自动",searchPlaceholder:"搜索参考页面...",options:(w==null?void 0:w.map(A=>({value:A.name,label:A.displayName})))||[],portalContainer:C})]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 gap-4",children:ie.map(A=>{const q=A.key===R,pe=A.key==="app_direct";return e.jsxs("button",{type:"button",onClick:()=>{pe||(L(A.key),xe(null))},disabled:pe,className:`flex items-center gap-2.5 rounded-md border p-3 text-left transition ${pe?"cursor-not-allowed border-border/50 bg-muted/20 text-muted-foreground":q?"border-foreground/60 bg-muted/40":"border-border hover:bg-muted/30"}`,children:[e.jsx("div",{className:"flex-shrink-0 text-muted-foreground/80 [&_svg]:h-6 [&_svg]:w-6",children:A.icon}),e.jsxs("div",{className:"grid gap-1",children:[e.jsx("div",{className:"text-sm font-medium leading-none",children:A.title}),e.jsx("div",{className:"text-[12px] leading-4 text-muted-foreground line-clamp-2",children:A.description})]})]},A.key)})}),Jn(R)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:"暂未开放"}):ba(R)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:"当前来源无需上传文件。点击底部按钮开始对话,并将链接发送给 AI 即可。"}):e.jsxs("div",{className:"space-y-3",children:[se?e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium",children:"上传方式"}),e.jsxs(Ga,{type:"single",value:F,onValueChange:A=>{(A==="zip"||A==="folder")&&(x(A),xe(null))},children:[e.jsx(Zs,{value:"zip",children:"ZIP"}),e.jsx(Zs,{value:"folder",children:"文件夹"})]})]}):null,e.jsxs("label",{className:"flex min-h-[150px] cursor-pointer flex-col items-center justify-center gap-2 rounded-md border border-dashed p-6 text-center hover:bg-muted/40",children:[V?e.jsx(gt,{className:"h-7 w-7 animate-spin text-primary"}):e.jsx(_n,{className:"h-7 w-7 text-primary"}),e.jsx("div",{className:"text-sm font-medium",children:R==="screenshot"?"点击上传截图":F==="folder"?"点击上传文件夹":"点击上传 ZIP 文件"}),e.jsx("div",{className:"text-[12px] leading-4 text-muted-foreground",children:R==="screenshot"?"系统会基于截图生成导入任务。":F==="folder"?"请选择本地文件夹,系统会按原目录结构上传。":"建议优先使用 ZIP 上传,导入更稳定。"}),e.jsx("input",{type:"file",accept:R==="screenshot"?"image/*":F==="zip"?".zip":void 0,multiple:R==="screenshot"||F==="folder",className:"hidden",onChange:A=>{S(A.target.files),A.currentTarget.value=""},disabled:V,...N})]})]})]})}),e.jsxs(Bn,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:s,disabled:V,children:"取消"}),y==="ai"?e.jsx(hs,{type:"primary",preferredClient:j,preferredIDE:$,scene:"create-theme",buildPrompt:()=>v(),onAfterCopy:D,copySuccessMessage:"复制成功,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt"}):Jn(R)?null:e.jsx(hs,{type:"primary",preferredClient:j,preferredIDE:$,scene:`theme-import-${R}`,buildPrompt:Y,onAfterCopy:()=>{k()},copySuccessMessage:"主题导入 Prompt 已复制,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",disabled:U})]})]})})})}function dm({state:t,actions:s}){return e.jsx(cm,{visible:t.visible,onClose:s.onClose,selectedSkillIds:t.selectedSkillIds,setSelectedSkillIds:s.setSelectedSkillIds,selectedDocs:t.selectedDocs,setSelectedDocs:s.setSelectedDocs,availableDocs:t.availableDocs,selectedReferencePages:t.selectedReferencePages,setSelectedReferencePages:s.setSelectedReferencePages,availableReferencePages:t.availableReferencePages,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE,buildCreateThemePrompt:s.buildCreateThemePrompt,onAfterCreatePromptAction:s.onAfterCreatePromptAction,onImportSuccess:s.onImportSuccess})}function um(t){const s=String((t==null?void 0:t.tableName)||"").trim();return`**系统指令**:你将作为 UI/UX 设计架构师 × 前端工程师(复合型),协助用户「新建一个数据资产(数据表)」。
|
||
|
||
⚠️ **重要提示**:先完成需求对齐与字段确认,再写入任何文件。
|
||
|
||
**📋 必读规范文档**:
|
||
- **\`/src/database/README.md\`** ⭐️ 数据表 JSON 格式强约束(必须遵循)
|
||
|
||
**系统交互要求**:
|
||
- 收到本条系统指令后,必须先向用户回复一次,并等待用户补充信息/确认;确认前不要写入或修改文件
|
||
- 首次回复保持轻量友好,并提示用户可以直接发任何材料(需求描述 / 截图 / 现有字段清单 / 参考页面 / 示例数据)
|
||
|
||
**目标目录**:\`src/database\`
|
||
**输出格式**:\`src/database/<table-name>.json\`${s?`(建议表名:${s})`:""}
|
||
|
||
**执行要求**:
|
||
- 文件名使用英文,优先 kebab-case(如 \`users.json\`、\`order-items.json\`)
|
||
- JSON 必须是对象,包含 \`tableName\`(中文)+ \`records\`(数组)
|
||
- 每条记录必须有唯一 \`id\`,并保证同一张表里 \`id\` 类型一致(number 或 string)
|
||
- 先给出:字段定义表(字段名/类型/含义/示例),以及 2-3 条示例记录;用户确认后再生成完整数据并落盘
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,准备新建数据表。
|
||
|
||
请告诉我:
|
||
1) 这个表要服务哪个页面/场景?
|
||
2) 你希望的表名(中文)和文件名(英文)是什么?
|
||
3) 字段清单(你可以先给核心 5-10 个字段),以及 id 用 number 还是 string?
|
||
\`\`\`
|
||
|
||
**完成后请输出**:
|
||
- 你创建/更新的文件路径(\`src/database/<table-name>.json\`)
|
||
- 字段定义(Markdown 表格)与示例记录(用于复核)`}const mm={local_axure:["/skills/local-axure-workflow/SKILL.md"],axure_prototype:["/skills/axure-prototype-workflow/SKILL.md","/skills/axure-prototype-workflow/asset-extraction.md","/skills/axure-prototype-workflow/data-generation.md"],web_page:["/skills/web-page-workflow/SKILL.md","/skills/web-page-workflow/asset-extraction.md","/skills/web-page-workflow/data-generation.md"],screenshot:["/skills/screen-to-code/SKILL.md","/skills/screen-to-code/screenshot-collection.md"],app_direct:[]};function hm(t){const s=String(t||"").trim();return s?s.startsWith("/")?s:`/${s}`:""}function pm(t){const s=[],n=new Set;for(const a of t){const o=hm(a);!o||n.has(o)||(n.add(o),s.push(o))}return s}function pl(t){return t.map(s=>`- \`${s}\``).join(`
|
||
`)}function fm(t){return Array.isArray(t)?t.map(s=>String(s||"").trim()).filter(Boolean):[]}function wa(t){return t==="axure_prototype"||t==="web_page"}function Qn(t){return t==="app_direct"}function fl(t){return t==="app_direct"?[]:pm(mm[t]||[])}function xm(t){const s=t==="axure_prototype"?"Axure 原型链接":"网页链接",n=fl(t);return`**系统指令**:你将作为 UI/UX 设计架构师 × 前端工程师(复合型),协助用户「基于${s}导入并创建数据资产」。
|
||
|
||
**📋 参考文档(必须阅读)**:
|
||
${pl(n)}
|
||
|
||
**目标输出**:
|
||
- \`src/database/<table-name>.json\`(可多表)
|
||
- 如需补充说明,可在 \`src/docs/\` 产出简要数据说明文档
|
||
|
||
**执行要求**:
|
||
- 先和用户确认:目标数据表范围、字段定义、主键策略、是否允许覆盖已有数据
|
||
- 未完成确认前,不要写入文件
|
||
- 输出数据前先给出字段映射与示例记录,待用户确认后再落盘
|
||
|
||
**首次回复模板**:
|
||
\`\`\`
|
||
收到,我将基于${s}协助你导入数据。
|
||
|
||
请先提供链接(URL),并告诉我目标数据表名称与关键字段。
|
||
\`\`\``}function gm(t,s){const n=fl(t),a=t==="screenshot"?"截图":"本地 Axure ZIP",o=String((s==null?void 0:s.filePath)||"").trim(),i=fm(s==null?void 0:s.files),l=String((s==null?void 0:s.prompt)||"").trim(),c=[];if(o&&c.push(`上传上下文目录:\`${o}\``),i.length>0&&c.push(`上传文件清单:
|
||
${i.map(d=>`- \`${d}\``).join(`
|
||
`)}`),c.length===0&&!l)throw new Error("请先上传文件并生成导入结果");return`**系统指令**:你将作为 UI/UX 设计架构师 × 前端工程师(复合型),协助用户「基于${a}导入并创建数据资产」。
|
||
|
||
**📋 参考文档(必须阅读)**:
|
||
${pl(n)}
|
||
|
||
**上传上下文**:
|
||
${c.length>0?c.join(`
|
||
|
||
`):"- 已完成上传,请结合系统上传结果继续处理"}
|
||
|
||
${l?`**系统上传结果补充**:
|
||
${l}
|
||
|
||
`:""}**目标输出**:
|
||
- \`src/database/<table-name>.json\`(可多表)
|
||
- 如需补充说明,可在 \`src/docs/\` 产出简要数据说明文档
|
||
|
||
**执行要求**:
|
||
- 先和用户确认:目标数据表范围、字段定义、主键策略、是否允许覆盖已有数据
|
||
- 未完成确认前,不要写入文件
|
||
- 输出数据前先给出字段映射与示例记录,待用户确认后再落盘`}function ym({visible:t,onClose:s,newTableName:n,setNewTableName:a,newTableNameError:o,clearNewTableNameError:i,dataTableCreating:l,onCreateSubmit:c,preferredPromptClient:d,preferredIDE:w,onImportSuccess:j}){const[$,v]=r.useState("create"),[D,u]=r.useState("local_axure"),[C,K]=r.useState(!1),[y,P]=r.useState(null),[R,L]=r.useState([]),F=l||C,x=r.useMemo(()=>[{key:"local_axure",title:"本地 Axure ZIP",description:"扩展导出的 ZIP 包",icon:e.jsx(ta,{className:"h-8 w-8 text-emerald-500"}),uploadModeSupport:"zip"},{key:"axure_prototype",title:"Axure 原型链接",description:"支持在线或本地预览的链接",icon:e.jsx(un,{className:"h-8 w-8 text-sky-500"}),uploadModeSupport:"none"},{key:"web_page",title:"网页链接",description:"支持任意网页链接",icon:e.jsx(pn,{className:"h-8 w-8 text-cyan-500"}),uploadModeSupport:"none"},{key:"screenshot",title:"截图导入",description:"支持多张截图",icon:e.jsx(Ci,{className:"h-8 w-8 text-violet-500"}),uploadModeSupport:"image"},{key:"app_direct",title:"移动端 APP",description:"暂未开放",icon:e.jsx(Ma,{className:"h-8 w-8 text-muted-foreground/60"}),uploadModeSupport:"none"}],[]),V=r.useMemo(()=>x.find(z=>z.key===D)||x[0],[x,D]);r.useEffect(()=>{t&&(v("create"),u("local_axure"),K(!1),P(null),L([]))},[t]);const re=r.useCallback(async z=>{if(z.length===0||wa(D)||Qn(D))return;const se=D==="screenshot",W=new FormData;if(se)z.forEach(S=>{W.append("files",S,S.name)});else{const S=z[0];if(!S.name.toLowerCase().endsWith(".zip")){H.error("请上传 ZIP 文件");return}W.append("uploadType",D),W.append("uploadMode","zip"),W.append("file",S,S.name)}L(z),K(!0);try{const S=se?"/api/upload-screenshots":"/api/upload",Y=await fetch(S,{method:"POST",body:W}),k=await Y.json().catch(()=>({}));if(!Y.ok||!(k!=null&&k.success))throw console.error("[CreateDataDialog] 数据导入上传失败:",{endpoint:S,status:Y.status,statusText:Y.statusText,result:k}),new Error((k==null?void 0:k.error)||"上传失败");P(k),H.success(k.message||"上传成功,请点击复制 Prompt")}catch(S){console.error("[CreateDataDialog] 数据导入异常详情:",S),H.error($a(S,"上传失败,请稍后重试"))}finally{K(!1)}},[D]),B=r.useCallback(()=>{if(Qn(D))throw new Error("该导入来源暂未开放");return wa(D)?xm(D):gm(D,y)},[D,y]),xe=r.useCallback(async()=>{try{await(j==null?void 0:j())}finally{s()}},[s,j]),ie=Qn(D)||!wa(D)&&!y;return e.jsx(zn,{open:t,onOpenChange:z=>{!z&&!F&&s()},children:e.jsx(fn,{side:"left",className:"flex w-full max-w-[620px] flex-col p-0 text-sm sm:max-w-[620px] [&>[data-sheet-close]]:hidden",children:e.jsxs(ca,{value:$,onValueChange:z=>{(z==="create"||z==="import")&&v(z)},className:"flex h-full flex-col",children:[e.jsxs(xn,{className:"border-b px-5 py-3.5",children:[e.jsx(gn,{className:"sr-only",children:"新建数据 / 导入数据"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(Wn,{className:"grid h-8 w-full max-w-[280px] grid-cols-2 rounded-lg border border-border/70 bg-muted/50 p-0.5",children:[e.jsx(Jt,{value:"create",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"新建数据"}),e.jsx(Jt,{value:"import",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"导入数据"})]}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md",onClick:s,"aria-label":"关闭",disabled:F,children:e.jsx(as,{className:"h-4 w-4"})})]})]}),e.jsx("div",{className:"flex-1 space-y-4 overflow-y-auto px-5 py-4.5",children:$==="create"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"rounded-md border border-border/60 bg-muted/30 px-3.5 py-2.5 text-[13px] leading-relaxed text-muted-foreground",children:"💡 你也可以直接与 AI 对话生成数据表,以下选项可帮助生成更精准的提示词。"}),e.jsxs(Dt,{children:[e.jsx(At,{children:"数据表名称"}),e.jsx(Ps,{value:n,onChange:z=>{a(z.target.value),o&&i()},placeholder:"例如:用户表、产品列表",autoFocus:!0,disabled:l,onKeyDown:z=>{z.key==="Enter"&&(z.preventDefault(),c())},"aria-invalid":!!o}),o?e.jsx(Ea,{className:"text-destructive",children:o}):null]})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 gap-4",children:x.map(z=>{const se=z.key===D,W=z.key==="app_direct";return e.jsxs("button",{type:"button",onClick:()=>{W||(u(z.key),P(null),L([]))},disabled:W,className:`flex items-center gap-2.5 rounded-md border p-3 text-left transition ${W?"cursor-not-allowed border-border/50 bg-muted/20 text-muted-foreground":se?"border-foreground/60 bg-muted/40":"border-border hover:bg-muted/30"}`,children:[e.jsx("div",{className:"flex-shrink-0 text-muted-foreground/80 [&_svg]:h-6 [&_svg]:w-6",children:z.icon}),e.jsxs("div",{className:"grid gap-1",children:[e.jsx("div",{className:"text-sm font-medium leading-none",children:z.title}),e.jsx("div",{className:"line-clamp-2 text-[12px] leading-4 text-muted-foreground",children:z.description})]})]},z.key)})}),Qn(D)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:"暂未开放"}):wa(D)?e.jsx("div",{className:"rounded-md border border-dashed p-3 text-sm text-muted-foreground",children:"当前来源无需上传文件。点击底部按钮开始对话,并将链接发送给 AI 即可。"}):e.jsx(dl,{title:V.uploadModeSupport==="image"?"点击上传或拖拽截图到此区域":"点击上传或拖拽 ZIP 文件到此区域",description:V.uploadModeSupport==="image"?"支持多张截图,上传后可生成数据导入 Prompt。":"建议优先使用 ZIP 上传,导入更稳定。",accept:V.uploadModeSupport==="image"?"image/*":".zip",multiple:V.uploadModeSupport==="image",disabled:C,loading:C,browseLabel:V.uploadModeSupport==="image"?"选择截图":"选择 ZIP 文件",selectedFiles:R,onFilesSelected:re,onClear:()=>{L([]),P(null)}})]})}),e.jsxs(Bn,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:s,disabled:F,children:"取消"}),$==="create"?e.jsxs(e.Fragment,{children:[e.jsx(hs,{type:"primary",preferredClient:d,preferredIDE:w,scene:"create-data",buildPrompt:()=>um({tableName:n.trim()}),copySuccessMessage:"复制成功,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",copyLabel:"AI Prompt"}),e.jsx(te,{variant:"brand",size:"sm",onClick:()=>void c(),disabled:l,children:l?e.jsxs(e.Fragment,{children:[e.jsx(Loader2,{className:"mr-2 h-4 w-4 animate-spin"}),"创建中..."]}):"创建"})]}):Qn(D)?null:e.jsx(hs,{type:"primary",preferredClient:d,preferredIDE:w,scene:`data-import-${D}`,buildPrompt:B,onAfterCopy:()=>{xe()},copySuccessMessage:"数据导入 Prompt 已复制,请返回 IDE 发送给 AI",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",disabled:ie})]})]})})})}function bm({state:t,actions:s}){return e.jsx(ym,{visible:t.visible,onClose:s.onClose,newTableName:t.newTableName,setNewTableName:s.setNewTableName,newTableNameError:t.newTableNameError,clearNewTableNameError:s.clearNewTableNameError,dataTableCreating:t.dataTableCreating,onCreateSubmit:s.onCreateSubmit,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE,onImportSuccess:s.onImportSuccess})}const wm=["/skills/axure-export-workflow/SKILL.md","/rules/axure-api-guide.md"];function jm(t){const{activeTab:s,itemName:n}=t,a=`src/${s}/${n}`,o=`${a}/index.tsx`,i=`${a}/spec.md`;return`请为当前项目执行「新增或更新 Axure API(代码+文档)」任务,严格按固定要求处理,不依赖已有解析结果。
|
||
|
||
必须先阅读并遵循以下固定技能/规范:
|
||
${wm.map(l=>`- \`${l}\``).join(`
|
||
`)}
|
||
|
||
目标文件:
|
||
- \`${o}\`
|
||
- \`${i}\`
|
||
|
||
任务要求:
|
||
1. 以 \`useImperativeHandle\` 返回对象作为 Axure API 真值来源,补齐或更新 \`eventList\` / \`actionList\` / \`varList\` / \`configList\` / \`dataList\`。
|
||
2. 保持现有业务行为、交互和视觉表现不变,只做 Axure API 相关必要改动。
|
||
3. 同步更新 \`${i}\` 的 5.x Axure API 章节(5.1-5.5),确保与代码一致;若文件不存在请创建。
|
||
4. 输出结果时给出改动摘要,并明确列出新增/更新了哪些 API。
|
||
5. 如当前文件缺失任意列表,完整新增并保证可被静态识别;如已存在,补齐字段描述并确保命名与规范一致。
|
||
|
||
输出要求:
|
||
- 列出 5 类列表各自是“新增 / 更新 / 保持不变”。
|
||
- 标注 \`${i}\` 是否已同步完成。
|
||
`}const Fo="axhub-admin-export-modal-preferences",Nm=["dynamicPrototype","staticPrototype","axureApi","copyConfig","usageGuide"],vm=["","code","codeAndDocs","codeAndDocsAndSource"];function Xr(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function zo(t){return typeof t=="number"&&Number.isFinite(t)&&t>0}function Sm(t){if(!Xr(t))return;const s=zo(t.width)?Math.round(t.width):void 0,n=zo(t.height)?Math.round(t.height):void 0,a=t.includeConfig==="none"||t.includeConfig==="code"||t.includeConfig==="codeAndDocs"||t.includeConfig==="codeAndDocsAndSource"?t.includeConfig:void 0,o=t.contentType==="title"||t.contentType==="screenshot"?t.contentType:void 0;if(!(s===void 0&&n===void 0&&a===void 0&&o===void 0))return{width:s??500,height:n??300,includeConfig:a??"code",contentType:o??"title"}}function Cm(t){if(!Xr(t))return;const s=typeof t.preserveHierarchy=="boolean"?t.preserveHierarchy:void 0,n=typeof t.preserveSvgIcons=="boolean"?t.preserveSvgIcons:void 0;if(!(s===void 0&&n===void 0))return{preserveHierarchy:s??!1,preserveSvgIcons:n??!0}}function xl(t){if(!Xr(t))return{version:1};const s=typeof t.activeTabKey=="string"&&Nm.includes(t.activeTabKey)?t.activeTabKey:void 0,n=typeof t.selectedExportType=="string"&&vm.includes(t.selectedExportType)?t.selectedExportType:void 0;return{version:1,activeTabKey:s,selectedExportType:n,imageConfig:Sm(t.imageConfig),axureCopyOptions:Cm(t.axureCopyOptions)}}function km(t){const s=typeof t=="string"?t.trim():"";return s?`${Fo}:${encodeURIComponent(s)}`:Fo}function Yr(t){if(typeof window>"u")return{version:1};try{const s=window.localStorage.getItem(t);return s?xl(JSON.parse(s)):{version:1}}catch{return{version:1}}}function gl(t,s){const n=Yr(t),a=xl({...n,...s,imageConfig:s.imageConfig?{...n.imageConfig,...s.imageConfig}:n.imageConfig,axureCopyOptions:s.axureCopyOptions?{...n.axureCopyOptions,...s.axureCopyOptions}:n.axureCopyOptions});if(typeof window<"u")try{window.localStorage.setItem(t,JSON.stringify(a))}catch{}return a}const yl=be.forwardRef(({className:t,...s},n)=>e.jsx(ki,{className:fe("grid gap-3",t),...s,ref:n}));yl.displayName=ki.displayName;const kr=be.forwardRef(({className:t,...s},n)=>e.jsx(Ei,{ref:n,className:fe("aspect-square h-4 w-4 rounded-full border border-foreground text-foreground ring-offset-background focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-white",t),...s,children:e.jsx(uc,{className:"flex items-center justify-center text-primary-foreground",children:e.jsx(di,{className:"h-2.5 w-2.5 fill-current text-current"})})}));kr.displayName=Ei.displayName;const Oa=yc,_a=bc,oa=be.forwardRef(({className:t,children:s,clearable:n=!1,hasValue:a=!1,onClear:o,disabled:i,...l},c)=>e.jsxs(Ti,{ref:c,className:fe("flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",t),disabled:i,...l,children:[s,e.jsxs("div",{className:"flex items-center gap-1",children:[n&&a&&!i?e.jsx("span",{role:"button","aria-label":"清除选择",className:"inline-flex h-4 w-4 items-center justify-center rounded-sm text-muted-foreground hover:bg-muted hover:text-foreground",onPointerDown:d=>{d.preventDefault(),d.stopPropagation(),o==null||o()},children:e.jsx(as,{className:"h-3.5 w-3.5"})}):null,e.jsx(mc,{asChild:!0,children:e.jsx(en,{className:"h-4 w-4 opacity-50"})})]})]}));oa.displayName=Ti.displayName;const bl=be.forwardRef(({className:t,...s},n)=>e.jsx(Ii,{ref:n,className:fe("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(hc,{className:"h-4 w-4"})}));bl.displayName=Ii.displayName;const wl=be.forwardRef(({className:t,...s},n)=>e.jsx(Pi,{ref:n,className:fe("flex cursor-default items-center justify-center py-1",t),...s,children:e.jsx(en,{className:"h-4 w-4"})}));wl.displayName=Pi.displayName;const ia=be.forwardRef(({className:t,children:s,position:n="popper",...a},o)=>e.jsx(pc,{children:e.jsxs(Di,{ref:o,className:fe("relative z-[120] max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out",n==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",t),position:n,...a,children:[e.jsx(bl,{}),e.jsx(fc,{className:fe("p-1",n==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:s}),e.jsx(wl,{})]})}));ia.displayName=Di.displayName;const Em=be.forwardRef(({className:t,...s},n)=>e.jsx(Ai,{ref:n,className:fe("py-1.5 pl-8 pr-2 text-sm font-semibold",t),...s}));Em.displayName=Ai.displayName;const vs=be.forwardRef(({className:t,children:s,...n},a)=>e.jsxs(Ri,{ref:a,className:fe("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",t),...n,children:[e.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:e.jsx(xc,{children:e.jsx(Fn,{className:"h-4 w-4"})})}),e.jsx(gc,{children:s})]}));vs.displayName=Ri.displayName;const Tm=be.forwardRef(({className:t,...s},n)=>e.jsx($i,{ref:n,className:fe("-mx-1 my-1 h-px bg-muted",t),...s}));Tm.displayName=$i.displayName;const Er=be.forwardRef(({className:t,...s},n)=>e.jsx(Oi,{ref:n,className:fe("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-input shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary",t),...s,children:e.jsx(wc,{className:fe("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-sm ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0")})}));Er.displayName=Oi.displayName;const jl=vc,Dn=be.forwardRef(({className:t,...s},n)=>e.jsx(jc,{ref:n,className:fe("border-b",t),...s}));Dn.displayName="AccordionItem";const An=be.forwardRef(({className:t,children:s,...n},a)=>e.jsx(Nc,{asChild:!0,children:e.jsx("div",{className:"m-0 flex h-full flex-1 items-center",children:e.jsxs(_i,{ref:a,className:fe("flex flex-1 items-center justify-between py-2 text-sm transition-all hover:underline [&[data-state=open]>svg]:rotate-180",t),...n,children:[s,e.jsx(en,{className:"h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200"})]})})}));An.displayName=_i.displayName;const Rn=be.forwardRef(({className:t,children:s,...n},a)=>e.jsx(Li,{ref:a,className:fe("overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",t),...n,children:e.jsx("div",{className:"flex min-h-0 flex-1 flex-col",children:s})}));Rn.displayName=Li.displayName;const Im=[{key:"eventList",title:"eventList 事件列表"},{key:"actionList",title:"actionList 动作列表"},{key:"varList",title:"varList 变量列表"},{key:"configList",title:"configList 配置列表"},{key:"dataList",title:"dataList 数据列表"}];function es(t){if(t==null)return"—";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t)}catch{return String(t)}}function Pm(t){return t==="parsed"?"结构化":t==="raw"?"部分解析":"未定义"}function Dm({open:t,preferencesStorageKey:s,onClose:n,imageConfig:a,setImageConfig:o,axureCopyOptions:i,setAxureCopyOptions:l,onDimensionChange:c,onSwapDimensions:d,onDimensionBlur:w,isExporting:j,onExport:$,onCopyRuntimeComponent:v,onCopyToAxure:D,onCopyConfig:u,activeTab:C,itemName:K,preferredPromptClient:y,preferredIDE:P}){const R=C==="components"?"组件":"原型",L='"><script type="text/javascript" src="https://static.axhub.im/lib/runtime.js" ><\/script> <link href="',[F,x]=r.useState(null),[V,re]=r.useState(!1),[B,xe]=r.useState(!1),[ie,z]=r.useState("dynamicPrototype"),[se,W]=r.useState(!1),[S,Y]=r.useState(""),[k,N]=r.useState(""),[U,A]=r.useState(!1),[q,pe]=r.useState(null),[Ne,Ce]=r.useState(!1),[Ie,ve]=r.useState(""),Ue=r.useRef(!1);r.useEffect(()=>{Ue.current=!1;const T=Yr(s);z(T.activeTabKey??"dynamicPrototype"),N(T.selectedExportType??""),Ue.current=!0},[s]),r.useEffect(()=>{Ue.current&&gl(s,{activeTabKey:ie,selectedExportType:k})},[ie,s,k]),r.useEffect(()=>{t||(Y(""),pe(null),ve(""))},[t]);const Fe=async()=>{if(!K)return!0;xe(!0);try{const T=`${C}/${K}`,Z=await Pt.reviewCode(T,{enforceComponentExportName:!0});return Z.passed?!0:(x(Z),re(!0),!1)}catch(T){return console.error("代码检查失败:",T),!0}finally{xe(!1)}};r.useEffect(()=>{(async()=>{if(t&&k&&ie==="copyConfig"){A(!0);try{if(!await Fe()){N(""),Y("");return}const de=await u(k);Y(de)}catch{H.error("加载配置失败"),Y("")}finally{A(!1)}}})()},[ie,u,t,k]);const Oe=async()=>{if(!K){pe(null),ve("请先选择一个条目");return}Ce(!0),ve("");try{const T=await Pt.getAxureApiPreview(`${C}/${K}`);pe(T)}catch(T){pe(null),ve((T==null?void 0:T.message)||"加载 Axure API 失败")}finally{Ce(!1)}};r.useEffect(()=>{!t||ie!=="axureApi"||Oe()},[t,ie,C,K]);const We=async()=>{await Fe()&&$()},E=async()=>{await Fe()&&v()},ce=async()=>{W(!0);try{await D(i)}finally{W(!1)}},Pe=async()=>{if(!S){H.warning("请先选择导出内容");return}try{await navigator.clipboard.writeText(S),H.success("配置已复制到剪贴板")}catch{H.error("复制失败,请检查浏览器剪贴板权限")}},Ee=async()=>{try{await navigator.clipboard.writeText(L),H.success("链接已复制到剪贴板")}catch{H.error("复制链接失败,请检查浏览器剪贴板权限")}},Te=async()=>{if(!K){H.warning("请先选择一个条目");return}const T=jm({activeTab:C,itemName:K});try{await navigator.clipboard.writeText(T),H.success("Prompt 已复制到剪贴板")}catch{H.error("复制 Prompt 失败,请检查浏览器剪贴板权限")}},Ye=(T,Z)=>{const de=T==="eventList"?"payload":T==="actionList"?"params":"扩展信息",J=T==="eventList"?"payload":T==="actionList"?"params":null;return e.jsx("div",{className:"overflow-x-auto rounded-md border",children:e.jsxs("table",{className:"min-w-full text-left text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 font-medium",children:"name"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"desc"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:de})]})}),e.jsx("tbody",{children:Z.items.length===0?e.jsx("tr",{children:e.jsx("td",{className:"px-3 py-2 text-muted-foreground",colSpan:3,children:"无条目"})}):Z.items.map((Ae,ze)=>e.jsxs("tr",{className:"border-t",children:[e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:es(Ae.name)}),e.jsx("td",{className:"px-3 py-2",children:es(Ae.desc)}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:es(J?Ae[J]:Ae)})]},`${T}-${ze}`))})]})})},nt=T=>T.items.length===0?e.jsx("div",{className:"px-1 py-2 text-sm text-muted-foreground",children:"无条目"}):e.jsx("div",{className:"overflow-x-auto rounded-md border",children:e.jsxs("table",{className:"min-w-full text-left text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 font-medium",children:"type"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"attributeId"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"displayName"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"info"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"initialValue"})]})}),e.jsx("tbody",{children:T.items.map((Z,de)=>e.jsxs("tr",{className:"border-t align-top",children:[e.jsx("td",{className:"px-3 py-2",children:es(Z.type)}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:es(Z.attributeId)}),e.jsx("td",{className:"px-3 py-2",children:es(Z.displayName)}),e.jsx("td",{className:"px-3 py-2",children:es(Z.info)}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:es(Z.initialValue)})]},`config-${de}`))})]})}),Me=T=>Array.isArray(T)?T.map(Z=>{if(Z&&typeof Z=="object"){const de=Z;return{name:es(de.name),desc:es(de.desc)}}return{name:es(Z),desc:"—"}}):[],b=T=>T.items.length===0?e.jsx("div",{className:"px-1 py-2 text-sm text-muted-foreground",children:"无条目"}):e.jsx("div",{className:"overflow-x-auto rounded-md border",children:e.jsxs("table",{className:"min-w-full text-left text-sm",children:[e.jsx("thead",{className:"bg-muted/40 text-muted-foreground",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-2 font-medium",children:"name"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"desc"}),e.jsx("th",{className:"px-3 py-2 font-medium",children:"keys"})]})}),e.jsx("tbody",{children:T.items.map((Z,de)=>{const J=Me(Z.keys);return e.jsxs("tr",{className:"border-t align-top",children:[e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:es(Z.name)}),e.jsx("td",{className:"px-3 py-2",children:es(Z.desc)}),e.jsx("td",{className:"px-3 py-2",children:J.length===0?e.jsx("span",{className:"text-xs text-muted-foreground",children:"无 keys"}):e.jsx("div",{className:"flex flex-wrap gap-1.5",children:J.map((Ae,ze)=>e.jsx("span",{className:"inline-flex items-center rounded bg-muted/50 px-2 py-0.5 font-mono text-[11px]",children:Ae.desc!=="—"?`${Ae.name} · ${Ae.desc}`:Ae.name},`data-${de}-key-${ze}`))})})]},`data-${de}`)})})]})}),he=async()=>{if(!F)throw new Error("没有可用的检查结果");const T=F.issues.filter(J=>J.type==="error"),Z=F.issues.filter(J=>J.type==="warning");let de=`代码检查未通过,请按 Axure 导出修复流程改造以下文件:
|
||
|
||
`;return de+=`文件:${F.file}
|
||
|
||
`,de+=`必读资料:
|
||
`,de+=`- /skills/axure-export-workflow/SKILL.md
|
||
|
||
`,de+=`修复目标:
|
||
`,de+=`- 修复当前检查问题,并保持现有业务功能不变
|
||
`,de+=`- 最终结果需要通过当前检测逻辑
|
||
|
||
`,T.length>0&&(de+=`❌ 错误 (${T.length} 个):
|
||
`,T.forEach((J,Ae)=>{de+=`
|
||
${Ae+1}. [${J.rule}] ${J.message}
|
||
`,J.suggestion&&(de+=` 建议: ${J.suggestion}
|
||
`)})),Z.length>0&&(de+=`
|
||
⚠️ 警告 (${Z.length} 个):
|
||
`,Z.forEach((J,Ae)=>{de+=`
|
||
${Ae+1}. [${J.rule}] ${J.message}
|
||
`,J.suggestion&&(de+=` 建议: ${J.suggestion}
|
||
`)})),de},ke=r.useMemo(()=>{const T=(F==null?void 0:F.issues)||[],Z=T.filter(J=>J.type==="error").length,de=T.filter(J=>J.type==="warning").length;return{errors:Z,warnings:de}},[F]);return e.jsxs(e.Fragment,{children:[e.jsx(Js,{open:t,onOpenChange:T=>!T&&n(),children:e.jsxs(Qs,{className:"flex h-[560px] w-[min(90vw,860px)] max-w-[860px] flex-col overflow-hidden p-0 text-sm [&>[data-dialog-close]]:hidden",children:[e.jsxs(mn,{className:"border-b px-5 py-3.5",children:[e.jsx(Xs,{className:"sr-only",children:"导出到 Axure"}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx(ca,{value:ie,onValueChange:T=>{(T==="dynamicPrototype"||T==="staticPrototype"||T==="axureApi"||T==="usageGuide"||T==="copyConfig")&&z(T)},className:"w-full max-w-[480px]",children:e.jsxs(Wn,{className:"grid h-8 w-full grid-cols-5 rounded-lg border border-border/70 bg-muted/50 p-0.5",children:[e.jsx(Jt,{value:"dynamicPrototype",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"动态原型"}),e.jsx(Jt,{value:"staticPrototype",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"可编辑原型"}),e.jsx(Jt,{value:"axureApi",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"Axure API"}),e.jsx(Jt,{value:"copyConfig",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"复制配置"}),e.jsx(Jt,{value:"usageGuide",className:"h-full rounded-md px-2.5 py-0 text-[13px] leading-none data-[state=active]:shadow-none",children:"使用说明"})]})}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 shrink-0 rounded-md",onClick:n,"aria-label":"关闭",children:e.jsx(as,{className:"h-4 w-4"})})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-5 py-4.5",children:ie==="dynamicPrototype"?e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_248px]",children:[e.jsx("div",{className:"flex h-[360px] items-center justify-center overflow-hidden rounded-md border bg-muted/30 p-3",children:a.previewUrl?e.jsx("img",{src:a.previewUrl,alt:"Preview",className:"h-full w-full object-contain"}):e.jsxs("div",{className:"text-center text-sm text-muted-foreground",children:[e.jsx(gt,{className:"mx-auto mb-2 h-5 w-5 animate-spin"}),"正在生成预览..."]})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"导出尺寸"}),e.jsxs("div",{className:"grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-2",children:[e.jsx(Ps,{type:"number",min:1,value:a.width,onChange:T=>c("width",Number(T.target.value||0)),onBlur:w,placeholder:"宽"}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-8 w-8 shrink-0 rounded-md text-muted-foreground hover:text-foreground",onClick:d,"aria-label":"交换宽高",children:e.jsx(Mi,{className:"h-4 w-4"})}),e.jsx(Ps,{type:"number",min:1,value:a.height,onChange:T=>c("height",Number(T.target.value||0)),onBlur:w,placeholder:"高"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"图片内容"}),e.jsxs(yl,{value:a.contentType,onValueChange:T=>{T&&o(Z=>({...Z,contentType:T}))},children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(kr,{value:"title",id:"export-content-title"}),e.jsxs(io,{htmlFor:"export-content-title",className:"text-sm font-normal",children:[R,"标题"]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(kr,{value:"screenshot",id:"export-content-screenshot"}),e.jsxs(io,{htmlFor:"export-content-screenshot",className:"text-sm font-normal",children:[R,"截图"]})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"包含配置"}),e.jsxs(Oa,{value:a.includeConfig,onValueChange:T=>o(Z=>({...Z,includeConfig:T})),children:[e.jsx(oa,{children:e.jsx(_a,{placeholder:"选择配置"})}),e.jsxs(ia,{children:[e.jsx(vs,{value:"none",children:"无"}),e.jsx(vs,{value:"code",children:"原型"}),e.jsx(vs,{value:"codeAndDocs",children:"原型 + 文档"}),e.jsx(vs,{value:"codeAndDocsAndSource",children:"原型 + 文档 + 代码"})]})]})]})]})]}):ie==="staticPrototype"?e.jsxs("div",{className:"mx-auto w-full max-w-[620px] space-y-3",children:[e.jsx("div",{className:"rounded-md border border-blue-200 bg-blue-50/50 p-3 text-sm text-blue-900 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-100",children:"粘贴到 Axure 后可自由编辑"}),e.jsxs("div",{className:"rounded-md border",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 px-4 py-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm font-medium",children:"保留 Axure 层级"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"关闭后将减少大量动态面板"})]}),e.jsx(Er,{checked:i.preserveHierarchy,onCheckedChange:T=>{l(Z=>({...Z,preserveHierarchy:T}))},"aria-label":"保留 Axure 层级"})]}),e.jsx("div",{className:"h-px bg-border"}),e.jsxs("div",{className:"flex items-start justify-between gap-4 px-4 py-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-sm font-medium",children:"保留 Axure SVG 图标"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"关闭后将转化为 PNG 导出"})]}),e.jsx(Er,{checked:i.preserveSvgIcons,onCheckedChange:T=>{l(Z=>({...Z,preserveSvgIcons:T}))},"aria-label":"保留 Axure SVG 图标"})]})]})]}):ie==="axureApi"?e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"rounded-md border border-blue-200 bg-blue-50/50 p-3 text-sm text-blue-900 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-100",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"font-medium",children:"当前 Axure Handle API 预览"}),e.jsxs("div",{className:"text-xs",children:["数据来源:当前 ",`src/${C}/${K||"<item>"}/index.tsx`," 的 ",e.jsx("code",{children:"useImperativeHandle"})]}),e.jsxs("div",{className:"text-xs",children:["固定技能:",e.jsx("code",{children:"/skills/axure-export-workflow/SKILL.md"}),"、",e.jsx("code",{children:"/rules/axure-api-guide.md"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(te,{variant:"outline",size:"sm",onClick:()=>void Oe(),disabled:Ne||!K,children:[e.jsx(Ln,{className:`h-4 w-4 ${Ne?"animate-spin":""}`}),"刷新"]}),e.jsxs(te,{variant:"brand",size:"sm",onClick:()=>void Te(),disabled:!K,children:[e.jsx(ss,{className:"h-4 w-4"}),"复制 Prompt"]})]})]})}),Ne?e.jsxs("div",{className:"rounded-md border p-4 text-center text-sm text-muted-foreground",children:[e.jsx(gt,{className:"mx-auto mb-2 h-5 w-5 animate-spin"}),"正在解析 Axure API..."]}):Ie?e.jsx("div",{className:"rounded-md border border-amber-300/60 bg-amber-50/50 p-3 text-sm text-amber-900 dark:border-amber-700/60 dark:bg-amber-950/30 dark:text-amber-100",children:Ie}):q?e.jsxs("div",{className:"space-y-3",children:[q.hasAxureHandle?null:e.jsxs("div",{className:"rounded-md border border-amber-300/60 bg-amber-50/50 p-3 text-sm text-amber-900 dark:border-amber-700/60 dark:bg-amber-950/30 dark:text-amber-100",children:["未检测到 ",e.jsx("code",{children:"useImperativeHandle"}),",可使用上方复制的 Prompt 让 AI 新增 Axure API。"]}),e.jsx("div",{className:"overflow-hidden rounded-md border",children:Im.map(({key:T,title:Z},de)=>{const J=q.lists[T],Ae=J.parseStatus==="raw"&&J.raw;return e.jsxs("div",{className:de===0?"":"border-t",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 bg-muted/20 px-3 py-2.5",children:[e.jsx("div",{className:"text-sm font-medium",children:Z}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["状态:",Pm(J.parseStatus)]}),J.sourceKey?e.jsxs("span",{children:["来源:",J.sourceKey]}):null]})]}),e.jsxs("div",{className:"space-y-2 px-3 py-3",children:[T==="configList"?nt(J):T==="dataList"?b(J):Ye(T,J),J.warnings.length>0?e.jsx("div",{className:"rounded-md border border-amber-300/60 bg-amber-50/50 px-3 py-2 text-xs text-amber-900 dark:border-amber-700/60 dark:bg-amber-950/30 dark:text-amber-100",children:J.warnings.map((ze,ue)=>e.jsxs("div",{children:["- ",ze]},`${T}-warning-${ue}`))}):null,Ae?e.jsxs("div",{className:"space-y-1",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"结构化解析不完整,已回退原始片段:"}),e.jsx("pre",{className:"max-h-48 overflow-auto rounded-md border bg-muted/30 p-2 font-mono text-xs",children:J.raw})]}):null]})]},T)})})]}):e.jsx("div",{className:"rounded-md border p-4 text-center text-sm text-muted-foreground",children:"暂无可展示的 Axure API 数据"})]}):ie==="copyConfig"?e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"rounded-md border border-blue-200 bg-blue-50/50 p-3 text-sm text-blue-900 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-100",children:"导出本地 html 或发布到 Axure Cloud 时若图片失效,可以使用此功能复制配置。"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"导出内容"}),e.jsxs(Oa,{value:k||void 0,onValueChange:T=>N(T),children:[e.jsx(oa,{children:e.jsx(_a,{placeholder:"请选择导出内容"})}),e.jsxs(ia,{children:[e.jsx(vs,{value:"code",children:"原型"}),e.jsx(vs,{value:"codeAndDocs",children:"原型 + 文档"}),e.jsx(vs,{value:"codeAndDocsAndSource",children:"原型 + 文档 + 代码"})]})]})]}),k?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:"配置内容"}),U?e.jsxs("div",{className:"rounded-md border p-4 text-center text-sm text-muted-foreground",children:[e.jsx(gt,{className:"mx-auto mb-2 h-5 w-5 animate-spin"}),"正在加载配置..."]}):e.jsx(Yo,{value:S,readOnly:!0,onFocus:T=>T.currentTarget.select(),className:"h-[320px] w-full font-mono text-sm",placeholder:"配置内容将显示在这里"})]}):null]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-md border border-blue-200 bg-blue-50/50 p-3 text-sm text-blue-900 dark:border-blue-900 dark:bg-blue-950/40 dark:text-blue-100",children:["以下为","四","种方式的准备工作与使用说明。"]}),e.jsx("div",{className:"rounded-md border",children:e.jsxs(jl,{type:"single",collapsible:!0,defaultValue:"runtime-component",className:"w-full",children:[e.jsxs(Dn,{value:"runtime-component",className:"border-b px-4",children:[e.jsx(An,{className:"py-3 text-[15px] font-semibold hover:no-underline",children:"复制 runtime 组件(推荐)"}),e.jsxs(Rn,{className:"pb-4",children:[e.jsx("div",{className:"text-xs font-semibold tracking-wide text-muted-foreground",children:"准备工作:"}),e.jsx("div",{className:"mt-1 space-y-1 text-sm text-muted-foreground",children:e.jsx("p",{children:"在 Axure 中-发布- 生成 html - 设置 - 字体 - 添加字体,填入以下链接(含引号)"})}),e.jsxs("div",{className:"mt-2 flex items-center gap-2 rounded-md border bg-muted/40 px-3 py-2",children:[e.jsx("div",{className:"min-w-0 flex-1 font-mono text-xs break-all",children:L}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-6 w-6 shrink-0",onClick:()=>void Ee(),"aria-label":"复制链接",children:e.jsx(ss,{className:"h-3.5 w-3.5"})})]}),e.jsx("div",{className:"mt-2 text-xs font-semibold tracking-wide text-muted-foreground",children:"使用:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"复制 runtime 组件,粘贴到需要演示的页面即可"})]})]}),e.jsxs(Dn,{value:"download-cover",className:"border-b px-4",children:[e.jsx(An,{className:"py-3 text-[15px] font-semibold hover:no-underline",children:"下载 runtime 封面"}),e.jsxs(Rn,{className:"pb-4",children:[e.jsx("div",{className:"text-xs font-semibold tracking-wide text-muted-foreground",children:"准备工作:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"下载 Axhub Runtime 元件,拖入需要演示的页面"}),e.jsx("div",{className:"mt-2 text-xs font-semibold tracking-wide text-muted-foreground",children:"使用:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"下载 runtime 封面,返回 Axure 双击替换 runtime 元件的封面图片"})]})]}),e.jsxs(Dn,{value:"copy-prototype",className:"border-b px-4",children:[e.jsx(An,{className:"py-3 text-[15px] font-semibold hover:no-underline",children:"复制原型"}),e.jsxs(Rn,{className:"pb-4",children:[e.jsx("div",{className:"text-xs font-semibold tracking-wide text-muted-foreground",children:"准备工作:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"打开 3743 及以上版本的 Axure"}),e.jsx("div",{className:"mt-2 text-xs font-semibold tracking-wide text-muted-foreground",children:"使用:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"复制后粘贴到需要演示的页面即可"})]})]}),e.jsxs(Dn,{value:"copy-config",className:"border-b-0 px-4",children:[e.jsx(An,{className:"py-3 text-[15px] font-semibold hover:no-underline",children:"复制配置"}),e.jsxs(Rn,{className:"pb-4",children:[e.jsx("div",{className:"text-xs font-semibold tracking-wide text-muted-foreground",children:"准备工作:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"下载 Axhub Runtime 元件,拖入需要演示的页面"}),e.jsx("div",{className:"mt-2 text-xs font-semibold tracking-wide text-muted-foreground",children:"使用:"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"复制配置,打开 Runtime 元件下的 config 中继器,粘贴到“编辑器配置”所在行的 value"})]})]})]})})]})}),e.jsxs(Ta,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:n,children:"取消"}),ie==="dynamicPrototype"?e.jsxs(e.Fragment,{children:[e.jsxs(te,{variant:"outline",size:"sm",onClick:()=>void We(),disabled:j||B,children:[j||B?e.jsx(gt,{className:"h-4 w-4 animate-spin"}):null,"下载 Runtime 封面"]}),e.jsxs(te,{variant:"brand",size:"sm",onClick:()=>void E(),disabled:j||B,children:[j||B?e.jsx(gt,{className:"h-4 w-4 animate-spin"}):null,"复制 Runtime 组件"]})]}):ie==="staticPrototype"?e.jsxs(te,{variant:"brand",size:"sm",onClick:()=>void ce(),disabled:se||B,children:[se||B?e.jsx(gt,{className:"h-4 w-4 animate-spin"}):null,"复制到 Axure"]}):ie==="copyConfig"?e.jsxs(te,{variant:"brand",size:"sm",onClick:()=>void Pe(),disabled:!S,children:[e.jsx(ss,{className:"h-4 w-4"}),"复制配置"]}):null]})]})}),e.jsx(Js,{open:V,onOpenChange:re,children:e.jsxs(Qs,{className:"max-h-[80vh] max-w-[760px] overflow-y-auto text-sm",children:[e.jsxs(mn,{children:[e.jsxs(Xs,{className:"flex items-center gap-2",children:[e.jsx(La,{className:"h-4 w-4 text-amber-500"}),"代码检查未通过"]}),e.jsx(Un,{children:"修复后才能导出,请先处理下列问题。"})]}),F?e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"rounded-md border border-amber-300/60 bg-amber-50/60 p-3 text-sm text-amber-900 dark:border-amber-700/60 dark:bg-amber-950/30 dark:text-amber-100",children:`错误 ${ke.errors} 项,警告 ${ke.warnings} 项`}),e.jsx("div",{className:"space-y-2",children:F.issues.map((T,Z)=>e.jsxs("div",{className:"rounded-md border p-3",children:[e.jsxs("div",{className:"text-sm font-medium",children:["[",T.rule,"] ",T.message]}),T.suggestion?e.jsxs("div",{className:"mt-1 text-sm text-muted-foreground",children:["建议: ",T.suggestion]}):null]},`${T.rule}-${Z}`))})]}):null,e.jsxs(Ta,{className:"gap-2",children:[e.jsx(te,{variant:"outline",size:"sm",onClick:()=>re(!1),children:"取消"}),e.jsx(hs,{type:"primary",preferredClient:y,preferredIDE:P,scene:`review-fix-${C}`,buildPrompt:he,getIdeTargetPath:()=>K?`src/${C}/${K}/index.tsx`:null,copySuccessMessage:"复制成功",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",onAfterCopy:()=>re(!1)})]})]})})]})}function Am({state:t,actions:s}){return e.jsx(Dm,{open:t.open,preferencesStorageKey:t.preferencesStorageKey,onClose:s.onClose,imageConfig:t.imageConfig,setImageConfig:s.setImageConfig,axureCopyOptions:t.axureCopyOptions,setAxureCopyOptions:s.setAxureCopyOptions,onDimensionChange:s.onDimensionChange,onSwapDimensions:s.onSwapDimensions,onDimensionBlur:s.onDimensionBlur,isExporting:t.isExporting,onExport:s.onExport,onCopyRuntimeComponent:s.onCopyRuntimeComponent,onCopyToAxure:s.onCopyToAxure,onCopyConfig:s.onCopyConfig,activeTab:t.activeTab,itemName:t.itemName,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE})}const Nl=be.forwardRef(({className:t,...s},n)=>e.jsx(Ui,{ref:n,className:fe("peer h-4 w-4 shrink-0 rounded-[4px] border border-primary shadow-xs transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-white",t),...s,children:e.jsx(Sc,{className:"flex items-center justify-center text-primary-foreground",children:e.jsx(Fn,{className:"h-3.5 w-3.5 text-current"})})}));Nl.displayName=Ui.displayName;const la=be.forwardRef(({className:t,orientation:s="horizontal",decorative:n=!0,...a},o)=>e.jsx(Fi,{ref:o,decorative:n,orientation:s,className:fe("shrink-0 bg-border",s==="horizontal"?"h-px w-full":"h-full w-px",t),...a}));la.displayName=Fi.displayName;const vl=[{value:"genie:claude",label:"ClaudeCode"},{value:"genie:codex",label:"Codex"},{value:"genie:gemini",label:"Gemini CLI"},{value:"genie:opencode",label:"OpenCode"}],Rm={host:"localhost",allowLAN:!0,projectName:"",projectDescription:"",defaultTheme:"",defaultPromptClient:"",defaultIDE:""},ja="__empty__";function $m(t){var a,o,i,l,c;const s=Da((a=t.automation)==null?void 0:a.defaultPromptClient),n=vl.some(d=>d.value===s)&&s||"";return{host:t.server.host||"localhost",allowLAN:t.server.allowLAN!==!1,projectName:((o=t.projectInfo)==null?void 0:o.name)||"",projectDescription:((i=t.projectInfo)==null?void 0:i.description)||"",defaultTheme:((l=t.projectDefaults)==null?void 0:l.defaultTheme)||"",defaultPromptClient:n,defaultIDE:((c=t.automation)==null?void 0:c.defaultIDE)||""}}function Om({open:t,onClose:s,onSaved:n}){const[a,o]=r.useState(!1),[i,l]=r.useState(!1),[c,d]=r.useState([]),[w,j]=r.useState(Rm);r.useEffect(()=>{t&&(D(),u())},[t]);const $=r.useMemo(()=>[{label:"跟随系统默认",value:""},...Mn.map(y=>({label:y.label,value:y.value}))],[]),v=(y,P)=>{j(R=>({...R,[y]:P}))},D=async()=>{try{const y=await fetch("/api/config");if(!y.ok)throw new Error("Failed to load config");const P=await y.json();j($m(P))}catch(y){console.error("Error loading config:",y),H.error("加载配置失败")}},u=async()=>{l(!0);try{const y=await fetch("/api/themes");if(y.ok){const P=await y.json();d(Array.isArray(P)?P:[])}}catch(y){console.error("Error loading assets:",y)}finally{l(!1)}},C=async()=>{const y=w.host.trim();if(!y){H.error("主机地址不能为空");return}try{o(!0);const P=await fetch("/api/config"),R=P.ok?await P.json():{server:{host:"localhost",port:51720,allowLAN:!0}},L={...R,server:{host:y,port:R.server.port||51720,allowLAN:w.allowLAN,enableCommandAPI:R.server.enableCommandAPI||!1},projectInfo:{name:w.projectName.trim()||null,description:w.projectDescription.trim()||null},projectDefaults:{defaultTheme:w.defaultTheme||null},automation:{...R.automation||{},defaultPromptClient:Da(w.defaultPromptClient),defaultIDE:w.defaultIDE?w.defaultIDE:null}},F=await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(L)});if(!F.ok){const V=await F.json().catch(()=>({}));throw new Error((V==null?void 0:V.error)||"Failed to save config")}const x=await F.json();H.success(x.message||"配置已保存"),n==null||n(),s()}catch(P){console.error("Error saving config:",P),H.error((P==null?void 0:P.message)||"保存配置失败")}finally{o(!1)}},K=(y,P,R,L)=>e.jsxs(Oa,{value:y||ja,onValueChange:F=>P(F===ja?"":F),children:[e.jsx(oa,{clearable:!0,hasValue:!!y,onClear:()=>P(""),children:e.jsx(_a,{placeholder:L})}),e.jsx(ia,{children:R.map(F=>e.jsx(vs,{value:F.value||ja,children:F.label},F.value||ja))})]});return e.jsx(zn,{open:t,onOpenChange:y=>!y&&s(),children:e.jsxs(fn,{side:"left",className:"flex w-full max-w-[620px] flex-col p-0 text-sm sm:max-w-[620px] [&>[data-sheet-close]]:hidden",children:[e.jsx(xn,{className:"border-b px-5 py-3.5",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(gn,{className:"m-0 text-[14px] font-medium leading-none",children:"项目设置"}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md",onClick:s,"aria-label":"关闭",children:e.jsx(as,{className:"h-4 w-4"})})]})}),e.jsxs("div",{className:"flex-1 overflow-y-auto px-5 py-4.5",children:[e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h3",{className:"text-base font-semibold text-foreground",children:"项目信息"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"用于定义项目基础信息与默认资产。"})]}),e.jsxs("div",{className:"flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-700 dark:border-amber-800/40 dark:bg-amber-950/30 dark:text-amber-300",children:[e.jsx(La,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),e.jsx("span",{children:"配置更新后需保存并重启服务,修改内容才会生效。"})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"用于 AI 理解项目定位与产出风格",children:"项目名称"}),e.jsx(Ps,{value:w.projectName,onChange:y=>v("projectName",y.target.value),placeholder:"请输入项目名称",maxLength:20})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"简要描述项目背景、目标用户与核心场景",children:"项目简介"}),e.jsx(Yo,{value:w.projectDescription,onChange:y=>v("projectDescription",y.target.value),placeholder:"例如:面向运营人员的活动配置后台,强调高效配置与稳定交付",maxLength:60,rows:3,className:"resize-none text-sm"}),e.jsxs(Ea,{children:[w.projectDescription.length,"/60"]})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"从“资产管理-主题”中选择一个作为项目默认主题",children:"默认主题"}),e.jsxs(Oa,{value:w.defaultTheme,onValueChange:y=>v("defaultTheme",y||""),children:[e.jsx(oa,{clearable:!0,hasValue:!!w.defaultTheme,onClear:()=>v("defaultTheme",""),children:e.jsx(_a,{placeholder:i?"加载中...":"请选择主题"})}),e.jsx(ia,{children:c.length>0?c.map(y=>e.jsx(vs,{value:y.name,children:y.displayName},y.name)):e.jsx(vs,{value:"__empty_themes__",disabled:!0,children:i?"加载中...":"暂无可选主题"})})]})]})]}),e.jsx(la,{className:"my-5"}),e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h3",{className:"text-base font-semibold text-foreground",children:"服务配置"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"配置服务监听地址与网络访问范围。"})]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"服务监听的主机地址。通常保持 localhost 即可。",children:"主机地址"}),e.jsx(Ps,{value:w.host,onChange:y=>v("host",y.target.value),placeholder:"localhost"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2 text-sm",children:[e.jsx(Nl,{checked:w.allowLAN,onCheckedChange:y=>v("allowLAN",y===!0),className:"data-[state=checked]:text-white"}),e.jsx("span",{className:"font-medium text-foreground",children:"允许局域网访问"})]})]}),e.jsx(la,{className:"my-5"}),e.jsxs("section",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("h3",{className:"text-base font-semibold text-foreground",children:"自动化执行"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"配置自动化执行的默认偏好。"})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[e.jsxs(Dt,{children:[e.jsx(At,{hint:"自动化执行时默认使用的 Genie 供应商。",children:"默认 Genie 供应商"}),K(w.defaultPromptClient,y=>v("defaultPromptClient",y),vl,"不设置")]}),e.jsxs(Dt,{children:[e.jsx(At,{hint:"“打开”按钮默认使用该 IDE。",children:"默认 IDE"}),K(w.defaultIDE,y=>v("defaultIDE",y),$,"跟随系统默认")]})]})]})]}),e.jsxs(Bn,{className:"flex flex-row justify-end gap-2 border-t px-5 py-3.5",children:[e.jsx(te,{type:"button",variant:"outline",size:"sm",onClick:s,disabled:a,children:"取消"}),e.jsx(te,{type:"button",variant:"brand",size:"sm",onClick:C,disabled:a,children:a?"保存中...":"保存"})]})]})})}const Xn={claudecode:"Claude Code",codex:"Codex",gemini:"Gemini CLI",cursor:"Cursor Agent",opencode:"OpenCode"},_m=2e3;function Lm(t){if(t<=0)return"0:00";const s=Math.ceil(t/1e3),n=Math.floor(s/60),a=s%60;return`${n}:${a.toString().padStart(2,"0")}`}function Mm({open:t,onOpenChange:s}){const[n,a]=r.useState("connected"),[o,i]=r.useState(null),[l,c]=r.useState(!1),[d,w]=r.useState([]),[j,$]=r.useState(null),[v,D]=r.useState([]),[u,C]=r.useState(!1),[K,y]=r.useState(!1),[P,R]=r.useState(!1),[L,F]=r.useState(null),[x,V]=r.useState("starting"),[re,B]=r.useState(null),[xe,ie]=r.useState(null),[z,se]=r.useState(0),[W,S]=r.useState(null),[Y,k]=r.useState("8:00"),[N,U]=r.useState(!1),[A,q]=r.useState(null),pe=r.useRef(null),Ne=r.useRef(null),Ce=r.useRef(null);r.useEffect(()=>{Ce.current=L},[L]);const Ie=r.useCallback(()=>{pe.current&&(clearInterval(pe.current),pe.current=null),Ne.current&&(clearInterval(Ne.current),Ne.current=null)},[]),ve=r.useCallback(async()=>{Ie();const T=Ce.current;if(T)try{await fetch(`/api/cc-connect/weixin/session?sessionId=${encodeURIComponent(T)}`,{method:"DELETE"})}catch{}},[Ie]);r.useEffect(()=>{if(!t){ve();const T=setTimeout(()=>{a("connected"),F(null),V("starting"),B(null),ie(null),se(0),S(null),k("8:00"),U(!1),q(null),w([]),R(!1)},300);return()=>clearTimeout(T)}},[t,ve]),r.useEffect(()=>()=>{Ie()},[Ie]),r.useEffect(()=>{if(!t)return;(async()=>{try{const Z=await fetch("/api/cc-connect/status");if(Z.ok){const J=(await Z.json()).installed===!0;if(i(J),!J)return}else{i(!1);return}}catch{i(!1);return}try{const Z=await fetch("/api/cc-connect/active-agent");if(Z.ok){const de=await Z.json();if(de.agent&&Array.isArray(de.availableAgents)&&de.availableAgents.length>0){$(de.agent),D(de.availableAgents),w(de.availableAgents),a("connected"),R(!0);return}}}catch{}R(!0),Fe()})()},[t]);const Ue=async()=>{c(!0);try{const Z=await(await fetch("/api/cc-connect/install",{method:"POST"})).json();Z.success?(i(!0),H.success(Z.message||"cc-connect@beta 安装成功"),Fe()):H.error(Z.error||"安装失败")}catch(T){H.error(`安装失败: ${(T==null?void 0:T.message)||"网络错误"}`)}finally{c(!1)}},Fe=async()=>{Ie(),a("qrcode"),$(null),D([]),F(null),U(!0),q(null),V("starting"),B(null),ie(null),S("正在启动微信连接...");try{const T=await fetch("/api/cc-connect/weixin/setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({})});if(!T.ok){const de=await T.json().catch(()=>({}));throw new Error((de==null?void 0:de.error)||"启动失败")}const Z=await T.json();F(Z.sessionId),Array.isArray(Z.agents)&&w(Z.agents),Oe(Z.sessionId)}catch(T){V("error"),q((T==null?void 0:T.message)||"启动失败"),S((T==null?void 0:T.message)||"启动失败"),H.error((T==null?void 0:T.message)||"启动微信连接失败")}finally{U(!1)}},Oe=r.useCallback(T=>{Ie();const Z=async()=>{try{const de=await fetch(`/api/cc-connect/weixin/status?sessionId=${encodeURIComponent(T)}`);if(!de.ok)return;const J=await de.json();V(J.status),S(J.message||null),J.qrUrl&&B(J.qrUrl),J.qrImageBase64&&ie(J.qrImageBase64),J.expiresAt&&se(J.expiresAt),(J.status==="confirmed"||J.status==="error")&&(Ie(),J.status==="confirmed"&&a("success"))}catch{}};Z(),pe.current=setInterval(Z,_m),Ne.current=setInterval(()=>{se(de=>{if(!de)return de;const J=de-Date.now();return J<=0?(k("0:00"),V(Ae=>Ae==="pending"||Ae==="starting"?"expired":Ae),de):(k(Lm(J)),de)})},1e3)},[Ie]),We=async()=>{if(L){U(!0),V("starting"),B(null),ie(null),S("正在刷新二维码..."),Ie();try{const T=await fetch(`/api/cc-connect/weixin/refresh?sessionId=${encodeURIComponent(L)}`,{method:"POST"});if(!T.ok){const de=await T.json().catch(()=>({}));throw new Error((de==null?void 0:de.error)||"刷新失败")}const Z=await T.json();F(Z.sessionId),Oe(Z.sessionId)}catch(T){V("error"),S((T==null?void 0:T.message)||"刷新失败")}finally{U(!1)}}},E=()=>{s(!1)},ce=async T=>{if(!(T===j||u)){C(!0);try{const de=await(await fetch("/api/cc-connect/switch-agent",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent:T})})).json();de.success?($(T),H.success(`已切换到 ${Xn[T]||T}`)):H.error(de.error||"切换失败")}catch(Z){H.error(`切换失败: ${(Z==null?void 0:Z.message)||"网络错误"}`)}finally{C(!1)}}},Pe=async()=>{y(!0);try{const Z=await(await fetch("/api/cc-connect/unbind",{method:"POST"})).json();Z.success?(H.success("已解除微信绑定"),$(null),D([]),a("qrcode"),Fe()):H.error(Z.error||"解绑失败")}catch(T){H.error(`解绑失败: ${(T==null?void 0:T.message)||"网络错误"}`)}finally{y(!1)}},Ee=()=>e.jsxs("div",{className:"flex flex-col items-center gap-4 py-6",children:[e.jsx("div",{className:"flex h-14 w-14 items-center justify-center rounded-full bg-amber-100 dark:bg-amber-900/30",children:e.jsx(Xa,{className:"h-7 w-7 text-amber-600 dark:text-amber-400"})}),e.jsxs("div",{className:"text-center",children:[e.jsx("h3",{className:"text-base font-semibold",children:"需要安装 cc-connect"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"微信连接需要 cc-connect@beta 工具,请先安装。"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"rounded bg-muted px-2 py-1 text-xs",children:"npm install -g cc-connect@beta"}),e.jsx(te,{size:"sm",onClick:Ue,disabled:l,children:l?e.jsxs(e.Fragment,{children:[e.jsx(gt,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}),"安装中..."]}):e.jsxs(e.Fragment,{children:[e.jsx(Ds,{className:"mr-1.5 h-3.5 w-3.5"}),"一键安装"]})})]})]}),Te=()=>e.jsxs("div",{className:"space-y-4",children:[d.length>0&&e.jsxs("div",{className:"rounded-lg border bg-muted/30 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-1.5",children:"已检测到的 AI 助手:"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:d.map(T=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-medium text-primary",children:Xn[T]||T},T))})]}),e.jsxs("div",{className:"flex flex-col items-center gap-4 py-2",children:[(x==="starting"||N)&&e.jsx("div",{className:"flex h-48 w-48 items-center justify-center rounded-lg border bg-muted/30",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx(gt,{className:"h-8 w-8 animate-spin text-primary"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"正在生成二维码..."})]})}),x==="pending"&&(xe||re)&&e.jsx("div",{className:"relative",children:xe?e.jsx("img",{src:`data:image/png;base64,${xe}`,alt:"微信登录二维码",className:"h-48 w-48 rounded-lg border"}):re?e.jsx("div",{className:"flex h-48 w-48 items-center justify-center rounded-lg border bg-white p-3",children:e.jsx("img",{src:re,alt:"微信登录二维码",className:"h-full w-full object-contain",onError:T=>{const Z=T.currentTarget;Z.style.display="none"}})}):null}),x==="scanned"&&e.jsx("div",{className:"flex h-48 w-48 items-center justify-center rounded-lg border bg-primary/5",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx(Ma,{className:"h-10 w-10 text-primary"}),e.jsx("span",{className:"text-sm font-medium text-primary",children:"已扫码"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"请在手机上确认"})]})}),x==="expired"&&e.jsx("div",{className:"flex h-48 w-48 items-center justify-center rounded-lg border bg-muted/30",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx(Xa,{className:"h-8 w-8 text-muted-foreground"}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"二维码已过期"})]})}),x==="error"&&e.jsx("div",{className:"flex h-48 w-48 items-center justify-center rounded-lg border bg-destructive/5",children:e.jsxs("div",{className:"flex flex-col items-center gap-2 px-4 text-center",children:[e.jsx(Xa,{className:"h-8 w-8 text-destructive"}),e.jsx("span",{className:"text-xs text-destructive",children:A||W||"出错了"})]})}),x==="pending"&&e.jsxs("div",{className:"flex flex-col items-center gap-1",children:[e.jsx("p",{className:"text-sm font-medium",children:"请使用微信扫描二维码"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["二维码有效期剩余 ",e.jsx("span",{className:"font-mono font-medium",children:Y})]})]}),(x==="expired"||x==="error")&&e.jsxs(te,{onClick:L?We:()=>void Fe(),disabled:N,size:"sm",variant:"outline",children:[N?e.jsx(gt,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):e.jsx(Ln,{className:"mr-1.5 h-3.5 w-3.5"}),L?"刷新二维码":"重试"]}),x==="pending"&&e.jsxs(te,{onClick:We,disabled:N,size:"sm",variant:"ghost",className:"text-muted-foreground",children:[e.jsx(Ln,{className:"mr-1.5 h-3.5 w-3.5"}),"刷新二维码"]})]})]}),Ye=()=>e.jsxs("div",{className:"flex flex-col gap-4 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3 rounded-lg border bg-green-50 p-3 dark:border-green-900/40 dark:bg-green-950/20",children:[e.jsx("div",{className:"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/40",children:e.jsx(Cc,{className:"h-4 w-4 text-green-600 dark:text-green-400"})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-sm font-medium text-green-700 dark:text-green-300",children:"微信已连接"}),e.jsxs("p",{className:"text-xs text-green-600/70 dark:text-green-400/70",children:["当前 AI 助手: ",Xn[j]||j]})]})]}),v.length>1&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground",children:"切换 AI 助手"}),e.jsx("div",{className:"grid gap-1.5",children:v.map(T=>{const Z=T===j;return e.jsxs("button",{onClick:()=>void ce(T),disabled:Z||u,className:`flex items-center gap-2.5 rounded-lg border px-3 py-2 text-left text-sm transition-colors ${Z?"border-primary/30 bg-primary/5 font-medium text-primary":"border-transparent bg-muted/30 text-foreground hover:bg-muted/60"} disabled:opacity-60`,children:[Z&&e.jsx(lo,{className:"h-3.5 w-3.5 shrink-0 text-primary"}),!Z&&u&&e.jsx(gt,{className:"h-3.5 w-3.5 shrink-0 animate-spin"}),!Z&&!u&&e.jsx(Mi,{className:"h-3.5 w-3.5 shrink-0 text-muted-foreground"}),e.jsx("span",{children:Xn[T]||T})]},T)})})]}),e.jsxs("div",{className:"flex items-center justify-between pt-1",children:[e.jsxs(te,{onClick:()=>void Pe(),size:"sm",variant:"outline",disabled:K,className:"text-destructive hover:text-destructive",children:[K?e.jsx(gt,{className:"mr-1.5 h-3.5 w-3.5 animate-spin"}):e.jsx(kc,{className:"mr-1.5 h-3.5 w-3.5"}),"解除绑定"]}),e.jsx(te,{onClick:E,size:"sm",children:"关闭"})]})]}),nt=()=>e.jsxs("div",{className:"flex flex-col items-center gap-4 py-6",children:[e.jsx("div",{className:"flex h-16 w-16 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/30",children:e.jsx(lo,{className:"h-8 w-8 text-green-600 dark:text-green-400"})}),e.jsxs("div",{className:"text-center",children:[e.jsx("h3",{className:"text-lg font-semibold",children:"微信连接成功!"}),d.length>0&&e.jsxs("div",{className:"mt-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground mb-1.5",children:"已配置的 AI 助手:"}),e.jsx("div",{className:"flex flex-wrap justify-center gap-1.5",children:d.map(T=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-[11px] font-medium text-green-700 dark:bg-green-900/30 dark:text-green-400",children:Xn[T]||T},T))})]})]}),e.jsx("div",{className:"space-y-2 w-full",children:e.jsx("div",{className:"rounded-lg border bg-blue-50 p-3 text-center dark:border-blue-900/40 dark:bg-blue-950/30",children:e.jsx("p",{className:"text-xs text-blue-700 dark:text-blue-300",children:"💡 请用微信给机器人发一条消息以完成激活。之后,你就可以通过微信与 AI 助手对话了。"})})}),e.jsx(te,{onClick:E,size:"sm",className:"mt-2",children:"完成"})]}),Me=o===!1,b=n==="connected"&&j&&P,he=()=>Me?"连接微信":b?"微信连接":n==="success"?"连接成功":"扫码连接",ke=()=>Me?"通过 cc-connect 将 AI 编程助手连接到微信,随时随地对话。":b?"管理微信与 AI 助手的连接和切换。":n==="success"?"你的微信已成功连接到 AI 助手。":"使用微信扫描下方二维码,自动配置所有已安装的 AI 助手。";return e.jsx(Js,{open:t,onOpenChange:s,children:e.jsxs(Qs,{className:"max-w-md w-[calc(100%-2rem)] rounded-2xl sm:rounded-lg",onOpenAutoFocus:T=>{T.preventDefault()},children:[e.jsxs(mn,{className:"text-left",children:[e.jsxs(Xs,{className:"flex items-center gap-2",children:[e.jsx(Pa,{className:"h-5 w-5"}),he(),e.jsx("span",{className:"inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary",children:"Beta"})]}),e.jsx(Un,{className:"ml-7",children:ke()})]}),Me&&Ee(),!Me&&b&&Ye(),!Me&&n==="qrcode"&&Te(),!Me&&n==="success"&&nt()]})})}function Um(t){return navigator.clipboard.writeText(t)}function Fm({open:t,onOpenChange:s}){const[n,a]=be.useState("复制"),o=be.useRef(null),i=be.useCallback(()=>{o.current!==null&&(window.clearTimeout(o.current),o.current=null)},[]);be.useEffect(()=>{t&&(i(),a("复制"))},[i,t]),be.useEffect(()=>()=>{i()},[i]);const l=async()=>{try{await Um(yo),i(),a("已复制"),o.current=window.setTimeout(()=>{a("复制"),o.current=null},1e3)}catch(c){console.error("Failed to copy welcome prompt:",c),i(),a("复制失败"),o.current=window.setTimeout(()=>{a("复制"),o.current=null},1e3)}};return e.jsx(Js,{open:t,onOpenChange:s,children:e.jsx(Qs,{className:"w-[min(92vw,620px)] max-w-[620px] overflow-hidden rounded-[24px] border-border bg-card p-0 shadow-md data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 [&>[data-dialog-close]]:hidden",children:e.jsxs("div",{className:"relative px-6 pb-6 pt-5 sm:px-7 sm:pb-7 sm:pt-6",children:[e.jsx("button",{type:"button","aria-label":"关闭新手指导",onClick:()=>s(!1),className:"absolute right-5 top-5 inline-flex h-7 w-7 items-center justify-center border-0 text-muted-foreground outline-none shadow-none ring-0 transition-colors hover:text-foreground focus:border-transparent focus:outline-none focus:ring-0 focus:shadow-none active:border-transparent active:outline-none active:ring-0 active:shadow-none focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-0 focus-visible:shadow-none",children:e.jsx(as,{className:"h-5 w-5"})}),e.jsxs("div",{className:"mb-3 inline-flex items-center gap-2 rounded-full bg-primary/10 px-3 py-1 text-xs font-semibold text-primary",children:[e.jsx(Ec,{className:"h-3.5 w-3.5"}),"新手指导"]}),e.jsx(Xs,{className:"text-[28px] font-semibold leading-tight tracking-tight text-foreground",children:"让 AI 教你使用 Make 吧"}),e.jsx(Un,{className:"mt-3 text-sm leading-7 text-muted-foreground",children:"复制 Prompt 后发给你常用的 AI,他会带你快速上手"}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-1.5 text-[12px] text-muted-foreground",children:[e.jsx("span",{children:"💡 推荐模型:"}),["Claude Opus 4.6","Gemini 3.1 Pro","GPT-5.4","Kimi K2.5","GLM-5.1"].map(c=>e.jsx("span",{className:"rounded-full border bg-muted/50 px-2 py-0.5",children:c},c))]}),e.jsx("div",{className:"mt-5 rounded-[18px] border border-white/8 bg-slate-950 px-4 py-4 text-sm leading-7 text-white/90 shadow-sm",children:e.jsx("pre",{className:"m-0 whitespace-pre-wrap break-all font-mono text-[13px] leading-7",children:yo})}),e.jsxs("p",{className:"mt-3 text-xs leading-6 text-muted-foreground",children:["后续有问题或需要建议,可以随时通过 ",e.jsx("code",{className:"rounded bg-muted px-1.5 py-0.5 text-[11px] text-foreground",children:"左上角菜单 -> 项目 Skills -> 项目引导"})," 重新触发向导。"]}),e.jsxs("div",{className:"mt-5 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",children:[e.jsx(te,{type:"button",variant:"outline",onClick:()=>s(!1),children:"我知道了"}),e.jsxs(te,{type:"button",variant:"brand",onClick:l,children:[e.jsx(ss,{className:"h-4 w-4"}),n]})]})]})})})}function zm({visible:t,onCancel:s,item:n,activeTab:a,preferredPromptClient:o,preferredIDE:i}){const l=Rr(),[c,d]=r.useState([]),[w,j]=r.useState(!1),[$,v]=r.useState(""),[D,u]=r.useState(""),[C,K]=r.useState(!1),[y,P]=r.useState(!1),[R,L]=r.useState(null),[F,x]=r.useState(null),V=N=>{let U=String(N||"").trim().replace(/\\/g,"/");const A=U.lastIndexOf("/src/");return A>=0?U=U.substring(A+5):U.startsWith("src/")&&(U=U.substring(4)),U.replace(/^\/+/,"").replace(/\/index\.(t|j)sx?$/i,"").replace(/\/+$/,"")},re=N=>{const U=N;let A="";return U.filePath?A=V(U.filePath):A=`${a==="prototypes"?"src/prototypes":"src/components"}/${N.name}`,V(A)},B=N=>{const U=new Date(N),A=q=>String(q).padStart(2,"0");return`${U.getFullYear()}/${A(U.getMonth()+1)}/${A(U.getDate())} ${A(U.getHours())}:${A(U.getMinutes())}:${A(U.getSeconds())}`},xe=N=>{const U=Math.floor((Date.now()-N)/1e3);let A=U/31536e3;return A>1?Math.floor(A)+" 年前":(A=U/2592e3,A>1?Math.floor(A)+" 个月前":(A=U/86400,A>1?Math.floor(A)+" 天前":(A=U/3600,A>1?Math.floor(A)+" 小时前":(A=U/60,A>1?Math.floor(A)+" 分钟前":"刚刚"))))},ie=async()=>{if(n){P(!0);try{const N=re(n);if(!N){H.error("无法获取文件路径");return}const U=await fetch(`/api/git/history?path=${encodeURIComponent(N)}`),A=await U.json();U.ok?(d(Array.isArray(A.commits)?A.commits:[]),j(!!A.hasUncommitted),v(typeof A.uncommittedFiles=="string"?A.uncommittedFiles:"")):H.error(A.error||"加载版本历史失败")}catch{H.error("加载版本历史失败")}finally{P(!1)}}};r.useEffect(()=>{t&&n&&ie()},[t,n]);const z=async N=>{if(!(!n||!await l.confirm({title:"恢复此版本?",description:"当前未提交的更改将会丢失,请确认是否继续。",confirmText:"确认恢复",cancelText:"取消",tone:"destructive",dismissible:!1})))try{const A=re(n),q=await fetch("/api/git/restore",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:A,commitHash:N})}),pe=await q.json();q.ok?(H.success("版本恢复成功"),ie()):H.error(pe.error||"版本恢复失败")}catch{H.error("版本恢复失败")}},se=async()=>{if(!n||!D.trim()){H.warning("请输入提交信息");return}K(!0);try{const N=re(n),U=await fetch("/api/git/commit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:N,message:D})}),A=await U.json();U.ok?(H.success("提交成功"),u(""),ie()):H.error(A.error||"提交失败")}catch{H.error("提交失败")}finally{K(!1)}},W=async()=>{if(!n)throw new Error("请选择条目后再执行");const N=re(n);return`我需要提交以下目录的更改,请帮我处理:
|
||
|
||
目标路径: src/${N}
|
||
|
||
请执行以下步骤:
|
||
1. 使用 git status 和 git diff 查看该路径下的变更内容。
|
||
2. 分析变更,生成一个简洁明了的中文提交信息(Commit Message)。
|
||
3. 向我展示变更摘要和建议的提交信息,并询问是否继续。
|
||
4. 获得确认后,执行:
|
||
git add src/${N}
|
||
git commit -m "你的提交信息"
|
||
|
||
请直接开始执行第 1 步。`},S=async N=>{if(n){L(N);try{const U=re(n),A=await fetch("/api/git/build-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:U,commitHash:N})}),q=await A.json();A.ok&&q.hasSpec&&q.specUrl?window.open(q.specUrl,"_blank"):q.hasSpec?H.error(q.error||"无法访问规格文档"):H.warning("该版本没有规格文档")}catch{H.error("加载规格文档失败")}finally{L(null)}}},Y=async N=>{if(n){x(N);try{const U=re(n),A=await fetch("/api/git/build-version",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:U,commitHash:N})}),q=await A.json();A.ok&&q.hasPrototype&&q.prototypeUrl?window.open(q.prototypeUrl,"_blank"):q.hasPrototype?H.error(q.error||"无法访问原型"):H.warning("该版本没有原型文件")}catch{H.error("加载原型失败")}finally{x(null)}}},k=r.useMemo(()=>$.split(`
|
||
`).filter(Boolean).length,[$]);return e.jsx(Js,{open:t,onOpenChange:N=>!N&&s(),children:e.jsxs(Qs,{className:"max-h-[80vh] max-w-[760px] overflow-y-auto text-sm",children:[e.jsxs(mn,{children:[e.jsxs(Xs,{className:"flex items-center gap-2",children:[e.jsx(gr,{className:"h-4 w-4"}),`版本管理 - ${(n==null?void 0:n.displayName)||"-"}`]}),e.jsx(Un,{children:"查看历史版本、提交未保存更改并回滚到指定版本。"})]}),y?e.jsx("div",{className:"py-8 text-center text-sm text-muted-foreground",children:"加载中..."}):c.length===0&&!w?e.jsx("div",{className:"rounded-md border border-dashed p-6 text-center text-sm text-muted-foreground",children:"暂无版本历史"}):e.jsxs("div",{className:"space-y-4",children:[w?e.jsxs("div",{className:"rounded-md border border-amber-300/60 bg-amber-50/50 p-3 dark:border-amber-700/70 dark:bg-amber-950/20",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium text-foreground",children:"未提交的更改"}),e.jsx("span",{className:"rounded-full bg-amber-200 px-2 py-0.5 text-sm text-amber-900 dark:bg-amber-700 dark:text-amber-100",children:"未保存"})]}),e.jsx(Ps,{placeholder:"手动输入提交信息...",value:D,onChange:N=>u(N.target.value),onKeyDown:N=>{N.key==="Enter"&&se()},className:"mb-2"}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:k>0?`${k} 个文件变更`:"有文件变更"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(hs,{type:"default",preferredClient:o,preferredIDE:i,scene:`version-commit-${a}`,buildPrompt:W,getIdeTargetPath:()=>n?`src/${re(n)}`:null,copySuccessMessage:"AI 指令已复制,请粘贴给助手",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt"}),e.jsxs(te,{variant:"brand",size:"sm",onClick:()=>void se(),disabled:C||!D.trim(),children:[e.jsx(Tc,{className:"h-4 w-4"}),C?"提交中...":"提交"]})]})]})]}):null,e.jsx("div",{className:"space-y-3",children:c.map((N,U)=>{const A=U===0&&!w;return e.jsx("div",{className:"rounded-md border bg-card p-3",children:e.jsxs("div",{className:"mb-1 flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-sm font-medium text-foreground",children:N.message}),e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2 text-sm text-muted-foreground",children:[e.jsx("span",{children:N.author||"Unknown"}),e.jsx("span",{children:"·"}),e.jsx("span",{title:B(N.timestamp),children:xe(N.timestamp)}),e.jsx("span",{children:"·"}),e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-sm",children:N.hash.substring(0,7)})]})]}),A?e.jsx("span",{className:"rounded-full bg-emerald-100 px-2 py-0.5 text-sm text-emerald-800 dark:bg-emerald-900/50 dark:text-emerald-100",children:"当前版本"}):e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(te,{variant:"ghost",size:"icon-xs",onClick:()=>void S(N.hash),disabled:R===N.hash,children:e.jsx(hn,{className:"h-4 w-4"})}),e.jsx(te,{variant:"ghost",size:"icon-xs",onClick:()=>void Y(N.hash),disabled:F===N.hash,children:e.jsx(Ic,{className:"h-4 w-4"})}),e.jsx(te,{variant:"ghost",size:"icon-xs",onClick:()=>void z(N.hash),children:e.jsx(Pc,{className:"h-4 w-4"})})]})]})},N.hash)})})]})]})})}function Bm({docReferencePromptDialog:t,setDocReferencePromptDialog:s,preferredPromptClient:n,preferredIDE:a,createDialog:o,createDocDialog:i,createThemeDialog:l,exportDialog:c,settingsDialogOpen:d,setSettingsDialogOpen:w,onSettingsSaved:j,wechatConnectOpen:$,setWechatConnectOpen:v,welcomeGuideOpen:D,onWelcomeGuideOpenChange:u,versionDialogVisible:C,setVersionDialogVisible:K,currentVersionItem:y,versionActiveTab:P,createDataDialog:R}){return e.jsxs(e.Fragment,{children:[e.jsx(Js,{open:!!t,onOpenChange:L=>{L||s(null)},children:e.jsxs(Qs,{className:"max-h-[80vh] max-w-[760px] overflow-y-auto text-sm",children:[e.jsxs(mn,{children:[e.jsx(Xs,{children:(t==null?void 0:t.title)||"检测到文档引用"}),e.jsx(Un,{children:(t==null?void 0:t.description)||"请先处理引用,再继续执行文档操作。"})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{className:"text-sm text-muted-foreground",children:"已检测到以下项目文件仍在引用该文档:"}),e.jsx("pre",{className:"max-h-72 overflow-auto rounded-md bg-muted p-3 text-xs leading-6 text-foreground",children:((t==null?void 0:t.references)||[]).map(L=>`- ${L}`).join(`
|
||
`)})]}),e.jsxs(Ta,{className:"gap-2 sm:justify-between",children:[e.jsx(te,{type:"button",variant:"outline",onClick:()=>s(null),children:"关闭"}),t?e.jsx(hs,{type:"primary",preferredClient:n,preferredIDE:a,getIdeTargetPath:()=>t.targetPath,scene:t.scene,buildPrompt:()=>t.prompt,copySuccessMessage:"已复制处理提示,请返回编辑器让 AI 处理。",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt",onAfterCopy:()=>s(null)}):null]})]})}),e.jsx(Xu,{state:{visible:o.visible,activeTab:o.activeTab,selectedThemes:o.selectedThemes,selectedSkills:o.selectedSkills,availableThemes:o.availableThemes,selectedDocs:o.selectedDocs,availableDocs:o.availableDocs,selectedDataAssets:o.selectedDataAssets,availableDataAssets:o.availableDataAssets,preferredPromptClient:n,preferredIDE:a},actions:{onClose:o.onClose,setSelectedSkills:o.setSelectedSkills,setSelectedDocs:o.setSelectedDocs,setSelectedThemes:o.setSelectedThemes,setSelectedDataAssets:o.setSelectedDataAssets,buildCreatePrompt:o.buildPrompt,onAfterCreatePromptAction:o.onAfterCreatePromptAction,onUploadSuccess:o.onUploadSuccess}}),e.jsx(em,{state:{visible:i.visible,selectedSkillIds:i.selectedSkillIds,availableDocSkills:i.availableDocSkills,selectedDocs:i.selectedDocs,availableDocs:i.availableDocs,selectedReferencePrototypes:i.selectedReferencePrototypes,availableReferencePrototypes:i.availableReferencePrototypes,selectedDataAssets:i.selectedDataAssets,availableDataAssets:i.availableDataAssets,selectedTemplates:i.selectedTemplates,availableTemplates:i.availableTemplates,preferredPromptClient:n,preferredIDE:a},actions:{onClose:i.onClose,setSelectedSkillIds:i.setSelectedSkillIds,setSelectedDocs:i.setSelectedDocs,setSelectedReferencePrototypes:i.setSelectedReferencePrototypes,setSelectedDataAssets:i.setSelectedDataAssets,setSelectedTemplates:i.setSelectedTemplates,buildCreateDocPrompt:i.buildCreateDocPrompt,onAfterCreatePromptAction:i.onAfterCreatePromptAction,onManualCreateSuccess:i.onManualCreateSuccess,onImportSuccess:i.onImportSuccess}}),e.jsx(dm,{state:{visible:l.visible,selectedSkillIds:l.selectedSkillIds,selectedDocs:l.selectedDocs,availableDocs:l.availableDocs,selectedReferencePages:l.selectedReferencePages,availableReferencePages:l.availableReferencePages,preferredPromptClient:n,preferredIDE:a},actions:{onClose:l.onClose,setSelectedSkillIds:l.setSelectedSkillIds,setSelectedDocs:l.setSelectedDocs,setSelectedReferencePages:l.setSelectedReferencePages,buildCreateThemePrompt:l.buildCreateThemePrompt,onAfterCreatePromptAction:l.onAfterCreatePromptAction,onImportSuccess:l.onImportSuccess}}),e.jsx(Am,{state:{open:c.open,preferencesStorageKey:c.preferencesStorageKey,imageConfig:c.imageConfig,axureCopyOptions:c.axureCopyOptions,isExporting:c.isExporting,activeTab:c.activeTab,itemName:c.itemName,preferredPromptClient:n,preferredIDE:a},actions:{onClose:c.onClose,setImageConfig:c.setImageConfig,setAxureCopyOptions:c.setAxureCopyOptions,onDimensionChange:c.onDimensionChange,onSwapDimensions:c.onSwapDimensions,onDimensionBlur:c.onDimensionBlur,onExport:c.onExport,onCopyRuntimeComponent:c.onCopyRuntimeComponent,onCopyToAxure:c.onCopyToAxure,onCopyConfig:c.onCopyConfig}}),e.jsx(Om,{open:d,onClose:()=>w(!1),onSaved:j}),e.jsx(Mm,{open:$,onOpenChange:v}),e.jsx(Fm,{open:D,onOpenChange:u}),e.jsx(zm,{visible:C,onCancel:()=>K(!1),item:y,activeTab:P,preferredPromptClient:n,preferredIDE:a}),e.jsx(bm,{state:{visible:R.visible,newTableName:R.newTableName,newTableNameError:R.newTableNameError,dataTableCreating:R.dataTableCreating,preferredPromptClient:n,preferredIDE:a},actions:{onClose:R.onClose,setNewTableName:R.setNewTableName,clearNewTableNameError:R.clearNewTableNameError,onCreateSubmit:R.onCreateSubmit,onImportSuccess:R.onImportSuccess}})]})}function Bo(t){return t??"claude-code"}const Sl=[{key:"claude-code",label:"Claude Code",skillsDir:".claude/skills"},{key:"codex",label:"Codex",skillsDir:".agents/skills"},{key:"opencode",label:"OpenCode",skillsDir:".opencode/skills"}],Wm={cursor:".cursor/skills",windsurf:".windsurf/skills",qoder:"skills",trae:".trae/skills",trae_cn:".trae/skills",vscode:".github/skills",kiro:".kiro/skills",antigravity:".agent/skills"},Cl=Mn.map(t=>({key:t.value,label:t.label,skillsDir:Wm[t.value]})),Wo=[...Sl,...Cl],Gm={cursor:na,trae:sa,vscode:_r,trae_cn:sa,windsurf:Or,kiro:$r,qoder:Fa,antigravity:Ua};function ur(t){if(t==="claude-code")return e.jsx(Vi,{size:14,color:"currentColor"});if(t==="codex")return e.jsx(yr,{size:14,color:"currentColor"});if(t==="opencode")return e.jsx(Ds,{className:"h-3.5 w-3.5"});const s=Gm[t];return s?e.jsx(s,{size:14,color:"currentColor"}):e.jsx(Ds,{className:"h-3.5 w-3.5"})}async function Km(t,s,n){if(rl(n))try{const a=Sr(n,t);window.open(a,"_blank","noopener,noreferrer");return}catch{}s&&await Aa({preferredIDE:s}).catch(()=>{})}function Vm({visible:t,onClose:s,preferredIDE:n=null,preferredPromptClient:a=null}){const[o,i]=r.useState(null),[l,c]=r.useState(new Map),[d,w]=r.useState(()=>Bo(n)),j=r.useMemo(()=>(Nd.skills??[]).filter(K=>K.id&&K.titleZh),[]),$=r.useMemo(()=>Wo.find(C=>C.key===d)??Wo[0],[d]),v=r.useCallback(async C=>{i(C.id);try{const K=await fetch("/api/prototype-admin/install-skill",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({skillId:C.id,client:d})}),y=await K.json().catch(()=>({}));if(!K.ok||!(y!=null&&y.success))throw new Error((y==null?void 0:y.error)||"安装失败");c(P=>new Map(P).set(C.id,"installed")),H.success("安装成功",{description:"可能需要重启编辑器或 AI 工具才能生效",duration:5e3})}catch(K){H.error((K==null?void 0:K.message)||"安装失败")}finally{i(null)}},[d]),D=r.useCallback(async C=>{const K=`请阅读技能文档 \`${C.skillMdPath}\`。阅读完成后,请暂时不要执行任何实质操作,仅回复:“收到,已准备好执行『${C.titleZh}』技能,请告诉我您的详细需求:”。等待我输入需求后,再严格按照文档中的流程指引开始工作。`;try{await navigator.clipboard.writeText(K),H.success("Prompt 已复制"),await Km(K,n,a)}catch{H.error("复制失败")}},[n,a]),u=r.useMemo(()=>{const C=new Map;for(const K of j){const y=K.category||"其他";C.has(y)||C.set(y,[]),C.get(y).push(K)}return C},[j]);return be.useEffect(()=>{c(new Map)},[d]),be.useEffect(()=>{t&&w(Bo(n))},[t,n]),e.jsx(zn,{open:t,onOpenChange:C=>!C&&s(),children:e.jsxs(fn,{side:"left",className:"flex w-full max-w-[640px] flex-col p-0 text-sm sm:max-w-[640px] [&>[data-sheet-close]]:hidden",children:[e.jsxs(xn,{className:"border-b px-5 py-3",children:[e.jsx(gn,{className:"sr-only",children:"项目 Skills"}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx(zi,{className:"h-4 w-4 text-brand"}),e.jsx("span",{className:"text-[15px] font-medium tracking-tight",children:"项目 Skills"})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[12px] text-muted-foreground/80",children:"安装至"}),e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"sm",className:"h-7 gap-1.5 px-2 text-[12px] hover:bg-muted/60 data-[state=open]:bg-muted/60 font-normal",children:[e.jsx("span",{className:"text-muted-foreground",children:ur(d)}),e.jsx("span",{className:"text-foreground/90",children:$.label})]})}),e.jsxs(ts,{align:"end",className:"w-48",children:[e.jsx(ra,{className:"text-[11px] font-normal text-muted-foreground",children:"AI 编码工具"}),Sl.map(C=>e.jsxs(Re,{className:"gap-2 text-[12px]",onClick:()=>w(C.key),children:[ur(C.key),e.jsx("span",{className:"flex-1",children:C.label})]},C.key)),e.jsx(Mt,{}),e.jsx(ra,{className:"text-[11px] font-normal text-muted-foreground",children:"本地编辑器"}),Cl.map(C=>e.jsxs(Re,{className:"gap-2 text-[12px]",onClick:()=>w(C.key),children:[ur(C.key),e.jsx("span",{className:"flex-1",children:C.label})]},C.key))]})]})]}),e.jsx("div",{className:"h-3 w-px bg-border/60"}),e.jsx(te,{variant:"ghost",size:"icon-sm",className:"h-7 w-7 rounded-md text-muted-foreground hover:text-foreground",onClick:s,"aria-label":"关闭",children:e.jsx(as,{className:"h-4 w-4"})})]})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-5 py-6",children:e.jsx("div",{className:"space-y-8",children:Array.from(u.entries()).map(([C,K])=>e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"px-2",children:e.jsx("span",{className:"text-[12px] font-medium text-muted-foreground/70 tracking-wide",children:C})}),e.jsx("div",{className:"space-y-1",children:K.map(y=>{const P=o===y.id,R=l.has(y.id);return e.jsxs("div",{className:"group flex flex-col sm:flex-row sm:items-center justify-between gap-4 rounded-xl px-3 py-2.5 hover:bg-muted/40 transition-colors border border-transparent hover:border-border/30",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[13px] font-medium text-foreground/90",children:y.titleZh}),y.slashCommand&&e.jsx("span",{className:"rounded bg-muted/60 px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground/70",children:y.slashCommand})]}),e.jsx("div",{className:"mt-1 text-[12px] text-muted-foreground/75 leading-relaxed",children:y.description})]}),e.jsxs("div",{className:"shrink-0 flex items-center gap-1.5 md:opacity-0 md:group-hover:opacity-100 transition-opacity",children:[e.jsxs("button",{type:"button",className:"inline-flex h-7 items-center justify-center gap-1.5 rounded-md px-3 text-[12px] font-medium text-muted-foreground transition-colors hover:bg-secondary/80 hover:text-foreground",onClick:()=>void D(y),children:[e.jsx(ss,{className:"h-3 w-3"}),"执行"]}),e.jsxs("button",{type:"button",className:"inline-flex h-7 min-w-[76px] items-center justify-center gap-1.5 rounded-md bg-secondary/40 px-3 text-[12px] font-medium text-foreground transition-colors hover:bg-secondary/80 disabled:pointer-events-none disabled:opacity-50",disabled:P,onClick:()=>void v(y),children:[P?e.jsx(gt,{className:"h-3 w-3 animate-spin"}):R?e.jsx(Fn,{className:"h-3 w-3"}):e.jsx(Ds,{className:"h-3 w-3"}),P?"安装中":R?"已安装":"安装"]})]})]},y.id)})})]},C))})})]})})}const Tr=be.forwardRef(({className:t,children:s,...n},a)=>e.jsxs(Bi,{ref:a,className:fe("relative overflow-hidden",t),...n,children:[e.jsx(Dc,{className:"h-full w-full rounded-[inherit]",children:s}),e.jsx(kl,{}),e.jsx(Ac,{})]}));Tr.displayName=Bi.displayName;const kl=be.forwardRef(({className:t,orientation:s="vertical",...n},a)=>e.jsx(Wi,{ref:a,orientation:s,className:fe("flex touch-none select-none transition-colors",s==="vertical"&&"h-full w-2 border-l border-l-transparent p-[1px]",s==="horizontal"&&"h-2 flex-col border-t border-t-transparent p-[1px]",t),...n,children:e.jsx(Rc,{className:"relative flex-1 rounded-full bg-border"})}));kl.displayName=Wi.displayName;function Hm({handleOpenProjectInIDE:t,preferredIDE:s,onPreferredIDEChange:n}){const[a,o]=r.useState(!1),i=s||Mn[0].value,l=j=>j==="cursor"?e.jsx(na,{size:14,color:"currentColor"}):j==="trae"||j==="trae_cn"?e.jsx(sa,{size:14,color:"currentColor"}):j==="windsurf"?e.jsx(Or,{size:14,color:"currentColor"}):j==="vscode"?e.jsx(_r,{size:14,color:"currentColor"}):j==="antigravity"?e.jsx(Ua,{size:14,color:"currentColor"}):j==="kiro"?e.jsx($r,{size:14,color:"currentColor"}):j==="qoder"?e.jsx(Fa,{size:14,color:"currentColor"}):e.jsx(hi,{className:"h-3.5 w-3.5"}),c=async j=>{var C,K,y;const $=await fetch("/api/config");if(!$.ok)throw new Error("加载配置失败,无法保存主力 IDE");const v=await $.json(),D={...v,server:{host:((C=v==null?void 0:v.server)==null?void 0:C.host)||"localhost",allowLAN:((K=v==null?void 0:v.server)==null?void 0:K.allowLAN)!==!1,enableCommandAPI:((y=v==null?void 0:v.server)==null?void 0:y.enableCommandAPI)||!1},automation:{...(v==null?void 0:v.automation)||{},defaultIDE:j}},u=await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(D)});if(!u.ok){const P=await u.json().catch(()=>({}));throw new Error((P==null?void 0:P.error)||"保存主力 IDE 失败")}n==null||n(j)},d=async j=>{if(!a){o(!0);try{if(!await Promise.resolve(t(j)))return;try{await c(j)}catch(v){H.warning((v==null?void 0:v.message)||"保存主力 IDE 失败")}}finally{o(!1)}}},w=()=>{d(i)};return e.jsxs(us,{children:[e.jsxs("div",{className:"inline-flex items-center h-6 shrink-0 rounded-md border border-border/60 overflow-hidden bg-background",children:[e.jsxs(te,{type:"button",variant:"ghost",size:"sm",className:"gap-1 h-6 px-2 leading-none rounded-none border-0 shadow-none",onClick:w,disabled:a,children:[a?e.jsx(gt,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx("span",{className:"text-foreground",children:l(i)}),e.jsx("span",{children:"打开"})]}),e.jsx(ms,{asChild:!0,children:e.jsx(te,{type:"button",variant:"ghost",size:"icon",className:"h-6 w-6 rounded-none border-0 border-l border-border/60",disabled:a,"aria-label":"打开菜单",children:e.jsx(en,{className:"h-3 w-3 opacity-70"})})})]}),e.jsxs(ts,{side:"right",align:"start",className:"w-48",children:[e.jsx(ra,{children:"在编辑器中打开"}),e.jsx(Mt,{}),Mn.map(j=>e.jsxs(Re,{onClick:()=>void d(j.value),className:"gap-2",children:[e.jsx("span",{className:"text-foreground",children:l(j.value)}),j.label]},j.value))]})]})}function qm(t,s){if(!t)return s;const n=t.match(/filename\*=UTF-8''([^;]+)/i);if(n!=null&&n[1])try{return decodeURIComponent(n[1])}catch{return n[1]}const a=t.match(/filename="([^"]+)"/i);if(a!=null&&a[1])return a[1];const o=t.match(/filename=([^;]+)/i);return o!=null&&o[1]?o[1].trim():s}async function Zm(t){try{const s=await t.json();if(typeof(s==null?void 0:s.error)=="string"&&s.error.trim())return s.error.trim()}catch{}try{const s=await t.text();if(s.trim())return s.trim()}catch{}return`导出失败(${t.status})`}async function Jm(t){const s=t?`/api/export-html?path=${encodeURIComponent(t)}`:"/api/export-html",n=await fetch(s);if(!n.ok)throw new Error(await Zm(n));const a=t?`${t.split("/").pop()||"export"}-html.zip`:"export-html.zip",o=qm(n.headers.get("Content-Disposition"),a),i=await n.blob(),l=URL.createObjectURL(i);try{const c=document.createElement("a");c.href=l,c.download=o,document.body.appendChild(c),c.click(),document.body.removeChild(c)}finally{setTimeout(()=>URL.revokeObjectURL(l),1e3)}return o}function El(t){return encodeURIComponent(String(t||"").trim())}async function Qm(t){const s=await fetch(`/api/sub-pages?prototype=${El(t)}`,{cache:"no-store"}),n=await s.json().catch(()=>({}));if(!s.ok)throw new Error(n.error||"读取子页面失败");return Array.isArray(n.pages)?n.pages:[]}async function Xm(t,s){const n=await fetch(`/api/sub-pages?prototype=${El(t)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({pages:s})}),a=await n.json().catch(()=>({}));if(!n.ok)throw new Error(a.error||"保存子页面失败");return Array.isArray(a.pages)?a.pages:[]}const on=40;function Yn({title:t,icon:s,suffix:n,actions:a,selected:o=!1,editable:i=!1,editingValue:l="",inputRef:c,paddingLeft:d="8px",className:w,titleClassName:j,draggable:$,beforeIndicator:v=!1,afterIndicator:D=!1,onEditingValueChange:u,onClick:C,onDoubleClick:K,onKeyDown:y,onEditClick:P,onEditBlur:R,onEditKeyDown:L,onDragStart:F,onDragOver:x,onDrop:V,onDragEnd:re}){return e.jsxs("div",{className:"relative",children:[e.jsxs("div",{role:"button",tabIndex:0,className:fe("menu-item-wrapper group flex min-w-0 w-full max-w-full items-center gap-1.5 overflow-hidden rounded-md py-1 pr-2 text-left text-[12px] leading-4 transition-colors",o?"bg-accent text-accent-foreground font-semibold":"text-foreground hover:bg-muted/50",o&&"is-selected",w),style:{paddingLeft:d},draggable:$,onClick:C,onDoubleClick:K,onKeyDown:y,onDragStart:F,onDragOver:x,onDrop:V,onDragEnd:re,children:[s?e.jsx("div",{className:"shrink-0 text-muted-foreground/80",children:s}):null,i?e.jsx("input",{ref:c,value:l,onChange:B=>u==null?void 0:u(B.target.value),onClick:P,onBlur:R,onKeyDown:L,maxLength:on,className:"ax-inline-rename-input min-w-0 w-0 max-w-full basis-0 flex-1"}):e.jsx("span",{className:fe("block min-w-0 w-0 basis-0 flex-1 truncate pr-1",j),title:t,children:t}),n?e.jsx("div",{className:"flex shrink-0 items-center",children:n}):null,a?e.jsx("div",{className:"flex shrink-0 items-center gap-0.5",children:a}):null]}),v?e.jsx("div",{className:"pointer-events-none absolute left-[-8px] right-[-8px] top-0 z-10 h-[2px] bg-primary"}):null,D?e.jsx("div",{className:"pointer-events-none absolute left-[-8px] right-[-8px] bottom-0 z-10 h-[2px] bg-primary"}):null]})}function Ir(t){return t.map(s=>({...s,children:s.children?Ir(s.children):void 0}))}function Ym(t){const s=[],n=a=>{for(const o of a)o.kind==="folder"&&(s.push(o.id),n(o.children||[]))};return n(t),s}function Pr(t,s){var n;for(let a=0;a<t.length;a+=1){const o=t[a];if(o.id===s)return t.splice(a,1),o;if((n=o.children)!=null&&n.length){const i=Pr(o.children,s);if(i)return i}}return null}function Tl(t,s,n){var a;for(let o=0;o<t.length;o+=1){const i=t[o];if(i.id===s)return t.splice(o,0,n),!0;if((a=i.children)!=null&&a.length&&Tl(i.children,s,n))return!0}return!1}function Il(t,s,n){var a;for(let o=0;o<t.length;o+=1){const i=t[o];if(i.id===s)return t.splice(o+1,0,n),!0;if((a=i.children)!=null&&a.length&&Il(i.children,s,n))return!0}return!1}function Pl(t,s,n){var a;for(const o of t){if(o.id===s&&o.kind==="folder")return Array.isArray(o.children)||(o.children=[]),o.children.push(n),!0;if((a=o.children)!=null&&a.length&&Pl(o.children,s,n))return!0}return!1}function Dl(t,s){let n=!1;const a=[];for(const o of t){if(o.kind==="folder"&&o.id===s){n=!0,Array.isArray(o.children)&&o.children.length>0&&a.push(...o.children);continue}if(o.kind==="folder"&&Array.isArray(o.children)&&o.children.length>0){const i=Dl(o.children,s);i.removed&&(n=!0),a.push({...o,children:i.nextTree});continue}a.push(o)}return{nextTree:a,removed:n}}function Al(t,s){var n;return t.id===s?!0:(n=t.children)!=null&&n.length?t.children.some(a=>Al(a,s)):!1}function ea(t,s){var n;for(const a of t){if(a.id===s)return a;if((n=a.children)!=null&&n.length){const o=ea(a.children,s);if(o)return o}}return null}function Rl(t,s,n){return t.map(a=>{if(a.kind!=="folder")return a;const o=Array.isArray(a.children)?Rl(a.children,s,n):a.children;return a.id===s?{...a,title:n,children:o}:o!==a.children?{...a,children:o}:a})}function eh(t,s,n){const a=s.trim().toLowerCase();if(!a)return t;const o=i=>{const l=[];for(const c of i){const w=n(c).toLowerCase().includes(a);if(c.kind==="folder"){const j=o(c.children||[]);(w||j.length>0)&&l.push({...c,children:j})}else w&&l.push(c)}return l};return o(t)}function mr(t,s,n){if(s===n)return t;const a=t.indexOf(s),o=t.indexOf(n);if(a<0||o<0)return t;const i=[...t],[l]=i.splice(a,1),c=a<o?o-1:o;return i.splice(c,0,l),i}function hr(t,s){const n=t.indexOf(s);if(n<0)return t;const a=[...t],[o]=a.splice(n,1);return a.push(o),a}function th(t,s,n,a){if(s===n)return t;const o=t.indexOf(s),i=t.indexOf(n);if(o<0||i<0)return t;const l=[...t],[c]=l.splice(o,1);let d;return a==="before"?d=o<i?i-1:i:d=o<i?i:i+1,l.splice(Math.max(0,Math.min(d,l.length)),0,c),l}function it(t){return String(t||"").trim().replace(/^\/+/,"").replace(/\/+$/,"").replace(/\/{2,}/g,"/")}function Go(t,s){return`${t}:${it(s)}`}function sh(t,s){return`${t.displayName} - ${s.name} (${it(s.path)}) [src/prototypes/${t.name}/index.tsx]`}function nh(t,s){const n=s.length>0?s.map((a,o)=>`${o+1}. ${a.name} (${it(a.path)})`).join(`
|
||
`):"当前还没有配置任何子页面。";return[`请帮我维护原型 "${t.displayName}" (${t.name}) 的子页面配置。`,"","请严格遵守以下规则:",`1. 子页面配置文件固定为 \`src/prototypes/${t.name}/pages.json\`。`,"2. 文件结构固定为:","{",' "pages": [',' { "name": "子页面名称", "path": "route-path" }'," ]","}","3. `name` 用于 sidebar 展示,`path` 用于 URL 路由,`path` 不能带前导或尾随 `/`。","4. 仅维护 `pages.json` 中的子页面入口顺序、名称和 path,不要改动原型目录名。","5. 如果新增、删除或重命名了子页面,请同步确保 `pages.json` 与原型内部实际路由实现保持一致。","","当前 pages.json 内容:",n].join(`
|
||
`)}function ah(t,s){return[`我刚刚从 \`src/prototypes/${t.name}/pages.json\` 中移除了子页面入口:${s.name} (${it(s.path)})。`,"","请继续帮我处理原型内部与这个子页面相关的实际内容,确保没有残留:",`1. 检查 \`src/prototypes/${t.name}/index.tsx\` 及其引用文件中的路由、导航、状态分支和文案。`,"2. 删除或清理这个子页面对应的视图、跳转入口、mock 数据和无用逻辑。","3. 如果还有其他页面会跳转到这个 path,请一并改为合理的目标。","4. 最后再次核对 `pages.json` 与实际实现保持一致。"].join(`
|
||
`)}function rh({activeTab:t,onTabChange:s,projectTitle:n,onTitleChange:a,tree:o,onTreeChange:i,onTreePersist:l,items:c,selectedItem:d,selectedSubPage:w,onItemClick:j,onSubPageSelect:$,onSearch:v,searchText:D,onCreateFile:u,onCreateResource:C,onCreateDocFile:K,onCreateCanvasFile:y,onCreatePrototypeFromDoc:P,onGenerateThemeFromPrototype:R,onCreateFolder:L,loading:F,handleOpenProjectInIDE:x,preferredIDE:V,onPreferredIDEChange:re,isDarkMode:B,handleRenameItem:xe,handleDuplicateItem:ie,handleCopyItemPath:z,handleVersionManagement:se,handleDownloadItemSource:W,handleDeleteItem:S,onSettingsClick:Y,onWeChatConnect:k,onToggleTheme:N,themes:U,dataTables:A,templates:q,selectedTheme:pe,selectedDataTable:Ne,selectedTemplate:Ce,onOpenThemeInIDE:Ie,onOpenThemeDocInIDE:ve,onRenameTheme:Ue,onDownloadThemeZip:Fe,onDeleteTheme:Oe,onOpenDataTableInIDE:We,onRenameDataTable:E,onDeleteDataTable:ce,onOpenTemplateInIDE:Pe,onRenameTemplate:Ee,onDuplicateTemplate:Te,onDeleteTemplate:Ye,onCopyTemplatePath:nt,onTemplateVersionManagement:Me,resourceSection:b,onResourceSectionChange:he,onSelectTheme:ke,onSelectDataTable:T,onSelectTemplate:Z,onReorderThemes:de,defaultThemeName:J,onSetDefaultTheme:Ae,onReorderDataTables:ze,onReorderTemplates:ue,onShowReadonlyPromptDialog:ne,onRequestTextInputDialog:me}){const je=async m=>{const f=t==="prototype";if(!f&&!(t==="assets")){H.warning("请先选择一个原型或组件");return}const X=`${f?"prototypes":"components"}/${m.name}`,Se=m.displayName||m.name,oe=f?"原型":"组件",Be=H.loading(`正在导出${oe}「${Se}」HTML,时间较长时请耐心等待...`);try{await Jm(X),H.success(`「${Se}」HTML 导出完成,已开始下载`,{id:Be})}catch(jt){H.error((jt==null?void 0:jt.message)||"HTML 导出失败",{id:Be})}},[De,ge]=r.useState(!1),[Ze,dt]=r.useState(!1),[St,Ut]=r.useState(n),wt=r.useRef(null),[Je,tt]=r.useState(!1),st=r.useRef(null),[rs,Kt]=r.useState(new Set),js=r.useRef(new Set),[pt,Rt]=r.useState(null),[yt,Qe]=r.useState(null),[ut,$e]=r.useState(!1),[Ke,mt]=r.useState(null),[os,Ot]=r.useState(""),[Vt,_t]=r.useState(null),[Ft,Lt]=r.useState(""),[is,et]=r.useState(null),[Ss,Ht]=r.useState(""),[qt,at]=r.useState(null),[Qt,Ct]=r.useState(""),[Xt,zt]=r.useState(null),[As,ps]=r.useState(""),[fs,Bt]=r.useState(null),[Us,ls]=r.useState(""),Yt=r.useRef(null),ft=r.useRef(!1),[tn,yn]=r.useState(null),[bn,wn]=r.useState(null),[He,Ns]=r.useState(null),[rt,$t]=r.useState(null),[Rs,jn]=r.useState(null),[xs,sn]=r.useState(null),[Gn,Nn]=r.useState(!1),[vn,Fs]=r.useState(new Set),[gs,Sn]=r.useState({}),[Kn,Cn]=r.useState(new Set),Cs=()=>{requestAnimationFrame(()=>{var f;const m=(f=Yt.current)==null?void 0:f.closest("[data-radix-scroll-area-viewport]");m&&m.scrollLeft!==0&&(m.scrollLeft=0)})},$s=t==="prototype"?"prototypes":t==="document"?"docs":t==="canvas"?"canvas":"components",kn=t!=="assets";r.useEffect(()=>{Ut(n)},[n]),r.useEffect(()=>{Ze&&wt.current&&wt.current.focus()},[Ze]),r.useEffect(()=>{Je&&st.current&&st.current.focus()},[Je]),r.useEffect(()=>{(Ke||Vt||is||qt||Xt||fs)&&Yt.current&&(Yt.current.focus(),Yt.current.select())},[Xt,Ke,Vt,is,fs,qt]),r.useEffect(()=>{const m=Ym(o),f=js.current,ae=m.filter(X=>!f.has(X));js.current=new Set(m),ae.length!==0&&Kt(X=>{const Se=new Set(X);return ae.forEach(oe=>Se.add(oe)),Se})},[o]),r.useEffect(()=>{if(!tn)return;const m=ea(o,tn);!m||m.kind!=="folder"||(qe(m.id,m.title),yn(null))},[tn,o]),r.useEffect(()=>{let m=!1;return fetch("/api/version").then(f=>f.ok?f.json():Promise.reject(new Error("Request failed"))).then(f=>{m||wn(typeof(f==null?void 0:f.version)=="string"?f.version:null)}).catch(()=>{m||wn(null)}),()=>{m=!0}},[]);const Os=r.useMemo(()=>{const m=new Map;for(const f of c)m.set(`${$s}/${f.name}`,f);return m},[c,$s]),p=m=>{if(m.kind==="item"&&m.itemKey){const f=Os.get(m.itemKey);if(f)return f.displayName}return m.title},Q=r.useMemo(()=>eh(o,D,m=>{if(m.kind==="item"&&m.itemKey){const f=Os.get(m.itemKey);if(f)return`${m.title} ${f.displayName} ${f.name}`}return m.title}),[kn,o,D,Os]),I=r.useCallback(async(m,f)=>{if(!(f!=null&&f.force)&&Object.prototype.hasOwnProperty.call(gs,m))return gs[m]||[];Cn(ae=>{const X=new Set(ae);return X.add(m),X});try{const ae=await Qm(m);return Sn(X=>({...X,[m]:ae})),ae}catch(ae){return H.error((ae==null?void 0:ae.message)||"读取子页面失败"),[]}finally{Cn(ae=>{const X=new Set(ae);return X.delete(m),X})}},[gs]),_=r.useCallback(async(m,f)=>{const ae=await Xm(m.name,f);return Sn(X=>({...X,[m.name]:ae})),ae},[]),O=r.useCallback(m=>{Fs(f=>{const ae=new Set(f);return ae.has(m.name)?ae.delete(m.name):(ae.add(m.name),Object.prototype.hasOwnProperty.call(gs,m.name)||I(m.name)),ae})},[I,gs]),G=r.useCallback(async(m,f)=>{try{await navigator.clipboard.writeText(sh(m,f)),H.success("子页面路径已复制")}catch{H.error("复制子页面路径失败")}},[]),le=r.useCallback(async m=>{const f=await I(m.name);await(ne==null?void 0:ne({title:`管理原型「${m.displayName}」的子页面`,description:"已整理好 `pages.json` 维护规则,可直接复制给 AI。",prompt:nh(m,f),successMessage:"子页面维护提示词已复制"}))},[I,ne]);r.useCallback(async m=>{if(!me){H.error("当前环境不支持新增子页面");return}const f=await I(m.name),ae=await me({title:`为「${m.displayName}」新增子页面`,description:"先输入 sidebar 中显示的子页面名称。",label:"子页面名称",placeholder:"例如:优惠券详情",confirmText:"下一步",validate:Se=>String(Se||"").trim()?null:"名称不能为空"});if(ae==null)return;const X=await me({title:`设置「${String(ae).trim()}」的路由 path`,description:"path 会拼接在原型 URL 后面,请勿输入前导 `/`。",label:"路由 Path",placeholder:"例如:coupon-detail",defaultValue:it(String(ae).trim().toLowerCase().replace(/\s+/g,"-")),confirmText:"创建",validate:Se=>{const oe=it(Se);return oe?f.some(Be=>it(Be.path)===oe)?"该 path 已存在":null:"path 不能为空"}});if(X!=null)try{const Se=[...f,{name:String(ae).trim(),path:it(X)}],oe=await _(m,Se);Fs(jt=>{const Ws=new Set(jt);return Ws.add(m.name),Ws});const Be=oe[oe.length-1];Be&&($==null||$(m,Be)),H.success("子页面已创建")}catch(Se){H.error((Se==null?void 0:Se.message)||"创建子页面失败")}},[I,me,$,_]);const ye=r.useCallback((m,f)=>{mt(null),Ot(""),_t(null),Lt(""),at(null),Ct(""),zt(null),ps(""),Bt(null),ls(""),et(Go(m.name,f.path)),Ht(f.name)},[]),_e=r.useCallback(()=>{et(null),Ht(""),Cs()},[]),ht=r.useCallback(async(m,f)=>{const ae=String(Ss||"").trim().slice(0,on);if(!ae||ae===f.name){_e();return}try{const Se=(await I(m.name)).map(jt=>it(jt.path)===it(f.path)?{...jt,name:ae}:jt),Be=(await _(m,Se)).find(jt=>it(jt.path)===it(f.path));Be&&w&&it(w.path)===it(f.path)&&($==null||$(m,Be)),H.success("子页面已重命名")}catch(X){H.error((X==null?void 0:X.message)||"重命名子页面失败")}finally{_e()}},[Ss,_e,I,$,_,w]),xt=r.useCallback((m,f)=>{const ae=m.getBoundingClientRect();return f-ae.top<ae.height/2?"before":"after"},[]),g=r.useCallback(async(m,f,ae,X)=>{const Se=await I(m.name),oe=Se.map(Nt=>it(Nt.path)),Be=th(oe,it(f),it(ae),X);if(Be.join("||")===oe.join("||"))return;const jt=new Map(Se.map(Nt=>[it(Nt.path),Nt])),Ws=Be.map(Nt=>jt.get(Nt)).filter(Nt=>!!Nt);try{await _(m,Ws)}catch(Nt){H.error((Nt==null?void 0:Nt.message)||"调整子页面顺序失败")}},[I,_]),h=r.useCallback(async(m,f)=>{try{const X=(await I(m.name)).filter(Se=>it(Se.path)!==it(f.path));await _(m,X),X.length===0&&Fs(Se=>{const oe=new Set(Se);return oe.delete(m.name),oe}),w&&it(w.path)===it(f.path)&&j(m),await(ne==null?void 0:ne({title:`已移除子页面入口:${f.name}`,description:"入口已经从 `pages.json` 中删除,下面的提示词可继续交给 AI 清理实际实现。",prompt:ah(m,f),successMessage:"删除子页面后的处理提示词已复制"})),H.success("子页面入口已移除")}catch(ae){H.error((ae==null?void 0:ae.message)||"删除子页面失败")}},[I,j,ne,_,w]);r.useEffect(()=>{t!=="prototype"||!(d!=null&&d.name)||!w||(I(d.name),Fs(m=>{const f=new Set(m);return f.add(d.name),f}))},[t,I,d,w]);const M=async()=>{const m=St.trim();if(!m){Ut(n),dt(!1);return}await Promise.resolve(a(m)),dt(!1)},ee=async m=>{m.key==="Enter"?await M():m.key==="Escape"&&(Ut(n),dt(!1))},we=()=>{tt(!Je),Je&&v("")},Ge=m=>{Kt(f=>{const ae=new Set(f);return ae.has(m)?ae.delete(m):ae.add(m),ae})},qe=(m,f)=>{Kt(ae=>{const X=new Set(ae);return X.add(m),X}),mt(m),Ot(f),_t(null),Lt(""),et(null),Ht(""),at(null),Ct(""),zt(null),ps(""),Bt(null),ls("")},Le=(m,f)=>{_t(m),Lt(f),mt(null),Ot(""),et(null),Ht(""),at(null),Ct(""),zt(null),ps(""),Bt(null),ls("")},Ve=()=>{mt(null),Ot(""),Cs()},Xe=()=>{_t(null),Lt(""),Cs()},Wt=async()=>{if(!Ke)return;const m=ea(o,Ke);if(!m||m.kind!=="folder"){Ve();return}const f=os.trim().slice(0,on);if(!f||f===m.title){Ve();return}const ae=Rl(o,Ke,f);i(ae),await Promise.resolve(l(ae)),Ve()},ys=async()=>{if(!(t!=="prototype"&&t!=="document"||ut)){$e(!0);try{const f=await L(t==="prototype"?"prototypes":"docs");f!=null&&f.createdFolderId&&yn(f.createdFolderId)}finally{$e(!1)}}},ks=async()=>{if(!Vt)return;const m=ea(o,Vt);if(!m||!m.itemKey){Xe();return}const f=Os.get(m.itemKey);if(!f){Xe();return}const ae=Ft.trim().slice(0,on),X=f.displayName||f.name;if(!ae||ae===X){Xe();return}await Promise.resolve(xe(f,ae)),Xe()},Vn=m=>{mt(null),Ot(""),_t(null),Lt(""),et(null),Ht(""),at(null),Ct(""),zt(null),ps(""),Bt(m.name),ls(m.displayName||m.name)},Hn=m=>{mt(null),Ot(""),_t(null),Lt(""),et(null),Ht(""),zt(null),ps(""),Bt(null),ls(""),at(m.name),Ct(m.displayName||m.name)},zs=()=>{at(null),Ct(""),Cs()},qn=async()=>{if(!qt){zs();return}const m=U.find(X=>X.name===qt);if(!m){zs();return}const f=Qt.trim().slice(0,on),ae=m.displayName||m.name;if(!f||f===ae){zs();return}await Promise.resolve(Ue(m,f)),zs()},ct=m=>{mt(null),Ot(""),_t(null),Lt(""),et(null),Ht(""),at(null),Ct(""),Bt(null),ls(""),zt(m.fileName),ps(m.tableName)},ot=()=>{zt(null),ps(""),Cs()},Gt=async()=>{if(!Xt){ot();return}const m=A.find(X=>X.fileName===Xt);if(!m){ot();return}const f=As.trim().slice(0,on),ae=m.tableName;if(!f||f===ae){ot();return}await Promise.resolve(E(m,f)),ot()},cs=()=>{Bt(null),ls(""),Cs()},Es=async()=>{if(!fs){cs();return}const m=q.find(X=>X.name===fs);if(!m){cs();return}const f=Us.trim().slice(0,on),ae=m.displayName||m.name;if(!f||f===ae){cs();return}await Promise.resolve(Ee(m,f)),cs()},Bs=(m,f,ae)=>{const X=f.getBoundingClientRect(),Se=ae-X.top;return m.kind==="folder"?Se<X.height*.3?"before":Se>X.height*.7?"after":"inside":Se<X.height/2?"before":"after"},Ts=async(m,f)=>{if(!pt||pt===m.id)return;const ae=Ir(o),X=Pr(ae,pt);if(!X||X.kind==="folder"&&Al(X,m.id))return;const Se=ea(ae,m.id);if(!Se){ae.push(X),i(ae),await Promise.resolve(l(ae));return}let oe=!1;f==="inside"&&Se.kind==="folder"?oe=Pl(ae,Se.id,X):f==="before"?oe=Tl(ae,Se.id,X):oe=Il(ae,Se.id,X),oe||ae.push(X),i(ae),await Promise.resolve(l(ae))},da=async()=>{if(!pt)return;const m=Ir(o),f=Pr(m,pt);f&&(m.push(f),i(m),await Promise.resolve(l(m)))},Va=async m=>{const f=Dl(o,m);f.removed&&(i(f.nextTree),await Promise.resolve(l(f.nextTree)))},Ll=(m,f)=>{const ae=$s==="docs",X=$s==="prototypes";return e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"icon",className:fe("more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",X&&"prototype-row-action"),onClick:Se=>Se.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"更多操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-48 text-sm",children:[ae?e.jsxs(Re,{onClick:()=>P(m),children:[e.jsx(dn,{className:"mr-2 h-4 w-4"}),"创建原型"]}):null,e.jsxs(Re,{onClick:()=>Le(f,m.displayName||m.name),children:[e.jsx(rn,{className:"mr-2 h-4 w-4"}),"重命名"]}),e.jsxs(Re,{onClick:()=>ie(m),children:[e.jsx(ss,{className:"mr-2 h-4 w-4"}),"创建副本"]}),e.jsxs(Re,{onClick:()=>z(m),children:[e.jsx(un,{className:"mr-2 h-4 w-4"}),"复制路径"]}),X?e.jsxs(Re,{onClick:()=>void le(m),children:[e.jsx(co,{className:"mr-2 h-4 w-4"}),"管理子页面"]}):null,!ae&&R?e.jsxs(Re,{onClick:()=>R(m),children:[e.jsx(Wc,{className:"mr-2 h-4 w-4"}),"生成主题"]}):null,e.jsx(Mt,{}),e.jsxs(Re,{onClick:()=>se(m),children:[e.jsx(gr,{className:"mr-2 h-4 w-4"}),"版本管理"]}),ae?null:e.jsxs(e.Fragment,{children:[e.jsxs(Re,{onClick:()=>W(m),children:[e.jsx(Ds,{className:"mr-2 h-4 w-4"}),"导出 ZIP"]}),e.jsxs(Re,{onClick:()=>{je(m)},children:[e.jsx(pn,{className:"mr-2 h-4 w-4"}),"导出 HTML"]})]}),e.jsx(Mt,{}),e.jsxs(Re,{onClick:()=>S(m),className:"text-destructive focus:text-destructive",children:[e.jsx(_s,{className:"mr-2 h-4 w-4"}),"删除"]})]})]})},Ml=m=>e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"icon",className:"more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",onClick:f=>f.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"文件夹操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-40 text-sm",children:[e.jsxs(Re,{onClick:()=>qe(m.id,m.title),children:[e.jsx(rn,{className:"mr-2 h-4 w-4"}),"重命名"]}),e.jsxs(Re,{onClick:()=>void Va(m.id),className:"text-destructive focus:text-destructive",children:[e.jsx(_s,{className:"mr-2 h-4 w-4"}),"删除"]})]})]}),Ul=(m,f)=>e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"icon",className:"more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",onClick:ae=>ae.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"子页面操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-44 text-sm",children:[e.jsxs(Re,{onClick:()=>ye(m,f),children:[e.jsx(rn,{className:"mr-2 h-4 w-4"}),"重命名"]}),e.jsxs(Re,{onClick:()=>void G(m,f),children:[e.jsx(un,{className:"mr-2 h-4 w-4"}),"复制路径"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"text-destructive focus:text-destructive",onClick:()=>void h(m,f),children:[e.jsx(_s,{className:"mr-2 h-4 w-4"}),"删除"]})]})]}),Fl=(m,f)=>{if(t!=="prototype"||!vn.has(m.name))return null;const ae=gs[m.name]||[],X=Kn.has(m.name),Se=`${24+f*8}px`;return e.jsxs("div",{className:"space-y-0.5",children:[X?e.jsx("div",{className:"px-2 py-1 text-[11px] text-muted-foreground",style:{paddingLeft:Se},children:"正在加载子页面..."}):null,ae.map(oe=>{const Be=Go(m.name,oe.path),jt=is===Be,Ws=!!((d==null?void 0:d.name)===m.name&&w&&it(w.path)===it(oe.path)),Nt=!!(xs&&xs.prototypeName===m.name&&it(xs.path)===it(oe.path)&&xs.placement==="before"),ma=!!(xs&&xs.prototypeName===m.name&&it(xs.path)===it(oe.path)&&xs.placement==="after");return e.jsx(Yn,{title:oe.name,icon:e.jsx(mo,{className:"h-3.5 w-3.5 text-muted-foreground/60"}),actions:Ul(m,oe),selected:Ws,editable:jt,editingValue:Ss,inputRef:Yt,paddingLeft:Se,className:"cursor-pointer",draggable:!jt,beforeIndicator:Nt,afterIndicator:ma,onEditingValueChange:Ht,onClick:()=>$==null?void 0:$(m,oe),onDoubleClick:bt=>{bt.stopPropagation(),ye(m,oe)},onDragStart:bt=>{bt.dataTransfer.effectAllowed="move",bt.dataTransfer.setData("text/plain",Be),jn({prototypeName:m.name,path:it(oe.path)})},onDragOver:bt=>{if(!Rs||Rs.prototypeName!==m.name)return;bt.preventDefault(),bt.stopPropagation();const nn=xt(bt.currentTarget,bt.clientY);sn(Gs=>{const En={prototypeName:m.name,path:it(oe.path),placement:nn};return(Gs==null?void 0:Gs.prototypeName)===En.prototypeName&&Gs.path===En.path&&Gs.placement===En.placement?Gs:En})},onDrop:bt=>{if(!Rs||Rs.prototypeName!==m.name)return;bt.preventDefault(),bt.stopPropagation();const nn=xt(bt.currentTarget,bt.clientY);sn(null),g(m,Rs.path,oe.path,nn)},onDragEnd:()=>{jn(null),sn(null)},onEditClick:bt=>bt.stopPropagation(),onEditBlur:()=>{if(ft.current){ft.current=!1;return}ht(m,oe)},onEditKeyDown:bt=>{if(bt.key==="Enter"){bt.preventDefault(),ht(m,oe);return}bt.key==="Escape"&&(bt.preventDefault(),ft.current=!0,_e())}},Be)})]})},eo=(m,f=0)=>m.map(X=>{var oo;const Se=X.kind==="folder",oe=rs.has(X.id),Be=X.kind==="item"&&X.itemKey&&Os.get(X.itemKey)||null,jt=!!(Be&&(d==null?void 0:d.name)===Be.name&&!w),Ws=p(X),Nt=Se&&Ke===X.id,ma=!Se&&Vt===X.id,nn=Nt||ma,Gs=`${8+f*8}px`,En=Be?gs[Be.name]||[]:[],Gl=!!(Be&&Object.prototype.hasOwnProperty.call(gs,Be.name)),Kl=!!(Be&&(Gl?En.length>0:Be.hasSubPages)),Vl=!!(t==="prototype"&&Be&&Kl),Hl=!!(Be&&vn.has(Be.name));let Ja,ro=null;Se?Ja=e.jsx(te,{type:"button",variant:"ghost",size:"icon-xs",className:"h-4 w-4 shrink-0 p-0 text-muted-foreground hover:text-foreground",onClick:lt=>{lt.stopPropagation(),Ge(X.id)},children:oe?e.jsx(Gc,{className:"h-4 w-4"}):e.jsx(Kc,{className:"h-4 w-4"})}):(Ja=e.jsx(mo,{className:"h-3.5 w-3.5"}),Vl&&(ro=e.jsx(te,{type:"button",variant:"ghost",size:"icon-xs",className:"prototype-row-action h-4 w-4 shrink-0 p-0 text-muted-foreground hover:text-foreground",onClick:lt=>{lt.stopPropagation(),Be&&O(Be)},children:e.jsx(ni,{className:fe("h-3.5 w-3.5 transition-transform",Hl&&"rotate-90")})})));let Qa=null;return Se?Qa=Ml(X):Be&&(Qa=Ll(Be,X.id)),e.jsxs("div",{className:"relative",children:[e.jsx(Yn,{title:Ws,icon:Ja,suffix:ro,actions:Qa,selected:jt,editable:nn,editingValue:Nt?os:Ft,inputRef:Yt,paddingLeft:Gs,className:fe(Se?"cursor-default":"cursor-pointer",(yt==null?void 0:yt.id)===X.id&&yt.placement==="inside"&&"bg-primary/10 text-foreground"),draggable:!nn,beforeIndicator:(yt==null?void 0:yt.id)===X.id&&yt.placement==="before",afterIndicator:(yt==null?void 0:yt.id)===X.id&&yt.placement==="after",onEditingValueChange:lt=>{ma?Lt(lt):Nt?Ot(lt):Lt(lt)},onClick:()=>{if(!nn){if(Se){Ge(X.id);return}Be&&j(Be)}},onDoubleClick:lt=>{if(lt.stopPropagation(),Se){qe(X.id,X.title);return}Be&&Le(X.id,Be.displayName||Be.name)},onDragStart:lt=>{lt.dataTransfer.effectAllowed="move",lt.dataTransfer.setData("text/plain",X.id),Rt(X.id)},onDragEnd:()=>{Rt(null),Qe(null)},onDragOver:lt=>{if(!pt)return;lt.preventDefault(),lt.stopPropagation();const ha=Bs(X,lt.currentTarget,lt.clientY);Qe(Zn=>(Zn==null?void 0:Zn.id)===X.id&&Zn.placement===ha?Zn:{id:X.id,placement:ha})},onDrop:lt=>{lt.preventDefault(),lt.stopPropagation();const ha=Bs(X,lt.currentTarget,lt.clientY);Qe(null),Ts(X,ha)},onEditClick:lt=>lt.stopPropagation(),onEditBlur:()=>{if(ft.current){ft.current=!1;return}Nt?Wt():ks()},onEditKeyDown:lt=>{if(lt.key==="Enter"){lt.preventDefault(),Nt?Wt():ks();return}lt.key==="Escape"&&(lt.preventDefault(),ft.current=!0,Nt?Ve():Xe())}}),Se&&oe&&(((oo=X.children)==null?void 0:oo.length)||0)>0?eo(X.children||[],f+1):null,!Se&&Be?Fl(Be,f+1):null]},X.id)}),to=()=>F?e.jsx("div",{className:"py-8 text-center text-[12px] text-muted-foreground",children:"加载中..."}):Q.length===0?e.jsx("div",{className:"py-8 text-center text-[12px] text-muted-foreground",children:"暂无内容"}):e.jsx("div",{className:"space-y-0.5 w-full min-w-0",onDragOver:m=>{pt&&m.target===m.currentTarget&&(m.preventDefault(),Qe(null))},onDrop:m=>{pt&&m.target===m.currentTarget&&(m.preventDefault(),Qe(null),da())},children:eo(Q)}),so=r.useMemo(()=>{let m=U;if(D.trim()){const f=D.trim().toLowerCase();m=m.filter(ae=>ae.displayName.toLowerCase().includes(f)||ae.name.toLowerCase().includes(f))}return J&&(m=[...m].sort((f,ae)=>f.name===J?-1:ae.name===J?1:0)),m},[U,D,J]),no=r.useMemo(()=>{if(!D.trim())return A;const m=D.trim().toLowerCase();return A.filter(f=>f.tableName.toLowerCase().includes(m)||f.fileName.toLowerCase().includes(m))},[A,D]),ao=r.useMemo(()=>{if(!D.trim())return q;const m=D.trim().toLowerCase();return q.filter(f=>f.displayName.toLowerCase().includes(m)||f.name.toLowerCase().includes(m))},[q,D]),Ha=async(m,f)=>{if(!(!He||He.section!==m)&&He.key!==f)if(m==="themes"){const ae=U.map(Se=>Se.name),X=mr(ae,He.key,f);await Promise.resolve(de(X))}else if(m==="data"){const ae=A.map(Se=>Se.fileName),X=mr(ae,He.key,f);await Promise.resolve(ze(X))}else{const ae=q.map(Se=>Se.name),X=mr(ae,He.key,f);await Promise.resolve(ue(X))}},qa=async m=>{if(!(!He||He.section!==m))if(m==="themes"){const f=U.map(X=>X.name),ae=hr(f,He.key);await Promise.resolve(de(ae))}else if(m==="data"){const f=A.map(X=>X.fileName),ae=hr(f,He.key);await Promise.resolve(ze(ae))}else{const f=q.map(X=>X.name),ae=hr(f,He.key);await Promise.resolve(ue(ae))}},zl=m=>e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{type:"button",variant:"ghost",size:"icon",className:"more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",onPointerDown:f=>f.stopPropagation(),onClick:f=>f.stopPropagation(),onKeyDown:f=>f.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"主题更多操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-48 text-sm",onCloseAutoFocus:f=>f.preventDefault(),children:[e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void Ie(m),children:[e.jsx(dn,{className:"h-3.5 w-3.5"}),"在编辑器中打开"]}),m.hasDoc?e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void ve(m),children:[e.jsx(hn,{className:"h-3.5 w-3.5"}),"打开规范文档"]}):null,e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void(Ae==null?void 0:Ae(m.name)),children:[e.jsx(Bc,{className:"h-3.5 w-3.5"}),J===m.name?"取消默认主题":"设为默认主题"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>Hn(m),children:[e.jsx(rn,{className:"h-3.5 w-3.5"}),"重命名"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void Fe(m),children:[e.jsx(Ds,{className:"h-3.5 w-3.5"}),"导出 ZIP"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm text-destructive focus:text-destructive",onClick:()=>void Oe(m),children:[e.jsx(_s,{className:"h-3.5 w-3.5"}),"删除主题"]})]})]}),Bl=m=>e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{type:"button",variant:"ghost",size:"icon",className:"more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",onPointerDown:f=>f.stopPropagation(),onClick:f=>f.stopPropagation(),onKeyDown:f=>f.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"数据表更多操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-44 text-sm",onCloseAutoFocus:f=>f.preventDefault(),children:[e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void We(m),children:[e.jsx(dn,{className:"h-3.5 w-3.5"}),"在编辑器中打开"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>ct(m),children:[e.jsx(rn,{className:"h-3.5 w-3.5"}),"重命名"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm text-destructive focus:text-destructive",onClick:()=>void ce(m),children:[e.jsx(_s,{className:"h-3.5 w-3.5"}),"删除数据表"]})]})]}),Wl=m=>e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"icon",className:"more-btn h-5 w-5 shrink-0 text-muted-foreground hover:text-foreground",onClick:f=>f.stopPropagation(),children:[e.jsx(Tn,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"sr-only",children:"模板更多操作"})]})}),e.jsxs(ts,{side:"right",align:"start",className:"w-44 text-sm",onCloseAutoFocus:f=>f.preventDefault(),children:[e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void Pe(m),children:[e.jsx(dn,{className:"h-3.5 w-3.5"}),"在编辑器中打开"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>Vn(m),children:[e.jsx(rn,{className:"h-3.5 w-3.5"}),"重命名"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void Te(m),children:[e.jsx(ss,{className:"h-3.5 w-3.5"}),"创建副本"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void nt(m),children:[e.jsx(un,{className:"h-3.5 w-3.5"}),"复制路径"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>void Me(m),children:[e.jsx(gr,{className:"h-3.5 w-3.5"}),"版本管理"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm text-destructive focus:text-destructive",onClick:()=>void Ye(m),children:[e.jsx(_s,{className:"h-3.5 w-3.5"}),"删除模板"]})]})]}),Za=m=>m==="themes"?so.length===0?e.jsx("div",{className:"py-6 text-center text-[12px] text-muted-foreground",children:"暂无主题"}):e.jsxs("div",{className:"space-y-0.5",onDragOver:f=>{!He||He.section!=="themes"||f.target===f.currentTarget&&(f.preventDefault(),$t({section:"themes",key:"__end__",placement:"end"}))},onDrop:f=>{!He||He.section!=="themes"||f.target===f.currentTarget&&(f.preventDefault(),$t(null),qa("themes"))},children:[so.map(f=>{const ae=(pe==null?void 0:pe.name)===f.name,X=qt===f.name,Se=(rt==null?void 0:rt.section)==="themes"&&rt.placement==="before"&&rt.key===f.name;return e.jsx(Yn,{title:f.displayName,suffix:J===f.name?e.jsx("span",{className:"ml-1 flex shrink-0 items-center rounded border border-primary/20 bg-primary/10 px-1 text-[10px] leading-[16px] text-primary",children:"默认"}):void 0,actions:zl(f),selected:ae,editable:X,editingValue:Qt,inputRef:Yt,className:"cursor-pointer",draggable:!X,beforeIndicator:Se,onDragStart:oe=>{oe.dataTransfer.effectAllowed="move",oe.dataTransfer.setData("text/plain",f.name),Ns({section:"themes",key:f.name})},onDragOver:oe=>{!He||He.section!=="themes"||(oe.preventDefault(),oe.stopPropagation(),$t({section:"themes",key:f.name,placement:"before"}))},onDrop:oe=>{!He||He.section!=="themes"||(oe.preventDefault(),oe.stopPropagation(),$t(null),Ha("themes",f.name))},onDragEnd:()=>{Ns(null),$t(null)},onClick:()=>{X||ke(f)},onDoubleClick:oe=>{oe.stopPropagation(),Hn(f)},onKeyDown:oe=>{(oe.key==="Enter"||oe.key===" ")&&(oe.preventDefault(),ke(f))},onEditingValueChange:Ct,onEditClick:oe=>oe.stopPropagation(),onEditBlur:()=>{if(ft.current){ft.current=!1;return}qn()},onEditKeyDown:oe=>{if(oe.key==="Enter"){oe.preventDefault(),qn();return}oe.key==="Escape"&&(oe.preventDefault(),ft.current=!0,zs())}},f.name)}),(rt==null?void 0:rt.section)==="themes"&&rt.placement==="end"?e.jsx("div",{className:"pointer-events-none relative h-0",children:e.jsx("div",{className:"absolute left-[-8px] right-[-8px] top-0 h-[2px] bg-primary z-10"})}):null]}):m==="data"&&no.length===0?e.jsx("div",{className:"py-6 text-center text-[12px] text-muted-foreground",children:"暂无数据表"}):m==="data"?e.jsxs("div",{className:"space-y-0.5",onDragOver:f=>{!He||He.section!=="data"||f.target===f.currentTarget&&(f.preventDefault(),$t({section:"data",key:"__end__",placement:"end"}))},onDrop:f=>{!He||He.section!=="data"||f.target===f.currentTarget&&(f.preventDefault(),$t(null),qa("data"))},children:[no.map(f=>{const ae=(Ne==null?void 0:Ne.fileName)===f.fileName,X=Xt===f.fileName,Se=(rt==null?void 0:rt.section)==="data"&&rt.placement==="before"&&rt.key===f.fileName;return e.jsx(Yn,{title:f.tableName,actions:Bl(f),selected:ae,editable:X,editingValue:As,inputRef:Yt,className:"cursor-pointer",draggable:!X,beforeIndicator:Se,onDragStart:oe=>{oe.dataTransfer.effectAllowed="move",oe.dataTransfer.setData("text/plain",f.fileName),Ns({section:"data",key:f.fileName})},onDragOver:oe=>{!He||He.section!=="data"||(oe.preventDefault(),oe.stopPropagation(),$t({section:"data",key:f.fileName,placement:"before"}))},onDrop:oe=>{!He||He.section!=="data"||(oe.preventDefault(),oe.stopPropagation(),$t(null),Ha("data",f.fileName))},onDragEnd:()=>{Ns(null),$t(null)},onClick:()=>{X||T(f)},onDoubleClick:oe=>{oe.stopPropagation(),ct(f)},onKeyDown:oe=>{(oe.key==="Enter"||oe.key===" ")&&(oe.preventDefault(),T(f))},onEditingValueChange:ps,onEditClick:oe=>oe.stopPropagation(),onEditBlur:()=>{if(ft.current){ft.current=!1;return}Gt()},onEditKeyDown:oe=>{if(oe.key==="Enter"){oe.preventDefault(),Gt();return}oe.key==="Escape"&&(oe.preventDefault(),ft.current=!0,ot())}},f.fileName)}),(rt==null?void 0:rt.section)==="data"&&rt.placement==="end"?e.jsx("div",{className:"pointer-events-none relative h-0",children:e.jsx("div",{className:"absolute left-[-8px] right-[-8px] top-0 h-[2px] bg-primary z-10"})}):null]}):ao.length===0?e.jsx("div",{className:"py-6 text-center text-[12px] text-muted-foreground",children:"暂无模板"}):e.jsxs("div",{className:"space-y-0.5",onDragOver:f=>{!He||He.section!=="templates"||f.target===f.currentTarget&&(f.preventDefault(),$t({section:"templates",key:"__end__",placement:"end"}))},onDrop:f=>{!He||He.section!=="templates"||f.target===f.currentTarget&&(f.preventDefault(),$t(null),qa("templates"))},children:[ao.map(f=>{const ae=(Ce==null?void 0:Ce.name)===f.name,X=fs===f.name,Se=(rt==null?void 0:rt.section)==="templates"&&rt.placement==="before"&&rt.key===f.name;return e.jsx(Yn,{title:f.displayName,actions:Wl(f),selected:ae,editable:X,editingValue:Us,inputRef:Yt,className:"cursor-pointer",draggable:!X,beforeIndicator:Se,onDragStart:oe=>{oe.dataTransfer.effectAllowed="move",oe.dataTransfer.setData("text/plain",f.name),Ns({section:"templates",key:f.name})},onDragOver:oe=>{!He||He.section!=="templates"||(oe.preventDefault(),oe.stopPropagation(),$t({section:"templates",key:f.name,placement:"before"}))},onDrop:oe=>{!He||He.section!=="templates"||(oe.preventDefault(),oe.stopPropagation(),$t(null),Ha("templates",f.name))},onDragEnd:()=>{Ns(null),$t(null)},onClick:()=>{X||Z(f)},onDoubleClick:oe=>{oe.stopPropagation(),Vn(f)},onKeyDown:oe=>{(oe.key==="Enter"||oe.key===" ")&&(oe.preventDefault(),Z(f))},onEditingValueChange:ls,onEditClick:oe=>oe.stopPropagation(),onEditBlur:()=>{if(ft.current){ft.current=!1;return}Es()},onEditKeyDown:oe=>{if(oe.key==="Enter"){oe.preventDefault(),Es();return}oe.key==="Escape"&&(oe.preventDefault(),ft.current=!0,cs())}},f.name)}),(rt==null?void 0:rt.section)==="templates"&&rt.placement==="end"?e.jsx("div",{className:"pointer-events-none relative h-0",children:e.jsx("div",{className:"absolute left-[-8px] right-[-8px] top-0 h-[2px] bg-primary z-10"})}):null]}),ua=(m,f,ae,X,Se,oe)=>{const Be=!De&&b===m;return e.jsxs(Dn,{value:m,className:fe("border-b last:border-b-0 overflow-hidden min-h-0",Be?"flex-1 flex flex-col":"flex-none"),children:[e.jsxs("div",{className:"flex h-8 items-center px-2",children:[e.jsx(An,{className:"h-8 min-w-0 flex-1 items-center justify-start gap-1.5 px-0 py-0 pr-1 text-[12px] font-normal leading-4 hover:no-underline [&>svg]:ml-auto [&>svg]:h-3.5 [&>svg]:w-3.5",children:e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[oe,e.jsx("span",{children:f}),e.jsxs("span",{className:"text-muted-foreground",children:["(",ae,")"]})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{type:"button",variant:"ghost",size:"icon",className:"ml-auto h-8 w-8 shrink-0 self-center text-muted-foreground hover:text-foreground",onClick:jt=>{jt.preventDefault(),jt.stopPropagation(),Se()},"aria-label":`新建${f}`,children:e.jsx(pa,{className:"h-3.5 w-3.5"})})}),e.jsx(It,{children:"新建"})]})})]}),e.jsx(Rn,{className:fe("min-h-0",Be?"flex-1 flex flex-col":""),children:e.jsx(Tr,{className:"ax-scrollarea-hide-chrome flex-1 min-h-0 [&_[data-radix-scroll-area-viewport]]:overflow-x-hidden [&_[data-radix-scroll-area-viewport]>div]:!block [&_[data-radix-scroll-area-viewport]>div]:!w-full [&_[data-radix-scroll-area-viewport]>div]:!min-w-0",children:e.jsx("div",{className:"min-w-0 px-2 pb-2 pt-1",children:X})})})]})};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-col h-full min-h-0 flex-1 bg-background text-[12px]",children:[e.jsxs("div",{className:"border-b",children:[e.jsxs("div",{className:"flex items-center justify-between p-2",children:[e.jsx(vt,{children:e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsxs(te,{variant:"ghost",size:"icon",className:"h-7 w-7 shrink-0",children:[e.jsx($c,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:"更多"})]})}),e.jsxs(ts,{align:"start",className:"text-sm min-w-[132px]",children:[e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:Y,children:[e.jsx(co,{className:"h-3.5 w-3.5"}),"项目设置"]}),k&&e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:k,children:[e.jsx(Pa,{className:"h-3.5 w-3.5"}),"连接微信 (Beta)"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:N,children:[B?e.jsx(Oc,{className:"h-3.5 w-3.5"}):e.jsx(_c,{className:"h-3.5 w-3.5"}),B?"浅色模式":"深色模式"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>Nn(!0),children:[e.jsx(zi,{className:"h-3.5 w-3.5"}),"项目 Skills"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>window.open("https://axhub-work.feishu.cn/wiki/space/7585489740036606927","_blank","noopener,noreferrer"),children:[e.jsx(Lc,{className:"h-3.5 w-3.5"}),"帮助中心"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>window.open("https://axhub-work.feishu.cn/wiki/W8KDwcZ8eiB68Nkw4sFcGL4Wn6e","_blank","noopener,noreferrer"),children:[e.jsx(Mc,{className:"h-3.5 w-3.5"}),"培训服务"]}),e.jsxs(Re,{className:"h-7 gap-2 text-sm",onClick:()=>window.open("https://axhub.im/","_blank","noopener,noreferrer"),children:[e.jsx(pn,{className:"h-3.5 w-3.5"}),"Axhub 官网"]}),e.jsx(Mt,{}),e.jsxs(Re,{className:"h-7 gap-2 text-sm opacity-80 pointer-events-none",children:[e.jsx(ei,{className:"h-3.5 w-3.5"}),e.jsxs("span",{className:"flex w-full items-center justify-between gap-2",children:[e.jsx("span",{children:"Axhub Make"}),e.jsx("span",{className:"text-muted-foreground",children:bn?`v${bn}`:"-"})]})]})]})]})}),e.jsx(Hm,{handleOpenProjectInIDE:x,preferredIDE:V,onPreferredIDEChange:re})]}),e.jsx("div",{className:"px-2 pb-2",children:Ze?e.jsx("div",{className:"h-6 flex items-center px-1 rounded text-[14px] leading-none font-semibold",children:e.jsx("input",{ref:wt,value:St,onChange:m=>Ut(m.target.value),onBlur:()=>void M(),onKeyDown:m=>void ee(m),className:"ax-inline-rename-input ax-inline-rename-input-title h-full"})}):e.jsx("div",{className:"h-6 flex items-center px-1 rounded text-[14px] leading-none font-semibold truncate cursor-pointer hover:bg-muted/50",onDoubleClick:()=>dt(!0),title:"双击编辑标题",children:e.jsx("span",{className:"truncate leading-none",children:n||"未命名项目"})})}),e.jsx("div",{className:"px-2 pb-2",children:e.jsxs(Ga,{type:"single",value:t,onValueChange:m=>m&&s(m),className:"w-auto justify-start p-0 gap-1",children:[e.jsx(Zs,{value:"prototype",className:"h-6 w-auto min-w-[36px] px-2 text-[11px] leading-none whitespace-nowrap rounded-sm bg-transparent hover:bg-muted/50 data-[state=off]:!text-muted-foreground/60 data-[state=off]:hover:!text-muted-foreground data-[state=on]:bg-accent data-[state=on]:!text-foreground data-[state=on]:!font-medium",children:"原型"}),e.jsx(Zs,{value:"document",className:"h-6 w-auto min-w-[36px] px-2 text-[11px] leading-none whitespace-nowrap rounded-sm bg-transparent hover:bg-muted/50 data-[state=off]:!text-muted-foreground/60 data-[state=off]:hover:!text-muted-foreground data-[state=on]:bg-accent data-[state=on]:!text-foreground data-[state=on]:!font-medium",children:"文档"}),e.jsx(Zs,{value:"assets",className:"h-6 w-auto min-w-[36px] px-2 text-[11px] leading-none whitespace-nowrap rounded-sm bg-transparent hover:bg-muted/50 data-[state=off]:!text-muted-foreground/60 data-[state=off]:hover:!text-muted-foreground data-[state=on]:bg-accent data-[state=on]:!text-foreground data-[state=on]:!font-medium",children:"资源"})]})}),e.jsxs("div",{className:"flex items-center gap-1 px-2 pb-2",children:[e.jsxs("div",{className:fe("relative flex items-center transition-all duration-300",Je?"flex-1":"w-auto"),children:[Je?e.jsx(Ps,{ref:st,value:D,onChange:m=>v(m.target.value),placeholder:"搜索...",className:"h-7 text-[12px] pr-7",onBlur:()=>!D&&tt(!1)}):e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:we,children:e.jsx(Ia,{className:"h-4 w-4"})})}),e.jsx(It,{children:"搜索"})]})}),Je&&e.jsx(Ia,{className:"absolute right-2 h-3 w-3 text-muted-foreground pointer-events-none"})]}),!Je&&t==="prototype"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-1"}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:u,children:e.jsx(pa,{className:"h-4 w-4"})})}),e.jsx(It,{children:"新建原型"})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>void ys(),disabled:ut,children:e.jsx(uo,{className:"h-4 w-4"})})}),e.jsx(It,{children:"新建文件夹"})]})})]}):null,!Je&&t==="document"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-1"}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:K,children:e.jsx(pa,{className:"h-4 w-4"})})}),e.jsx(It,{children:"新建文件"})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>void ys(),disabled:ut,children:e.jsx(uo,{className:"h-4 w-4"})})}),e.jsx(It,{children:"新建文件夹"})]})})]}):null,!Je&&t==="canvas"?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex-1"}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:y,children:e.jsx(pa,{className:"h-4 w-4"})})}),e.jsx(It,{children:"新建画布"})]})})]}):null]})]}),kn?e.jsx(Tr,{className:"flex-1 min-h-0 p-2 [&_[data-radix-scroll-area-viewport]>div]:!block [&_[data-radix-scroll-area-viewport]>div]:!w-full [&_[data-radix-scroll-area-viewport]>div]:!min-w-0",children:to()}):e.jsx("div",{className:"flex-1 min-h-0 flex flex-col",children:e.jsxs(jl,{type:"single",collapsible:!0,value:De?"":b,onValueChange:m=>{if(!m){ge(!0);return}ge(!1),he(m)},className:"flex-1 min-h-0 flex flex-col",children:[ua("themes","主题",U.length,Za("themes"),()=>C("themes"),e.jsx(Uc,{className:"h-3.5 w-3.5 text-muted-foreground"})),ua("components","组件",c.length,to(),()=>C("components"),e.jsx(Fc,{className:"h-3.5 w-3.5 text-muted-foreground"})),ua("data","数据",A.length,Za("data"),()=>C("data"),e.jsx(zc,{className:"h-3.5 w-3.5 text-muted-foreground"})),ua("templates","文档模板",q.length,Za("templates"),()=>C("templates"),e.jsx(hn,{className:"h-3.5 w-3.5 text-muted-foreground"}))]})})]}),e.jsx(Vm,{visible:Gn,onClose:()=>Nn(!1),preferredIDE:V})]})}function oh(t){return"state"in t?{...t.state,...t.actions,...t.preferences}:t}function ih(t){const{collapsed:s,loading:n,handleTabChange:a,sidebarTab:o,onSidebarTabChange:i,data:l,docsItems:c,canvasItems:d,themes:w,dataTables:j,templates:$,searchText:v,setSearchText:D,selectedItem:u,selectedSubPage:C,selectedDoc:K,selectedCanvas:y,selectedTheme:P,selectedDataTable:R,selectedTemplate:L,onOpenThemeInIDE:F,onOpenThemeDocInIDE:x,onRenameTheme:V,onDownloadThemeZip:re,onDeleteTheme:B,onOpenDataTableInIDE:xe,onRenameDataTable:ie,onDeleteDataTable:z,onOpenTemplateInIDE:se,onRenameTemplate:W,onDuplicateTemplate:S,onDeleteTemplate:Y,onCopyTemplatePath:k,onTemplateVersionManagement:N,resourceSection:U,onResourceSectionChange:A,onSelectDoc:q,onSelectCanvas:pe,onSelectTheme:Ne,onSelectDataTable:Ce,onSelectTemplate:Ie,onReorderThemes:ve,defaultThemeName:Ue,onSetDefaultTheme:Fe,onReorderDataTables:Oe,onReorderTemplates:We,onSubPageSelect:E,onSubPageClear:ce,onShowReadonlyPromptDialog:Pe,onRequestTextInputDialog:Ee,handleMenuClick:Te,handleDownloadItemSource:Ye,handleRenameItem:nt,handleDuplicateItem:Me,handleDeleteItem:b,handleCopyItemPath:he,handleRenameDocItem:ke,handleDuplicateDocItem:T,handleDeleteDocItem:Z,handleCopyDocPath:de,handleDocVersionManagement:J,onCreatePrototypeFromDoc:Ae,onOpenCreateDialog:ze,onCreateResource:ue,onCreateDocFile:ne,onCreateCanvasFile:me,handleRenameCanvasItem:je,handleDuplicateCanvasItem:De,handleDeleteCanvasItem:ge,handleCopyCanvasPath:Ze,onCreateFolder:dt,onGenerateThemeFromPrototype:St,preferredIDE:Ut,onSettingsClick:wt,onWeChatConnect:Je,onToggleTheme:tt,projectTitle:st,onTitleChange:rs,handleOpenProjectInIDE:Kt,onPreferredIDEChange:js,isDarkMode:pt,handleVersionManagement:Rt,sidebarTrees:yt,onSidebarTreeChange:Qe,onSidebarTreePersist:ut}=oh(t),$e=et=>{if(i(et),et==="prototype"){a("prototypes");return}et==="assets"&&a("components")},Ke=o==="prototype"?"prototypes":o==="document"?"docs":o==="canvas"?"canvas":"components",mt=d.map(et=>({name:et.name,displayName:et.displayName,jsUrl:"",demoUrl:"",specUrl:""})),os=Ke==="prototypes"?l.prototypes:Ke==="docs"?c:Ke==="canvas"?mt:l.components,Ot=o==="document"?K:o==="canvas"?y?{name:y.name,displayName:y.displayName,jsUrl:"",demoUrl:"",specUrl:""}:null:u,Vt=Ke==="docs"?ke:Ke==="canvas"?je:nt,_t=Ke==="docs"?T:Ke==="canvas"?De:Me,Ft=Ke==="docs"?Z:Ke==="canvas"?ge:b,Lt=Ke==="docs"?de:Ke==="canvas"?Ze:he,is=Ke==="docs"?J:Rt;return e.jsx("div",{className:fe("flex flex-col h-full min-h-0 bg-background border-r transition-all duration-300",s?"w-0 overflow-hidden border-none":"w-[240px]"),children:e.jsx(rh,{activeTab:o,onTabChange:$e,projectTitle:st,onTitleChange:rs,tree:yt[Ke]||[],onTreeChange:et=>Qe(Ke,et),onTreePersist:et=>ut(Ke,et),items:os,selectedItem:Ot,selectedSubPage:Ke==="prototypes"?C:null,onItemClick:et=>{if(o==="document"){q(et);return}if(o==="canvas"){pe({name:et.name,displayName:et.displayName});return}ce==null||ce(),Te({key:et.name})},onSubPageSelect:E,onSearch:D,searchText:v,onCreateFile:ze,onCreateResource:ue,onCreateDocFile:ne,onCreateCanvasFile:me,onCreatePrototypeFromDoc:et=>{Ae(et)},onCreateFolder:dt,onGenerateThemeFromPrototype:St,loading:n,handleOpenProjectInIDE:Kt,preferredIDE:Ut,onPreferredIDEChange:js,isDarkMode:pt,handleRenameItem:Vt,handleDuplicateItem:_t,handleCopyItemPath:Lt,handleVersionManagement:is,handleDownloadItemSource:Ye,handleDeleteItem:Ft,onSettingsClick:wt,onWeChatConnect:Je,onToggleTheme:tt,themes:w,dataTables:j,templates:$,selectedTheme:P,selectedDataTable:R,selectedTemplate:L,onOpenThemeInIDE:F,onOpenThemeDocInIDE:x,onRenameTheme:V,onDownloadThemeZip:re,onDeleteTheme:B,onOpenDataTableInIDE:xe,onRenameDataTable:ie,onDeleteDataTable:z,onOpenTemplateInIDE:se,onRenameTemplate:W,onDuplicateTemplate:S,onDeleteTemplate:Y,onCopyTemplatePath:k,onTemplateVersionManagement:N,resourceSection:U,onResourceSectionChange:A,onSelectTheme:Ne,onSelectDataTable:Ce,onSelectTemplate:Ie,onReorderThemes:ve,defaultThemeName:Ue,onSetDefaultTheme:Fe,onReorderDataTables:Oe,onReorderTemplates:We,onShowReadonlyPromptDialog:Pe,onRequestTextInputDialog:Ee})})}const Ko=[{label:"批注",value:"annotation"},{label:"编辑",value:"edit"}];function Vo(t){return t==="annotation"?["copyPrompt","exit"]:["save","exit"]}function Ho(t){const{enabled:s,currentMode:n,nextMode:a,dirty:o}=t;return!s||n===a?{type:"noop"}:a==="edit"||!o?{type:"switch",mode:a}:{type:"confirm",mode:"annotation"}}function lh(t){if(!t)return"尚未导出";const s=new Date(t);return Number.isNaN(s.getTime())?t:new Intl.DateTimeFormat("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"}).format(s)}function ch({open:t,onOpenChange:s,itemName:n,preferredPromptClient:a,preferredIDE:o}){const i=n?`prototypes/${n}`:"",[l,c]=be.useState(null),[d,w]=be.useState(!1),[j,$]=be.useState(!1),v=be.useCallback(async()=>{if(!i){c(null);return}w(!0);try{const y=await Pt.probeExportMake(i);c(y)}catch(y){c(null),H.error((y==null?void 0:y.message)||"加载导出状态失败")}finally{w(!1)}},[i]);be.useEffect(()=>{t&&v()},[v,t]);const D=be.useCallback(async()=>{if(!i){H.warning("请先选择一个原型页面");return}$(!0);try{const y=await fetch(`/api/export-make?path=${encodeURIComponent(i)}`);if(!y.ok){const x=await y.json().catch(()=>({}));throw new Error((x==null?void 0:x.error)||"下载 .fig 失败")}const P=await y.blob(),R=(l==null?void 0:l.fileName)||`${n||"project"}.fig`,L=URL.createObjectURL(P),F=document.createElement("a");F.href=L,F.download=R,document.body.appendChild(F),F.click(),F.remove(),URL.revokeObjectURL(L),H.success(".fig 文件已开始下载"),await v()}catch(y){H.error((y==null?void 0:y.message)||"下载 .fig 失败")}finally{$(!1)}},[n,v,l==null?void 0:l.fileName,i]),u=!!(l!=null&&l.hasMakeAssets)&&!(l!=null&&l.hasDriftRisk)&&!d&&!j,C=(l==null?void 0:l.fileName)||`${n||"project"}.fig`,K=lh((l==null?void 0:l.lastExportedAt)||null);return e.jsx(Js,{open:t,onOpenChange:s,children:e.jsxs(Qs,{className:"sm:max-w-[560px]",children:[e.jsxs(mn,{className:"gap-1.5",children:[e.jsx(Xs,{className:"text-[18px] font-semibold tracking-tight",children:"导出 Figma.Make"}),e.jsx(Un,{className:"text-sm leading-6",children:"使用 AI 导出或更新 .fig 文件"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("div",{className:"text-sm font-medium",children:"MAKE 文件"}),e.jsxs(te,{type:"button",variant:"ghost",size:"sm",className:"h-8 gap-1.5 px-2 text-xs",onClick:()=>void v(),disabled:d,children:[d?e.jsx(gt,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(Ln,{className:"h-3.5 w-3.5"}),"刷新状态"]})]}),e.jsx("div",{className:"rounded-xl border bg-card p-4 shadow-sm",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("div",{className:`rounded-lg p-2 ${l!=null&&l.hasMakeAssets?"bg-emerald-50 text-emerald-600":"bg-amber-50 text-amber-600"}`,children:e.jsx(Vc,{className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0 space-y-1",children:[e.jsx("div",{className:"truncate text-sm font-medium",children:l!=null&&l.hasMakeAssets?C:"尚未生成"}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["最后更新:",K]})]})]}),e.jsxs(te,{type:"button",variant:"brand",size:"sm",className:"shrink-0 self-center gap-1.5",onClick:()=>void D(),disabled:!u,children:[j?e.jsx(gt,{className:"h-4 w-4 animate-spin"}):e.jsx(Ds,{className:"h-4 w-4"}),"下载 Make"]})]})}),l!=null&&l.hasDriftRisk&&l.driftReasons.length>0?e.jsx("div",{className:"rounded-lg border border-dashed px-3 py-2.5 text-xs text-muted-foreground",children:l.driftReasons.map(y=>e.jsxs("div",{children:["- ",y]},y))}):null]}),e.jsxs(Ta,{className:"gap-2 sm:justify-end",children:[e.jsx(hs,{type:"default",preferredClient:a,preferredIDE:o,scene:"export-figma-make",buildPrompt:async()=>{if(!i)throw new Error("请先选择一个原型页面");return(await Pt.getExportMakePrompt(i)).prompt},getIdeTargetPath:()=>n?`src/prototypes/${n}`:null,copySuccessMessage:"导出 Prompt 已复制,请发送给 AI 继续生成或更新 .fig 文件",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制导出 Prompt",copyLabel:"用 Codex 执行",disabled:!i}),e.jsx(te,{type:"button",variant:"outline",size:"sm",onClick:()=>s(!1),children:"关闭"})]})]})})}const dh=t=>e.jsx("span",{role:"img","aria-label":"figma",...t,children:e.jsxs("svg",{fill:"currentColor",fillRule:"evenodd",height:"1em",width:"1em",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",style:{verticalAlign:"middle"},children:[e.jsx("title",{children:"Figma"}),e.jsx("path",{clipRule:"evenodd",d:"M6.082 8.241C4.83 7.441 4 6.057 4 4.483 4 2.007 6.05 0 8.578 0h7.844C18.95 0 21 2.007 21 4.483c0 1.574-.829 2.959-2.082 3.758C20.17 9.041 21 10.426 21 12c0 2.476-2.05 4.483-4.578 4.483h-.084A4.615 4.615 0 0113.24 15.3v4.176C13.24 21.98 11.145 24 8.599 24 6.076 24 4 21.998 4 19.517c0-1.574.829-2.959 2.082-3.758C4.829 14.959 4 13.574 4 12c0-1.574.829-2.959 2.082-3.759zM13.24 12c0 1.676 1.387 3.034 3.098 3.034h.084c1.711 0 3.099-1.358 3.099-3.034 0-1.676-1.388-3.034-3.1-3.034h-.083c-1.71 0-3.098 1.358-3.098 3.034zm-1.48-3.034H8.578C6.867 8.966 5.48 10.324 5.48 12c0 1.672 1.382 3.029 3.089 3.034H11.76V8.966zm-3.182 7.517h-.01c-1.707.005-3.089 1.362-3.089 3.034 0 1.67 1.403 3.034 3.12 3.034 1.74 0 3.161-1.381 3.161-3.075v-2.993H8.578zm3.182-8.966H8.578c-1.711 0-3.099-1.358-3.099-3.034 0-1.676 1.388-3.034 3.1-3.034h3.181v6.068zm4.662 0H13.24V1.45h3.182c1.711 0 3.099 1.358 3.099 3.034 0 1.676-1.388 3.034-3.1 3.034z"})]})});function uh({collapsed:t,setCollapsed:s,selectedItem:n,viewMode:a,activeTab:o,setViewMode:i,selectedDeviceId:l,setSelectedDeviceId:c,deviceSegmentOptions:d,localShareUrl:w,handleOpenWebEditor:j,handleOpenQuickEditInNewPage:$,handleExitWebEditor:v,handleSaveWebEditorText:D,handleSaveWebEditorStyle:u,handleClearWebEditorForcedStyles:C,handleRefreshElement:K,handleCopyLocalLink:y,handleCopyLANLink:P,getLANUrl:R,qrCodeVisible:L,setQrCodeVisible:F,handlePushToFigma:x,handleCopyToFigma:V,handleDownloadFigmaJson:re,setIsExportModalOpen:B,handleQuickCopyEditablePrototype:xe,handleQuickCopyRuntimeComponent:ie,handleQuickDownloadRuntimeCover:z,handleOpenIdeFile:se,handleOpenDocInIDE:W,handleEnableDocEdit:S,handleSaveDocEdit:Y,handleExitDocEdit:k,handleSwitchDocQuickEditMode:N,handleOpenThemeInIDE:U,handleOpenDataTableInIDE:A,handleEnableSpecEdit:q,handleSaveSpecEdit:pe,handleExitSpecEdit:Ne,handleSwitchSpecQuickEditMode:Ce,handleExecuteSpecPrompt:Ie,specPromptCopying:ve,specPromptExecutingClient:Ue,specExecuteMenuItems:Fe,currentSpecDocKey:Oe="spec",specEditState:We,specQuickEditMode:E,textEditAvailable:ce,editorMode:Pe="none",allowLAN:Ee,contentMode:Te="preview",selectedDoc:Ye=null,selectedTemplate:nt=null,docEditState:Me={enabled:!1,dirty:!1,saving:!1,quickEditMode:"annotation"},selectedTheme:b=null,selectedDataTable:he=null,preferredPromptClient:ke,preferredIDE:T,assistantVisible:Z=!1,onToggleAssistant:de}){var qt;const[J,Ae]=be.useState(!1),ze=Pe==="webEditorV2",ue=o==="prototypes"&&!!n,ne="p-0 inline-flex items-center justify-center text-sm [&_svg]:h-4 [&_svg]:w-4",me="p-0 inline-flex items-center justify-center text-sm [&_svg]:h-[18px] [&_svg]:w-[18px]",je=window.location.protocol==="file:",De=je?window.location.href:w,ge=at=>{at&&window.open(at,"_blank")},dt=Ee&&!je?R():"",St=!!dt,Ut=a==="demo"?"spec":"demo",wt=Ut==="spec"?"切换到文档":"切换到原型",Je=a==="spec"?e.jsx(hn,{}):e.jsx(po,{}),tt=Te==="preview",st=a==="demo"&&ze,rs=tt&&!(a==="spec"&&We.enabled)&&!st,Kt="h-7 w-7 shrink-0 text-muted-foreground hover:text-foreground",js=({name:at,url:Qt,onCopy:Ct})=>e.jsxs("div",{className:"flex items-center justify-between py-0.5",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:at}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:Kt,onClick:Ct,children:e.jsx(ss,{className:"h-3.5 w-3.5"})})}),e.jsx(It,{children:"复制链接"})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon",className:Kt,onClick:()=>ge(Qt),children:e.jsx(ho,{className:"h-3.5 w-3.5"})})}),e.jsx(It,{children:"新窗口打开"})]})})]})]}),pt=e.jsxs("div",{className:"w-[280px] p-4 flex flex-col gap-3",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsx("h4",{className:"font-medium text-sm",children:"分享预览"})}),e.jsxs("div",{className:"grid gap-1.5",children:[js({name:"本地链接",url:De,onCopy:y}),St&&js({name:"局域网链接",url:dt,onCopy:P})]}),St&&e.jsxs(e.Fragment,{children:[e.jsx(la,{}),e.jsxs("div",{className:"flex flex-col items-center gap-2 pt-0.5",children:[e.jsx("div",{className:"rounded-xl border border-border bg-card p-2.5 shadow-sm",children:e.jsx(ed,{value:dt,size:160,bordered:!1})}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"手机扫码预览"})]})]})]}),Rt=e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx("span",{className:"inline-block",style:{marginLeft:2,marginRight:2},children:e.jsx(Hi,{state:Z?"awake":"sleeping",size:28,onClick:de})})}),e.jsx(It,{children:"Axhub Genie"})]})}),yt=(()=>{if(Te==="doc"&&Ye||Te==="template"&&nt){const at=Te==="template"?nt:Ye,Qt=Te==="template"?"模板":"文档",Ct=/\.md$/i.test((at==null?void 0:at.name)||"");if(Me.enabled){const zt=Vo(Me.quickEditMode).includes("save");return e.jsxs(e.Fragment,{children:[e.jsx(fo,{size:"small",value:Me.quickEditMode,options:Ko,style:{fontSize:12},onChange:As=>N(As)}),zt?e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:Y,disabled:!Me.dirty||Me.saving,children:[e.jsx(Sa,{})," 保存"]}):null,e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:K,children:[e.jsx(fa,{})," 刷新"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:k,disabled:Me.saving,children:[e.jsx(Ya,{})," 退出"]})]})}return e.jsxs(e.Fragment,{children:[e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:W,children:e.jsx(er,{})})}),e.jsx(It,{children:`在编辑器中打开${Qt}`})]})}),Ct?e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:S,children:e.jsx(Hc,{})})}),e.jsx(It,{children:`编辑${Qt}`})]})}):null]})}return Te==="theme"&&b?e.jsx(e.Fragment,{children:e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:U,children:e.jsx(er,{})})}),e.jsx(It,{children:"在编辑器中打开主题"})]})})}):Te==="data"&&he?e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:A,children:e.jsx(er,{})})}),e.jsx(It,{children:"在编辑器中打开数据表"})]})}):null})(),Qe=a==="spec"&&We.enabled,$e=Vo(E).includes("save"),Ke=a==="demo"?!ce:!1,mt=a==="spec"?`在编辑器中打开 ${Oe==="prd"?"PRD":"SPEC"} 文档`:"在编辑器中打开",os=a==="demo"&&ze?"退出快速编辑":"快速编辑",Ot=()=>{if(a==="spec"){q();return}if(ze){v();return}j()},Vt=e.jsx(e.Fragment,{children:(n||Qe)&&e.jsx(e.Fragment,{children:Qe?e.jsxs(e.Fragment,{children:[e.jsx(fo,{size:"small",value:E,options:Ko,style:{fontSize:12},onChange:at=>Ce(at)}),$e?e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:pe,disabled:!We.dirty,children:[e.jsx(Sa,{})," 保存"]}):null,e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:K,children:[e.jsx(fa,{})," 刷新"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:Ne,children:[e.jsx(Ya,{})," 退出"]})]}):st?e.jsxs(e.Fragment,{children:[e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:D,children:[e.jsx(hn,{})," 保存文本"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:u,children:[e.jsx(Sa,{})," 保存强制样式"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:C,children:[e.jsx(_s,{})," 清空强制样式"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:K,children:[e.jsx(fa,{})," 刷新"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:$,children:[e.jsx(ho,{})," 新页面打开"]}),e.jsxs(te,{variant:"ghost",size:"xs",className:"gap-1.5 [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:v,children:[e.jsx(Ya,{})," 退出"]})]}):e.jsxs(e.Fragment,{children:[e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:se,children:e.jsx(dn,{})})}),e.jsx(It,{children:mt})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx("div",{className:"relative inline-flex",children:e.jsx(te,{variant:st?"secondary":"ghost",size:"icon-xs",className:fe(ne,st&&"bg-secondary text-secondary-foreground"),disabled:Ke,onClick:Ot,children:e.jsx(Si,{})})})}),e.jsx(It,{children:os})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:K,children:e.jsx(fa,{})})}),e.jsx(It,{children:"刷新"})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsxs(Wr,{open:L,onOpenChange:F,children:[e.jsx(Tt,{asChild:!0,children:e.jsx(Gr,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,children:e.jsx(un,{})})})}),e.jsx(Wa,{align:"end",className:"p-0",onOpenAutoFocus:at=>at.preventDefault(),children:pt})]}),e.jsx(It,{children:"分享链接"})]})}),e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsxs(us,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(ms,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,children:e.jsx(dh,{})})})}),e.jsxs(ts,{className:"text-sm",children:[e.jsxs(Re,{onClick:V,className:"gap-2 h-7 text-sm",children:[e.jsx(ss,{className:"h-3.5 w-3.5"})," 复制到 Figma"]}),e.jsxs(Re,{onClick:x,className:"gap-2 h-7 text-sm",children:[e.jsx(_n,{className:"h-3.5 w-3.5"})," 推送到 Figma"]}),ue?e.jsxs(Re,{onClick:()=>Ae(!0),className:"gap-2 h-7 text-sm",children:[e.jsx(Ds,{className:"h-3.5 w-3.5"})," 导出 Make"]}):null]})]}),e.jsx(It,{children:"同步到 Figma"})]})}),e.jsxs("div",{className:"inline-flex items-center rounded-md",children:[e.jsxs(te,{variant:"brand",size:"xs",className:"h-6 rounded-r-none px-2.5 gap-1.5 font-medium [&_svg]:h-3.5 [&_svg]:w-3.5",onClick:()=>B(!0),children:[e.jsx(po,{}),"导出到 Axure"]}),e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:e.jsx(te,{variant:"brand",size:"xs",className:"h-6 w-6 rounded-l-none border-l border-white/20 p-0","aria-label":"更多导出操作",children:e.jsx(en,{className:"h-3.5 w-3.5"})})}),e.jsxs(ts,{align:"end",className:"text-sm",children:[e.jsxs(Re,{onClick:xe,className:"gap-2 h-7 text-sm",children:[e.jsx(ss,{className:"h-3.5 w-3.5"})," 复制可编辑原型"]}),e.jsxs(Re,{onClick:ie,className:"gap-2 h-7 text-sm",children:[e.jsx(ss,{className:"h-3.5 w-3.5"})," 复制 runtime 组件"]}),e.jsxs(Re,{onClick:z,className:"gap-2 h-7 text-sm",children:[e.jsx(Ds,{className:"h-3.5 w-3.5"})," 下载 runtime 封面"]})]})]})]})]})})}),_t=yt??(tt?Vt:null),Ft=e.jsx(vt,{children:e.jsxs(Et,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx(te,{variant:"ghost",size:"icon-xs",className:ne,onClick:()=>i(Ut),children:Je})}),e.jsx(It,{children:wt})]})}),Lt=((qt=d.find(at=>at.value===l))==null?void 0:qt.icon)||e.jsx(Gi,{className:"h-3.5 w-3.5"}),is=a==="spec",et=e.jsx(te,{variant:"ghost",size:"icon-xs",className:fe(ne,"rounded-full hover:bg-muted/80",is&&"opacity-50 cursor-not-allowed hover:bg-transparent"),disabled:is,children:Lt}),Ht=tt&&!Qe&&!st?is?et:e.jsxs(us,{children:[e.jsx(ms,{asChild:!0,children:et}),e.jsx(ts,{className:"min-w-[100px] text-sm",children:d.map(at=>e.jsxs(Re,{onClick:()=>c(at.value),className:"gap-2 text-sm h-7 cursor-pointer",children:[e.jsx("span",{className:"[&_svg]:h-3.5 [&_svg]:w-3.5",children:at.icon}),e.jsxs("span",{children:[at.value==="desktop"&&"桌面端",at.value==="mobile"&&"移动端",at.value==="tablet"&&"平板"]})]},at.value))})]}):null;return e.jsxs("div",{className:"relative h-10 flex items-center justify-between border-b px-2 bg-background shrink-0 text-sm",children:[e.jsx("div",{className:"flex items-center z-10",children:e.jsx(te,{variant:"ghost",size:"icon-xs",onClick:()=>s(!t),className:me,children:t?e.jsx(qc,{}):e.jsx(Zc,{})})}),e.jsxs("div",{className:"flex-1 flex justify-center items-center gap-2 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",children:[rs?Ft:null,Ht,Ht?e.jsx(la,{orientation:"vertical",className:"h-4 mx-0.5"}):null,e.jsx("div",{className:"flex items-center gap-1 [&>*]:self-center text-sm",children:_t})]}),e.jsx("div",{className:"flex items-center justify-end gap-1.5 z-10",children:Rt}),e.jsx(ch,{open:J,onOpenChange:Ae,itemName:ue?n==null?void 0:n.name:null,itemDisplayName:ue?(n==null?void 0:n.displayName)||(n==null?void 0:n.name):null,preferredPromptClient:ke,preferredIDE:T})]})}const mh=({width:t,height:s,children:n,scale:a=1,className:o})=>e.jsx("div",{className:fe("relative flex origin-center flex-col rounded-[40px] border-4 p-3 shadow-2xl",o),style:{transform:`scale(${a})`,backgroundColor:"hsl(var(--device-shell-bg))",borderColor:"hsl(var(--device-shell-border))",boxShadow:"var(--shadow-md)"},children:e.jsx("div",{className:"relative overflow-hidden rounded-[32px]",style:{width:t,height:s,backgroundColor:"hsl(var(--device-screen-bg))"},children:n})}),hh=be.forwardRef(({className:t,...s},n)=>e.jsx("div",{className:"relative w-full overflow-auto",children:e.jsx("table",{ref:n,className:fe("w-full caption-bottom text-sm",t),...s})}));hh.displayName="Table";const $l=be.forwardRef(({className:t,...s},n)=>e.jsx("thead",{ref:n,className:fe("[&_tr]:border-b",t),...s}));$l.displayName="TableHeader";const Ol=be.forwardRef(({className:t,...s},n)=>e.jsx("tbody",{ref:n,className:fe("[&_tr:last-child]:border-0",t),...s}));Ol.displayName="TableBody";const ph=be.forwardRef(({className:t,...s},n)=>e.jsx("tfoot",{ref:n,className:fe("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",t),...s}));ph.displayName="TableFooter";const Dr=be.forwardRef(({className:t,...s},n)=>e.jsx("tr",{ref:n,className:fe("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",t),...s}));Dr.displayName="TableRow";const Ar=be.forwardRef(({className:t,...s},n)=>e.jsx("th",{ref:n,className:fe("h-10 px-3 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",t),...s}));Ar.displayName="TableHead";const ka=be.forwardRef(({className:t,...s},n)=>e.jsx("td",{ref:n,className:fe("p-3 align-middle [&:has([role=checkbox])]:pr-0",t),...s}));ka.displayName="TableCell";const fh=be.forwardRef(({className:t,...s},n)=>e.jsx("caption",{ref:n,className:fe("mt-4 text-sm text-muted-foreground",t),...s}));fh.displayName="TableCaption";const xh=["utf-8","gb18030","gbk","utf-16le","utf-16be"],gh=["锘","锟","涓","鏂","鐨","鍚","鍙","璇","鈥","Ã","Â","æ","ä¸","å"],yh=t=>t.length>=3&&t[0]===239&&t[1]===187&&t[2]===191?{encoding:"utf-8",offset:3}:t.length>=2&&t[0]===255&&t[1]===254?{encoding:"utf-16le",offset:2}:t.length>=2&&t[0]===254&&t[1]===255?{encoding:"utf-16be",offset:2}:null,cn=(t,s)=>{const n=t.match(s);return(n==null?void 0:n.length)??0},bh=t=>gh.reduce((s,n)=>n?s+t.split(n).length-1:s,0),wh=t=>cn(t,/,/g)+cn(t,/\r?\n/g),jh=t=>{const s=t.match(/[^\t\n\r\u0020-\u007E\u00A0-\u00FF\u2000-\u206F\u3000-\u303F\u3400-\u9FFF\uF900-\uFAFF]/g);return(s==null?void 0:s.length)??0},Nh=t=>{if(!t.trim())return Number.NEGATIVE_INFINITY;let s=0;s-=cn(t,/\uFFFD/g)*120,s-=cn(t,/\u0000/g)*80,s-=cn(t,/[\uE000-\uF8FF]/g)*60,s-=cn(t,/[\u0001-\u0008\u000B\u000C\u000E-\u001F]/g)*40,s-=bh(t)*12,s-=jh(t)*10,s+=Math.min(cn(t,/[\u3400-\u9FFF]/g),32)*3,s+=Math.min(wh(t),64)*5;const n=td.parse(t,{header:!0,skipEmptyLines:!0,preview:5,transformHeader:o=>o.trim()});n.errors.length===0?s+=24:s-=n.errors.length*15;const a=n.data[0];if(a){const o=Object.keys(a).filter(l=>l.trim()!=="");s+=o.length>1?o.length*12:-20;const i=Object.values(a).filter(l=>String(l??"").trim()!=="");s+=i.length*4}return s},vh=(t,s)=>{try{return s==="utf-8"?new TextDecoder(s,{fatal:!0}).decode(t):new TextDecoder(s).decode(t)}catch{return null}},Sh=t=>{const s=yh(t);if(s)return{encoding:s.encoding,text:new TextDecoder(s.encoding).decode(t.subarray(s.offset))};const n=[];for(const a of xh){const o=vh(t,a);o!=null&&n.push({encoding:a,text:o,score:Nh(o)})}return n.length===0?{encoding:"utf-8",text:new TextDecoder("utf-8").decode(t)}:(n.sort((a,o)=>o.score-a.score),{encoding:n[0].encoding,text:n[0].text})},Ch=[20,50,100];function kh(t){if(t==null)return"";if(typeof t=="object")try{return JSON.stringify(t)}catch{return String(t)}return String(t)}function Eh(t,s){const n=t.trim();if(n==="")return"";if(typeof s=="number"){const a=Number(n);return Number.isNaN(a)?s:a}if(typeof s=="boolean")return n==="true"?!0:n==="false"?!1:s;if(s&&typeof s=="object")try{return JSON.parse(t)}catch{return s}return t}function pr(t){if(t==null||t==="")return"-";if(typeof t=="object")try{return JSON.stringify(t)}catch{return String(t)}return String(t)}function Th({fileName:t,tableName:s}){const n=Rr(),[a,o]=r.useState(!1),[i,l]=r.useState([]),[c,d]=r.useState(null),[w,j]=r.useState({}),[$,v]=r.useState(1),[D,u]=r.useState(20),C=r.useRef(null),K=r.useCallback(async()=>{o(!0);try{const z=await fetch(`/api/data/${encodeURIComponent(t)}`);if(!z.ok)throw new Error("加载数据失败");const se=await z.json();l(Array.isArray(se)?se:[])}catch(z){H.error((z==null?void 0:z.message)||"加载数据失败"),l([])}finally{o(!1)}},[t]);r.useEffect(()=>{K()},[K]);const y=r.useMemo(()=>{if(i.length===0)return[];const z=[...Object.keys(i[0])],se=new Set(z);return i.slice(1).forEach(W=>{Object.keys(W).forEach(S=>{se.has(S)||(se.add(S),z.push(S))})}),z},[i]),P=Math.max(1,Math.ceil(i.length/D));r.useEffect(()=>{$>P&&v(P)},[$,P]);const R=r.useMemo(()=>{const z=($-1)*D;return i.slice(z,z+D)},[i,$,D]),L=z=>{const se={};Object.keys(z).forEach(W=>{se[W]=kh(z[W])}),d(z.id),j(se)},F=()=>{d(null),j({})},x=async()=>{if(c===null)return;const z=i.find(S=>String(S.id)===String(c));if(!z){F();return}const se={};Object.keys(w).forEach(S=>{S!=="id"&&(se[S]=Eh(w[S],z[S]))});const W=H.loading("正在保存...");try{const S=await fetch(`/api/data/${encodeURIComponent(t)}/${encodeURIComponent(String(c))}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(se)});if(!S.ok){const Y=await S.json().catch(()=>({}));throw new Error((Y==null?void 0:Y.error)||"保存失败")}H.success("保存成功",{id:W}),F(),await K()}catch(S){H.error((S==null?void 0:S.message)||"保存失败",{id:W})}},V=async z=>{if(!await n.confirm({title:`删除「${s}」中的这条记录?`,description:"删除后无法恢复,请确认是否继续。",confirmText:"确认删除",cancelText:"取消",tone:"destructive",dismissible:!1}))return;const W=H.loading("正在删除...");try{const S=await fetch(`/api/data/${encodeURIComponent(t)}/${encodeURIComponent(String(z))}`,{method:"DELETE"});if(!S.ok){const Y=await S.json().catch(()=>({}));throw new Error((Y==null?void 0:Y.error)||"删除失败")}H.success("删除成功",{id:W}),c!==null&&String(c)===String(z)&&F(),await K()}catch(S){H.error((S==null?void 0:S.message)||"删除失败",{id:W})}},re=async()=>{const z=H.loading("正在导出...");try{const se=await fetch(`/api/data/${encodeURIComponent(t)}/export`);if(!se.ok){const k=await se.json().catch(()=>({}));throw new Error((k==null?void 0:k.error)||"导出失败")}const W=await se.blob(),S=URL.createObjectURL(W),Y=document.createElement("a");Y.href=S,Y.download=`${t}.csv`,Y.click(),URL.revokeObjectURL(S),H.success("导出成功",{id:z})}catch(se){H.error((se==null?void 0:se.message)||"导出失败",{id:z})}},B=async z=>{const se=H.loading("正在导入...");try{const W=await z.arrayBuffer(),S=Sh(new Uint8Array(W)).text,Y=await fetch(`/api/data/${encodeURIComponent(t)}/import`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({csvData:S})});if(!Y.ok){const k=await Y.json().catch(()=>({}));throw new Error((k==null?void 0:k.error)||"导入失败")}H.success("导入成功",{id:se}),await K()}catch(W){H.error((W==null?void 0:W.message)||"导入失败",{id:se})}},xe=()=>{var z;(z=C.current)==null||z.click()},ie=async z=>{var W;const se=(W=z.target.files)==null?void 0:W[0];se&&(await B(se),z.target.value="")};return e.jsxs("div",{className:"flex h-full min-h-0 flex-col gap-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("h3",{className:"m-0 text-sm font-semibold",children:["数据表: ",s]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{ref:C,type:"file",accept:".csv,text/csv",className:"hidden",onChange:z=>{ie(z)}}),e.jsxs(te,{size:"xs",variant:"outline",onClick:xe,disabled:a||c!==null,children:[e.jsx(Jc,{className:"h-3.5 w-3.5"}),"导入 CSV"]}),e.jsxs(te,{size:"xs",variant:"outline",onClick:()=>void re(),disabled:a,children:[e.jsx(Ds,{className:"h-3.5 w-3.5"}),"导出 CSV"]}),e.jsxs(te,{size:"xs",variant:"outline",onClick:()=>void K(),disabled:a,children:[e.jsx(Ln,{className:fe("h-3.5 w-3.5",a&&"animate-spin")}),"刷新"]})]})]}),e.jsx("div",{className:"min-h-0 flex-1 rounded-md border bg-card",children:a?e.jsxs("div",{className:"flex h-full items-center justify-center text-xs text-muted-foreground",children:[e.jsx(gt,{className:"mr-2 h-4 w-4 animate-spin"}),"加载中..."]}):i.length===0?e.jsx("div",{className:"flex h-full items-center justify-center text-xs text-muted-foreground",children:"暂无数据,请导入 CSV"}):e.jsx("div",{className:"h-full w-full overflow-auto",children:e.jsxs("table",{className:"w-max min-w-full caption-bottom text-xs",children:[e.jsx($l,{children:e.jsxs(Dr,{children:[y.map(z=>e.jsx(Ar,{className:"h-9 whitespace-nowrap px-2 py-1",children:z},z)),e.jsx(Ar,{className:"sticky right-0 z-30 h-9 whitespace-nowrap border-l bg-card px-2 py-1 text-right",children:"操作"})]})}),e.jsx(Ol,{children:R.map(z=>{const se=c!==null&&String(c)===String(z.id);return e.jsxs(Dr,{className:"group",children:[y.map(W=>!se||W==="id"?e.jsx(ka,{className:"px-2 py-1 whitespace-nowrap",children:e.jsx("span",{className:fe("block leading-5",pr(z[W])==="-"&&"text-muted-foreground"),title:pr(z[W]),children:pr(z[W])})},W):e.jsx(ka,{className:"px-2 py-1",children:e.jsx(Ps,{value:w[W]??"",className:"h-7 text-xs",onChange:Y=>{const k=Y.target.value;j(N=>({...N,[W]:k}))}})},W)),e.jsx(ka,{className:"sticky right-0 z-20 border-l bg-card px-2 py-1 text-right group-hover:bg-muted/50",children:e.jsx("div",{className:"flex items-center justify-end gap-1",children:se?e.jsxs(e.Fragment,{children:[e.jsx(te,{size:"icon-xs",variant:"ghost",onClick:()=>void x(),"aria-label":"保存",children:e.jsx(Sa,{className:"h-3.5 w-3.5"})}),e.jsx(te,{size:"icon-xs",variant:"ghost",onClick:F,"aria-label":"取消",children:e.jsx(as,{className:"h-3.5 w-3.5"})})]}):e.jsxs(e.Fragment,{children:[e.jsx(te,{size:"icon-xs",variant:"ghost",onClick:()=>L(z),disabled:c!==null,"aria-label":"编辑",children:e.jsx(Qc,{className:"h-3.5 w-3.5"})}),e.jsx(te,{size:"icon-xs",variant:"ghost",onClick:()=>void V(z.id),disabled:c!==null,"aria-label":"删除",children:e.jsx(_s,{className:"h-3.5 w-3.5 text-destructive"})})]})})})]},String(z.id))})})]})})}),e.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-muted-foreground",children:[e.jsxs("div",{children:["共 ",i.length," 条记录"]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{children:"每页"}),e.jsx("select",{className:"h-7 rounded-md border bg-background px-2 text-xs",value:String(D),onChange:z=>{const se=Number(z.target.value);u(se),v(1)},children:Ch.map(z=>e.jsx("option",{value:z,children:z},z))}),e.jsx(te,{size:"xs",variant:"outline",disabled:$<=1,onClick:()=>v(z=>Math.max(1,z-1)),children:"上一页"}),e.jsxs("span",{children:[$," / ",P]}),e.jsx(te,{size:"xs",variant:"outline",disabled:$>=P,onClick:()=>v(z=>Math.min(P,z+1)),children:"下一页"})]})]})]})}function Ih({containerRef:t,previewIframeRef:s,selectedItem:n,activeTab:a,currentDevice:o,displaySize:i,scale:l,elementIframeKey:c,iframeUrl:d,elementIframeSize:w,setElementIframeSize:j,viewMode:$,contentMode:v="preview",selectedDoc:D=null,selectedTemplate:u=null,selectedCanvas:C=null,isDarkMode:K=!1,selectedTheme:y=null,selectedDataTable:P=null}){const[R,L]=r.useState(""),[F,x]=r.useState(!1),[V,re]=r.useState(""),B=v==="template"?u:D,xe=(B==null?void 0:B.name)||"",ie=/\.md$/i.test(xe),z=v==="template"?"/api/docs/templates":"/api/docs",se=v==="template"?"/docs/templates":"/docs",W=v==="template"?"模板":"文档";if(r.useEffect(()=>{if(v!=="doc"&&v!=="template"||!B||ie){L(""),x(!1),re("");return}let S=!1;return(async()=>{x(!0),re("");try{const k=await fetch(`${z}/${encodeURIComponent(B.name)}`);if(!k.ok)throw new Error(`读取${W}失败 (${k.status})`);const N=await k.text();S||L(N)}catch(k){S||(re((k==null?void 0:k.message)||`读取${W}失败`),L(""))}finally{S||x(!1)}})(),()=>{S=!0}},[v,B,ie,z,W]),v==="doc"||v==="template"){if(!B)return e.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground text-[12px]",children:`请选择${W}`});if(ie){const S=B.name.replace(/\.md$/i,""),Y=`${se}/${encodeURIComponent(S)}`;return e.jsx("div",{className:"h-full min-h-0 bg-muted/20",children:e.jsx("iframe",{ref:s,src:Y,className:"w-full h-full border-none",title:B.displayName})})}return e.jsx("div",{className:"h-full min-h-0 overflow-auto bg-muted/20 p-4",children:F?e.jsx("div",{className:"text-[12px] text-muted-foreground",children:"加载中..."}):V?e.jsx("div",{className:"text-[12px] text-destructive",children:V}):e.jsx("pre",{className:"whitespace-pre-wrap break-words text-[12px] leading-5 text-foreground",children:R})})}return v==="canvas"?C?e.jsx("div",{className:"h-full min-h-0 bg-background",children:e.jsx("iframe",{ref:s,src:`/canvas/${encodeURIComponent(C.name)}`,className:"w-full h-full border-none",title:C.displayName})}):e.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground text-[12px]",children:"请选择画布"}):v==="theme"?y?e.jsx("div",{className:"h-full min-h-0 bg-muted/20",children:e.jsx("iframe",{src:`/themes/${encodeURIComponent(y.name)}`,className:"w-full h-full border-none",title:y.displayName})}):e.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground text-[12px]",children:"请选择主题"}):v==="data"?P?e.jsx("div",{className:"h-full min-h-0 overflow-hidden bg-background p-3",children:e.jsx(Th,{fileName:P.fileName,tableName:P.tableName})}):e.jsx("div",{className:"flex items-center justify-center h-full text-muted-foreground text-[12px]",children:"请选择数据表"}):e.jsx("div",{ref:t,className:fe("relative h-full min-h-0 min-w-0 flex items-center justify-center overflow-hidden bg-muted/20"),children:n?$==="spec"?e.jsx("iframe",{ref:s,src:d,className:"w-full h-full border-none block",title:n.displayName},c):a==="prototypes"&&o.id!=="desktop"?e.jsx("div",{className:"w-full h-full flex items-center justify-center",children:e.jsx(mh,{width:i.width,height:i.height,scale:l,children:e.jsx("iframe",{ref:s,src:d,className:"w-full h-full border-none",title:n.displayName},c)})}):a==="components"?e.jsx("div",{className:"flex items-center gap-4",children:e.jsx("div",{className:"relative inline-block",children:e.jsx(Ki,{size:w,onResize:(S,Y,k)=>{if(k){const N=k.getBoundingClientRect();j({width:N.width,height:N.height})}},minWidth:50,minHeight:50,bounds:"window",enable:{top:!1,right:!0,bottom:!0,left:!1,topRight:!1,bottomRight:!0,bottomLeft:!1,topLeft:!1},handleStyles:{right:{width:"8px",right:"-4px",background:"transparent",borderRadius:"4px",transition:"all 0.2s"},bottom:{height:"8px",bottom:"-4px",background:"transparent",borderRadius:"4px",transition:"all 0.2s"},bottomRight:{width:"12px",height:"12px",right:"-6px",bottom:"-6px",background:"transparent",borderRadius:"0 0 6px 0",transition:"all 0.2s"}},handleClasses:{right:"resize-handle-right",bottom:"resize-handle-bottom",bottomRight:"resize-handle-bottomRight"},style:{overflow:"hidden"},className:"border rounded-md bg-background shadow-sm transition-shadow hover:shadow-md",children:e.jsx("iframe",{ref:s,src:d,className:"w-full h-full border-none",title:n.displayName},c)})})}):e.jsx("iframe",{ref:s,src:d,className:"w-full h-full border-none block",title:n.displayName},c):e.jsx("div",{className:"flex flex-col items-center justify-center h-full text-muted-foreground",children:e.jsxs("div",{className:"text-center",children:[e.jsx(Xc,{className:"mx-auto mb-4 h-16 w-16 opacity-20"}),e.jsxs("div",{className:"text-base",children:["请从左侧选择一个",a==="components"?"组件":"原型"]})]})})})}function Ph(t){return"state"in t?{...t.state,...t.actions}:t}function Dh(t){const s=Ph(t);return e.jsxs("div",{className:"flex flex-col flex-1 h-full min-h-0 min-w-0 bg-background",children:[e.jsx(uh,{collapsed:s.collapsed,setCollapsed:s.setCollapsed,selectedItem:s.selectedItem,viewMode:s.viewMode,activeTab:s.activeTab,setViewMode:s.setViewMode,selectedDeviceId:s.selectedDeviceId,setSelectedDeviceId:s.setSelectedDeviceId,deviceSegmentOptions:s.deviceSegmentOptions,localShareUrl:s.localShareUrl,handleOpenWebEditor:s.handleOpenWebEditor,handleOpenQuickEditInNewPage:s.handleOpenQuickEditInNewPage,handleExitWebEditor:s.handleExitWebEditor,handleSaveWebEditorText:s.handleSaveWebEditorText,handleSaveWebEditorStyle:s.handleSaveWebEditorStyle,handleClearWebEditorForcedStyles:s.handleClearWebEditorForcedStyles,handleRefreshElement:s.handleRefreshElement,handleCopyLocalLink:s.handleCopyLocalLink,handleCopyLANLink:s.handleCopyLANLink,getLANUrl:s.getLANUrl,qrCodeVisible:s.qrCodeVisible,setQrCodeVisible:s.setQrCodeVisible,handlePushToFigma:s.handlePushToFigma,handleCopyToFigma:s.handleCopyToFigma,handleDownloadFigmaJson:s.handleDownloadFigmaJson,setIsExportModalOpen:s.setIsExportModalOpen,handleQuickCopyEditablePrototype:s.handleQuickCopyEditablePrototype,handleQuickCopyRuntimeComponent:s.handleQuickCopyRuntimeComponent,handleQuickDownloadRuntimeCover:s.handleQuickDownloadRuntimeCover,handleOpenIdeFile:s.handleOpenIdeFile,handleOpenDocInIDE:s.handleOpenDocInIDE,handleEnableDocEdit:s.handleEnableDocEdit,handleSaveDocEdit:s.handleSaveDocEdit,handleExitDocEdit:s.handleExitDocEdit,handleSwitchDocQuickEditMode:s.handleSwitchDocQuickEditMode,handleOpenThemeInIDE:s.handleOpenThemeInIDE,handleOpenThemeDocInIDE:s.handleOpenThemeDocInIDE,handleOpenDataTableInIDE:s.handleOpenDataTableInIDE,handleEnableSpecEdit:s.handleEnableSpecEdit,handleSaveSpecEdit:s.handleSaveSpecEdit,handleExitSpecEdit:s.handleExitSpecEdit,handleSwitchSpecQuickEditMode:s.handleSwitchSpecQuickEditMode,handleExecuteSpecPrompt:s.handleExecuteSpecPrompt,specPromptCopying:s.specPromptCopying,specPromptExecutingClient:s.specPromptExecutingClient,specExecuteMenuItems:s.specExecuteMenuItems,currentSpecDocKey:s.currentSpecDocKey,specEditState:s.specEditState,specQuickEditMode:s.specQuickEditMode,textEditAvailable:s.textEditAvailable,editorMode:s.editorMode,allowLAN:s.allowLAN,contentMode:s.contentMode,selectedDoc:s.selectedDoc,selectedTemplate:s.selectedTemplate,docEditState:s.docEditState,selectedTheme:s.selectedTheme,selectedDataTable:s.selectedDataTable,preferredPromptClient:s.preferredPromptClient,preferredIDE:s.preferredIDE,assistantVisible:s.assistantVisible,onToggleAssistant:s.onToggleAssistant}),e.jsx("div",{className:"flex-1 min-h-0 relative",children:e.jsx(Ih,{containerRef:s.containerRef,previewIframeRef:s.previewIframeRef,selectedItem:s.selectedItem,activeTab:s.activeTab,currentDevice:s.currentDevice,displaySize:s.displaySize,scale:s.scale,elementIframeKey:s.elementIframeKey,iframeUrl:s.iframeUrl,elementIframeSize:s.elementIframeSize,setElementIframeSize:s.setElementIframeSize,viewMode:s.viewMode,contentMode:s.contentMode,selectedDoc:s.selectedDoc,selectedTemplate:s.selectedTemplate,selectedCanvas:s.selectedCanvas,isDarkMode:s.isDarkMode,selectedTheme:s.selectedTheme,selectedDataTable:s.selectedDataTable})})]})}function Ah({mounted:t,visible:s,width:n,minWidth:a,maxWidth:o,iframeSrc:i,iframeRef:l,onLoad:c,onResize:d}){return t?e.jsx(Ki,{size:{width:Math.min(Math.max(n,a),o),height:"100%"},minWidth:a,maxWidth:o,enable:{left:!0,right:!1,top:!1,bottom:!1,topLeft:!1,topRight:!1,bottomLeft:!1,bottomRight:!1},onResize:(w,j,$)=>{const v=Math.min(Math.max($.getBoundingClientRect().width,a),o);d(v)},style:{borderLeft:"1px solid hsl(var(--border-strong))",background:"hsl(var(--card))",display:s?"flex":"none",flexDirection:"column",height:"100vh",minHeight:0},children:e.jsx("iframe",{ref:l,src:i,title:"Axhub Genie",onLoad:c,style:{border:"none",width:"100%",height:"100%"}})}):null}function Rh({sidebarProps:t,presentationAreaProps:s,assistantPanel:n}){return e.jsx("div",{className:"pc-layout",children:e.jsxs("div",{style:{display:"flex",height:"100vh",minHeight:0},children:[e.jsx(ih,{...t}),e.jsxs("div",{style:{display:"flex",flex:1,minWidth:0},children:[e.jsx(Dh,{...s}),e.jsx(Ah,{mounted:n.mounted,visible:n.visible,width:n.width,minWidth:n.minWidth,maxWidth:n.maxWidth,iframeSrc:n.iframeSrc,iframeRef:n.iframeRef,onLoad:n.onLoad,onResize:n.onResize})]})]})})}function $h({loading:t,items:s,searchText:n,assistantVisible:a,onSearchTextChange:o,onWeChatConnect:i,onCopyProjectDirectory:l,onOpenAssistant:c,onOpenItem:d,onOpenQuickEdit:w,onOpenAssistantWithItemContext:j}){const $=s.filter(v=>{const D=n.toLowerCase();return v.name.toLowerCase().includes(D)||v.displayName.toLowerCase().includes(D)});return e.jsx("div",{className:"mobile-layout",style:{display:"none"},children:e.jsxs("div",{style:{padding:"16px",minHeight:"100vh",background:"hsl(var(--surface-page))"},children:[e.jsxs("div",{style:{marginBottom:"16px",display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsx("div",{children:e.jsxs("h1",{style:{margin:0,fontSize:"24px",fontWeight:600,color:"hsl(var(--foreground))"},children:["Axhub ",e.jsx("span",{style:{color:"hsl(var(--brand))"},children:"Make"})]})}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsx(te,{variant:"ghost",size:"icon",title:"连接微信 (Beta)","aria-label":"连接微信 (Beta)",onClick:i,children:e.jsx(Pa,{className:"h-4 w-4"})}),e.jsx(te,{variant:"ghost",size:"icon",title:"复制项目目录","aria-label":"复制项目目录",onClick:()=>void l(),children:e.jsx(ss,{className:"h-4 w-4"})}),e.jsx(Hi,{state:a?"awake":"sleeping",size:32,onClick:c})]})]}),e.jsxs("div",{style:{position:"relative",marginBottom:"16px"},children:[e.jsx(Ia,{className:"h-4 w-4",style:{position:"absolute",left:10,top:10,color:"hsl(var(--muted-foreground))"}}),e.jsx(Ps,{placeholder:"搜索...",value:n,onChange:v=>o(v.target.value),style:{paddingLeft:34}})]}),t?e.jsxs("div",{style:{textAlign:"center",padding:"40px 0"},children:[e.jsx(gt,{className:"mx-auto h-5 w-5 animate-spin"}),e.jsx("div",{style:{marginTop:8,color:"hsl(var(--muted-foreground))",fontSize:12},children:"加载中..."})]}):e.jsx("div",{children:$.length===0?e.jsx("div",{style:{textAlign:"center",padding:"40px 0",color:"hsl(var(--muted-foreground))"},children:"暂无原型"}):$.map(v=>e.jsxs("div",{className:"mobile-item-card",onClick:()=>d(v),style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[e.jsxs("div",{style:{flex:1,minWidth:0,paddingRight:12},children:[e.jsx("div",{className:"mobile-item-title truncate",children:v.displayName}),e.jsx("div",{className:"mobile-item-name truncate",children:v.name})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:2},children:[e.jsx(te,{variant:"ghost",size:"icon",title:"快速编辑",className:"shrink-0",onClick:D=>{D.stopPropagation(),w(v)},children:e.jsx(rn,{className:"h-4 w-4"})}),e.jsx(te,{variant:"ghost",size:"icon",title:"使用上下文对话",className:"shrink-0",onClick:D=>{D.stopPropagation(),j(v)},children:e.jsx(Pa,{className:"h-4 w-4"})})]})]},v.name))})]})})}function Oh({sidebarProps:t,presentationAreaProps:s,assistantPanelProps:n,dialogsProps:a,mobileProps:o}){return e.jsxs("div",{style:{overflowX:"hidden",minHeight:"100vh","--mobile-item-bg":"hsl(var(--card))","--mobile-item-border":"hsl(var(--border))","--mobile-item-hover-border":"hsl(var(--ring))","--mobile-item-hover-shadow":"var(--shadow-sm)","--mobile-item-title-color":"hsl(var(--foreground))","--mobile-item-name-color":"hsl(var(--muted-foreground))"},children:[e.jsx(Rh,{sidebarProps:t,presentationAreaProps:s,assistantPanel:n}),e.jsx(Bm,{...a}),e.jsx($h,{...o})]})}function Na(t,s,n,a){if(s.contentType==="title"){const o=s.width,i=s.height,l=o/2,c=i/2;return`<svg width="${o}" height="${i}" viewBox="0 0 ${o} ${i}" xmlns="http://www.w3.org/2000/svg" role="img">
|
||
<rect width="100%" height="100%" fill="transparent" />
|
||
<g id="textGroup" transform="translate(${l},${c})">
|
||
<!-- Main Title -->
|
||
<text id="mainTitle"
|
||
x="0" y="-12"
|
||
text-anchor="middle"
|
||
font-family="Arial, Helvetica, sans-serif"
|
||
font-size="28"
|
||
font-weight="700"
|
||
fill="#333">
|
||
${n}
|
||
</text>
|
||
|
||
<!-- Description -->
|
||
<text id="description"
|
||
x="0" y="18"
|
||
text-anchor="middle"
|
||
font-family="Arial, Helvetica, sans-serif"
|
||
font-size="14"
|
||
font-weight="400"
|
||
fill="#999">
|
||
Axhub Runtime ${a}
|
||
</text>
|
||
</g>
|
||
</svg>`}else return`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${s.width}" height="${s.height}" viewBox="0 0 ${s.width} ${s.height}">
|
||
<rect width="100%" height="100%" fill="transparent" />
|
||
<image x="0" y="0" width="${s.width}" height="${s.height}" preserveAspectRatio="xMidYMin meet" xlink:href="${t}"/>
|
||
</svg>`}function qo(t,s,n,a=2){return new Promise((o,i)=>{const l=new Image,c=new Blob([t],{type:"image/svg+xml;charset=utf-8"}),d=URL.createObjectURL(c);l.onload=()=>{const w=document.createElement("canvas");w.width=s*a,w.height=n*a;const j=w.getContext("2d");if(!j){i(new Error("Could not get canvas context"));return}j.drawImage(l,0,0,w.width,w.height),URL.revokeObjectURL(d),o(w.toDataURL("image/png"))},l.onerror=w=>{URL.revokeObjectURL(d),i(w)},l.src=d})}const _l=qi;function Ka(t){const s=Array.from(new Set(t.map(n=>String(n||"").trim()).filter(Boolean)));return s.length===0?"- 当前未提供引用列表,请你先补充扫描并核对项目内引用。":s.map(n=>`- \`${n}\``).join(`
|
||
`)}function va(t){const{title:s,selected:n,available:a,toLine:o}=t;return n.length===0?"":`
|
||
|
||
${s}${n.map(i=>{const l=a.find(c=>c.name===i);return`
|
||
${o(i,l)}`}).join("")}`}function _h(t){const s=new Set(t.map(c=>String(c||"").trim()).filter(Boolean));if(s.size===0)return"";const n=new Set,a=[],o=new Set,i=[];for(const c of _l.skills??[]){if(!s.has(c.id))continue;let d=!1;for(const w of c.localPaths??[]){const j=String(w||"").trim();!j||n.has(j)||(n.add(j),a.push(j),d=!0)}if(!d)for(const w of c.references??[]){const j=String(w||"").trim();!j||o.has(j)||(o.add(j),i.push(j))}}return a.length===0&&i.length===0?"":`
|
||
|
||
**使用项目技能**:
|
||
${(a.length>0?a:i).map(c=>`- \`${c}\``).join(`
|
||
`)}`}function Zo(){const t=(_l.skills??[]).filter(s=>!!s.defaultSelected).map(s=>s.id).filter(Boolean);return t.length>0?t:["brainstorming"]}function Lh(t=[],s=[],n=[],a=[],o=[],i=[],l=[],c=[],d=[]){const w=_h(t),j=va({title:"**📚 参考文档**:",selected:s,available:n,toLine:(u,C)=>`- **\`/docs/${u}\`** - ${(C==null?void 0:C.displayName)||u}`}),$=va({title:"**📊 参考数据**:",selected:a,available:o,toLine:(u,C)=>`- **\`/src/database/${u}\`** - ${(C==null?void 0:C.displayName)||u}`}),v=va({title:"**🧩 参考模板**:",selected:i,available:l,toLine:(u,C)=>`- **\`/docs/templates/${u}\`** - ${(C==null?void 0:C.displayName)||u}`}),D=va({title:"**🖼️ 参考原型**:",selected:c,available:d,toLine:(u,C)=>`- **\`/src/prototypes/${u}/\`** - ${(C==null?void 0:C.displayName)||u}`});return`**系统指令**:协助用户「新建一个文档」。
|
||
|
||
⚠️ **重要提示**:请务必完整阅读以下要求与参考资料,先完成需求对齐,再进行文档产出。
|
||
|
||
**系统交互要求**:
|
||
- 收到本条系统指令后,必须先向用户回复一次,并等待用户补充信息/确认;未完成对齐前不要写入/更新任何文件
|
||
- 告知:已经准备好开始新建文档
|
||
|
||
**目标目录**:\`src/docs\`
|
||
**输出格式**:一个 \`.md\` 文件(文件名由你和用户一起确定,优先 kebab-case)${w}${j}${D?"\n\n补充说明:对于参考原型,请直接读取对应原型目录下的源码与 `spec.md` 等信息,作为当前文档内容的参考。":""}${D}${$}${v}
|
||
|
||
**完成后请输出**:
|
||
- 你创建/更新的文件路径(\`src/docs/<file>.md\`)
|
||
- 文档的目录结构(TOC 或大纲)`}function Mh(t){const s=String(t.docName||"").trim(),n=String(t.currentDisplayName||"").trim()||s,a=String(t.nextBaseName||"").trim(),o=s.includes(".")?s.slice(s.lastIndexOf(".")):".md",i=a.toLowerCase().endsWith(o.toLowerCase())?a:`${a}${o}`;return`我想重命名文档「${n}」。
|
||
|
||
当前文件路径:\`src/docs/${s}\`
|
||
目标文件路径:\`src/docs/${i}\`
|
||
|
||
已检测到以下项目内引用文件:
|
||
${Ka(t.references)}
|
||
|
||
请按以下要求处理:
|
||
1. 先核对以上引用是否完整准确,并补充遗漏的引用位置。
|
||
2. 将所有引用 \`src/docs/${s}\`、\`/docs/${s}\`、\`/docs/${s.replace(/\.[^./\\]+$/u,"")}\` 的位置同步更新为新路径。
|
||
3. 确认所有引用修复完成后,再执行文档重命名。
|
||
4. 最后反馈:修改了哪些文件、最终文档路径是什么、是否还有残留引用。`}function Uh(t){const s=String(t.docName||"").trim();return`我想删除文档「${String(t.currentDisplayName||"").trim()||s}」。
|
||
|
||
目标文件路径:\`src/docs/${s}\`
|
||
|
||
已检测到以下项目内引用文件:
|
||
${Ka(t.references)}
|
||
|
||
请按以下要求处理:
|
||
1. 先核对以上引用是否完整准确,并补充遗漏的引用位置。
|
||
2. 对所有引用该文档的位置,执行替换、移除或改写,确保项目内不再依赖 \`src/docs/${s}\` 或对应 \`/docs/\` 链接。
|
||
3. 确认所有引用都已清理后,再删除该文档。
|
||
4. 最后反馈:修改了哪些文件、文档是否已删除、是否还有残留引用。`}function Fh(t){const s=String(t.templateName||"").trim(),n=String(t.currentDisplayName||"").trim()||s,a=String(t.nextBaseName||"").trim(),o=s.includes(".")?s.slice(s.lastIndexOf(".")):".md",i=a.toLowerCase().endsWith(o.toLowerCase())?a:`${a}${o}`;return`我想重命名文档模板「${n}」。
|
||
|
||
当前文件路径:\`src/docs/templates/${s}\`
|
||
目标文件路径:\`src/docs/templates/${i}\`
|
||
|
||
已检测到以下项目内引用文件:
|
||
${Ka(t.references)}
|
||
|
||
请按以下要求处理:
|
||
1. 先核对以上引用是否完整准确,并补充遗漏的引用位置。
|
||
2. 将所有引用 \`src/docs/templates/${s}\`、\`/docs/templates/${s}\`、\`/docs/templates/${s.replace(/\.[^./\\]+$/u,"")}\` 的位置同步更新为新路径。
|
||
3. 确认所有引用修复完成后,再执行模板重命名。
|
||
4. 最后反馈:修改了哪些文件、最终模板路径是什么、是否还有残留引用。`}function zh(t){const s=String(t.templateName||"").trim();return`我想删除文档模板「${String(t.currentDisplayName||"").trim()||s}」。
|
||
|
||
目标文件路径:\`src/docs/templates/${s}\`
|
||
|
||
已检测到以下项目内引用文件:
|
||
${Ka(t.references)}
|
||
|
||
请按以下要求处理:
|
||
1. 先核对以上引用是否完整准确,并补充遗漏的引用位置。
|
||
2. 对所有引用该模板的位置,执行替换、移除或改写,确保项目内不再依赖 \`src/docs/templates/${s}\` 或对应 \`/docs/templates/\` 链接。
|
||
3. 确认所有引用都已清理后,再删除该模板。
|
||
4. 最后反馈:修改了哪些文件、模板是否已删除、是否还有残留引用。`}function Ks(t){return Array.isArray(t)?t.map(s=>String(s||"").trim()).filter(Boolean):[]}function Bh(t){const{activeTab:s,data:n,docsItems:a,canvasItems:o,themes:i,setThemes:l,dataTables:c,setDataTables:d,templateAssets:w,setTemplateAssets:j,resourceOrders:$,setResourceOrders:v,sidebarTrees:D,setSidebarTrees:u,projectTitle:C,setProjectTitle:K,availableDocOptions:y,availablePrototypeOptions:P,availableReferencePrototypeOptions:R,availableDataAssetOptions:L,availableTemplateOptions:F,messageApi:x,modal:V,appDialog:re,setActiveTab:B,setSelectedItem:xe,setSidebarTab:ie,setResourceSection:z,setCreateDialogVisible:se,setCreateDialogSelectedDocs:W,loadData:S,reloadSidebarAssets:Y,reloadDocsItems:k,reloadCanvasItems:N,getSidebarTabItems:U}=t,[A,q]=r.useState(null),[pe,Ne]=r.useState(null),[Ce,Ie]=r.useState(null),[ve,Ue]=r.useState(null),[Fe,Oe]=r.useState(null),[We,E]=r.useState(null),[ce,Pe]=r.useState(!1),[Ee,Te]=r.useState(()=>Zo()),[Ye,nt]=r.useState([]),[Me,b]=r.useState([]),[he,ke]=r.useState([]),[T,Z]=r.useState([]),[de,J]=r.useState(!1),[Ae,ze]=r.useState(()=>Uo()),[ue,ne]=r.useState([]),[me,je]=r.useState([]),[De,ge]=r.useState(!1),[Ze,dt]=r.useState(""),[St,Ut]=r.useState(!1),[wt,Je]=r.useState(""),[tt,st]=r.useState(!1),[rs,Kt]=r.useState(null),[js,pt]=r.useState(null);r.useEffect(()=>{Ne(p=>p&&a.some(Q=>Q.name===p.name)?p:a[0]||null)},[a]),r.useEffect(()=>{Ie(p=>p&&w.some(Q=>Q.name===p.name)?p:w[0]?ln(w[0]):null)},[w]),r.useEffect(()=>{Ue(p=>p&&o.some(Q=>Q.name===p.name)?p:o[0]||null)},[o]),r.useEffect(()=>{Oe(p=>p&&i.some(Q=>Q.name===p.name)?p:i[0]||null)},[i]),r.useEffect(()=>{E(p=>p&&c.some(Q=>Q.fileName===p.fileName)?p:c[0]||null)},[c]),r.useEffect(()=>{if(R.length===0){b([]);return}const p=new Set(R.map(Q=>Q.name));b(Q=>Q.filter(I=>p.has(I)))},[R]);const Rt=r.useCallback(async(p,Q,I)=>{const _=await fetch("/api/docs/check-references",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({docName:p,action:Q,...typeof I=="string"&&I.trim()?{nextBaseName:I.trim()}:{}})}),O=await _.json().catch(()=>({}));if(!_.ok)throw new Error((O==null?void 0:O.error)||"检查文档引用失败");return{docName:String((O==null?void 0:O.docName)||p),references:Ks(O==null?void 0:O.references),hasReferences:!!(O!=null&&O.hasReferences),protected:!!(O!=null&&O.protected),code:typeof(O==null?void 0:O.code)=="string"?O.code:void 0,error:typeof(O==null?void 0:O.error)=="string"?O.error:void 0}},[]),yt=r.useCallback(async(p,Q,I)=>{const _=await fetch("/api/docs/templates/check-references",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({templateName:p,action:Q,...typeof I=="string"&&I.trim()?{nextBaseName:I.trim()}:{}})}),O=await _.json().catch(()=>({}));if(!_.ok)throw new Error((O==null?void 0:O.error)||"检查模板引用失败");return{docName:String((O==null?void 0:O.templateName)||p),references:Ks(O==null?void 0:O.references),hasReferences:!!(O!=null&&O.hasReferences),protected:!!(O!=null&&O.protected),code:typeof(O==null?void 0:O.code)=="string"?O.code:void 0,error:typeof(O==null?void 0:O.error)=="string"?O.error:void 0}},[]),Qe=r.useCallback(p=>{const Q=Array.from(new Set(Ks(p.references))),I=p.action==="rename"?Mh({docName:p.item.name,currentDisplayName:p.item.displayName,nextBaseName:String(p.nextBaseName||"").trim(),references:Q}):Uh({docName:p.item.name,currentDisplayName:p.item.displayName,references:Q});pt({title:p.action==="rename"?"检测到文档引用,需先处理后改名":"检测到文档引用,需先处理后删除",description:p.action==="rename"?`文档「${p.item.displayName}」当前仍被项目内文件引用,请先修复引用,再执行改名。`:`文档「${p.item.displayName}」当前仍被项目内文件引用,请先清理引用,再执行删除。`,references:Q,prompt:I,scene:p.action==="rename"?"rename-doc-ref-fix":"delete-doc-ref-fix",targetPath:Is("doc",p.item.filePath||p.item.name)})},[]),ut=r.useCallback(p=>{const Q=Array.from(new Set(Ks(p.references))),I=p.action==="rename"?Fh({templateName:p.item.name,currentDisplayName:p.item.displayName,nextBaseName:String(p.nextBaseName||"").trim(),references:Q}):zh({templateName:p.item.name,currentDisplayName:p.item.displayName,references:Q});pt({title:p.action==="rename"?"检测到模板引用,需先处理后改名":"检测到模板引用,需先处理后删除",description:p.action==="rename"?`模板「${p.item.displayName}」当前仍被项目内文件引用,请先修复引用,再执行改名。`:`模板「${p.item.displayName}」当前仍被项目内文件引用,请先清理引用,再执行删除。`,references:Q,prompt:I,scene:p.action==="rename"?"rename-template-ref-fix":"delete-template-ref-fix",targetPath:Is("template",p.item.name)})},[]),$e=r.useCallback(async()=>{await Y()},[Y]),Ke=r.useCallback(async()=>{await Promise.all([S(),Y()])},[S,Y]),mt=r.useCallback(()=>{Pe(!1),nt([]),b([]),ke([]),Z([]),Te(Zo())},[]),os=r.useCallback(()=>{J(!1),ne([]),je([]),ze(Uo())},[]),Ot=r.useCallback(()=>{mt()},[mt]),Vt=r.useCallback(()=>{os()},[os]),_t=r.useCallback(()=>{ie("assets"),z("data"),ge(!0),dt(""),Je("")},[z,ie]),Ft=r.useCallback(()=>{St||(ge(!1),dt(""),Je(""))},[St]),Lt=r.useCallback(async()=>{const p=String(Ze||"").trim();if(!p){Je("请输入数据表名称");return}Je(""),Ut(!0);const Q=x.loading("正在创建数据表...",0);try{const I=await fetch("/api/data/tables",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tableName:p})}),_=await I.json().catch(()=>null);if(!I.ok)throw new Error((_==null?void 0:_.error)||"创建数据表失败");const O=String((_==null?void 0:_.fileName)||p);await Y();const G=$.data.includes(O)?$.data:[O,...$.data];v(le=>({...le,data:G})),kt.saveResourceOrder("data",G).catch(()=>{}),E(le=>(le==null?void 0:le.fileName)===O?le:c.find(ye=>ye.fileName===O)||le),Ft(),x.success(`数据表「${String((_==null?void 0:_.tableName)||p)}」创建成功`)}catch(I){x.error((I==null?void 0:I.message)||"创建数据表失败")}finally{Q(),Ut(!1)}},[Ft,c,x,Ze,Y,$.data,v]),is=r.useCallback(async p=>{const Q=A===p?null:p;q(Q);try{const I=await fetch("/api/config"),_=I.ok?await I.json():{},O={..._,projectDefaults:{..._.projectDefaults||{},defaultTheme:Q}};if(!(await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(O)})).ok)throw new Error("保存默认主题失败");await fetch("/api/themes/sync-design",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({themeName:Q||""})}).catch(()=>{}),x.success(Q?"已设为默认主题":"已取消默认主题")}catch(I){q(A),x.error((I==null?void 0:I.message)||"设置默认主题失败")}},[A,x]),et=r.useCallback(async p=>{const Q=Ks(p);l(I=>Ls(I,Q,_=>_.name)),v(I=>({...I,themes:Q}));try{await kt.saveResourceOrder("themes",Q)}catch(I){x.error((I==null?void 0:I.message)||"保存主题排序失败")}},[x,v,l]),Ss=r.useCallback(async p=>{const Q=Ks(p);d(I=>Ls(I,Q,_=>_.fileName)),v(I=>({...I,data:Q}));try{await kt.saveResourceOrder("data",Q)}catch(I){x.error((I==null?void 0:I.message)||"保存数据表排序失败")}},[x,d,v]),Ht=r.useCallback(async p=>{const Q=Ks(p);j(I=>Ls(I,Q,_=>_.name)),v(I=>({...I,templates:Q}));try{await kt.saveResourceOrder("templates",Q)}catch(I){x.error((I==null?void 0:I.message)||"保存模板排序失败")}},[x,v,j]),qt=r.useCallback(async(p,Q)=>{const I=x.loading("正在导出 ZIP...",0);try{const _=`/api/zip?path=${encodeURIComponent(p)}`,O=await fetch(`${_}&probe=1`);if(!O.ok){const le=await O.json().catch(()=>({}));throw new Error((le==null?void 0:le.error)||`导出失败(${O.status})`)}const G=document.createElement("a");G.href=`${_}&download=1&_ts=${Date.now()}`,G.download=Q,document.body.appendChild(G),G.click(),document.body.removeChild(G),x.success("已开始下载 ZIP")}catch(_){x.error((_==null?void 0:_.message)||"ZIP 导出失败")}finally{I()}},[x]),at=r.useCallback(p=>{qt(`themes/${p.name}`,`${p.name}.zip`)},[qt]),Qt=r.useCallback(async(p,Q)=>{const I=typeof Q=="string"?Q:await re.prompt({title:"重命名主题",description:"请输入新的主题名称。",label:"主题名称",defaultValue:p.displayName||p.name,confirmText:"确认重命名",cancelText:"取消",validate:G=>String(G||"").trim()?null:"主题名称不能为空"});if(I==null)return;const _=String(I||"").trim();if(!_||_===(p.displayName||p.name))return;const O=x.loading("正在重命名主题...",0);try{const G=await fetch(`/api/themes/${encodeURIComponent(p.name)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:_})});if(!G.ok){const le=await G.json().catch(()=>({}));throw new Error((le==null?void 0:le.error)||"主题重命名失败")}l(le=>le.map(ye=>ye.name===p.name?{...ye,displayName:_}:ye)),Oe(le=>(le==null?void 0:le.name)===p.name?{...le,displayName:_}:le),x.success("主题重命名成功")}catch(G){x.error((G==null?void 0:G.message)||"主题重命名失败")}finally{O()}},[re,x,l]),Ct=r.useCallback(async p=>{if(!await re.confirm({title:`删除主题「${p.displayName||p.name}」?`,description:"删除后无法恢复,请确认是否继续。",confirmText:"确认删除",cancelText:"取消",tone:"destructive",dismissible:!1}))return;const I=x.loading("正在删除主题...",0);try{const _=await fetch(`/api/themes/${encodeURIComponent(p.name)}`,{method:"DELETE"});if(!_.ok){const G=await _.json().catch(()=>({}));throw new Error((G==null?void 0:G.error)||"删除失败")}l(G=>G.filter(le=>le.name!==p.name)),Oe(G=>(G==null?void 0:G.name)===p.name?null:G);const O=$.themes.filter(G=>G!==p.name);v(G=>({...G,themes:O})),kt.saveResourceOrder("themes",O).catch(()=>{}),x.success("主题删除成功")}catch(_){x.error((_==null?void 0:_.message)||"主题删除失败")}finally{I()}},[re,x,$.themes,v,l]),Xt=r.useCallback(async(p,Q)=>{const I=typeof Q=="string"?Q:await re.prompt({title:"重命名数据表",description:"请输入新的数据表名称。",label:"数据表名称",defaultValue:p.tableName,confirmText:"确认重命名",cancelText:"取消",validate:G=>String(G||"").trim()?null:"数据表名称不能为空"});if(I==null)return;const _=String(I||"").trim();if(!_||_===p.tableName)return;const O=x.loading("正在重命名数据表...",0);try{const G=await fetch(`/api/data/tables/${encodeURIComponent(p.fileName)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({tableName:_})});if(!G.ok){const le=await G.json().catch(()=>({}));throw new Error((le==null?void 0:le.error)||"重命名失败")}d(le=>le.map(ye=>ye.fileName===p.fileName?{...ye,tableName:_}:ye)),E(le=>(le==null?void 0:le.fileName)===p.fileName?{...le,tableName:_}:le),x.success("数据表重命名成功")}catch(G){x.error((G==null?void 0:G.message)||"数据表重命名失败")}finally{O()}},[re,x,d]),zt=r.useCallback(async p=>{if(!await re.confirm({title:`删除数据表「${p.tableName}」?`,description:"删除后无法恢复,请确认是否继续。",confirmText:"确认删除",cancelText:"取消",tone:"destructive",dismissible:!1}))return;const I=x.loading("正在删除数据表...",0);try{const _=await fetch(`/api/data/tables/${encodeURIComponent(p.fileName)}`,{method:"DELETE"});if(!_.ok){const G=await _.json().catch(()=>({}));throw new Error((G==null?void 0:G.error)||"删除失败")}d(G=>G.filter(le=>le.fileName!==p.fileName)),E(G=>(G==null?void 0:G.fileName)===p.fileName?null:G);const O=$.data.filter(G=>G!==p.fileName);v(G=>({...G,data:O})),kt.saveResourceOrder("data",O).catch(()=>{}),x.success("数据表删除成功")}catch(_){x.error((_==null?void 0:_.message)||"数据表删除失败")}finally{I()}},[re,x,$.data,d,v]),As=r.useCallback(async()=>{const p=await re.prompt({title:"新建模板",description:"请输入模板文件名,建议使用英文 kebab-case,可不带 .md。",label:"模板文件名",placeholder:"例如 landing-hero.md",confirmText:"创建模板",cancelText:"取消",validate:_=>String(_||"").trim()?null:"模板文件名不能为空"});if(p==null)return;const Q=String(p||"").trim();if(!Q){x.warning("模板文件名不能为空");return}const I=x.loading("正在创建模板...",0);try{const _=await fetch("/api/docs/templates",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:qs(Q)||Q,fileName:Q})}),O=await _.json().catch(()=>null);if(!_.ok)throw new Error((O==null?void 0:O.error)||"创建模板失败");await Y();const G=String((O==null?void 0:O.name)||"").trim();if(G){const le=ln({name:G});Ie(le),ie("assets"),z("templates"),v(ye=>{const _e=ye.templates.includes(G)?ye.templates:[G,...ye.templates];return kt.saveResourceOrder("templates",_e).catch(()=>{}),{...ye,templates:_e}})}x.success(`模板「${qs(G)||Q}」创建成功`)}catch(_){x.error((_==null?void 0:_.message)||"创建模板失败")}finally{I()}},[re,x,Y,v,z,ie]),ps=r.useCallback(async(p,Q)=>{const I=p.name,_=I.lastIndexOf("."),O=_>0?I.slice(0,_):I,G=_>0?I.slice(_):"";let le=typeof Q=="string"?Q:"";if(!le){const _e=await re.prompt({title:"重命名模板",description:"请输入新的模板文件名。",label:"模板文件名",defaultValue:O,confirmText:"确认重命名",cancelText:"取消",validate:ht=>String(ht||"").trim()?null:"模板文件名不能为空"});if(_e==null)return;le=_e}const ye=x.loading("正在重命名模板...",0);try{if(ir(I))throw new Error("系统模板不支持重命名");let _e=String(le||"").trim();if(!_e)throw new Error("模板文件名不能为空");if(G&&_e.toLowerCase().endsWith(G.toLowerCase())&&(_e=_e.slice(0,-G.length).trim()),!_e||_e===O)return;const ht=await yt(I,"rename",_e);if(ht.protected||ir(I))throw new Error(ht.error||"系统模板不支持重命名");if(ht.references.length>0){ut({action:"rename",item:p,references:ht.references,nextBaseName:_e});return}const xt=await fetch(`/api/docs/templates/${encodeURIComponent(I)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({newBaseName:_e})}),g=await xt.json().catch(()=>({}));if(!xt.ok){if(g.code==="PROTECTED_TEMPLATE")throw new Error(g.error||"系统模板不支持重命名");if(g.code==="TEMPLATE_REFERENCED"&&Array.isArray(g.references)&&g.references.length>0){ut({action:"rename",item:p,references:g.references,nextBaseName:_e});return}throw new Error(g.error||"重命名失败")}const h=typeof(g==null?void 0:g.name)=="string"?g.name:`${_e}${G}`,M=ln({name:h});Ie(ee=>(ee==null?void 0:ee.name)===I?M:ee),Z(ee=>ga(ee,I,h)),j(ee=>ee.map(we=>we.name===I?{...we,name:h,displayName:M.displayName}:we)),v(ee=>{const we=ga(ee.templates,I,h);return kt.saveResourceOrder("templates",we).catch(()=>{}),{...ee,templates:we}}),x.success("模板重命名成功")}catch(_e){x.error((_e==null?void 0:_e.message)||"模板重命名失败")}finally{ye()}},[re,yt,x,ut,v,j]),fs=r.useCallback(async p=>{const Q=x.loading("正在创建模板副本...",0);try{const I=await fetch(`/api/docs/templates/${encodeURIComponent(p.name)}/copy`,{method:"POST"}),_=await I.json().catch(()=>({}));if(!I.ok)throw new Error(_.error||"创建副本失败");await Y();const O=String((_==null?void 0:_.name)||"").trim();O&&(Ie(ln({name:O})),v(G=>{const le=G.templates.includes(O)?G.templates:[O,...G.templates];return kt.saveResourceOrder("templates",le).catch(()=>{}),{...G,templates:le}})),x.success("模板副本创建成功")}catch(I){x.error((I==null?void 0:I.message)||"创建模板副本失败")}finally{Q()}},[x,Y,v]),Bt=r.useCallback(async p=>{const Q=x.loading("正在检查模板引用...",0);try{const O=await yt(p.name,"delete");if(O.protected||ir(p.name)){x.error(O.error||"系统模板不支持删除");return}if(O.references.length>0){ut({action:"delete",item:p,references:O.references});return}}catch(O){x.error((O==null?void 0:O.message)||"检查模板引用失败");return}finally{Q()}if(!await re.confirm({title:`删除模板「${p.displayName}」?`,description:"删除后无法恢复,请确认是否继续。",confirmText:"确认删除",cancelText:"取消",tone:"destructive",dismissible:!1}))return;const _=x.loading("正在删除模板...",0);try{const O=await fetch(`/api/docs/templates/${encodeURIComponent(p.name)}`,{method:"DELETE"}),G=await O.json().catch(()=>({}));if(!O.ok){if(G.code==="PROTECTED_TEMPLATE")throw new Error(G.error||"系统模板不支持删除");if(G.code==="TEMPLATE_REFERENCED"&&Array.isArray(G.references)&&G.references.length>0){ut({action:"delete",item:p,references:G.references});return}throw new Error(G.error||"删除失败")}j(ye=>ye.filter(_e=>_e.name!==p.name)),Ie(ye=>(ye==null?void 0:ye.name)===p.name?null:ye),Z(ye=>ye.filter(_e=>_e!==p.name));const le=$.templates.filter(ye=>ye!==p.name);v(ye=>({...ye,templates:le})),kt.saveResourceOrder("templates",le).catch(()=>{}),x.success("模板删除成功")}catch(O){x.error((O==null?void 0:O.message)||"模板删除失败")}finally{_()}},[re,yt,x,ut,$.templates,v,j]),Us=r.useCallback(async p=>{try{await navigator.clipboard.writeText(Is("template",p.name)),x.success("路径已复制")}catch{x.error("复制失败")}},[x]),ls=r.useCallback(p=>{Kt(ln(p)),st(!0)},[]),Yt=r.useCallback(p=>{qt(`${s}/${p.name}`,`${p.name}.zip`)},[s,qt]),ft=r.useCallback(async(p,Q)=>{let I=typeof Q=="string"?Q:"";if(!I){const G=await re.prompt({title:s==="components"?"重命名组件":"重命名原型",description:"请输入新的显示名称。",label:"显示名称",defaultValue:p.displayName,confirmText:"确认重命名",cancelText:"取消",validate:le=>String(le||"").trim()?null:"名称不能为空"});if(G==null)return;I=G}const _=String(I||"").trim();if(!_||_===p.displayName)return;const O=x.loading("正在重命名...",0);try{const G=s==="components"?`components/${p.name}`:`prototypes/${p.name}`,le=await fetch("/api/rename",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:G,newName:_})});if(!le.ok){const ye=await le.json().catch(()=>({}));throw new Error(ye.error||"重命名失败")}x.success(s==="components"?"组件重命名成功":"原型重命名成功"),await S()}catch(G){x.error((G==null?void 0:G.message)||"重命名失败")}finally{O()}},[s,re,S,x]),tn=r.useCallback(async p=>{const Q=s==="components"?"components":"prototypes",I=(s==="components"?n.components:n.prototypes).map(G=>G.name),_=G=>{let le=`${G}-copy`,ye=1;for(;I.includes(le);)ye+=1,le=`${G}-copy${ye}`;return le},O=x.loading("正在创建副本...",0);try{const G=_(p.name),le=await fetch("/api/copy",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourcePath:`src/${Q}/${p.name}`,targetPath:`src/${Q}/${G}`})});if(!le.ok){const ye=await le.json().catch(()=>({}));throw new Error(ye.error||"创建副本失败")}x.success(`副本 "${G}" 创建成功`),await S()}catch(G){x.error((G==null?void 0:G.message)||"创建副本失败")}finally{O()}},[s,n.components,n.prototypes,S,x]),yn=r.useCallback(async(p,Q,I)=>{const _=s,O=s==="components"?"组件":"原型",G=`${_}/${p.name}`,le=async()=>{const _e=x.loading("正在删除...",0);try{const ht=await fetch("/api/delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:G})});if(!ht.ok){const xt=await ht.json().catch(()=>({}));throw new Error(xt.error||"删除失败")}xe(null),await S(),x.success("删除成功")}catch(ht){throw x.error((ht==null?void 0:ht.message)||"删除失败"),ht}finally{_e()}},ye=x.loading("正在检查引用...",0);try{const _e=await fetch("/api/items/check-references",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({itemType:_,itemName:p.name})}),ht=_e.ok?await _e.json().catch(()=>null):null,xt=Ks(ht==null?void 0:ht.references),g=[`- src/${_}/${p.name}`].join(`
|
||
`);if(xt.length>0){const h=xt.map(ee=>`- ${ee}`).join(`
|
||
`),M=[`我希望删除${O} "${p.displayName}" (${p.name})。`,"本次将删除以下目录:",g,"",`已检测到以下文件引用了本次待删除的${O}:`,h,"","请帮我执行以下检查和操作:","1. 核对上述引用是否准确,并补充遗漏的引用文件(优先检查 `src/components/` 与 `src/prototypes/`)。","2. 如果确认继续删除,请协助我将这些引用替换为合适的实现,并更新引用路径,使这些原型不再依赖上述目录。","3. 完成上述解耦操作后,再彻底删除以上目录。"].join(`
|
||
`);V.confirm({title:`检测到${O}引用`,width:720,okText:"关闭",cancelText:"取消",content:e.jsxs("div",{children:[e.jsx("div",{style:{marginBottom:8},children:"本次将删除以下目录:"}),e.jsx("pre",{style:{maxHeight:160,overflow:"auto",background:"hsl(var(--muted))",padding:12,borderRadius:6},children:g}),e.jsxs("div",{style:{marginTop:12,marginBottom:8},children:["已检测到以下文件引用了本次待删除的",O,":"]}),e.jsx("pre",{style:{maxHeight:260,overflow:"auto",background:"hsl(var(--muted))",padding:12,borderRadius:6},children:h}),e.jsx("div",{style:{marginTop:12,display:"flex",justifyContent:"flex-end"},children:e.jsx(hs,{type:"primary",preferredClient:Q??null,preferredIDE:I??null,getIdeTargetPath:()=>`src/${_}/${p.name}`,scene:`delete-ref-fix-${_}`,buildPrompt:()=>M,copySuccessMessage:"已复制处理提示,请返回编辑器让 AI 处理。",executeSuccessMessage:"已打开新会话",fallbackMessage:"自动执行失败,已回退为复制 Prompt"})})]})});return}}catch(_e){x.error((_e==null?void 0:_e.message)||"检查引用失败");return}finally{ye()}V.confirm({title:`确定要删除${O} "${p.displayName}" 吗?`,content:"未检测到引用文件。删除后无法恢复,请谨慎操作。",okText:"确认删除",okType:"danger",cancelText:"取消",onOk:le})},[s,S,x,V,xe]),bn=r.useCallback(async(p,Q)=>{const I=p.name,_=I.lastIndexOf("."),O=_>0?I.slice(0,_):I,G=_>0?I.slice(_):"",le=x.loading("正在重命名...",0);try{let ye=String(Q||"").trim();if(!ye)throw new Error("文档名称不能为空");if(G&&ye.toLowerCase().endsWith(G.toLowerCase())&&(ye=ye.slice(0,-G.length).trim()),!ye||ye===O)return;const _e=await Rt(I,"rename",ye);if(_e.protected||Ro(I))throw new Error(_e.error||"项目总览入口文档禁止改名,可继续编辑内容");if(_e.references.length>0){Qe({action:"rename",item:p,references:_e.references,nextBaseName:ye});return}const ht=await fetch(`/api/docs/${encodeURIComponent(I)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({newBaseName:ye})}),xt=await ht.json().catch(()=>({}));if(!ht.ok){if(xt.code==="PROTECTED_DOC")throw new Error(xt.error||"项目总览入口文档禁止改名,可继续编辑内容");if(xt.code==="DOC_REFERENCED"&&Array.isArray(xt.references)&&xt.references.length>0){Qe({action:"rename",item:p,references:xt.references,nextBaseName:ye});return}throw new Error(xt.error||"重命名失败")}const g=typeof(xt==null?void 0:xt.name)=="string"?xt.name:`${ye}${G}`,h=qs(g)||g,M=(()=>{let Xe=!1;const Wt=a.map(ys=>ys.name!==I?ys:(Xe=!0,{...ys,name:g,displayName:h,filePath:Is("doc",g)}));return Xe||Wt.push(cl({name:g})),Wt})(),ee=`docs/${I}`,we=`docs/${g}`,{nextTree:Ge,replaced:qe}=vu(D.docs,ee,we,h);if(qe){const Xe=Vs("docs",Ge,M);u(Wt=>({...Wt,docs:Xe}));try{await kt.saveSidebarTree("docs",Xe)}catch{}}nt(Xe=>ga(Xe,I,g)),ne(Xe=>ga(Xe,I,g));const Le=await k(),Ve=Le.find(Xe=>Xe.name===g);Ne(Ve||Le[0]||null),x.success("重命名成功")}catch(ye){x.error((ye==null?void 0:ye.message)||"重命名失败")}finally{le()}},[Rt,a,x,Qe,k,u,D.docs]),wn=r.useCallback(async p=>{const Q=x.loading("正在创建副本...",0);try{const I=await fetch(`/api/docs/${encodeURIComponent(p.name)}/copy`,{method:"POST"}),_=await I.json().catch(()=>({}));if(!I.ok)throw new Error(_.error||"创建副本失败");const G=(await k()).find(le=>le.name===(_==null?void 0:_.name));G&&Ne(G),x.success("文档副本创建成功")}catch(I){x.error((I==null?void 0:I.message)||"创建副本失败")}finally{Q()}},[x,k]),He=r.useCallback(async p=>{const Q=x.loading("正在检查引用...",0);try{const I=await Rt(p.name,"delete");if(I.protected||Ro(p.name)){x.error(I.error||"项目总览入口文档禁止删除");return}if(I.references.length>0){Qe({action:"delete",item:p,references:I.references});return}}catch(I){x.error((I==null?void 0:I.message)||"检查文档引用失败");return}finally{Q()}V.confirm({title:`确定要删除文档 "${p.displayName}" 吗?`,content:"删除后无法恢复,请谨慎操作。",okText:"确认删除",okType:"danger",cancelText:"取消",onOk:async()=>{const I=x.loading("正在删除...",0);try{const _=await fetch(`/api/docs/${encodeURIComponent(p.name)}`,{method:"DELETE"}),O=await _.json().catch(()=>({}));if(!_.ok){if(O.code==="PROTECTED_DOC")throw new Error(O.error||"项目总览入口文档禁止删除");if(O.code==="DOC_REFERENCED"&&Array.isArray(O.references)&&O.references.length>0){Qe({action:"delete",item:p,references:O.references});return}throw new Error(O.error||"删除失败")}const G=await k();Ne(le=>le&&le.name!==p.name?G.find(ye=>ye.name===le.name)||G[0]||null:G[0]||null),x.success("删除成功")}catch(_){return x.error((_==null?void 0:_.message)||"删除失败"),Promise.reject(_)}finally{I()}}})},[Rt,x,V,Qe,k]),Ns=r.useCallback(async p=>{try{await navigator.clipboard.writeText(Is("doc",p.filePath||p.name)),x.success("路径已复制")}catch{x.error("复制失败")}},[x]),rt=r.useCallback(p=>{Kt({...p,filePath:Is("doc",p.filePath||p.name)}),st(!0)},[]),$t=r.useCallback(async p=>{W([p.name]),B("prototypes"),ie("prototype"),se(!0)},[B,W,se,ie]),Rs=r.useCallback(p=>{if(p==="components"){ie("assets"),z("components"),B("components"),se(!0);return}if(p==="themes"){ie("assets"),z("themes"),J(!0);return}if(p==="data"){_t();return}ie("assets"),z("templates"),As()},[As,_t,B,se,z,ie]),jn=r.useCallback(()=>{ie("document"),Pe(!0)},[ie]),xs=r.useCallback(async()=>{try{const p=await fetch("/api/canvas/create",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({displayName:""})});if(!p.ok){const O=await p.json().catch(()=>({}));throw new Error((O==null?void 0:O.error)||"创建画布失败")}const Q=await p.json(),_=(await N()).find(O=>O.name===Q.name);_&&(ie("canvas"),Ue(_))}catch(p){x.error((p==null?void 0:p.message)||"创建画布失败")}},[x,N,ie]),sn=r.useCallback(async(p,Q)=>{const I=x.loading("正在重命名...",0);try{const _=await fetch(`/api/canvas/${encodeURIComponent(p.name)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({newBaseName:Q})});if(!_.ok){const ye=await _.json().catch(()=>({}));throw new Error((ye==null?void 0:ye.error)||"重命名失败")}const O=await _.json(),le=(await N()).find(ye=>ye.name===O.name);le&&Ue(le)}catch(_){x.error((_==null?void 0:_.message)||"重命名画布失败")}finally{I()}},[x,N]),Gn=r.useCallback(async p=>{const Q=x.loading("正在复制...",0);try{const I=await fetch(`/api/canvas/${encodeURIComponent(p.name)}/copy`,{method:"POST"});if(!I.ok){const le=await I.json().catch(()=>({}));throw new Error((le==null?void 0:le.error)||"复制画布失败")}const _=await I.json(),G=(await N()).find(le=>le.name===_.name);G&&Ue(G)}catch(I){x.error((I==null?void 0:I.message)||"复制画布失败")}finally{Q()}},[x,N]),Nn=r.useCallback(async p=>{V.confirm({title:"确认删除",content:`确定要删除画布 "${p.displayName}" 吗?`,okText:"删除",cancelText:"取消",okButtonProps:{danger:!0},onOk:async()=>{try{const Q=await fetch(`/api/canvas/${encodeURIComponent(p.name)}`,{method:"DELETE"});if(!Q.ok){const _=await Q.json().catch(()=>({}));throw new Error((_==null?void 0:_.error)||"删除画布失败")}const I=await N();Ue(_=>_&&_.name!==p.name?_:I[0]||null)}catch(Q){x.error((Q==null?void 0:Q.message)||"删除画布失败")}}})},[x,V,N]),vn=r.useCallback(async p=>{try{await navigator.clipboard.writeText(`src/canvas/${p.name}`),x.success("路径已复制")}catch{x.error("复制路径失败")}},[x]),Fs=r.useCallback(async p=>{try{const Q=await kt.createSidebarFolder(p),I=U(p),_=Vs(p,Array.isArray(Q.tree)?Q.tree:[],I);return u(O=>({...O,[p]:_})),{createdFolderId:Q.createdFolderId}}catch(Q){return x.error((Q==null?void 0:Q.message)||"新建文件夹失败"),null}},[U,x,u]),gs=r.useCallback(p=>{ie("assets"),z("themes"),je(p!=null&&p.name?[p.name]:[]),J(!0)},[z,ie]),Sn=r.useCallback((p,Q)=>{const I=U(p),_=Vs(p,Q,I);u(O=>({...O,[p]:_}))},[U,u]),Kn=r.useCallback(async(p,Q)=>{const I=U(p),_=Vs(p,Q,I);u(O=>({...O,[p]:_}));try{const O=await kt.saveSidebarTree(p,_),G=U(p),le=Vs(p,Array.isArray(O.tree)?O.tree:[],G);u(ye=>({...ye,[p]:le}))}catch(O){x.error((O==null?void 0:O.message)||"保存侧栏结构失败");try{const G=await kt.getSidebarTree(p),le=U(p),ye=Vs(p,Array.isArray(G.tree)?G.tree:[],le);u(_e=>({..._e,[p]:ye}))}catch{}}},[U,x,u]),Cn=r.useCallback(p=>{Kt(p),st(!0)},[]),Cs=r.useCallback(async p=>{try{await navigator.clipboard.writeText(`src/${s}/${p.name}`),x.success("路径已复制")}catch{x.error("复制路径失败")}},[s,x]),$s=r.useMemo(()=>Ls(i,$.themes,p=>p.name),[$.themes,i]),kn=r.useMemo(()=>Ls(c,$.data,p=>p.fileName),[c,$.data]),Os=r.useMemo(()=>Ls(w,$.templates,p=>p.name),[$.templates,w]);return{defaultThemeName:A,setDefaultThemeName:q,selectedDoc:pe,setSelectedDoc:Ne,selectedTemplate:Ce,setSelectedTemplate:Ie,selectedCanvas:ve,handleSelectCanvas:Ue,selectedTheme:Fe,setSelectedTheme:Oe,selectedDataTable:We,setSelectedDataTable:E,docCreateDialogVisible:ce,setDocCreateDialogVisible:Pe,selectedDocSkillIds:Ee,setSelectedDocSkillIds:Te,selectedDocRefs:Ye,setSelectedDocRefs:nt,selectedDocReferencePrototypes:Me,setSelectedDocReferencePrototypes:b,selectedDataRefs:he,setSelectedDataRefs:ke,selectedTemplateRefs:T,setSelectedTemplateRefs:Z,themeCreateDialogVisible:de,setThemeCreateDialogVisible:J,selectedThemeSkillIds:Ae,setSelectedThemeSkillIds:ze,selectedThemeDocRefs:ue,setSelectedThemeDocRefs:ne,selectedThemeReferencePages:me,setSelectedThemeReferencePages:je,dataTableCreateOpen:De,setDataTableCreateOpen:ge,newDataTableName:Ze,setNewDataTableName:dt,dataTableCreating:St,newDataTableNameError:wt,setNewDataTableNameError:Je,versionDialogVisible:tt,setVersionDialogVisible:st,currentVersionItem:rs,setCurrentVersionItem:Kt,docReferencePromptDialog:js,setDocReferencePromptDialog:pt,themes:$s,dataTables:kn,templateAssets:Os,buildDocPrompt:()=>Lh(Ee,Ye,y,he,L,T,F,Me,R),buildThemePrompt:()=>lm(Ae,ue,y,me,P),clearDocCreateDialogState:mt,clearThemeCreateDialogState:os,handleDocCreateCancel:Ot,handleThemeCreateCancel:Vt,refreshSidebarAssets:$e,handleCreateDialogUploadSuccess:Ke,closeDataTableCreateDialog:Ft,handleDataTableCreateSubmit:Lt,handleReorderThemes:et,handleReorderDataTables:Ss,handleReorderTemplates:Ht,handleSetDefaultTheme:is,handleRenameThemeResource:Qt,handleDownloadThemeZip:at,handleDeleteThemeResource:Ct,handleRenameDataTableResource:Xt,handleDeleteDataTableResource:zt,handleRenameTemplateResource:ps,handleDuplicateTemplateResource:fs,handleDeleteTemplateResource:Bt,handleCopyTemplatePath:Us,handleTemplateVersionManagement:ls,handleDownloadItemSource:Yt,handleRenameItem:ft,handleDuplicateItem:tn,handleDeleteItem:yn,handleRenameDocItem:bn,handleDuplicateDocItem:wn,handleDeleteDocItem:He,handleCopyDocPath:Ns,handleDocVersionManagement:rt,handleCreatePrototypeFromDoc:$t,handleCreateResource:Rs,handleCreateDocFile:jn,handleCreateCanvasFile:xs,handleRenameCanvasItem:sn,handleDuplicateCanvasItem:Gn,handleDeleteCanvasItem:Nn,handleCopyCanvasPath:vn,handleCreateFolder:Fs,handleGenerateThemeFromPrototype:gs,handleProjectTitleChange:async p=>{const I=p.trim()||"未命名项目",_=C;K(I);try{await kt.updateProjectTitle(I)}catch(O){K(_),x.error((O==null?void 0:O.message)||"项目标题保存失败")}},handleSidebarTreeChange:Sn,handleSidebarTreePersist:Kn,handleVersionManagement:Cn,handleCopyTemplatePrompt:async()=>{if(!Ce){x.warning("请先选择一个模板");return}await Us(Ce)},handleCopyItemPath:Cs}}const Wh=({layers:t,widgetId:s,pageId:n})=>{const a={layers:Array.isArray(t)?t:[]};return s&&(a.widgetId=s),n&&(a.pageId=n),a},Gh=async t=>{const{safeCopyToFigmaWithKiwi:s}=await sd(async()=>{const{safeCopyToFigmaWithKiwi:a}=await import("./chunks/index.js?v=1775123024591");return{safeCopyToFigmaWithKiwi:a}},__vite__mapDeps([0,1,2,3,4,5,6])),n=await s({layers:Array.isArray(t)?t:[]});if(n.skipped)throw n.reason==="clipboard_unavailable"?new Error("当前环境不支持剪贴板写入,请检查浏览器权限后重试"):new Error("复制到 Figma 失败");return n.data},Jo={workflow:aa("/skills/genie-editor-cli-workflow/SKILL.md")??"/skills/genie-editor-cli-workflow/SKILL.md",reference:aa("/skills/genie-editor-cli-workflow/references/cli-reference.md")??"/skills/genie-editor-cli-workflow/references/cli-reference.md"};function Kh(t){return t.length===0?"- 当前没有明确的页面选中元素,请结合 Genie editor backlog、自身截图与当前文件内容判断修改位置。":t.map(s=>{const n=String(s.label||"").trim()||String(s.tag||"").trim()||"未命名元素",a=String(s.selector||"").trim();return a?`- ${n}(${a})`:`- ${n}`}).join(`
|
||
`)}function Vh(t){var c,d;const s=String(t.currentFilePath||"").trim();if(!s)throw new Error("当前文件路径为空,无法生成快速编辑 Prompt");const n=String(t.currentFileDisplayName||"").trim(),a=String(t.projectPath||"").trim(),o=Array.isArray(t.selectedElements)?t.selectedElements:[],i=String(((c=t.skillPaths)==null?void 0:c.workflow)||"").trim()||Jo.workflow,l=String(((d=t.skillPaths)==null?void 0:d.reference)||"").trim()||Jo.reference;return`请执行网页快速编辑任务。
|
||
|
||
【前置阅读】
|
||
1. 工作流指南:\`${i}\`
|
||
2. CLI 参考与示例:\`${l}\`
|
||
|
||
【任务上下文】
|
||
- 目标文件:\`${s}\`${n?`(${n})`:""}
|
||
${a?`- 项目目录:\`${a}\`
|
||
`:""}
|
||
【选中元素】
|
||
${Kh(o)}
|
||
|
||
【执行要求】
|
||
1. 严格遵循工作流:务必完整走通 CLI 流程(获取 clients、截图、获取 nodes、认领并回写 editing/idle 状态、以及最终的复核)。
|
||
2. 小范围精准修改:涵盖结构、样式或文案的调整。请以目标文件为主进行修改,避免扩大影响范围。无法准确定位时请先利用截图辅助确认,严禁盲改。
|
||
3. 任务统筹:若节点过多可交由子代理执行,但主代理必须负责统筹节点状态的领取与回写,并做好最终清点。
|
||
4. 如实反馈进度:结束后务必确认节点是否卡在 editing 状态,处理好所有 backlog 的消费与闭环。
|
||
|
||
【最终回复要求(重要)】
|
||
与你对话的用户通常是产品经理或设计师,他们不关心底层代码。请在任务完成后,使用通俗、业务导向的语言简要回复用户:
|
||
1. 说明完成了哪些具体界面/业务修改(例如:修改了某处文案、调整了按钮颜色等)。
|
||
2. 若有未处理完或存在异常的节点,只需做简单的业务提示即可。
|
||
**切勿**在回复中罗列修改了哪些具体代码文件、展示哪些技术排查排错过程,也无需向用户汇报底层节点的脏状态(如 dirty/error 等技术词汇),保持沟通自然、简短。`}const Qo={desktop:{id:"desktop",width:1440,height:900},mobile:{id:"mobile",width:393,height:852},tablet:{id:"tablet",width:820,height:1180}},fr={preserveHierarchy:!1,preserveSvgIcons:!0},xr={width:1920,height:1080,includeConfig:"code",contentType:"title",rawScreenshotUrl:"",screenshotWidth:0,screenshotHeight:0,previewUrl:""};function Hh(t){const s=new TextEncoder().encode(t);let n="";return s.forEach(a=>{n+=String.fromCharCode(a)}),window.btoa(n)}function qh(t){var i,l;const s=Hh(t.svgContent);let n=0;for(let c=0;c<s.length;c+=1)n=(n<<5)-n+s.charCodeAt(c),n|=0;const a=`(svg)${Math.abs(n).toString(36)}`,o=((l=(i=globalThis.crypto)==null?void 0:i.randomUUID)==null?void 0:l.call(i))??`axhub-runtime-${Date.now()}-${Math.random().toString(16).slice(2,10)}`;return{scene:{items:[{data:a,isHash:!0,corners:[],rect:{location:{x:113,y:69},size:{width:t.width,height:t.height}},type:4,opacity:1,backgroundFills:[{color:{r:1,g:1,b:1,a:1},type:1,enabled:!0}],strokes:[{fill:{color:{r:.8,g:.8,b:.8,a:1},type:1,enabled:!0},alignment:0}],strokePattern:[0,0],strokeThickness:0,text:{paragraphs:[{inlines:[{text:"",textColor:{r:0,g:0,b:0,a:1},highlight:{r:0,g:0,b:0,a:0},size:13,family:"Arial",typeface:null,underline:!1,strikethrough:!1,superscript:0,baselineOffset:0,characterSpacing:0,transform:0,weight:400,style:0,stretch:5,type:0}],horizontalAlignment:0,lineSpacing:15,textListInfo:{indentLevel:0,listChar:null,listType:0}}]},textAlignment:1,textPadding:[2,2,2,2],effects:[{shadowType:1,offset:{x:0,y:5},blur:5,spread:0,color:{r:0,g:0,b:0,a:.34901960784313724},type:1,enabled:!1},{shadowType:0,offset:{x:5,y:5},blur:5,spread:0,color:{r:0,g:0,b:0,a:.34901960784313724},type:1,enabled:!1},{blurType:1,radius:4,type:0,enabled:!1},{blurType:0,radius:4,type:0,enabled:!1}],textShadows:[{shadowType:0,offset:{x:1,y:1},blur:5,spread:0,color:{r:0,g:0,b:0,a:.6470588235294118},type:1,enabled:!1}],rotation:0,textRotation:0,flippedHorizontal:!1,flippedVertical:!1,visible:!0,isMask:!1,maskedScene:null,meta:null,isLocked:!1,itemType:1,id:o,name:"axhub-react-runtime",resizingConstraints:{hasFixedHeight:!1,hasFixedWidth:!1,hasFixedBottom:!1,hasFixedTop:!1,hasFixedRight:!1,hasFixedLeft:!1},isNameDynamic:!1}]},masters:null,imageMap:{[a]:s}}}function Zh(t){const{activeTab:s,collapsed:n,setCollapsed:a,sidebarTab:o,resourceSection:i,setSidebarTab:l,setResourceSection:c,selectedItem:d,selectedSubPage:w,selectedDoc:j,setSelectedDoc:$,selectedTemplate:v,setSelectedTemplate:D,messageApi:u,modal:C,appDialog:K,viewMode:y,currentSpecDocKey:P,setCurrentSpecDocKey:R,assistantContextV1:L,assistantProjectPath:F,assistantApiBaseUrl:x,assistantWebEditorClientId:V,handleWebEditorGenieRequest:re,clearAssistantSelectedElementsOnExit:B,tryOpenByAssistantIframe:xe}=t,ie=r.useRef(null),z=r.useRef(null),se=r.useRef(!1),W=r.useRef(new Map),S=r.useRef(null),Y=r.useRef(null),k=r.useRef(null),N=r.useRef(null),U=r.useRef(null),A=r.useRef(null),q=r.useRef(!1),pe=r.useRef(!1),[Ne,Ce]=r.useState("desktop"),[Ie,ve]=r.useState({width:600,height:400}),[Ue,Fe]=r.useState(0),[Oe,We]=r.useState(!1),[E,ce]=r.useState(!1),[Pe,Ee]=r.useState(!1),[Te,Ye]=r.useState(!1),[nt,Me]=r.useState(fr),[b,he]=r.useState(xr),[ke,T]=r.useState({mode:"none"}),[Z,de]=r.useState({enabled:!1,editedCount:0}),[J,Ae]=r.useState(xa),[ze,ue]=r.useState({enabled:!1,dirty:!1,saving:!1}),[ne,me]=r.useState("annotation"),[je,De]=r.useState(!1),[ge,Ze]=r.useState(null),[dt,St]=r.useState(!1),Ut=r.useMemo(()=>o==="document"?{item:j,kind:"doc"}:o==="assets"&&i==="templates"?{item:v,kind:"template"}:{item:null,kind:"doc"},[i,j,v,o]),wt=Ut.item,Je=Ut.kind==="template"?"模板":"文档",tt=r.useMemo(()=>o==="document"&&j?{kind:"doc",label:"文档",cacheKey:`doc:${j.name}`}:o==="assets"&&i==="templates"&&v?{kind:"template",label:"模板",cacheKey:`template:${v.name}`}:d?{kind:"spec",label:"条目",cacheKey:`spec:${d.name}:${P}`}:null,[P,i,j,d,v,o]),st=Qo[Ne]??Qo.desktop,rs={width:st.width,height:st.height},Kt=1,js=r.useMemo(()=>[{value:"desktop",icon:e.jsx(Gi,{className:"h-4 w-4"})},{value:"mobile",icon:e.jsx(Ma,{className:"h-4 w-4"})},{value:"tablet",icon:e.jsx(Yc,{className:"h-4 w-4"})}],[]),pt=r.useMemo(()=>Su(s,Ne),[s,Ne]),Rt=r.useMemo(()=>km(F),[F]),yt=r.useMemo(()=>[{key:"genie:claude",label:"ClaudeCode"},{key:"genie:codex",label:"Codex"},{key:"genie:gemini",label:"Gemini CLI"},{key:"genie:opencode",label:"OpenCode"}],[]),Qe=r.useCallback(()=>z.current,[]),ut=r.useCallback(g=>{const h=g??Qe();if(!h)return window.location.origin;const M=h.getAttribute("src")||h.src;if(!M)return window.location.origin;try{return new URL(M,window.location.origin).origin}catch{return window.location.origin}},[Qe]),$e=r.useCallback((g,h)=>{const M=h??Qe();return!M||!M.contentWindow?(u.warning("未找到可操作的预览窗口"),!1):(M.contentWindow.postMessage(g,ut(M)),!0)},[ut,Qe,u]),Ke=r.useCallback(g=>{var ee,we;const h=g??Qe(),M=h==null?void 0:h.contentWindow;return((ee=M==null?void 0:M.DevTemplateBootstrap)==null?void 0:ee.editors)??((we=M==null?void 0:M.SpecTemplateBootstrap)==null?void 0:we.editors)},[Qe]),mt=r.useCallback(()=>{var h,M;const g=(M=(h=Ke())==null?void 0:h.getStatus)==null?void 0:M.call(h);T(g||{mode:"none"})},[Ke]),os=r.useCallback(()=>st.id==="desktop"?null:(rs.width?Math.round(rs.width):st.width)||null,[st.id,st.width,rs.width]),Ot=r.useCallback(g=>{const h=Date.now(),M=(g==null?void 0:g.timeoutMs)??5e3,ee=g==null?void 0:g.expectedEditor;return new Promise(we=>{const Ge=Le=>{if(!ee)return!0;const Ve=Le.getAttribute("src")||Le.src;if(!Ve)return!1;try{return new URL(Ve,window.location.origin).searchParams.get("editor")===ee}catch{return!1}},qe=()=>{var Xe,Wt;const Le=Qe();if(!Le||!Le.isConnected){if(Date.now()-h>=M){we(null);return}setTimeout(qe,50);return}if(g!=null&&g.previousIframe&&Le===g.previousIframe&&Date.now()-h<M){setTimeout(qe,50);return}if(!Ge(Le)){if(Date.now()-h>=M){we(null);return}setTimeout(qe,50);return}const Ve=Le.contentWindow;if((Xe=Ve==null?void 0:Ve.DevTemplateBootstrap)!=null&&Xe.editors||(Wt=Ve==null?void 0:Ve.SpecTemplateBootstrap)!=null&&Wt.editors){we(Le);return}if(Date.now()-h>=M){we(null);return}setTimeout(qe,50)};qe()})},[Qe]),Vt=Te||ke.mode==="webEditorV2"?"webEditorV2":ke.mode,_t=Te||ke.mode==="webEditorV2"?U.current??void 0:void 0,Ft=r.useMemo(()=>o==="document"?(j==null?void 0:j.specUrl)||"":o==="assets"&&i==="templates"?(v==null?void 0:v.specUrl)||"":Od(d,y,Vt,{width:_t,selectedSubPage:w,integrationWs:{enabled:Vt==="webEditorV2",apiBaseUrl:x,channel:Xo,clientId:V},genieBridge:{projectPath:F}}),[x,F,V,Vt,_t,i,j,d,w,v,o,y]),Lt=!!d&&y!=="spec",is=!!(d&&y!=="spec"&&vr(L)),et=r.useMemo(()=>{const g=wr(d,"demo",{selectedSubPage:w});return g?g.toString():""},[d,w]),Ss=r.useCallback(()=>{const g=wr(d,"demo",{selectedSubPage:w}),h=g?`${g.pathname}${g.search}${g.hash}`:"",M=window.__LOCAL_IP__||"localhost",ee=window.location.port||(window.location.protocol==="https:"?"443":"80");return`${window.location.protocol}//${M}:${ee}${h}`},[d,w]),Ht=r.useCallback(()=>{if(!et){u.error("当前没有可复制的链接");return}navigator.clipboard.writeText(et).then(()=>{H.success("本地链接已复制"),We(!1)}).catch(()=>{u.error("复制失败")})},[et,u]),qt=r.useCallback(()=>{navigator.clipboard.writeText(Ss()).then(()=>{H.success("局域网链接已复制"),We(!1)}).catch(()=>{u.error("复制失败")})},[Ss,u]),at=r.useCallback(()=>{Fe(g=>g+1)},[]),Qt=r.useCallback((g,h)=>{const M=typeof h=="string"?h.trim():"";if(!M)return;(u[typeof g=="string"?g:"info"]||u.info)(M)},[u]),Ct=r.useCallback(()=>{Y.current=null,Ae(xa())},[]),Xt=r.useCallback((g,h)=>{if(S.current=null,g==="doc"){l("document"),$(h);return}l("assets"),c("templates"),D(h)},[c,$,D,l]),zt=r.useCallback((g,h)=>{if(!J.enabled||!wt||wt.name===h.name){Xt(g,h);return}const M=()=>{Ct(),Xt(g,h)};if(!J.dirty){$e({type:"SPEC_EDIT_EXIT"}),M();return}C.confirm({title:`切换${g==="template"?"模板":"文档"}`,content:`当前${Je}有未保存更改,是否先保存再切换?`,okText:"保存并切换",cancelText:"不保存切换",onOk:()=>{Y.current={item:h,kind:g},$e({type:"SPEC_EDIT_SAVE",exitAfterSave:!0})?Ae(ee=>({...ee,saving:!0})):Y.current=null},onCancel:()=>{$e({type:"SPEC_EDIT_EXIT",discardChanges:!0}),M()}})},[wt,Je,J.dirty,J.enabled,C,$e,Ct,Xt]),As=r.useCallback(g=>{zt("doc",g)},[zt]),ps=r.useCallback(g=>{zt("template",g)},[zt]),fs=r.useCallback(g=>new Promise((h,M)=>{const ee=tt;if(!ee){M(new Error(o==="assets"&&i==="templates"?"请先选择一个模板":o==="document"?"请先选择一个文档":"请先选择一个条目"));return}const we=ee.kind==="spec";if(we){if(y!=="spec"){M(new Error("请先切换到文档模式"));return}if(!ze.enabled){M(new Error("请先开启文档编辑"));return}}else if(!J.enabled){M(new Error(`请先开启${ee.label}编辑`));return}if((we?ne:J.quickEditMode)!=="annotation"){M(new Error("请先切换到标注模式"));return}const qe=we?ze.dirty:J.dirty,Le=ee.cacheKey,Ve=S.current;if(!qe&&Ve&&Ve.key===Le){h(Ve.result);return}const Xe=`spec-prompt-${Date.now()}-${Math.random().toString(36).slice(2,10)}`,Wt=window.setTimeout(()=>{W.current.delete(Xe),M(new Error("生成 Prompt 超时,请重试"))},1e4);if(W.current.set(Xe,{resolve:h,reject:M,timeoutId:Wt}),!$e({type:"SPEC_EDIT_PROMPT_REQUEST",requestId:Xe,saveBeforePrompt:!!(g!=null&&g.saveBeforePrompt)})){const ks=W.current.get(Xe);ks&&(window.clearTimeout(ks.timeoutId),W.current.delete(Xe)),M(new Error("未找到可操作的预览窗口"))}}),[tt,J.dirty,J.enabled,J.quickEditMode,$e,i,o,ze.dirty,ze.enabled,ne,y]),Bt=r.useCallback((g=!0)=>new Promise((h,M)=>{const ee=Qe();if(!ee||!ee.contentWindow){M(new Error("未找到可导出的预览窗口"));return}const we=ut(ee),Ge=window.setTimeout(()=>{window.removeEventListener("message",qe),M(new Error("导出超时,请重试"))},15e3),qe=Le=>{if(Le.source===ee.contentWindow&&Le.origin===we&&!(!Le.data||Le.data.type!=="FIGMA_JSON_READY")){if(window.removeEventListener("message",qe),window.clearTimeout(Ge),Le.data.success){const Ve=Le.data.json??Le.data.data??Le.data.payload,Xe=Array.isArray(Ve)?Ve:(Ve==null?void 0:Ve.layers)||[];h({layers:Xe,widgetId:Le.data.widgetId,pageId:Le.data.pageId});return}M(new Error(Le.data.error||"导出失败"))}};window.addEventListener("message",qe),ee.contentWindow.postMessage({type:"EXPORT_FIGMA_JSON",rootName:(d==null?void 0:d.displayName)||(d==null?void 0:d.name),enableAutoLayout:g},we)}),[ut,Qe,d]),Us=r.useCallback(g=>new Promise((h,M)=>{const ee=Qe();if(!ee||!ee.contentWindow){M(new Error("未找到可导出的预览窗口"));return}const we=ut(ee),Ge=window.setTimeout(()=>{window.removeEventListener("message",qe),M(new Error("导出超时,请重试"))},15e3),qe=Le=>{if(Le.source===ee.contentWindow&&Le.origin===we&&!(!Le.data||Le.data.type!=="AXURE_JSON_READY")){if(window.removeEventListener("message",qe),window.clearTimeout(Ge),Le.data.success){h(Le.data.payload??Le.data.json??Le.data.data);return}M(new Error(Le.data.error||"导出失败"))}};window.addEventListener("message",qe),ee.contentWindow.postMessage({type:"EXPORT_AXURE_JSON",rootName:(d==null?void 0:d.displayName)||(d==null?void 0:d.name),preserveHierarchy:g.preserveHierarchy,preserveSvgIcons:g.preserveSvgIcons},we)}),[ut,Qe,d]),ls=r.useCallback(async()=>{let g;try{g=await fetch(`${Io}/available`,{method:"GET",cache:"no-store"})}catch(ee){throw new Error(`无法连接到 Axure Bridge(localhost:32767):${Oo(ee)}`)}const{body:h,text:M}=await _o(g);if(!g.ok)throw new Error(ya(`Axure Bridge 不可用(HTTP ${g.status})`,h,M));if(typeof h=="boolean")return h;if(h&&typeof h=="object"){if(h.available===!1||h.running===!1||h.success===!1)throw new Error(ya("Axure Bridge 报告当前不可用",h,M));if(typeof h.available=="boolean")return h.available;if(typeof h.running=="boolean")return h.running;if(typeof h.success=="boolean")return h.success}return!0},[]),Yt=r.useCallback(async g=>{let h;try{h=await fetch(`${Io}/copyaxvg`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)})}catch(we){throw new Error(`请求 Axure Bridge 失败:${Oo(we)}`)}const{body:M,text:ee}=await _o(h);if(!h.ok)throw new Error(`复制到 Axure 失败:${ya(h.statusText||`HTTP ${h.status}`,M,ee)}`);if(M&&typeof M=="object"&&(M.success===!1||M.available===!1))throw new Error(`复制到 Axure 失败:${ya("服务返回失败",M,ee)}`)},[]),ft=r.useCallback((g,h)=>{const M={type:"CAPTURE_SCREENSHOT"},ee=typeof g=="number"&&Number.isFinite(g),we=typeof h=="number"&&Number.isFinite(h);se.current||ee||we?(M.targetWidth=g??b.width,M.targetHeight=h??b.height):M.targetWidth=b.width;const qe=Qe();qe&&qe.contentWindow&&qe.contentWindow.postMessage(M,ut(qe))},[ut,Qe,b.height,b.width]),tn=r.useCallback((g,h)=>{se.current=!0,he(M=>({...M,[g]:h||0}))},[]),yn=r.useCallback(()=>{b.contentType==="screenshot"&&E&&ft()},[ft,b.contentType,E]),bn=r.useCallback(()=>{se.current=!0,he(g=>({...g,width:g.height,height:g.width})),setTimeout(()=>{b.contentType==="screenshot"&&E&&ft(b.height,b.width)},0)},[ft,b.contentType,b.height,b.width,E]),wn=r.useCallback(async()=>{if(!d){u.warning("请先选择一个条目");return}if(y==="spec"){u.warning("文档模式下无法进行编辑");return}try{const g=Qe(),h=os();U.current=h??null,Ye(!0),st.id!=="desktop"&&(k.current=Ne,Ce("desktop"));const M=await Ot({previousIframe:st.id!=="desktop"?g:null,expectedEditor:"webEditorV2"});if(!M){Ye(!1),u.warning("预览窗口尚未就绪");return}const ee=Ke(M);if(!(ee!=null&&ee.enable)){Ye(!1),u.warning("当前预览页未启用编辑器");return}h&&$e({type:"WEB_EDITOR_SET_ROOT_SIZE",width:h},M),await Promise.resolve(ee.enable("webEditorV2")),mt(),N.current===null&&(N.current=n),a(!0)}catch(g){console.error("[Axhub] 启动编辑器失败:",g),u.error("启动编辑器失败")}},[n,st.id,Ke,Qe,os,u,$e,mt,Ne,d,a,y,Ot]),He=r.useCallback(async g=>{const h=Ke();if(!(h!=null&&h.disable)){B(),Ye(!1),N.current!==null&&(a(N.current),N.current=null),U.current&&($e({type:"WEB_EDITOR_RESET_ROOT_SIZE"}),U.current=null),(g==null?void 0:g.restoreDevice)!==!1&&k.current&&Ce(k.current),k.current=null;return}try{await Promise.resolve(h.disable()),B(),mt(),Ye(!1),N.current!==null&&(a(N.current),N.current=null),U.current&&($e({type:"WEB_EDITOR_RESET_ROOT_SIZE"}),U.current=null),(g==null?void 0:g.restoreDevice)!==!1&&k.current&&Ce(k.current),k.current=null}catch(M){console.error("[Axhub] 退出编辑器失败:",M),u.error("退出编辑器失败")}},[B,Ke,u,$e,mt,a]),Ns=r.useCallback(async()=>{const g=Ke();if(!(g!=null&&g.saveWebEditorTextChanges)){u.warning("当前预览页未启用文本保存");return}try{await Promise.resolve(g.saveWebEditorTextChanges()),mt()}catch(h){console.error("[Axhub] 保存文本失败:",h),u.error(h instanceof Error?h.message:"保存文本失败")}},[Ke,u,mt]),rt=r.useCallback(async()=>{const g=Ke();if(!(g!=null&&g.saveWebEditorStyleChanges)){u.warning("当前预览页未启用样式保存");return}try{await Promise.resolve(g.saveWebEditorStyleChanges()),mt()}catch(h){console.error("[Axhub] 保存强制样式失败:",h),u.error(h instanceof Error?h.message:"保存强制样式失败")}},[Ke,u,mt]),$t=r.useCallback(async()=>{const g=Ke();if(!(g!=null&&g.clearWebEditorForcedStyles)){u.warning("当前预览页未启用强制样式清空");return}try{await Promise.resolve(g.clearWebEditorForcedStyles()),mt()}catch(h){console.error("[Axhub] 清空强制样式失败:",h),u.error(h instanceof Error?h.message:"清空强制样式失败")}},[Ke,u,mt]),Rs=r.useCallback(()=>{if(!wt){u.warning(`请先选择${Je}`);return}if(!/\.md$/i.test(wt.name||"")){u.warning(`仅支持 Markdown ${Je}在线编辑`);return}$e({type:"SPEC_EDIT_ENABLE"})&&Ae(g=>({...g,enabled:!0,quickEditMode:"annotation"}))},[wt,Je,u,$e]),jn=r.useCallback(()=>{if(!wt){u.warning(`请先选择${Je}`);return}if(!J.enabled){u.warning(`请先开启${Je}编辑`);return}if(!J.dirty){u.info(`当前${Je}没有需要保存的更改`);return}J.saving||$e({type:"SPEC_EDIT_SAVE"})&&Ae(g=>({...g,saving:!0}))},[wt,Je,J.dirty,J.enabled,J.saving,u,$e]),xs=r.useCallback(g=>{const h=Ho({enabled:J.enabled,currentMode:J.quickEditMode,nextMode:g,dirty:J.dirty});if(h.type!=="noop"){if(S.current=null,h.type==="switch"){$e({type:"SPEC_EDIT_SET_MODE",mode:h.mode}),Ae(M=>({...M,quickEditMode:h.mode}));return}C.confirm({title:"切换到标注模式",content:`检测到未保存的${Je}更改,是否先保存后再切换到标注模式?`,okText:"保存并切换",cancelText:"不保存切换",onOk:()=>{$e({type:"SPEC_EDIT_SET_MODE",mode:"annotation",saveBehavior:"save"}),Ae(M=>({...M,saving:!0}))},onCancel:()=>{$e({type:"SPEC_EDIT_SET_MODE",mode:"annotation",saveBehavior:"discard"}),Ae(M=>({...M,quickEditMode:"annotation"}))}})}},[Je,J.dirty,J.enabled,J.quickEditMode,C,$e]),sn=r.useCallback(()=>{if(!(!J.enabled||J.saving)){if(J.dirty){C.confirm({title:`退出${Je}编辑`,content:`检测到未保存的${Je}更改,是否先保存后退出?`,okText:"保存并退出",cancelText:"不保存退出",onOk:()=>{$e({type:"SPEC_EDIT_SAVE",exitAfterSave:!0})&&Ae(g=>({...g,saving:!0}))},onCancel:()=>{$e({type:"SPEC_EDIT_EXIT",discardChanges:!0}),Ct()}});return}$e({type:"SPEC_EDIT_EXIT"}),Ct()}},[Je,J.dirty,J.enabled,J.saving,C,$e,Ct]),Gn=r.useCallback(()=>{if(!d){u.warning("请先选择一个条目");return}if(y!=="spec"){u.warning("请先切换到文档模式");return}$e({type:"SPEC_EDIT_ENABLE"})&&(S.current=null,ue(g=>({...g,enabled:!0})),me("annotation"))},[u,$e,d,y]),Nn=r.useCallback(()=>{if(!d){u.warning("请先选择一个条目");return}if(y!=="spec"){u.warning("请先切换到文档模式");return}if(!ze.enabled){u.warning("请先开启文档编辑");return}if(!ze.dirty){u.info("当前文档没有需要保存的更改");return}ze.saving||$e({type:"SPEC_EDIT_SAVE"})&&ue(g=>({...g,saving:!0}))},[u,$e,d,ze.dirty,ze.enabled,ze.saving,y]),vn=r.useCallback(g=>{const h=Ho({enabled:ze.enabled,currentMode:ne,nextMode:g,dirty:ze.dirty});if(h.type!=="noop"){if(S.current=null,h.type==="switch"){$e({type:"SPEC_EDIT_SET_MODE",mode:h.mode}),me(h.mode);return}C.confirm({title:"切换到标注模式",content:"检测到未保存的文档更改,是否先保存后再切换到标注模式?",okText:"保存并切换",cancelText:"不保存切换",onOk:()=>{$e({type:"SPEC_EDIT_SET_MODE",mode:"annotation",saveBehavior:"save"}),ue(M=>({...M,saving:!0}))},onCancel:()=>{$e({type:"SPEC_EDIT_SET_MODE",mode:"annotation",saveBehavior:"discard"}),me("annotation")}})}},[C,$e,ze.dirty,ze.enabled,ne]),Fs=r.useCallback(()=>{if(!d){u.warning("请先选择一个条目");return}if(y!=="spec"){u.warning("请先切换到文档模式");return}if(ne==="annotation"){S.current=null,$e({type:"SPEC_EDIT_EXIT",discardChanges:!1});return}if(ze.dirty){C.confirm({title:"退出文档编辑",content:"检测到未保存的文档更改,是否先保存后退出?",okText:"保存并退出",cancelText:"不保存退出",onOk:()=>{$e({type:"SPEC_EDIT_SAVE",exitAfterSave:!0}),ue(g=>({...g,saving:!0}))},onCancel:()=>{$e({type:"SPEC_EDIT_EXIT",discardChanges:!0})}});return}$e({type:"SPEC_EDIT_EXIT",discardChanges:!1})},[u,C,$e,d,ze.dirty,ne,y]),gs=r.useCallback(async()=>{if(je||ge)return;if(((tt==null?void 0:tt.kind)==="spec"?ne:J.quickEditMode)!=="annotation"){u.warning("请先切换到标注模式");return}De(!0);try{const h=await fs({saveBeforePrompt:!0});await navigator.clipboard.writeText(h.prompt),u.success("Prompt 已复制到剪贴板")}catch(h){u.error((h==null?void 0:h.message)||"复制 Prompt 失败")}finally{De(!1)}},[tt==null?void 0:tt.kind,J.quickEditMode,u,fs,je,ge,ne]),Sn=r.useCallback(async g=>{if(je||ge)return;const h=Fr(g);if(!h){u.error("无效的 Genie 供应商");return}Ze(g);try{const M=await fs({saveBeforePrompt:!0});await navigator.clipboard.writeText(M.prompt);try{const ee=await Pt.executePrompt({scene:"spec-edit-sync",client:h,prompt:M.prompt});xe(ee.url,M.targetPath)||window.open(ee.url,"_blank","noopener,noreferrer"),u.success("已打开 Genie 会话")}catch(ee){String((ee==null?void 0:ee.message)||"").includes("Axhub Genie")||String((ee==null?void 0:ee.message)||"").includes("@axhub/genie")?u.warning("Genie 未就绪,已回退为复制 Prompt。请先安装/启动 Axhub Genie。"):u.warning("自动执行失败,已回退为复制 Prompt")}}catch(M){u.error((M==null?void 0:M.message)||"执行失败")}finally{Ze(null)}},[u,fs,je,ge,xe]),Kn=r.useCallback(async()=>{if(dt)return;const g=vr(L);if(!g){u.warning("当前文件路径为空,无法生成快速编辑 Prompt");return}St(!0);try{const h=Vh({currentFilePath:g,currentFileDisplayName:(d==null?void 0:d.displayName)||"",projectPath:F,selectedElements:L.selectedElements});await navigator.clipboard.writeText(h),u.success("Prompt 已复制到剪贴板")}catch(h){u.error((h==null?void 0:h.message)||"复制 Prompt 失败")}finally{St(!1)}},[L,F,u,dt,d]),Cn=r.useCallback(()=>{if(!Ft){u.warning("当前没有可打开的页面");return}try{const g=new URL(Ft,window.location.origin).toString();window.open(g,"_blank","noopener,noreferrer")}catch{window.open(Ft,"_blank","noopener,noreferrer")}},[Ft,u]),Cs=r.useCallback(g=>{const h=g==null?void 0:g.demoUrl;if(!h){u.warning("当前没有可打开的页面");return}try{const M=new URL(h,window.location.origin);M.searchParams.set("editor","webEditorV2"),window.open(M.toString(),"_blank","noopener,noreferrer")}catch{window.open(h,"_blank","noopener,noreferrer")}},[u]),$s=r.useCallback(async()=>{try{return await Pt.getWsClients()}catch{return[]}},[]),kn=r.useCallback(async()=>{if(!d){u.warning("请先选择一个条目");return}const g=u.loading("正在检查连接...",0),h=await $s();if(g(),h.length===0){u.warning("未检测到 Figma 连接,请先打开 Figma 插件并完成连接");return}const M=u.loading("正在获取数据...",0);try{const{layers:ee,widgetId:we,pageId:Ge}=await Bt();if(M(),!Array.isArray(ee)||ee.length===0){u.error("图层数据为空,无法推送");return}const qe=s==="components"?{type:"sync-widget-content",widgetId:we||`element-${(d==null?void 0:d.name)||"unknown"}-${Date.now()}`,data:{layers:ee},blurImages:!1,metadata:{source:"extension",timestamp:Date.now()}}:{type:"sync-page-content",...Ge?{pageId:Ge}:{},data:{layers:ee},blurImages:!1,metadata:{source:"extension",timestamp:Date.now()}},Le=u.loading("正在推送到 Figma...",0);try{await Pt.sendWsMessage(qe),u.success("推送成功")}catch(Ve){u.error(`推送失败: ${Ve.message}`)}finally{Le()}}catch(ee){M(),u.error((ee==null?void 0:ee.message)||"获取数据失败")}},[s,$s,u,Bt,d]),Os=r.useCallback(async(g=!0)=>{if(!d){u.warning("请先选择一个条目");return}const h=u.loading("正在生成 Figma JSON...",0);try{const{layers:M,widgetId:ee,pageId:we}=await Bt(g),Ge=Wh({layers:M,widgetId:ee,pageId:we}),qe=new Blob([JSON.stringify(Ge,null,2)],{type:"application/json"}),Le=URL.createObjectURL(qe),Ve=document.createElement("a");Ve.href=Le,Ve.download=`${d.name}-${s}.json`,document.body.appendChild(Ve),Ve.click(),document.body.removeChild(Ve),URL.revokeObjectURL(Le),u.success("JSON 已下载")}catch(M){u.error((M==null?void 0:M.message)||"导出失败")}finally{h()}},[s,u,Bt,d]),p=r.useCallback(async()=>{if(!d){u.warning("请先选择一个条目");return}const g=u.loading("正在生成可粘贴的 Figma 数据...",0);try{const{layers:h}=await Bt(!0);await Gh(h),u.success("复制成功,粘贴后若文本不显示,需切换页面再返回")}catch(h){u.error((h==null?void 0:h.message)||"复制到 Figma 失败")}finally{g()}},[u,Bt,d]),Q=r.useCallback(async g=>{if(!d){u.warning("请先选择一个条目");return}const h=u.loading("正在复制到 Axure...",0);try{const M=await Us(g);if(!await ls())throw new Error(`Axure Bridge 可用性检查返回 false;${ll}`);await Yt(M),u.success("已复制到 Axure")}catch(M){console.error("复制到 Axure 失败:",M),u.error(Cu(String((M==null?void 0:M.message)||"")))}finally{h()}},[ls,u,Yt,Us,d]),I=r.useCallback(async()=>{if(!d)return u.warning("请先选择一个条目"),!1;try{const g=`${s}/${d.name}`,h=await Pt.reviewCode(g,{enforceComponentExportName:!0});if(h!=null&&h.passed)return!0;const M=Array.isArray(h==null?void 0:h.issues)?h.issues:[],ee=M.find(we=>(we==null?void 0:we.type)==="error")||M[0];return u.error(`代码检查未通过${ee!=null&&ee.message?`:${ee.message}`:""}`),ce(!0),!1}catch{return!0}},[s,u,d]),_=r.useCallback(async(g=!1)=>{if(!d)return null;const h=`${window.location.origin}/${s}/${d.name}`,M={};for(const we of["spec","prd"])try{const Ge=await fetch(`${h}/${we}.md`);Ge.ok&&(M[we]={name:we==="spec"?"规格文档":"需求文档",content:await Ge.text()})}catch{}if(g)try{const we=await fetch(`${window.location.origin}/api/source?path=${encodeURIComponent(`${s}/${d.name}`)}`);if(we.ok){const Ge=await we.text();M.code={name:"参考代码",content:`\`\`\`tsx
|
||
${Ge}
|
||
\`\`\`
|
||
`}}}catch{}const ee=Object.keys(M);return ee.length>1?M:ee.length===1?M[ee[0]].content:null},[s,d]),O=r.useCallback(async()=>{if(!d)throw new Error("未选择项目");if(b.contentType==="screenshot"&&!b.rawScreenshotUrl)throw new Error("正在生成截图,请稍候...");const g=window.location.origin+d.jsUrl,h=await Pt.fetchCode(g),M=await Pt.fetchHackCss(s,d.name);let ee="",we="";b.includeConfig!=="none"&&(ee=h,(b.includeConfig==="codeAndDocs"||b.includeConfig==="codeAndDocsAndSource")&&(we=await _(b.includeConfig==="codeAndDocsAndSource")));const Ge=s==="components"?"组件":"原型";let qe="";if(b.contentType==="title"){const ys=Na("",b,d.displayName,Ge),ks=await qo(ys,b.width,b.height,2);qe=`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${b.width}" height="${b.height}" viewBox="0 0 ${b.width} ${b.height}"><rect width="100%" height="100%" fill="transparent" /><image x="0" y="0" width="${b.width}" height="${b.height}" preserveAspectRatio="xMidYMin meet" xlink:href="${ks}"/></svg>`}else qe=Na(b.rawScreenshotUrl,b,d.displayName,Ge);const Ve=new DOMParser().parseFromString(qe,"image/svg+xml"),Xe=Ve.querySelector("svg");if(!Xe)throw new Error("SVG generation failed");return(ee||we)&&Xe.setAttribute("AxExtraData",encodeURIComponent(JSON.stringify({code:ee,spec:we}))),b.includeConfig!=="none"&&Xe.setAttribute("AxData",encodeURIComponent(JSON.stringify({time:Math.floor(Date.now()/1e3),config:{codeLink:g,...s==="prototypes"?{isFullScreen:!0}:{},...M?{hackCss:M}:{}}}))),{updatedSvg:new XMLSerializer().serializeToString(Ve),fileName:`${d.name}.svg`}},[s,_,b,d]),G=r.useCallback(async()=>{if(!d)return;const g=u.loading("正在下载 Runtime 封面...",0);Ee(!0);try{const{updatedSvg:h,fileName:M}=await O(),ee=new Blob([h],{type:"image/svg+xml;charset=utf-8"}),we=URL.createObjectURL(ee),Ge=document.createElement("a");Ge.href=we,Ge.download=M,document.body.appendChild(Ge),Ge.click(),document.body.removeChild(Ge),URL.revokeObjectURL(we),u.success("Runtime 封面下载成功"),ce(!1)}catch(h){u.error((h==null?void 0:h.message)||"下载 Runtime 封面失败")}finally{g(),Ee(!1)}},[O,u,d]),le=r.useCallback(async()=>{if(!d)return;const g=u.loading("正在复制 Runtime 组件...",0);Ee(!0);try{if(!navigator.clipboard||typeof navigator.clipboard.writeText!="function")throw new Error("当前环境不支持文本复制,请检查浏览器剪贴板权限后重试");const{updatedSvg:h}=await O(),M=qh({svgContent:h,width:b.width,height:b.height});await navigator.clipboard.writeText(`// axvg
|
||
${JSON.stringify(M)}`),u.success("Runtime 组件已复制到剪贴板")}catch(h){u.error((h==null?void 0:h.message)||"复制 Runtime 组件失败")}finally{g(),Ee(!1)}},[O,b.height,b.width,u,d]),ye=r.useCallback(async g=>{if(!d)throw new Error("未选择项目");const h=window.location.origin+d.jsUrl,M=await Pt.fetchCode(h),ee=await Pt.fetchHackCss(s,d.name),we={time:Math.floor(Date.now()/1e3),config:{code:M,...s==="prototypes"?{isFullScreen:!0}:{},...ee?{hackCss:ee}:{}}};if(g==="codeAndDocs"||g==="codeAndDocsAndSource"){const Ge=await _(g==="codeAndDocsAndSource");Ge&&(we.config.spec=Ge)}return JSON.stringify(we,null,2)},[s,_,d]),_e=r.useCallback(()=>{Q(nt)},[nt,Q]),ht=r.useCallback(()=>{(async()=>await I()&&await le())()},[I,le]),xt=r.useCallback(()=>{(async()=>await I()&&await G())()},[I,G]);return r.useEffect(()=>{var ee,we;if(A.current===Rt)return;A.current=Rt,q.current=!1;const g=Yr(Rt),h=g.imageConfig?{...xr,...g.imageConfig,rawScreenshotUrl:"",screenshotWidth:0,screenshotHeight:0,previewUrl:""}:xr,M=g.axureCopyOptions?{...fr,...g.axureCopyOptions}:fr;pe.current=!0,se.current=!!((ee=g.imageConfig)!=null&&ee.width&&((we=g.imageConfig)!=null&&we.height)),he(h),Me(M),q.current=!0},[Rt]),r.useEffect(()=>{q.current&&gl(Rt,{imageConfig:{width:b.width,height:b.height,includeConfig:b.includeConfig,contentType:b.contentType},axureCopyOptions:{preserveHierarchy:nt.preserveHierarchy,preserveSvgIcons:nt.preserveSvgIcons}})},[nt.preserveHierarchy,nt.preserveSvgIcons,Rt,b.contentType,b.height,b.includeConfig,b.width]),r.useEffect(()=>{if(pe.current){pe.current=!1;return}se.current=!1,b.contentType==="screenshot"?he(g=>({...g,width:pt.width,height:pt.height,screenshotWidth:0,screenshotHeight:0,rawScreenshotUrl:""})):he(g=>({...g,width:500,height:300}))},[b.contentType,pt.height,pt.width]),r.useEffect(()=>{se.current||b.contentType==="screenshot"&&(!b.screenshotWidth||!b.screenshotHeight||he(g=>({...g,width:b.screenshotWidth,height:b.screenshotHeight})))},[b.contentType,b.screenshotHeight,b.screenshotWidth]),r.useEffect(()=>{const g=h=>{var we,Ge,qe,Le,Ve,Xe,Wt,ys,ks,Vn,Hn,zs,qn;const M=z.current;if(!M||h.source!==M.contentWindow)return;const ee=ut(M);if(!(ee!=="*"&&h.origin!==ee)){if(((we=h.data)==null?void 0:we.type)==="SCREENSHOT_CAPTURED"){he(ct=>({...ct,rawScreenshotUrl:h.data.dataUrl,screenshotWidth:h.data.width,screenshotHeight:h.data.height}));return}if(((Ge=h.data)==null?void 0:Ge.type)==="SCREENSHOT_FAILED"){he(ct=>({...ct,rawScreenshotUrl:"",screenshotWidth:0,screenshotHeight:0,previewUrl:""})),Qt("error",h.data.error||"截图生成失败");return}if(((qe=h.data)==null?void 0:qe.type)==="spec-doc-changed"){S.current=null,R(h.data.activeDocKey==="prd"?"prd":"spec");return}if(((Le=h.data)==null?void 0:Le.type)==="SPEC_EDIT_NOTICE"||((Ve=h.data)==null?void 0:Ve.type)==="TEXT_EDIT_NOTICE"||((Xe=h.data)==null?void 0:Xe.type)==="WEB_EDITOR_NOTICE"){Qt(h.data.level,h.data.message);return}if(((Wt=h.data)==null?void 0:Wt.type)==="WEB_EDITOR_DIALOG_REQUEST"){const ct=typeof h.data.requestId=="string"?h.data.requestId.trim():"",ot=h.data.kind==="confirm"?"confirm":"alert";if(!ct)return;const Gt=typeof h.data.title=="string"&&h.data.title.trim()?h.data.title.trim():ot==="confirm"?"确认操作":"提示",cs=typeof h.data.description=="string"?h.data.description:"",Es=typeof h.data.confirmText=="string"&&h.data.confirmText.trim()?h.data.confirmText.trim():ot==="confirm"?"确定":"知道了",Bs=typeof h.data.cancelText=="string"&&h.data.cancelText.trim()?h.data.cancelText.trim():"取消",Ts=h.data.dismissible!==!1,da=h.data.tone==="destructive"?"destructive":h.data.tone==="default"?"default":"brand";(async()=>{if(ot==="confirm"){const Va=await K.confirm({title:Gt,description:cs,confirmText:Es,cancelText:Bs,tone:da,dismissible:Ts});$e({type:"WEB_EDITOR_DIALOG_RESPONSE",requestId:ct,confirmed:Va},M);return}Qt(h.data.level??(da==="destructive"?"error":"info"),cs),$e({type:"WEB_EDITOR_DIALOG_RESPONSE",requestId:ct,confirmed:!0},M)})();return}if(((ys=h.data)==null?void 0:ys.type)==="SPEC_EDIT_STATUS"){const ct=!!h.data.dirty,ot=!!h.data.enabled,Gt=!!h.data.saving,cs=h.data.quickEditMode==="edit"?"edit":"annotation",Es=M.getAttribute("src")||M.src||"";if((()=>{try{const Ts=new URL(Es,window.location.origin).pathname;if(Ts.startsWith("/docs/templates/"))return"template";if(Ts.startsWith("/docs/"))return"doc"}catch{if(Es.includes("/docs/templates/"))return"template";if(Es.includes("/docs/"))return"doc"}return!1})()){if(ct&&(S.current=null),Ae({enabled:ot,dirty:ct,saving:Gt,quickEditMode:ot?cs:"annotation"}),Y.current&&!Gt)if(ot)Y.current=null;else{const Ts=Y.current;Y.current=null,Ts&&Xt(Ts.kind,Ts.item)}return}ct&&(S.current=null),ue({enabled:ot,dirty:ct,saving:Gt}),me(ot?cs:"annotation");return}if(((ks=h.data)==null?void 0:ks.type)==="TEXT_EDIT_STATUS"){de({enabled:!!h.data.enabled,editedCount:Number(h.data.editedCount||0)});return}if(((Vn=h.data)==null?void 0:Vn.type)==="TEXT_EDIT_SAVE_CONFIRM_REQUEST"){const ct=Number(h.data.changedCount||0),ot=Number(h.data.totalCount||0),Gt=!!h.data.exitAfterSave;C.confirm({title:"确认保存文本修改?",content:e.jsxs("div",{children:[e.jsxs("div",{children:["检测到 ",ct," 处文本修改。"]}),e.jsxs("div",{children:[ot>0?`预计会替换 ${ot} 处文本。`:"当前无法预估替换数量。",Gt?" 保存后会退出文本编辑模式。":""]})]}),okText:"确认保存",cancelText:"取消",onOk:()=>{$e({type:"TEXT_EDIT_SAVE_CONFIRM",confirmed:!0},M)},onCancel:()=>{$e({type:"TEXT_EDIT_SAVE_CONFIRM",confirmed:!1},M)}});return}if(((Hn=h.data)==null?void 0:Hn.type)==="TEXT_EDIT_SAVE_RESULT"){h.data.success&&de(ct=>({...ct,editedCount:0}));return}if(((zs=h.data)==null?void 0:zs.type)==="TEXT_EDIT_CONFLICT"){const ct=Array.isArray(h.data.conflicts)?h.data.conflicts:[];C.warning({title:"存在文本编辑冲突",content:ct.length>0?e.jsxs("div",{children:[e.jsx("div",{children:"同一段原文被改成了多个不同结果,暂时无法批量保存。"}),e.jsx("ul",{style:{margin:"8px 0 0",paddingLeft:18},children:ct.slice(0,5).map((ot,Gt)=>e.jsxs("li",{children:["原文“",String((ot==null?void 0:ot.original)||""),"”"]},`${(ot==null?void 0:ot.original)||"conflict"}-${Gt}`))}),ct.length>5?e.jsxs("div",{children:["其余 ",ct.length-5," 项请回到页面继续检查。"]}):null]}):"存在相同原文但不同修改的内容,暂时无法批量保存。",okText:"知道了"});return}if(((qn=h.data)==null?void 0:qn.type)==="SPEC_EDIT_PROMPT_RESPONSE"){const ct=String(h.data.requestId||"").trim();if(!ct)return;const ot=W.current.get(ct);if(!ot)return;if(window.clearTimeout(ot.timeoutId),W.current.delete(ct),!h.data.success){ot.reject(new Error(h.data.error||"生成 Prompt 失败"));return}const Gt=typeof h.data.prompt=="string"?h.data.prompt:"";if(!Gt.trim()){ot.reject(new Error("生成 Prompt 失败:内容为空"));return}const cs=typeof h.data.targetPath=="string"?h.data.targetPath:void 0,Es=Mr(h.data.context,{fallbackCurrentFile:L.currentFile})??void 0,Bs={prompt:Gt,targetPath:cs,context:Es};tt&&(S.current={key:tt.cacheKey,result:Bs}),ot.resolve(Bs);return}Bd(h.data)&&re(h.data.payload)}};return window.addEventListener("message",g),()=>window.removeEventListener("message",g)},[tt,L,K,ut,re,C,Qt,$e,R,Xt]),r.useEffect(()=>()=>{W.current.forEach(g=>{window.clearTimeout(g.timeoutId),g.reject(new Error("请求已取消"))}),W.current.clear()},[]),r.useEffect(()=>{ue({enabled:!1,dirty:!1,saving:!1}),me("annotation"),Y.current=null,Ae(xa()),De(!1),Ze(null),W.current.forEach(g=>{window.clearTimeout(g.timeoutId),g.reject(new Error("请求已取消"))}),W.current.clear()},[d,y,Ue]),r.useEffect(()=>{o==="document"&&!!j||o==="assets"&&i==="templates"&&!!v||(Y.current=null,Ae(xa()))},[i,j,v,o]),r.useEffect(()=>{if(!E||!d)return;if(b.contentType==="screenshot"&&!b.rawScreenshotUrl){he(ee=>({...ee,previewUrl:""}));return}let g=!1,h="";const M=s==="components"?"组件":"原型";return(async()=>{try{let ee="";if(b.contentType==="title"){const Ge=Na("",b,d.displayName,M),qe=await qo(Ge,b.width,b.height,2);ee=`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${b.width}" height="${b.height}" viewBox="0 0 ${b.width} ${b.height}"><rect width="100%" height="100%" fill="transparent" /><image x="0" y="0" width="${b.width}" height="${b.height}" preserveAspectRatio="xMidYMin meet" xlink:href="${qe}"/></svg>`}else ee=Na(b.rawScreenshotUrl,b,d.displayName,M);const we=new Blob([ee],{type:"image/svg+xml;charset=utf-8"});h=URL.createObjectURL(we),g||he(Ge=>({...Ge,previewUrl:h}))}catch{g||he(ee=>({...ee,previewUrl:""}))}})(),()=>{g=!0,h&&URL.revokeObjectURL(h)}},[s,b.contentType,b.height,b.rawScreenshotUrl,b.width,E,d]),r.useEffect(()=>{if(E&&b.contentType==="screenshot"&&b.width===pt.width&&b.height===pt.height&&ft(),!E){const g=Qe();g!=null&&g.contentWindow&&g.contentWindow.postMessage({type:"RESET_SCREENSHOT_STYLES"},ut(g))}},[ut,Qe,ft,b.contentType,b.height,b.width,E,pt.height,pt.width]),{selectedDeviceId:Ne,setSelectedDeviceId:Ce,deviceSegmentOptions:js,qrCodeVisible:Oe,setQrCodeVisible:We,specPromptCopying:je,specPromptExecutingClient:ge,specExecuteMenuItems:yt,specEditState:ze,specQuickEditMode:ne,textEditState:Z,textEditAvailable:Lt,quickEditPromptAvailable:is,quickEditPromptCopying:dt,editorStatus:ke,containerRef:ie,previewIframeRef:z,currentDevice:st,displaySize:rs,scale:Kt,elementIframeKey:Ue,iframeUrl:Ft,localShareUrl:et,elementIframeSize:Ie,setElementIframeSize:ve,docEditState:J,isExportModalOpen:E,setIsExportModalOpen:ce,exportPreferencesStorageKey:Rt,isExporting:Pe,imageConfig:b,setImageConfig:he,axureCopyOptions:nt,setAxureCopyOptions:Me,handleDimensionChange:tn,handleSwapDimensions:bn,handleDimensionBlur:yn,handleExport:G,handleCopyRuntimeComponent:le,handleCopyToAxure:Q,handleCopyConfig:ye,handleSelectDoc:As,handleSelectTemplate:ps,handleOpenWebEditor:wn,handleOpenQuickEditInNewPage:Cn,handleExitWebEditor:He,handleSaveWebEditorText:Ns,handleSaveWebEditorStyle:rt,handleClearWebEditorForcedStyles:$t,handleCopyQuickEditPrompt:Kn,handleRefreshElement:at,handleCopyLocalLink:Ht,handleCopyLANLink:qt,getLANUrl:Ss,handlePushToFigma:kn,handleCopyToFigma:p,handleDownloadFigmaJson:Os,handleQuickCopyEditablePrototype:_e,handleQuickCopyRuntimeComponent:ht,handleQuickDownloadRuntimeCover:xt,handleEnableDocEdit:Rs,handleSaveDocEdit:jn,handleExitDocEdit:sn,handleSwitchDocQuickEditMode:xs,handleEnableSpecEdit:Gn,handleSaveSpecEdit:Nn,handleExitSpecEdit:Fs,handleSwitchSpecQuickEditMode:vn,handleCopySpecPrompt:gs,handleExecuteSpecPrompt:Sn,handleOpenQuickEditForMobile:Cs,handleSaveWebEditor:Ns,handleWebEditorGenieRequest:re,clearAssistantSelectedElementsOnExit:B,tryOpenByAssistantIframe:xe,handleOpenAssistantIframe:()=>{u.info("助手面板由页面控制器管理")},assistantProjectPath:F}}function Jh({assistantProjectPath:t,projectTitle:s,setDefaultThemeName:n}){const[a,o]=r.useState(null),[i,l]=r.useState(null),[c,d]=r.useState(!1),[w,j]=r.useState(null),$=r.useRef(!1);r.useEffect(()=>{let u=!1;return Pt.getConfig().then(C=>{var y,P,R,L;if(u)return;o(Da((y=C==null?void 0:C.automation)==null?void 0:y.defaultPromptClient)),l(((P=C==null?void 0:C.automation)==null?void 0:P.defaultIDE)||null),n(((R=C==null?void 0:C.projectDefaults)==null?void 0:R.defaultTheme)||null);const K=or(C==null?void 0:C.projectPath,(L=C==null?void 0:C.projectInfo)==null?void 0:L.name);j(K),!$.current&&!Ao(K)&&($.current=!0,d(!0))}).catch(()=>{if(!u){o(null),l(null),n(null);const C=or();j(C),!$.current&&!Ao(C)&&($.current=!0,d(!0))}}),()=>{u=!0}},[n]);const v=r.useCallback(()=>{Pt.getConfig().then(u=>{var C,K;o(Da((C=u==null?void 0:u.automation)==null?void 0:C.defaultPromptClient)),l(((K=u==null?void 0:u.automation)==null?void 0:K.defaultIDE)||null)}).catch(()=>{o(null),l(null)})},[]),D=r.useCallback(u=>{if(d(u),!u&&c){const C=w||or(t,s);yu(C)}},[t,s,c,w]);return{preferredPromptClient:a,preferredIDE:i,setPreferredIDE:l,welcomeGuideOpen:c,handleWelcomeGuideOpenChange:D,handleSettingsSaved:v}}function Qh({state:t,preview:s,actions:n}){return r.useMemo(()=>({state:{collapsed:t.collapsed,selectedItem:t.selectedItem,selectedSubPage:t.selectedSubPage,viewMode:t.viewMode,activeTab:t.activeTab,selectedDeviceId:s.selectedDeviceId,deviceSegmentOptions:s.deviceSegmentOptions,qrCodeVisible:s.qrCodeVisible,specPromptCopying:s.specPromptCopying,specPromptExecutingClient:s.specPromptExecutingClient,specExecuteMenuItems:s.specExecuteMenuItems,currentSpecDocKey:t.currentSpecDocKey,specEditState:s.specEditState,specQuickEditMode:s.specQuickEditMode,textEditAvailable:s.textEditAvailable,editorMode:s.editorStatus.mode,allowLAN:!0,assistantVisible:t.assistantVisible,containerRef:s.containerRef,previewIframeRef:s.previewIframeRef,currentDevice:s.currentDevice,displaySize:s.displaySize,scale:s.scale,elementIframeKey:s.elementIframeKey,iframeUrl:s.iframeUrl,localShareUrl:s.localShareUrl,elementIframeSize:s.elementIframeSize,contentMode:t.contentMode,selectedDoc:t.selectedDoc,selectedTemplate:t.selectedTemplate,docEditState:s.docEditState,selectedCanvas:t.selectedCanvas,isDarkMode:t.isDarkMode,selectedTheme:t.selectedTheme,selectedDataTable:t.selectedDataTable,preferredPromptClient:t.preferredPromptClient,preferredIDE:t.preferredIDE},actions:{setCollapsed:n.setCollapsed,setViewMode:n.setViewMode,setSelectedDeviceId:s.setSelectedDeviceId,handleOpenWebEditor:s.handleOpenWebEditor,handleOpenQuickEditInNewPage:s.handleOpenQuickEditInNewPage,handleExitWebEditor:s.handleExitWebEditor,handleSaveWebEditorText:s.handleSaveWebEditorText,handleSaveWebEditorStyle:s.handleSaveWebEditorStyle,handleClearWebEditorForcedStyles:s.handleClearWebEditorForcedStyles,handleRefreshElement:s.handleRefreshElement,handleCopyLocalLink:s.handleCopyLocalLink,handleCopyLANLink:s.handleCopyLANLink,getLANUrl:s.getLANUrl,setQrCodeVisible:s.setQrCodeVisible,handlePushToFigma:s.handlePushToFigma,handleCopyToFigma:s.handleCopyToFigma,handleDownloadFigmaJson:s.handleDownloadFigmaJson,setIsExportModalOpen:s.setIsExportModalOpen,handleQuickCopyEditablePrototype:s.handleQuickCopyEditablePrototype,handleQuickCopyRuntimeComponent:s.handleQuickCopyRuntimeComponent,handleQuickDownloadRuntimeCover:s.handleQuickDownloadRuntimeCover,handleOpenIdeFile:n.handleOpenIdeFile,handleOpenDocInIDE:n.handleOpenSelectedDocInIDE,handleEnableDocEdit:s.handleEnableDocEdit,handleSaveDocEdit:s.handleSaveDocEdit,handleExitDocEdit:s.handleExitDocEdit,handleSwitchDocQuickEditMode:s.handleSwitchDocQuickEditMode,handleOpenThemeInIDE:n.handleOpenSelectedThemeInIDE,handleOpenThemeDocInIDE:n.handleOpenSelectedThemeDocInIDE,handleOpenDataTableInIDE:n.handleOpenSelectedDataTableInIDE,handleEnableSpecEdit:s.handleEnableSpecEdit,handleSaveSpecEdit:s.handleSaveSpecEdit,handleExitSpecEdit:s.handleExitSpecEdit,handleSwitchSpecQuickEditMode:s.handleSwitchSpecQuickEditMode,handleExecuteSpecPrompt:s.handleExecuteSpecPrompt,onToggleAssistant:n.handleToggleAssistant,setElementIframeSize:s.setElementIframeSize}}),[n,s,t])}function Xh({loading:t,data:s,searchText:n,setSearchText:a,activeTab:o,setActiveTab:i,selectedItem:l,setSelectedItem:c,selectedSubPage:d,setSelectedSubPage:w,sidebarTab:j,setSidebarTab:$,resourceSection:v,setResourceSection:D,currentSpecDocKey:u,setCurrentSpecDocKey:C,editorMode:K,onExitWebEditor:y,setElementIframeSize:P}){r.useEffect(()=>{localStorage.setItem(ad,o)},[o]),r.useEffect(()=>{if(!t&&s){const x=o==="components"?s.components:s.prototypes;x.length>0?(c(x[0]),w(null),o==="components"&&P({width:600,height:400})):(c(null),w(null))}},[o,s,t,P,w]),r.useEffect(()=>{j==="prototype"&&o!=="prototypes"?i("prototypes"):j==="assets"&&o!=="components"&&i("components")},[o,j]);const R=r.useMemo(()=>{const x=o==="components"?s.components:s.prototypes;if(!n)return x;const V=n.toLowerCase();return x.filter(re=>re.displayName.toLowerCase().includes(V)||re.name.toLowerCase().includes(V))},[o,s.components,s.prototypes,n]),L=r.useCallback(async({key:x})=>{K==="webEditorV2"&&await y({restoreDevice:!1});const V=R.find(re=>re.name===x);V&&(c(V),w(null),C("spec"),o==="components"&&P({width:600,height:400}))},[o,K,R,y,P,w]),F=r.useCallback(x=>{if(x===o)return;i(x),a(""),C("spec");const V=x==="components"?s.components:s.prototypes;if(V.length>0){c(V[0]),w(null),x==="components"&&P({width:600,height:400});return}c(null),w(null)},[o,s.components,s.prototypes,P,a,w]);return r.useEffect(()=>{o!=="prototypes"&&d&&w(null)},[o,d,w]),{activeTab:o,setActiveTab:i,selectedItem:l,setSelectedItem:c,sidebarTab:j,setSidebarTab:$,resourceSection:v,setResourceSection:D,currentSpecDocKey:u,setCurrentSpecDocKey:C,filteredItems:R,handleMenuClick:L,handleTabChange:F}}function Yh({state:t,deps:s}){return r.useMemo(()=>({state:{collapsed:t.collapsed,loading:t.loading,sidebarTab:t.sidebarTab,data:t.data,docsItems:t.docsItems,canvasItems:t.canvasItems,themes:t.themes,dataTables:t.dataTables,templates:t.templateAssets,searchText:t.searchText,selectedItem:t.selectedItem,selectedSubPage:t.selectedSubPage,selectedDoc:t.selectedDoc,selectedCanvas:t.selectedCanvas,selectedTheme:t.selectedTheme,selectedDataTable:t.selectedDataTable,selectedTemplate:t.selectedTemplate,resourceSection:t.resourceSection,defaultThemeName:t.defaultThemeName,projectTitle:t.projectTitle,isDarkMode:t.isDarkMode,sidebarTrees:t.sidebarTrees},actions:{handleTabChange:s.handleTabChange,onSidebarTabChange:s.setSidebarTab,setSearchText:s.setSearchText,onOpenThemeInIDE:n=>{s.handleOpenSelectedThemeInIDE(n)},onOpenThemeDocInIDE:n=>{s.handleOpenSelectedThemeDocInIDE(n)},onRenameTheme:n=>{s.resources.handleRenameThemeResource(n)},onDownloadThemeZip:s.resources.handleDownloadThemeZip,onDeleteTheme:n=>{s.resources.handleDeleteThemeResource(n)},onOpenDataTableInIDE:n=>{s.handleOpenSelectedDataTableInIDE(n)},onRenameDataTable:n=>{s.resources.handleRenameDataTableResource(n)},onDeleteDataTable:n=>{s.resources.handleDeleteDataTableResource(n)},onOpenTemplateInIDE:n=>{s.handleOpenSelectedDocInIDE(ln(n),"template")},onRenameTemplate:n=>{s.resources.handleRenameTemplateResource(n)},onDuplicateTemplate:n=>{s.resources.handleDuplicateTemplateResource(n)},onDeleteTemplate:n=>{s.resources.handleDeleteTemplateResource(n)},onCopyTemplatePath:n=>{s.resources.handleCopyTemplatePath(n)},onTemplateVersionManagement:n=>{s.resources.handleTemplateVersionManagement(n)},onResourceSectionChange:s.setResourceSection,onSelectDoc:s.previewHandleSelectDoc,onSelectCanvas:s.resources.handleSelectCanvas,onSelectTheme:n=>{s.setSidebarTab("assets"),s.setResourceSection("themes"),s.resources.setSelectedTheme(n)},onSelectDataTable:n=>{s.setSidebarTab("assets"),s.setResourceSection("data"),s.resources.setSelectedDataTable(n)},onSelectTemplate:n=>{s.previewHandleSelectTemplate(ln(n))},onReorderThemes:s.resources.handleReorderThemes,onSetDefaultTheme:s.resources.handleSetDefaultTheme,onReorderDataTables:s.resources.handleReorderDataTables,onReorderTemplates:s.resources.handleReorderTemplates,onSubPageSelect:(n,a)=>{s.handleMenuClick({key:n.name}),s.setSelectedSubPage(a)},onSubPageClear:()=>{s.setSelectedSubPage(null)},onShowReadonlyPromptDialog:s.showReadonlyPromptDialog,onRequestTextInputDialog:s.requestTextInputDialog,handleMenuClick:s.handleMenuClick,handleDownloadItemSource:s.resources.handleDownloadItemSource,handleRenameItem:s.resources.handleRenameItem,handleDuplicateItem:n=>{s.resources.handleDuplicateItem(n)},handleDeleteItem:n=>{s.resources.handleDeleteItem(n,s.preferredPromptClient,s.preferredIDE)},handleCopyItemPath:n=>{s.handleCopyItemPath(n)},handleRenameDocItem:s.resources.handleRenameDocItem,handleDuplicateDocItem:n=>{s.resources.handleDuplicateDocItem(n)},handleDeleteDocItem:n=>{s.resources.handleDeleteDocItem(n)},handleCopyDocPath:n=>{s.resources.handleCopyDocPath(n)},handleDocVersionManagement:s.resources.handleDocVersionManagement,onCreatePrototypeFromDoc:n=>{s.resources.handleCreatePrototypeFromDoc(n)},onOpenCreateDialog:()=>{t.sidebarTab==="assets"?s.setActiveTab("components"):t.sidebarTab==="prototype"&&s.setActiveTab("prototypes"),s.setCreateDialogVisible(!0)},onCreateResource:s.resources.handleCreateResource,onCreateDocFile:s.resources.handleCreateDocFile,onCreateCanvasFile:()=>{s.resources.handleCreateCanvasFile()},handleRenameCanvasItem:s.resources.handleRenameCanvasItem,handleDuplicateCanvasItem:s.resources.handleDuplicateCanvasItem,handleDeleteCanvasItem:s.resources.handleDeleteCanvasItem,handleCopyCanvasPath:s.resources.handleCopyCanvasPath,onCreateFolder:s.resources.handleCreateFolder,onGenerateThemeFromPrototype:s.resources.handleGenerateThemeFromPrototype,onSettingsClick:()=>s.setSettingsDialogOpen(!0),onWeChatConnect:()=>s.setWechatConnectOpen(!0),onToggleTheme:()=>s.setIsDarkMode(!t.isDarkMode),onTitleChange:s.resources.handleProjectTitleChange,handleOpenProjectInIDE:s.handleOpenProjectInIDE,onSidebarTreeChange:s.resources.handleSidebarTreeChange,onSidebarTreePersist:s.resources.handleSidebarTreePersist,handleVersionManagement:s.resources.handleVersionManagement},preferences:{preferredIDE:s.preferredIDE,onPreferredIDEChange:s.setPreferredIDE}}),[s,t])}function ep(){const t=Rr(),s=r.useMemo(()=>({success:a=>H.success(a),error:a=>H.error(a),warning:a=>H.warning(a),info:a=>H.info(a),loading:(a,o)=>{const i=H.loading(a);return()=>H.dismiss(i)}}),[]),n=r.useMemo(()=>({confirm:a=>{(async()=>{var i,l;await t.confirm({title:a.title,description:a.content,confirmText:a.okText??"确定",cancelText:a.cancelText??"取消",tone:"brand",dismissible:!1})?await((i=a.onOk)==null?void 0:i.call(a)):(l=a.onCancel)==null||l.call(a)})()},warning:a=>{t.alert({title:a.title,description:a.content,confirmText:a.okText??"知道了",tone:"brand",dismissible:!0})}}),[t]);return{appDialog:t,messageApi:s,modal:n}}const tp=(qi.skills??[]).map(t=>({id:String(t.id||"").trim(),title:String(t.title||"").trim(),titleZh:String(t.titleZh||"").trim()||void 0,description:String(t.description||"").trim()||void 0,references:Array.isArray(t.references)?t.references:[],defaultSelected:!!t.defaultSelected,category:t.category})).filter(t=>!!t.id&&!!(t.title||t.titleZh));function sp({isDarkMode:t,setIsDarkMode:s}){var Ae,ze,ue,ne;const{appDialog:n,messageApi:a,modal:o}=ep(),i=ku({messageApi:a}),[l,c]=r.useState(!1),[d,w]=r.useState(!1),[j,$]=r.useState(!1),[v,D]=r.useState("demo"),[u,C]=r.useState("prototypes"),[K,y]=r.useState(null),[P,R]=r.useState(null),[L,F]=r.useState("prototype"),[x,V]=r.useState("themes"),[re,B]=r.useState("spec"),xe=r.useMemo(()=>i.docsItems.map(me=>({name:me.name,displayName:me.displayName||me.name})),[i.docsItems]),ie=r.useMemo(()=>{var je,De;return[...((je=i.data)==null?void 0:je.prototypes)||[],...((De=i.data)==null?void 0:De.components)||[]].map(ge=>({name:ge.name,displayName:ge.displayName||ge.name}))},[(Ae=i.data)==null?void 0:Ae.components,(ze=i.data)==null?void 0:ze.prototypes]),z=r.useMemo(()=>{var me;return(((me=i.data)==null?void 0:me.prototypes)||[]).map(je=>({name:je.name,displayName:je.displayName||je.name}))},[(ue=i.data)==null?void 0:ue.prototypes]),se=r.useMemo(()=>i.dataTables.map(me=>({name:`${me.fileName}.json`,displayName:me.tableName})),[i.dataTables]),W=r.useMemo(()=>i.templateAssets,[i.templateAssets]),{createDialogVisible:S,selectedSkills:Y,setSelectedSkills:k,selectedThemes:N,availableThemes:U,selectedDocs:A,availableDocs:q,selectedDataAssets:pe,availableDataAssets:Ne,setCreateDialogVisible:Ce,setSelectedThemes:Ie,setSelectedDocs:ve,setSelectedDataAssets:Ue,buildPrompt:Fe,clearCreateDialogState:Oe,handleCreateCancel:We}=Pd(u,i.data),E=Bh({activeTab:u,data:i.data,docsItems:i.docsItems,canvasItems:i.canvasItems,themes:i.themes,setThemes:i.setThemes,dataTables:i.dataTables,setDataTables:i.setDataTables,templateAssets:i.templateAssets,setTemplateAssets:i.setTemplateAssets,resourceOrders:i.resourceOrders,setResourceOrders:i.setResourceOrders,sidebarTrees:i.sidebarTrees,setSidebarTrees:i.setSidebarTrees,projectTitle:i.projectTitle,setProjectTitle:i.setProjectTitle,availableDocOptions:xe,availablePrototypeOptions:ie,availableReferencePrototypeOptions:z,availableDataAssetOptions:se,availableTemplateOptions:W,messageApi:a,modal:o,appDialog:n,setActiveTab:C,setSelectedItem:y,setSidebarTab:F,setResourceSection:V,setCreateDialogVisible:Ce,setCreateDialogSelectedDocs:ve,loadData:i.loadData,reloadSidebarAssets:i.reloadSidebarAssets,reloadDocsItems:i.reloadDocsItems,reloadCanvasItems:i.reloadCanvasItems,getSidebarTabItems:i.getSidebarTabItems}),ce=mu({messageApi:a,modal:o,preferredPromptClient:null,activeTab:u,viewMode:v,currentSpecDocKey:re,selectedItem:K}),Pe=Zh({activeTab:u,collapsed:l,setCollapsed:c,sidebarTab:L,setSidebarTab:F,resourceSection:x,setResourceSection:V,selectedItem:K,selectedSubPage:P,selectedDoc:E.selectedDoc,setSelectedDoc:E.setSelectedDoc,selectedTemplate:E.selectedTemplate,setSelectedTemplate:E.setSelectedTemplate,messageApi:a,modal:o,appDialog:n,viewMode:v,currentSpecDocKey:re,setCurrentSpecDocKey:B,assistantContextV1:ce.assistantContextV1,assistantProjectPath:ce.assistantProjectPath,assistantApiBaseUrl:ce.assistantApiBaseUrl,assistantWebEditorClientId:ce.assistantWebEditorClientId,handleWebEditorGenieRequest:ce.handleWebEditorGenieRequest,clearAssistantSelectedElementsOnExit:ce.clearAssistantSelectedElementsOnExit,tryOpenByAssistantIframe:ce.tryOpenByAssistantIframe}),Ee=Xh({loading:i.loading,data:i.data,searchText:i.searchText,setSearchText:i.setSearchText,activeTab:u,setActiveTab:C,selectedItem:K,setSelectedItem:y,selectedSubPage:P,setSelectedSubPage:R,sidebarTab:L,setSidebarTab:F,resourceSection:x,setResourceSection:V,currentSpecDocKey:re,setCurrentSpecDocKey:B,editorMode:Pe.editorStatus.mode,onExitWebEditor:Pe.handleExitWebEditor,setElementIframeSize:Pe.setElementIframeSize}),Te=Jh({assistantProjectPath:ce.assistantProjectPath,projectTitle:i.projectTitle,setDefaultThemeName:E.setDefaultThemeName});r.useEffect(()=>{i.ensureSidebarTreeLoaded(L)},[L,i]);const Ye=r.useMemo(()=>L==="document"?{item:E.selectedDoc,kind:"doc"}:L==="assets"&&x==="templates"?{item:E.selectedTemplate,kind:"template"}:{item:null,kind:"doc"},[x,E.selectedDoc,E.selectedTemplate,L]),nt=Ye.item;Ye.kind;const Me=Du({messageApi:a,preferredIDE:Te.preferredIDE,selectedItem:K,activeTab:u,viewMode:v,currentSpecDocKey:re,currentMarkdownResource:{kind:Ye.kind,item:nt},selectedTheme:E.selectedTheme,selectedDataTable:E.selectedDataTable}),b=r.useMemo(()=>{if(L==="document")return"doc";if(L==="canvas")return"canvas";if(L==="assets"){if(x==="themes")return"theme";if(x==="data")return"data";if(x==="templates")return"template"}return"preview"},[x,L]),he=Yh({state:{collapsed:l,loading:i.loading,sidebarTab:L,data:i.data,docsItems:i.docsItems,canvasItems:i.canvasItems,themes:i.themes,dataTables:i.dataTables,templateAssets:i.templateAssets,searchText:i.searchText,selectedItem:K,selectedSubPage:P,resourceSection:x,projectTitle:i.projectTitle,isDarkMode:t,sidebarTrees:i.sidebarTrees,defaultThemeName:E.defaultThemeName,selectedDoc:E.selectedDoc,selectedCanvas:E.selectedCanvas,selectedTheme:E.selectedTheme,selectedDataTable:E.selectedDataTable,selectedTemplate:E.selectedTemplate},deps:{preferredPromptClient:Te.preferredPromptClient,preferredIDE:Te.preferredIDE,setPreferredIDE:Te.setPreferredIDE,setIsDarkMode:s,setSettingsDialogOpen:w,setWechatConnectOpen:$,setActiveTab:C,setSidebarTab:F,setResourceSection:V,setSearchText:i.setSearchText,setCreateDialogVisible:Ce,handleTabChange:Ee.handleTabChange,handleMenuClick:Ee.handleMenuClick,setSelectedSubPage:R,showReadonlyPromptDialog:async({title:me,description:je,prompt:De,confirmText:ge,successMessage:Ze})=>{await n.prompt({title:me,description:je,label:"提示词",defaultValue:De,mode:"textarea",readOnly:!0,selectOnOpen:!0,confirmText:ge||"复制提示词",cancelText:"关闭"})!=null&&(await navigator.clipboard.writeText(De),a.success(Ze||"提示词已复制"))},requestTextInputDialog:me=>n.prompt({title:me.title,description:me.description,label:me.label,placeholder:me.placeholder,defaultValue:me.defaultValue,confirmText:me.confirmText,validate:me.validate}),handleOpenProjectInIDE:Me.handleOpenProjectInIDE,handleOpenSelectedDocInIDE:Me.handleOpenSelectedDocInIDE,handleOpenSelectedThemeInIDE:Me.handleOpenSelectedThemeInIDE,handleOpenSelectedThemeDocInIDE:Me.handleOpenSelectedThemeDocInIDE,handleOpenSelectedDataTableInIDE:Me.handleOpenSelectedDataTableInIDE,handleCopyItemPath:Me.handleCopyItemPath,previewHandleSelectDoc:Pe.handleSelectDoc,previewHandleSelectTemplate:Pe.handleSelectTemplate,resources:E}}),ke=Qh({state:{collapsed:l,selectedItem:K,selectedSubPage:P,viewMode:v,activeTab:u,currentSpecDocKey:re,assistantVisible:ce.assistantVisible,isDarkMode:t,contentMode:b,selectedDoc:E.selectedDoc,selectedTemplate:E.selectedTemplate,selectedCanvas:E.selectedCanvas,selectedTheme:E.selectedTheme,selectedDataTable:E.selectedDataTable,preferredPromptClient:Te.preferredPromptClient,preferredIDE:Te.preferredIDE},preview:Pe,actions:{setCollapsed:c,setViewMode:D,handleToggleAssistant:ce.handleToggleAssistant,handleOpenIdeFile:Me.handleOpenIdeFile,handleOpenSelectedDocInIDE:Me.handleOpenSelectedDocInIDE,handleOpenSelectedThemeInIDE:Me.handleOpenSelectedThemeInIDE,handleOpenSelectedThemeDocInIDE:Me.handleOpenSelectedThemeDocInIDE,handleOpenSelectedDataTableInIDE:Me.handleOpenSelectedDataTableInIDE}}),T=me=>{window.open(window.location.origin+me.demoUrl,"_blank")},Z={mounted:ce.assistantPanelMounted,visible:ce.assistantVisible,width:ce.assistantPanelWidth,minWidth:ce.assistantPanelMinWidth,maxWidth:ce.assistantPanelMaxWidth,iframeSrc:ce.assistantIframeSrc,iframeRef:ce.assistantIframeRef,onLoad:ce.handleAssistantIframeLoad,onResize:ce.setAssistantPanelWidth},de={docReferencePromptDialog:E.docReferencePromptDialog,setDocReferencePromptDialog:E.setDocReferencePromptDialog,preferredPromptClient:Te.preferredPromptClient,preferredIDE:Te.preferredIDE,createDialog:{visible:S,activeTab:Ee.activeTab,selectedThemes:N,selectedSkills:Y,availableThemes:U,selectedDocs:A,availableDocs:q,selectedDataAssets:pe,availableDataAssets:Ne,onClose:We,setSelectedSkills:k,setSelectedDocs:ve,setSelectedThemes:Ie,setSelectedDataAssets:Ue,buildPrompt:Fe,onAfterCreatePromptAction:Oe,onUploadSuccess:E.handleCreateDialogUploadSuccess},createDocDialog:{visible:E.docCreateDialogVisible,selectedSkillIds:E.selectedDocSkillIds,availableDocSkills:tp,selectedDocs:E.selectedDocRefs,availableDocs:xe,selectedReferencePrototypes:E.selectedDocReferencePrototypes,availableReferencePrototypes:z,selectedDataAssets:E.selectedDataRefs,availableDataAssets:se,selectedTemplates:E.selectedTemplateRefs,availableTemplates:W,onClose:E.handleDocCreateCancel,setSelectedSkillIds:E.setSelectedDocSkillIds,setSelectedDocs:E.setSelectedDocRefs,setSelectedReferencePrototypes:E.setSelectedDocReferencePrototypes,setSelectedDataAssets:E.setSelectedDataRefs,setSelectedTemplates:E.setSelectedTemplateRefs,buildCreateDocPrompt:E.buildDocPrompt,onAfterCreatePromptAction:E.clearDocCreateDialogState,onManualCreateSuccess:E.refreshSidebarAssets,onImportSuccess:E.refreshSidebarAssets},createThemeDialog:{visible:E.themeCreateDialogVisible,selectedSkillIds:E.selectedThemeSkillIds,selectedDocs:E.selectedThemeDocRefs,availableDocs:xe,selectedReferencePages:E.selectedThemeReferencePages,availableReferencePages:ie,onClose:E.handleThemeCreateCancel,setSelectedSkillIds:E.setSelectedThemeSkillIds,setSelectedDocs:E.setSelectedThemeDocRefs,setSelectedReferencePages:E.setSelectedThemeReferencePages,buildCreateThemePrompt:E.buildThemePrompt,onAfterCreatePromptAction:E.clearThemeCreateDialogState,onImportSuccess:E.refreshSidebarAssets},exportDialog:{open:Pe.isExportModalOpen,preferencesStorageKey:Pe.exportPreferencesStorageKey,imageConfig:Pe.imageConfig,axureCopyOptions:Pe.axureCopyOptions,isExporting:Pe.isExporting,activeTab:Ee.activeTab,itemName:(ne=Ee.selectedItem)==null?void 0:ne.name,onClose:()=>Pe.setIsExportModalOpen(!1),setImageConfig:Pe.setImageConfig,setAxureCopyOptions:Pe.setAxureCopyOptions,onDimensionChange:Pe.handleDimensionChange,onSwapDimensions:Pe.handleSwapDimensions,onDimensionBlur:Pe.handleDimensionBlur,onExport:Pe.handleExport,onCopyRuntimeComponent:Pe.handleCopyRuntimeComponent,onCopyToAxure:Pe.handleCopyToAxure,onCopyConfig:Pe.handleCopyConfig},settingsDialogOpen:d,setSettingsDialogOpen:w,onSettingsSaved:Te.handleSettingsSaved,wechatConnectOpen:j,setWechatConnectOpen:$,welcomeGuideOpen:Te.welcomeGuideOpen,onWelcomeGuideOpenChange:Te.handleWelcomeGuideOpenChange,versionDialogVisible:E.versionDialogVisible,setVersionDialogVisible:E.setVersionDialogVisible,currentVersionItem:E.currentVersionItem,versionActiveTab:Ee.activeTab,createDataDialog:{visible:E.dataTableCreateOpen,newTableName:E.newDataTableName,newTableNameError:E.newDataTableNameError,dataTableCreating:E.dataTableCreating,onClose:E.closeDataTableCreateDialog,setNewTableName:E.setNewDataTableName,clearNewTableNameError:()=>E.setNewDataTableNameError(""),onCreateSubmit:E.handleDataTableCreateSubmit,onImportSuccess:i.loadData}},J={loading:i.loading,items:i.data.prototypes,searchText:i.searchText,assistantVisible:ce.assistantVisible,onSearchTextChange:i.setSearchText,onWeChatConnect:()=>$(!0),onCopyProjectDirectory:ce.handleCopyProjectDirectory,onOpenAssistant:ce.handleOpenAssistantInNewWindowNoContext,onOpenItem:T,onOpenQuickEdit:Pe.handleOpenQuickEditForMobile,onOpenAssistantWithItemContext:ce.handleOpenAssistantWithItemContext};return e.jsx(Oh,{sidebarProps:he,presentationAreaProps:ke,assistantPanelProps:Z,dialogsProps:de,mobileProps:J})}function np(){const[t,s]=r.useState(()=>{try{return localStorage.getItem(xo)==="true"}catch{return!1}}),n=a=>{s(a);try{localStorage.setItem(xo,String(a))}catch(o){console.error("Failed to save dark mode preference:",o)}};return r.useEffect(()=>{document.documentElement.classList.toggle("dark",t),document.body.classList.toggle("dark",t)},[t]),e.jsxs("div",{className:t?"ax-admin-theme h-full dark":"ax-admin-theme h-full",children:[e.jsx(Jl,{children:e.jsx(sp,{isDarkMode:t,setIsDarkMode:n})}),e.jsx(nd,{position:"top-right",theme:t?"dark":"light",duration:2500,closeButton:!0,visibleToasts:2,offset:16,mobileOffset:16})]})}const ap=ql.createRoot(document.getElementById("root"));ap.render(e.jsx(np,{}));
|