@voobase/cli 0.1.1-nonprod.2019 → 0.1.1-nonprod.2036

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));var require_punycode=__commonJS({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js"(exports,module){"use strict";var regexPunycode=/^xn--/,regexNonASCII=/[^\0-\x7F]/,regexSeparators=/[\x2E\u3002\uFF0E\uFF61]/g,errors={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},baseMinusTMin=35,floor=Math.floor,stringFromCharCode=String.fromCharCode;function error(type){throw new RangeError(errors[type])}function map(array,callback){let result=[],length=array.length;for(;length--;)result[length]=callback(array[length]);return result}function mapDomain(domain,callback){let parts=domain.split("@"),result="";parts.length>1&&(result=parts[0]+"@",domain=parts[1]),domain=domain.replace(regexSeparators,".");let labels=domain.split("."),encoded=map(labels,callback).join(".");return result+encoded}function ucs2decode(string){let output=[],counter=0,length=string.length;for(;counter<length;){let value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){let extra=string.charCodeAt(counter++);(extra&64512)==56320?output.push(((value&1023)<<10)+(extra&1023)+65536):(output.push(value),counter--)}else output.push(value)}return output}var ucs2encode=codePoints=>String.fromCodePoint(...codePoints),basicToDigit=function(codePoint){return codePoint>=48&&codePoint<58?26+(codePoint-48):codePoint>=65&&codePoint<91?codePoint-65:codePoint>=97&&codePoint<123?codePoint-97:36},digitToBasic=function(digit,flag){return digit+22+75*(digit<26)-((flag!=0)<<5)},adapt=function(delta,numPoints,firstTime){let k=0;for(delta=firstTime?floor(delta/700):delta>>1,delta+=floor(delta/numPoints);delta>baseMinusTMin*26>>1;k+=36)delta=floor(delta/baseMinusTMin);return floor(k+(baseMinusTMin+1)*delta/(delta+38))},decode2=function(input){let output=[],inputLength=input.length,i=0,n=128,bias=72,basic=input.lastIndexOf("-");basic<0&&(basic=0);for(let j=0;j<basic;++j)input.charCodeAt(j)>=128&&error("not-basic"),output.push(input.charCodeAt(j));for(let index=basic>0?basic+1:0;index<inputLength;){let oldi=i;for(let w=1,k=36;;k+=36){index>=inputLength&&error("invalid-input");let digit=basicToDigit(input.charCodeAt(index++));digit>=36&&error("invalid-input"),digit>floor((2147483647-i)/w)&&error("overflow"),i+=digit*w;let t=k<=bias?1:k>=bias+26?26:k-bias;if(digit<t)break;let baseMinusT=36-t;w>floor(2147483647/baseMinusT)&&error("overflow"),w*=baseMinusT}let out=output.length+1;bias=adapt(i-oldi,out,oldi==0),floor(i/out)>2147483647-n&&error("overflow"),n+=floor(i/out),i%=out,output.splice(i++,0,n)}return String.fromCodePoint(...output)},encode2=function(input){let output=[];input=ucs2decode(input);let inputLength=input.length,n=128,delta=0,bias=72;for(let currentValue of input)currentValue<128&&output.push(stringFromCharCode(currentValue));let basicLength=output.length,handledCPCount=basicLength;for(basicLength&&output.push("-");handledCPCount<inputLength;){let m=2147483647;for(let currentValue of input)currentValue>=n&&currentValue<m&&(m=currentValue);let handledCPCountPlusOne=handledCPCount+1;m-n>floor((2147483647-delta)/handledCPCountPlusOne)&&error("overflow"),delta+=(m-n)*handledCPCountPlusOne,n=m;for(let currentValue of input)if(currentValue<n&&++delta>2147483647&&error("overflow"),currentValue===n){let q=delta;for(let k=36;;k+=36){let t=k<=bias?1:k>=bias+26?26:k-bias;if(q<t)break;let qMinusT=q-t,baseMinusT=36-t;output.push(stringFromCharCode(digitToBasic(t+qMinusT%baseMinusT,0))),q=floor(qMinusT/baseMinusT)}output.push(stringFromCharCode(digitToBasic(q,0))),bias=adapt(delta,handledCPCountPlusOne,handledCPCount===basicLength),delta=0,++handledCPCount}++delta,++n}return output.join("")},toUnicode=function(input){return mapDomain(input,function(string){return regexPunycode.test(string)?decode2(string.slice(4).toLowerCase()):string})},toASCII=function(input){return mapDomain(input,function(string){return regexNonASCII.test(string)?"xn--"+encode2(string):string})},punycode2={version:"2.3.1",ucs2:{decode:ucs2decode,encode:ucs2encode},decode:decode2,encode:encode2,toASCII,toUnicode};module.exports=punycode2}});import{spawn as spawn5}from"node:child_process";import{existsSync as existsSync24,readFileSync as readFileSync26}from"node:fs";import process7 from"node:process";async function batchUpdateTenantCmsItems(args){let collection=args.payload.collection.trim(),itemIds=Array.from(new Set(args.payload.item_ids.map(itemId=>itemId.trim()).filter(Boolean))),tagAdds=dedupeTags(args.payload.changes.tags.add),discover=await args.sdk.discoverTenantCmsCollection(collection),schemaSpec=discover.active_schema??discover.draft_schema;if(!schemaSpec)throw new Error(`Collection \`${collection}\` \u5F53\u524D\u6CA1\u6709\u53EF\u7528 schema\u3002`);let succeeded=[],failed=[];for(let itemId of itemIds){let title=itemId;try{let item=await args.sdk.getTenantCmsItem({collection,id:itemId});title=resolveCmsItemTitle(item);let currentStatus=item.system.publish_status??"draft",targetStatus=args.payload.changes.publish_status.mode==="set"?args.payload.changes.publish_status.value:void 0,hasCategoryChange=args.payload.changes.category.mode!=="keep",hasTagChange=tagAdds.length>0,hasMetadataChange=hasCategoryChange||hasTagChange,effectiveStatus=currentStatus;if(hasMetadataChange){currentStatus==="archived"&&targetStatus&&targetStatus!=="archived"&&(await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus}),effectiveStatus=targetStatus);let payload=buildCmsItemWritePayloadFromDelivery({item,schemaSpec,publishStatus:targetStatus&&targetStatus!=="archived"?targetStatus:effectiveStatus,categoryChange:args.payload.changes.category,tagsToAdd:tagAdds});await args.sdk.configureTenantCmsItem({...payload,item_id:itemId}),targetStatus==="archived"&&effectiveStatus!=="archived"?await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:"archived"}):targetStatus&&targetStatus!=="archived"&&(effectiveStatus=targetStatus)}else targetStatus&&targetStatus!==effectiveStatus&&await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus});succeeded.push({item_id:itemId,title})}catch(error){failed.push({item_id:itemId,title,message:error instanceof Error?error.message:"\u6279\u91CF\u66F4\u65B0\u5931\u8D25"})}}return{total:itemIds.length,succeeded,failed}}function buildCmsItemWritePayloadFromDelivery(args){let nextTags=dedupeTags([...args.item.system.tags??[],...args.tagsToAdd]);return{collection:args.item.collection,system:{publish_status:args.publishStatus,...args.item.system.slug?{slug:args.item.system.slug}:{},featured:args.item.system.featured??!1,tags:nextTags,category_id:resolveNextCategoryId(args.item,args.categoryChange),...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:normalizeCmsContentForWrite(args.item.content,args.schemaSpec.fields)}}function resolveNextCategoryId(item,categoryChange){return categoryChange.mode==="clear"?null:categoryChange.mode==="set"?categoryChange.category_id?.trim()||null:item.system.category_id??null}function resolveCmsItemTitle(item){let title=item.content.title,name=item.content.name;return typeof title=="string"&&title.trim()?title.trim():typeof name=="string"&&name.trim()?name.trim():item.system.slug??item.system.id??"Untitled item"}function dedupeTags(values){let seen=new Set,next=[];for(let value of values){let normalized=value.trim();if(!normalized)continue;let lowered=normalized.toLowerCase();seen.has(lowered)||(seen.add(lowered),next.push(normalized))}return next}function normalizeCmsContentForWrite(content,fields){let normalized={};for(let field of fields)normalized[field.name]=normalizeFieldValueForPayload(field,content[field.name]);return normalized}function normalizeFieldValueForPayload(field,value){switch(field.type){case"date":if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}return value??null;case"number":if(typeof value=="string"){let parsed=Number.parseFloat(value.trim());return Number.isFinite(parsed)?field.ui?.number_kind==="integer"?Math.trunc(parsed):parsed:0}return value;case"bool":return!!value;case"multi_select":return normalizeStringArrayValue(value);case"image":case"file":return normalizeAssetValue(value);case"images":case"files":return normalizeAssetArrayValue(value);case"relation":return normalizeRelationId(value);case"relations":return normalizeRelationArrayValue(value);default:return typeof value=="string"?value:value??""}}function normalizeRelationId(value){if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}if(value&&typeof value=="object"&&!Array.isArray(value)&&"id"in value){let id=value.id;return typeof id=="string"&&id.trim().length>0?id.trim():null}return null}function normalizeAssetValue(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:null}function normalizeStringArrayValue(value){return Array.isArray(value)?value.map(item=>String(item)):typeof value=="string"?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function normalizeAssetArrayValue(value){return Array.isArray(value)?value.filter(item=>!!item&&typeof item=="object"&&!Array.isArray(item)):[]}function normalizeRelationArrayValue(value){return Array.isArray(value)?value.map(item=>normalizeRelationId(item)).filter(item=>!!item):[]}import{createHash}from"node:crypto";import{URL as URL2}from"node:url";var IMAGE_URL_ATTRS=["src","data-src","data-original","data-original-src","data-lazy-src"],IMAGE_SRCSET_ATTRS=["srcset","data-srcset"];function trimToUndefined(value){let normalized=value?.trim();return normalized||void 0}function normalizeUrl(value,baseUrl){let trimmed=trimToUndefined(value);if(trimmed)try{return baseUrl?new URL2(trimmed,baseUrl).toString():new URL2(trimmed).toString()}catch{return}}function isPlatformHostedAssetUrl(value){try{let parsed=new URL2(value);return/^\/assets\/[^/]+\/(original|variants\/[^/]+)$/.test(parsed.pathname)||parsed.pathname.startsWith("/api/tenant/assets/")}catch{return!1}}function inferMimeTypeFromUrl(value){if(!value)return;let pathname=(()=>{try{return new URL2(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg";if(pathname.endsWith(".avif"))return"image/avif"}function computeChecksum(content){return`sha256:${createHash("sha256").update(content).digest("hex")}`}function inferRemoteImageFileName(url,mimeType){let lastSegment=(()=>{try{return new URL2(url).pathname}catch{return url}})().split("/").filter(Boolean).at(-1);return lastSegment&&/\.[a-z0-9]{2,6}$/i.test(lastSegment)?decodeURIComponent(lastSegment):`remote-image.${(()=>{switch(mimeType){case"image/png":return"png";case"image/webp":return"webp";case"image/gif":return"gif";case"image/svg+xml":return"svg";case"image/avif":return"avif";case"image/jpeg":default:return"jpg"}})()}`}function buildTenantAssetReference(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function replaceImageAttributeUrls(html,replacementsByUrl,attribute2){let pattern=new RegExp(`(<img\\b[^>]*?\\s${attribute2}\\s*=\\s*)(["'])(.*?)\\2`,"gi");return html.replace(pattern,(fullMatch,prefix,quote,rawUrl)=>{let replacement=replacementsByUrl.get(rawUrl);return!replacement||replacement.finalUrl===rawUrl?fullMatch:`${prefix}${quote}${replacement.finalUrl}${quote}`})}function stripImageAttributes(html,attributes){let nextHtml=html;for(let attribute2 of attributes){let pattern=new RegExp(`\\s${attribute2}\\s*=\\s*(["']).*?\\1`,"gi");nextHtml=nextHtml.replace(pattern,"")}return nextHtml}async function fetchRemoteImageBinary(args){let response=await(args.fetchImpl??fetch)(args.url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u56FE\u7247\u62C9\u53D6\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let normalizedMimeType=String(response.headers.get("content-type")??"").split(";")[0]?.trim().toLowerCase()||inferMimeTypeFromUrl(args.url);if(!normalizedMimeType||!normalizedMimeType.startsWith("image/"))throw new Error("\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u53D7\u652F\u6301\u7684\u56FE\u7247\u7C7B\u578B");let content=new Uint8Array(await response.arrayBuffer()),maxBytes=args.maxBytes??20*1024*1024;if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");if(content.byteLength>maxBytes)throw new Error(`\u8FDC\u7A0B\u56FE\u7247\u8D85\u8FC7\u5927\u5C0F\u9650\u5236\uFF08${content.byteLength} bytes\uFF09`);return{content,mimeType:normalizedMimeType}}async function ingestRemoteImageCandidates(args){let uniqueCandidates=new Map;for(let candidate of args.candidates)uniqueCandidates.has(candidate.url)||uniqueCandidates.set(candidate.url,candidate);let resultsByUrl=new Map,resultsByChecksum=new Map,warnings=[];for(let candidate of uniqueCandidates.values())try{let{content,mimeType}=await fetchRemoteImageBinary({url:candidate.url,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),checksum3=computeChecksum(content),existingByChecksum=resultsByChecksum.get(checksum3);if(existingByChecksum){let reused={...existingByChecksum,originalUrl:candidate.url,status:"reused"};resultsByUrl.set(candidate.url,reused);continue}let fileName=inferRemoteImageFileName(candidate.url,mimeType),uploadedAsset=await args.sdk.createTenantAssetBinary({fileName,mimeType,content,title:candidate.title,...args.folderId?{folderId:args.folderId}:{}}),uploaded={originalUrl:candidate.url,finalUrl:uploadedAsset.original_url,asset:uploadedAsset,assetReference:buildTenantAssetReference(uploadedAsset),mimeType,checksum:checksum3,status:"uploaded"};resultsByUrl.set(candidate.url,uploaded),resultsByChecksum.set(checksum3,uploaded)}catch(error){let message=error instanceof Error?error.message:"\u5916\u94FE\u56FE\u7247\u8D44\u4EA7\u5316\u5931\u8D25";warnings.push(`\u56FE\u7247 \`${candidate.url}\` \u8D44\u4EA7\u5316\u5931\u8D25\uFF0C\u5DF2\u56DE\u9000\u539F\u94FE\u63A5\uFF1A${message}`),resultsByUrl.set(candidate.url,{originalUrl:candidate.url,finalUrl:candidate.url,mimeType:inferMimeTypeFromUrl(candidate.url),status:"fallback",warning:message})}return{resultsByUrl,warnings}}function collectExternalImageCandidatesFromHtml(args){let candidates=new Map;return args.html.replace(/<img\b[^>]*>/gi,tag=>{for(let attribute2 of IMAGE_URL_ATTRS){let rawUrl=tag.match(new RegExp(`(?:^|\\s)${attribute2}\\s*=\\s*(["'])(.*?)\\1`,"i"))?.[2],normalizedUrl=normalizeUrl(rawUrl,args.baseUrl);!normalizedUrl||normalizedUrl.startsWith("data:")||isPlatformHostedAssetUrl(normalizedUrl)||candidates.has(normalizedUrl)||candidates.set(normalizedUrl,{url:normalizedUrl,title:args.title,source:"body"})}return""}),[...candidates.values()]}async function assetizeExternalImagesInHtml(args){let bodyCandidates=collectExternalImageCandidatesFromHtml({html:args.html,baseUrl:args.baseUrl,title:args.bodyTitle}),normalizedCoverUrl=normalizeUrl(args.coverUrl,args.baseUrl),coverCandidate=normalizedCoverUrl&&!normalizedCoverUrl.startsWith("data:")&&!isPlatformHostedAssetUrl(normalizedCoverUrl)?{url:normalizedCoverUrl,title:args.coverTitle??args.bodyTitle,source:"cover"}:null,candidates=coverCandidate?[coverCandidate,...bodyCandidates]:bodyCandidates,{resultsByUrl,warnings}=await ingestRemoteImageCandidates({sdk:args.sdk,candidates,folderId:args.folderId,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),html=args.html;for(let attribute2 of IMAGE_URL_ATTRS)html=replaceImageAttributeUrls(html,resultsByUrl,attribute2);html=stripImageAttributes(html,IMAGE_SRCSET_ATTRS);let replacements=[...resultsByUrl.values()].map(result=>({originalUrl:result.originalUrl,finalUrl:result.finalUrl,...result.asset?.asset.asset_id?{assetId:result.asset.asset.asset_id}:{},status:result.status}));if(!normalizedCoverUrl)return{html,cover:{mode:"none"},replacements,warnings};let coverResult=resultsByUrl.get(normalizedCoverUrl);return coverResult?.assetReference?{html,cover:{mode:"asset",value:coverResult.assetReference},replacements,warnings}:{html,cover:{mode:"remote",value:{title:args.coverTitle??args.bodyTitle??"Remote cover",...coverResult?.mimeType||args.coverMimeType?{mime_type:coverResult?.mimeType??args.coverMimeType}:{},original_url:normalizedCoverUrl}},replacements,warnings}}var PlatformApiError=class extends Error{status;code;detail;requestId;capability;category;remediation;constructor(message,status,code2,detail,requestId,capability,category,remediation){super(message),this.status=status,this.code=code2,this.detail=detail,this.requestId=requestId,this.capability=capability,this.category=category,this.remediation=remediation,this.name="PlatformApiError"}},BasePlatformSdk=class{options;fetchImpl;constructor(options){this.options=options,this.fetchImpl=options.fetchImpl??fetch}async request(path2,init={}){return this.requestUrl(new URL(path2,this.options.baseUrl),init)}async requestBinary(path2,init={}){return this.requestBinaryUrl(new URL(path2,this.options.baseUrl),init)}async requestVoid(path2,init={}){return this.requestVoidUrl(new URL(path2,this.options.baseUrl),init)}async requestUrl(url,init={}){let response=await this.fetchResponse(url,init),payload=await parseJsonResponse(response);if(!response.ok){let errorPayload=payload,error=errorPayload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??errorPayload.detail,errorPayload.request_id,error?.capability,error?.category,error?.remediation)}return payload}async requestBinaryUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}return new Uint8Array(await response.arrayBuffer())}async requestVoidUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}}async fetchResponse(url,init={}){let headers=new Headers(init.headers);!headers.has("Content-Type")&&init.body&&headers.set("Content-Type","application/json");let extraHeaders=await this.options.getHeaders?.();return extraHeaders&&new Headers(extraHeaders).forEach((value,key)=>{headers.set(key,value)}),this.fetchImpl(url,{...init,headers})}};async function parseJsonResponse(response){let text2=await response.text();if(text2.trim().length===0)return{};try{return JSON.parse(text2)}catch{if(response.ok)return{};throw new PlatformApiError(`Request failed with non-JSON response: ${response.status}`,response.status,"non_json_response",{content_type:response.headers.get("content-type")??void 0,body_preview:text2.replace(/\s+/g," ").slice(0,240)})}}var PlatformSdk=class extends BasePlatformSdk{notification;constructor(options){super(options),this.notification=new NotificationSdkNamespace(this)}async listNotificationInbox(filters={}){let url=new URL("/api/tenant/notification/inbox",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"inbox_type",filters.inbox_type),setOptionalSearchParam(url,"status",filters.status),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async updateNotificationInboxItemStatus(itemId,payload){return(await this.request(`/api/tenant/notification/inbox/${encodeURIComponent(itemId)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async batchUpdateNotificationInboxItemsStatus(payload){return this.request("/api/tenant/notification/inbox:batch",{method:"PATCH",body:JSON.stringify(payload)})}async listNotificationDeliveries(filters={}){let url=new URL("/api/tenant/notification/deliveries",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async announcePlatformNotification(payload){return(await this.request("/api/admin/notification/announcements/platform",{method:"POST",body:JSON.stringify(payload)})).item}async announceAppNotification(appId,payload){return(await this.request(`/api/tenant/notification/apps/${encodeURIComponent(appId)}/announcements`,{method:"POST",body:JSON.stringify(payload)})).item}async getAppNotificationConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/config`)}async listAppNotificationAnnouncements(appId,options={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,this.options.baseUrl);return typeof options.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async createAppNotificationAnnouncement(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,{method:"POST",body:JSON.stringify(payload)})}async archiveAppNotificationAnnouncement(appId,announcementId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements/${encodeURIComponent(announcementId)}:archive`,{method:"POST"})}async publishEndUserNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/publish`,{method:"POST",body:JSON.stringify(payload)})}async createEndUserNotificationReminder(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/reminders`,{method:"POST",body:JSON.stringify(payload)})}async projectEndUserTaskNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/task-projections`,{method:"POST",body:JSON.stringify(payload)})}async listEndUserNotificationInbox(appId,query){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/inbox`,this.options.baseUrl);return url.searchParams.set("end_user_id",query.end_user_id),setOptionalSearchParam(url,"status",query.status),setOptionalSearchParam(url,"inbox_type",query.inbox_type),typeof query.limit=="number"&&Number.isFinite(query.limit)&&url.searchParams.set("limit",String(query.limit)),this.request(`${url.pathname}${url.search}`)}async getEndUserNotificationUnreadCount(appId,endUserId){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/unread-count`,this.options.baseUrl);return url.searchParams.set("end_user_id",endUserId),this.request(`${url.pathname}${url.search}`)}async createWorkflowDefinition(payload){return(await this.request("/api/workflow/definitions",{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowTemplates(){return(await this.request("/api/workflow/templates")).items}async listWorkflowDefinitions(filters={}){let url=new URL("/api/workflow/definitions",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async listWorkflowBindings(filters={}){let url=new URL("/api/workflow/bindings",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"definition_key",filters.definition_key),(await this.request(`${url.pathname}${url.search}`)).items}async updateWorkflowDefinitionMetadata(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async saveWorkflowRoleBindings(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/role-bindings`,{method:"POST",body:JSON.stringify(payload)})).items}async getWorkflowBindingOverride(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/binding-override`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).item}async saveWorkflowBindingOverride(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/binding-override`,{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowRoleBindings(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/role-bindings`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).items}async startWorkflow(payload){return(await this.request("/api/workflow/instances/start",{method:"POST",body:JSON.stringify(payload)})).item}async performWorkflowAction(instanceId,payload){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}/actions`,{method:"POST",body:JSON.stringify(payload)})).item}async getWorkflowInstance(instanceId){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}`)).item}async listWorkflowTasks(filters={}){let url=new URL("/api/workflow/tasks",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async getWhoAmI(){return this.request("/api/auth/whoami")}async getResolvedPermissions(){return this.request("/api/auth/permissions")}async switchTenantContext(payload){return this.request("/api/auth/context/switch-tenant",{method:"POST",body:JSON.stringify(payload)})}async listTenantWorkspaces(){return this.request("/api/auth/workspaces")}async ensurePersonalWorkspace(){return this.request("/api/auth/workspaces/ensure-personal",{method:"POST"})}async getAdminOverview(){return this.request("/api/admin/overview")}async listAdminWorkbenchEntries(){return this.request("/api/admin/workbench-entries")}async getAdminWorkbenchEntryDetail(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}`)}async updateAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"PUT",body:JSON.stringify(payload)})}async resetAdminWorkbenchEntryVisibility(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"DELETE"})}async previewAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility:preview`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAsset(payload){return this.request("/api/tenant/assets",{method:"POST",body:JSON.stringify(payload)})}async createTenantAssetBinary(args){let headers=new Headers({"Content-Type":args.mimeType,"X-Asset-File-Name":encodeURIComponent(args.fileName)});return args.title?.trim()&&headers.set("X-Asset-Title",encodeURIComponent(args.title.trim())),args.folderId?.trim()&&headers.set("X-Asset-Folder-Id",encodeURIComponent(args.folderId.trim())),this.request("/api/tenant/assets/upload",{method:"POST",headers,body:Buffer.from(args.content)})}async listTenantAssets(filters={}){let url=new URL("/api/tenant/assets",this.options.baseUrl);return setOptionalSearchParam(url,"q",filters.q),setOptionalSearchParam(url,"media_type",filters.media_type),setOptionalSearchParam(url,"mime_type",filters.mime_type),setOptionalSearchParam(url,"folder_id",filters.folder_id),setOptionalSearchParam(url,"tag_ids",filters.tag_ids?.join(",")),setOptionalSearchParam(url,"scene",filters.scene),setOptionalSearchParam(url,"objects",filters.objects?.join(",")),setOptionalSearchParam(url,"safety_flags",filters.safety_flags?.join(",")),setOptionalSearchParam(url,"orientation",filters.orientation),setOptionalBooleanSearchParam(url,"has_ocr",filters.has_ocr),setOptionalBooleanSearchParam(url,"has_person",filters.has_person),setOptionalBooleanSearchParam(url,"is_svg",filters.is_svg),typeof filters.page=="number"&&Number.isFinite(filters.page)&&url.searchParams.set("page",String(filters.page)),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`)}async deleteTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`,{method:"DELETE"})}async batchUpdateTenantAssets(payload){return this.request("/api/tenant/assets/batch",{method:"POST",body:JSON.stringify(payload)})}async listTenantAssetFolders(){return this.request("/api/tenant/assets/folders")}async createTenantAssetFolder(payload){return this.request("/api/tenant/assets/folders",{method:"POST",body:JSON.stringify(payload)})}async updateTenantAssetFolderMetadata(folderId,payload){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAssetFolder(folderId){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"DELETE"})}async moveTenantAssetFolder(folderId,direction){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}/move-${direction}`,{method:"POST"})}async updateTenantAssetFolder(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/folder`,{method:"PATCH",body:JSON.stringify(payload)})}async updateTenantAssetMetadata(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/metadata`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAssetTags(options){let url=new URL("/api/tenant/assets/tags",this.options.baseUrl);return options?.assetId&&url.searchParams.set("asset_id",options.assetId),this.request(`${url.pathname}${url.search}`)}async addTenantAssetTag(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,{method:"POST",body:JSON.stringify(payload)})}async removeTenantAssetTag(assetId,label){let url=new URL(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,this.options.baseUrl);return url.searchParams.set("label",label),this.request(`${url.pathname}${url.search}`,{method:"DELETE"})}async downloadTenantAssetOriginal(assetId){return this.requestBinary(`/api/tenant/assets/${encodeURIComponent(assetId)}/original`)}async downloadTenantAssetVariant(assetId,variantKind){return this.requestBinary(`/assets/${encodeURIComponent(assetId)}/variants/${encodeURIComponent(variantKind)}`)}async createTenantBlobUploadSession(payload){return this.request("/api/tenant/blobs/upload-sessions",{method:"POST",body:JSON.stringify(payload)})}async uploadTenantBlobBinary(uploadSessionId,payload){let url=resolveRelativeOrAbsoluteUrl(payload.upload_url??`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/content`,this.options.baseUrl),headers=new Headers(payload.headers);headers.set("Content-Type",payload.content_type?.trim()||"application/octet-stream"),await this.requestVoidUrl(url,{method:"PUT",headers,body:Buffer.from(payload.content)})}async completeTenantBlobUpload(uploadSessionId,payload={}){return this.request(`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/complete`,{method:"POST",body:JSON.stringify(payload)})}async createTenantBlobBinary(args){let contentType=args.contentType?.trim()||"application/octet-stream",session=await this.createTenantBlobUploadSession({original_filename:args.fileName,content_type:contentType,size_bytes:args.content.byteLength,...args.appId?.trim()?{app_id:args.appId.trim()}:{},...args.clientRequestId?.trim()?{client_request_id:args.clientRequestId.trim()}:{}});return await this.uploadTenantBlobBinary(session.upload_session_id,{content:args.content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}),this.completeTenantBlobUpload(session.upload_session_id,{size_bytes:args.content.byteLength,...args.sha256?.trim()?{sha256:args.sha256.trim()}:{}})}async listTenantBlobs(filters={}){let url=new URL("/api/tenant/blobs",this.options.baseUrl);return setOptionalSearchParam(url,"cursor",filters.cursor),setOptionalSearchParam(url,"app_id",filters.app_id??void 0),setOptionalSearchParam(url,"q",filters.q??void 0),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantBlob(blobId){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}`)}async issueTenantBlobDownloadUrl(blobId,payload={}){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}/download-url`,{method:"POST",body:JSON.stringify(payload)})}async getTenantOverview(){return this.request("/api/tenant/overview")}async getTenantEffectiveState(){return this.request("/api/tenant/effective-state")}async getTenantWorkbenchNavigation(){return this.request("/api/tenant/workbench/navigation")}async createTenantApp(payload){return this.request("/api/tenant/apps",{method:"POST",body:JSON.stringify(payload)})}async updateTenantApp(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listAppTemplates(){return this.request("/api/tenant/app-templates")}async createAppTemplate(payload){return this.request("/api/tenant/app-templates",{method:"POST",body:JSON.stringify(payload)})}async getAppTemplate(templateId){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`)}async openAppTemplatePreview(templateId){return this.requestVoid(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/preview`)}async updateAppTemplateSettings(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteAppTemplate(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"DELETE",body:JSON.stringify(payload)})}async createAppTemplateInitializationTask(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/initialization-tasks`,{method:"POST",body:JSON.stringify(payload)})}async getAppTemplateInitializationTask(taskId){return this.request(`/api/tenant/app-template-initialization-tasks/${encodeURIComponent(taskId)}`)}async createAppMarketSubmission(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/market-submissions`,{method:"POST",body:JSON.stringify(payload)})}async cancelAppMarketSubmission(submissionId){return this.request(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/cancel`,{method:"POST"})}async listTenantAppMarketSubmissions(options){let url=new URL("/api/tenant/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async listAppMarketListings(options){let url=new URL("/api/tenant/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async listAdminAppMarketListings(options){let url=new URL("/api/admin/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async getAppMarketListing(listingId){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}`)}async openAppMarketSubmissionPreview(submissionId){return this.requestVoid(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/preview`)}async createAppMarketInstall(listingId,payload){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}/installs`,{method:"POST",body:JSON.stringify(payload)})}async listAdminAppMarketSubmissions(options){let url=new URL("/api/admin/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async approveAppMarketSubmission(submissionId){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/approve`,{method:"POST"})}async rejectAppMarketSubmission(submissionId,payload={}){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/reject`,{method:"POST",body:JSON.stringify(payload)})}async unlistAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/unlist`,{method:"POST",body:JSON.stringify(payload)})}async publishAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/publish`,{method:"POST",body:JSON.stringify(payload)})}async listAdminLightAppLibraries(options){let url=new URL("/api/admin/light-app-library/libraries",this.options.baseUrl);return options?.visibility&&url.searchParams.set("visibility",options.visibility),this.request(`${url.pathname}${url.search}`)}async setAdminLightAppLibraryVisibility(libraryId,payload){return this.request(`/api/admin/light-app-library/libraries/${encodeURIComponent(libraryId)}/visibility`,{method:"POST",body:JSON.stringify(payload)})}async listLightAppLibraryEntries(options){let url=new URL("/api/tenant/light-app-library/entries",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.status&&url.searchParams.set("status",options.status),options?.template_key&&url.searchParams.set("template_key",options.template_key),options?.tag&&url.searchParams.set("tag",options.tag),options?.visibility&&url.searchParams.set("visibility",options.visibility),typeof options?.include_public=="boolean"&&url.searchParams.set("include_public",String(options.include_public)),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntries(query){let url=new URL("/api/tenant/light-app-library/entries/search",this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async getLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`)}async createLightAppLibraryEntry(payload){return this.request("/api/tenant/light-app-library/entries",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppLibraryEntry(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async submitLightAppLibraryEntrySnapshot(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/snapshots`,{method:"POST",body:JSON.stringify(payload)})}async publishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/publish`,{method:"POST"})}async unpublishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/unpublish`,{method:"POST"})}async archiveLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/archive`,{method:"POST"})}async deleteLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async getLightAppLibraryEntrySource(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source`)}async readLightAppLibraryEntrySourceFile(entryId,path2){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/files`,this.options.baseUrl);return url.searchParams.set("path",path2),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntrySource(entryId,query){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/search`,this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async listLightAppPrototypeEntries(options){let url=new URL("/api/tenant/prototypes",this.options.baseUrl);return options?.q&&url.searchParams.set("q",options.q),options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async getLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`)}async createLightAppPrototypeEntry(payload){return this.request("/api/tenant/prototypes",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppPrototypeEntry(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async copyLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/copy`,{method:"POST"})}async deleteLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async saveLightAppPrototypeCurrentVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/current-version`,{method:"PUT",body:JSON.stringify(payload)})}async submitLightAppPrototypeVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions`,{method:"POST",body:JSON.stringify(payload)})}async getLightAppPrototypeVersion(entryId,versionId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions/${encodeURIComponent(versionId)}`)}async deleteTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"DELETE"})}async getTenantAppDeletePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/delete-preview`,{method:"POST"})}async getTenantAppDeleteJob(jobId){return this.request(`/api/tenant/app-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppUndeployPreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy-preview`,{method:"POST"})}async undeployTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy`,{method:"POST"})}async getTenantAppUndeployJob(jobId){return this.request(`/api/tenant/app-undeploy-jobs/${encodeURIComponent(jobId)}`)}async createBuild(payload){return this.request("/api/builds",{method:"POST",body:JSON.stringify(payload)})}async listBuilds(appId,options){let url=new URL("/api/builds",this.options.baseUrl);return url.searchParams.set("app_id",appId),typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getBuildPrecheck(appId,args){let url=new URL("/api/builds/precheck",this.options.baseUrl);return url.searchParams.set("app_id",appId),url.searchParams.set("source_version_id",args.source_version_id),args.build_config?.dockerfile_path&&url.searchParams.set("dockerfile_path",args.build_config.dockerfile_path),args.build_config?.context_subdir&&url.searchParams.set("context_subdir",args.build_config.context_subdir),args.build_config?.target&&url.searchParams.set("target",args.build_config.target),this.request(`${url.pathname}${url.search}`)}async getBuild(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}`)}async listBuildEvents(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}/events`)}async createLocalBuildSession(payload){return this.request("/api/builds/local-sessions",{method:"POST",body:JSON.stringify(payload)})}async completeLocalBuildSession(buildId,payload){return this.request(`/api/builds/${encodeURIComponent(buildId)}/local-complete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceWorkspace(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/source-workspace`,this.options.baseUrl);return options?.sourceVersionId&&url.searchParams.set("source_version_id",options.sourceVersionId),this.request(`${url.pathname}${url.search}`)}async getTenantAppDevWorkspace(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace`)}async pushTenantAppDevWorkspace(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/push`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)})}async createTenantAppDevWorkspacePreview(appId,payload={}){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDevWorkspacePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`)}async listTenantAppSourceVersions(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`)}async updateTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async getTenantAppEndUserAuthConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/config`)}async getTenantAppEndUserAuthDiscovery(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/discovery`)}async getTenantAppEndUserAuthInspect(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/inspect`)}async configureTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/configure`,{method:"POST",body:JSON.stringify(payload)})}async bindTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/bind`,{method:"POST",body:JSON.stringify(payload)})}async listTenantAppEndUsers(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users`)}async listTenantAppEndUserRoles(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`)}async createTenantAppEndUserRole(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppEndUserRole(appId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`)}async updateTenantAppEndUserRole(appId,roleKey,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAppUserRoles(appId,appUserId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`)}async assignTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles:assign`,{method:"POST",body:JSON.stringify(payload)})}async replaceTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`,{method:"PUT",body:JSON.stringify(payload)})}async removeTenantAppUserRole(appId,appUserId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles/${encodeURIComponent(roleKey)}`,{method:"DELETE"})}async discoverTenantCmsCollection(collection){let url=new URL("/api/tenant/cms/discover",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsCollections(){return this.request("/api/tenant/cms/collections")}async inspectTenantCmsSchema(collection){let url=new URL("/api/tenant/cms/inspect/schema",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsItems(args){let url=new URL("/api/tenant/cms/items",this.options.baseUrl);return url.searchParams.set("collection",args.collection),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"status",args.status),setOptionalSearchParam(url,"q",args.query),this.request(`${url.pathname}${url.search}`)}async getTenantCmsItem(args){let url=new URL(`/api/tenant/cms/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("collection",args.collection),this.request(`${url.pathname}${url.search}`)}async configureTenantCmsCollection(spec){return this.request("/api/tenant/cms/configure/collection",{method:"POST",body:JSON.stringify(spec)})}async configureTenantCmsItem(payload){return this.request("/api/tenant/cms/configure/item",{method:"POST",body:JSON.stringify(payload)})}async configureTenantCmsCategory(payload){return this.request("/api/tenant/cms/configure/category",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsSchema(payload){return this.request("/api/tenant/cms/apply/schema",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsCollectionStatus(payload){return this.request("/api/tenant/cms/apply/collection-status",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsPublish(payload){return this.request("/api/tenant/cms/apply/publish",{method:"POST",body:JSON.stringify(payload)})}async listPublicCmsItems(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items`,this.options.baseUrl);url.searchParams.set("tenant_id",args.tenantId),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"sort_field",args.sortField),setOptionalSearchParam(url,"sort_direction",args.sortDirection);for(let tag of args.tags??[])url.searchParams.append("tag",tag);return this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemBySlug(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/by-slug/${encodeURIComponent(args.slug)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemById(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listPublicCmsCategories(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/categories`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listTenantAppDeploymentTimeline(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/deployments`,this.options.baseUrl);return typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAppPublishSettings(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`)}async updateTenantAppPublishSettings(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`,{method:"PATCH",body:JSON.stringify(payload)})}async setTenantAppCurrentPublishedVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings/current-version`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppPreview(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/previews`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersionFromTemplate(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions:from-template`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppReleaseDeletePreview(appId,releaseId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete-preview`,{method:"POST"})}async deleteTenantAppRelease(appId,releaseId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceVersionDeletePreview(appId,sourceVersionId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete-preview`,{method:"POST"})}async deleteTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantVersionDeleteJob(jobId){return this.request(`/api/tenant/version-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppBuildDeletePreview(appId,buildId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete-preview`,{method:"POST"})}async deleteTenantAppBuild(appId,buildId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDbInstance(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbRuntimeBindings(appId,env="preview",purpose){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/runtime-bindings`,this.options.baseUrl);return url.searchParams.set("env",env),purpose&&url.searchParams.set("purpose",purpose),this.requestUrl(url)}async resolveDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/resolve",{method:"POST",body:JSON.stringify(payload)})}async revokeDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/revoke",{method:"POST",body:JSON.stringify(payload)})}async listTenantAppDbTables(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableSchema(appId,tableName,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/schema`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableRows(appId,tableName,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.page=="number"&&url.searchParams.set("page",String(args.page)),typeof args.page_size=="number"&&url.searchParams.set("page_size",String(args.page_size)),typeof args.sort_by=="string"&&args.sort_by.trim().length>0&&url.searchParams.set("sort_by",args.sort_by),args.sort_order==="desc"&&url.searchParams.set("sort_order","desc"),typeof args.filter_column=="string"&&args.filter_column.trim().length>0&&url.searchParams.set("filter_column",args.filter_column),typeof args.filter_value=="string"&&args.filter_value.length>0&&url.searchParams.set("filter_value",args.filter_value),typeof args.search_query=="string"&&args.search_query.trim().length>0&&url.searchParams.set("search_query",args.search_query),this.requestUrl(url)}async listTenantAppDbMigrationRuns(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/migrations`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async listTenantAppDbChangeAudits(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/audits`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.table_name=="string"&&args.table_name.trim().length>0&&url.searchParams.set("table_name",args.table_name),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async insertTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"POST",body:JSON.stringify(payload)})}async updateTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"DELETE",body:JSON.stringify(payload)})}async queryTenantAppDb(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/query`,{method:"POST",body:JSON.stringify(payload)})}async createWorkspace(payload){return this.request("/api/admin/workspaces",{method:"POST",body:JSON.stringify(payload)})}async deleteWorkspace(workspaceId,payload){return this.request(`/api/admin/workspaces/${encodeURIComponent(workspaceId)}`,{method:"DELETE",...payload?{body:JSON.stringify(payload)}:{}})}async createApproval(payload){return this.request("/api/admin/resource-approvals",{method:"POST",body:JSON.stringify(payload)})}async listApprovals(filters){let url=new URL("/api/admin/resource-approvals",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.status&&url.searchParams.set("status",filters.status),filters?.operation&&url.searchParams.set("operation",filters.operation),this.requestUrl(url)}async decideApproval(approvalId,payload){return this.request(`/api/admin/resource-approvals/${approvalId}/decision`,{method:"POST",body:JSON.stringify(payload)})}async listResourceLocks(filters){let url=new URL("/api/admin/resource-locks",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.env&&url.searchParams.set("env",filters.env),this.requestUrl(url)}async diffResources(payload){return this.request("/api/resources/diff",{method:"POST",body:JSON.stringify(payload)})}async applyResources(payload){return this.request("/api/resources/apply",{method:"POST",body:JSON.stringify(payload)})}async rollbackResources(payload){return this.request("/api/resources/rollback",{method:"POST",body:JSON.stringify(payload)})}async deployRelease(payload){return this.request("/api/releases/deploy",{method:"POST",body:JSON.stringify(payload)})}async rollbackRelease(payload){return this.request("/api/releases/rollback",{method:"POST",body:JSON.stringify(payload)})}async queryLogs(payload){return this.request("/api/logs/query",{method:"POST",body:JSON.stringify(payload)})}};function setOptionalSearchParam(url,key,value){typeof value=="string"&&value.trim().length>0&&url.searchParams.set(key,value)}function setOptionalBooleanSearchParam(url,key,value){typeof value=="boolean"&&url.searchParams.set(key,value?"true":"false")}function resolveRelativeOrAbsoluteUrl(pathOrUrl,baseUrl){return new URL(pathOrUrl,baseUrl)}function createPlatformSdk(options){return new PlatformSdk(options)}var NotificationSdkNamespace=class{sdk;endUser;constructor(sdk){this.sdk=sdk,this.endUser=new EndUserNotificationNamespace(sdk)}},EndUserNotificationNamespace=class{sdk;constructor(sdk){this.sdk=sdk}forApp(appId){return new EndUserNotificationAppClient(this.sdk,appId)}},EndUserNotificationAppClient=class{sdk;appId;announcements;constructor(sdk,appId){this.sdk=sdk,this.appId=appId,this.announcements=new EndUserNotificationAppAnnouncementsClient(sdk,appId)}listUsers(){return this.sdk.listTenantAppEndUsers(this.appId)}forUser(endUserId){return new EndUserNotificationUserClient(this.sdk,this.appId,endUserId)}listInbox(endUserId,query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:endUserId,...query})}getUnreadCount(endUserId){return this.sdk.getEndUserNotificationUnreadCount(this.appId,endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,input.end_user_id),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,input.end_user_id)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,input.end_user_id)})}},EndUserNotificationAppAnnouncementsClient=class{sdk;appId;constructor(sdk,appId){this.sdk=sdk,this.appId=appId}getConfig(){return this.sdk.getAppNotificationConfig(this.appId)}list(limit){return this.sdk.listAppNotificationAnnouncements(this.appId,{limit})}create(input){return this.sdk.createAppNotificationAnnouncement(this.appId,input)}archive(announcementId){return this.sdk.archiveAppNotificationAnnouncement(this.appId,announcementId)}},EndUserNotificationUserClient=class{sdk;appId;endUserId;constructor(sdk,appId,endUserId){this.sdk=sdk,this.appId=appId,this.endUserId=endUserId}buildRecipientRef(){return buildDirectEndUserRecipientRef(this.appId,this.endUserId)}listInbox(query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:this.endUserId,...query})}getUnreadCount(){return this.sdk.getEndUserNotificationUnreadCount(this.appId,this.endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:this.buildRecipientRef(),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,this.endUserId),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:this.buildRecipientRef(),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,this.endUserId)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:this.buildRecipientRef(),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,this.endUserId)})}};function buildDirectEndUserRecipientRef(appId,endUserId){return{app_id:appId,end_user_id:endUserId,recipient_type:"direct_user"}}function buildNotificationIdempotencyKey(prefix,appId,endUserId){return`${prefix}:${appId}:${endUserId}:${Date.now()}`}var AUTH_PAGE_HTML=String.raw`<!doctype html>
2
+ var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __getProtoOf=Object.getPrototypeOf,__hasOwnProp=Object.prototype.hasOwnProperty;var __commonJS=(cb,mod)=>function(){return mod||(0,cb[__getOwnPropNames(cb)[0]])((mod={exports:{}}).exports,mod),mod.exports};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},__copyProps=(to,from,except,desc)=>{if(from&&typeof from=="object"||typeof from=="function")for(let key of __getOwnPropNames(from))!__hasOwnProp.call(to,key)&&key!==except&&__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to};var __toESM=(mod,isNodeMode,target)=>(target=mod!=null?__create(__getProtoOf(mod)):{},__copyProps(isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target,mod));var require_punycode=__commonJS({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js"(exports,module){"use strict";var regexPunycode=/^xn--/,regexNonASCII=/[^\0-\x7F]/,regexSeparators=/[\x2E\u3002\uFF0E\uFF61]/g,errors={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},baseMinusTMin=35,floor=Math.floor,stringFromCharCode=String.fromCharCode;function error(type){throw new RangeError(errors[type])}function map(array,callback){let result=[],length=array.length;for(;length--;)result[length]=callback(array[length]);return result}function mapDomain(domain,callback){let parts=domain.split("@"),result="";parts.length>1&&(result=parts[0]+"@",domain=parts[1]),domain=domain.replace(regexSeparators,".");let labels=domain.split("."),encoded=map(labels,callback).join(".");return result+encoded}function ucs2decode(string){let output=[],counter=0,length=string.length;for(;counter<length;){let value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){let extra=string.charCodeAt(counter++);(extra&64512)==56320?output.push(((value&1023)<<10)+(extra&1023)+65536):(output.push(value),counter--)}else output.push(value)}return output}var ucs2encode=codePoints=>String.fromCodePoint(...codePoints),basicToDigit=function(codePoint){return codePoint>=48&&codePoint<58?26+(codePoint-48):codePoint>=65&&codePoint<91?codePoint-65:codePoint>=97&&codePoint<123?codePoint-97:36},digitToBasic=function(digit,flag){return digit+22+75*(digit<26)-((flag!=0)<<5)},adapt=function(delta,numPoints,firstTime){let k=0;for(delta=firstTime?floor(delta/700):delta>>1,delta+=floor(delta/numPoints);delta>baseMinusTMin*26>>1;k+=36)delta=floor(delta/baseMinusTMin);return floor(k+(baseMinusTMin+1)*delta/(delta+38))},decode2=function(input){let output=[],inputLength=input.length,i=0,n=128,bias=72,basic=input.lastIndexOf("-");basic<0&&(basic=0);for(let j=0;j<basic;++j)input.charCodeAt(j)>=128&&error("not-basic"),output.push(input.charCodeAt(j));for(let index=basic>0?basic+1:0;index<inputLength;){let oldi=i;for(let w=1,k=36;;k+=36){index>=inputLength&&error("invalid-input");let digit=basicToDigit(input.charCodeAt(index++));digit>=36&&error("invalid-input"),digit>floor((2147483647-i)/w)&&error("overflow"),i+=digit*w;let t=k<=bias?1:k>=bias+26?26:k-bias;if(digit<t)break;let baseMinusT=36-t;w>floor(2147483647/baseMinusT)&&error("overflow"),w*=baseMinusT}let out=output.length+1;bias=adapt(i-oldi,out,oldi==0),floor(i/out)>2147483647-n&&error("overflow"),n+=floor(i/out),i%=out,output.splice(i++,0,n)}return String.fromCodePoint(...output)},encode2=function(input){let output=[];input=ucs2decode(input);let inputLength=input.length,n=128,delta=0,bias=72;for(let currentValue of input)currentValue<128&&output.push(stringFromCharCode(currentValue));let basicLength=output.length,handledCPCount=basicLength;for(basicLength&&output.push("-");handledCPCount<inputLength;){let m=2147483647;for(let currentValue of input)currentValue>=n&&currentValue<m&&(m=currentValue);let handledCPCountPlusOne=handledCPCount+1;m-n>floor((2147483647-delta)/handledCPCountPlusOne)&&error("overflow"),delta+=(m-n)*handledCPCountPlusOne,n=m;for(let currentValue of input)if(currentValue<n&&++delta>2147483647&&error("overflow"),currentValue===n){let q=delta;for(let k=36;;k+=36){let t=k<=bias?1:k>=bias+26?26:k-bias;if(q<t)break;let qMinusT=q-t,baseMinusT=36-t;output.push(stringFromCharCode(digitToBasic(t+qMinusT%baseMinusT,0))),q=floor(qMinusT/baseMinusT)}output.push(stringFromCharCode(digitToBasic(q,0))),bias=adapt(delta,handledCPCountPlusOne,handledCPCount===basicLength),delta=0,++handledCPCount}++delta,++n}return output.join("")},toUnicode=function(input){return mapDomain(input,function(string){return regexPunycode.test(string)?decode2(string.slice(4).toLowerCase()):string})},toASCII=function(input){return mapDomain(input,function(string){return regexNonASCII.test(string)?"xn--"+encode2(string):string})},punycode2={version:"2.3.1",ucs2:{decode:ucs2decode,encode:ucs2encode},decode:decode2,encode:encode2,toASCII,toUnicode};module.exports=punycode2}});import{spawn as spawn5}from"node:child_process";import{existsSync as existsSync24,readFileSync as readFileSync26}from"node:fs";import{resolve as resolve18}from"node:path";import process7 from"node:process";async function batchUpdateTenantCmsItems(args){let collection=args.payload.collection.trim(),itemIds=Array.from(new Set(args.payload.item_ids.map(itemId=>itemId.trim()).filter(Boolean))),tagAdds=dedupeTags(args.payload.changes.tags.add),discover=await args.sdk.discoverTenantCmsCollection(collection),schemaSpec=discover.active_schema??discover.draft_schema;if(!schemaSpec)throw new Error(`Collection \`${collection}\` \u5F53\u524D\u6CA1\u6709\u53EF\u7528 schema\u3002`);let succeeded=[],failed=[];for(let itemId of itemIds){let title=itemId;try{let item=await args.sdk.getTenantCmsItem({collection,id:itemId});title=resolveCmsItemTitle(item);let currentStatus=item.system.publish_status??"draft",targetStatus=args.payload.changes.publish_status.mode==="set"?args.payload.changes.publish_status.value:void 0,hasCategoryChange=args.payload.changes.category.mode!=="keep",hasTagChange=tagAdds.length>0,hasMetadataChange=hasCategoryChange||hasTagChange,effectiveStatus=currentStatus;if(hasMetadataChange){currentStatus==="archived"&&targetStatus&&targetStatus!=="archived"&&(await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus}),effectiveStatus=targetStatus);let payload=buildCmsItemWritePayloadFromDelivery({item,schemaSpec,publishStatus:targetStatus&&targetStatus!=="archived"?targetStatus:effectiveStatus,categoryChange:args.payload.changes.category,tagsToAdd:tagAdds});await args.sdk.configureTenantCmsItem({...payload,item_id:itemId}),targetStatus==="archived"&&effectiveStatus!=="archived"?await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:"archived"}):targetStatus&&targetStatus!=="archived"&&(effectiveStatus=targetStatus)}else targetStatus&&targetStatus!==effectiveStatus&&await args.sdk.applyTenantCmsPublish({collection,item_id:itemId,target_status:targetStatus});succeeded.push({item_id:itemId,title})}catch(error){failed.push({item_id:itemId,title,message:error instanceof Error?error.message:"\u6279\u91CF\u66F4\u65B0\u5931\u8D25"})}}return{total:itemIds.length,succeeded,failed}}function buildCmsItemWritePayloadFromDelivery(args){let nextTags=dedupeTags([...args.item.system.tags??[],...args.tagsToAdd]);return{collection:args.item.collection,system:{publish_status:args.publishStatus,...args.item.system.slug?{slug:args.item.system.slug}:{},featured:args.item.system.featured??!1,tags:nextTags,category_id:resolveNextCategoryId(args.item,args.categoryChange),...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:normalizeCmsContentForWrite(args.item.content,args.schemaSpec.fields)}}function resolveNextCategoryId(item,categoryChange){return categoryChange.mode==="clear"?null:categoryChange.mode==="set"?categoryChange.category_id?.trim()||null:item.system.category_id??null}function resolveCmsItemTitle(item){let title=item.content.title,name=item.content.name;return typeof title=="string"&&title.trim()?title.trim():typeof name=="string"&&name.trim()?name.trim():item.system.slug??item.system.id??"Untitled item"}function dedupeTags(values){let seen=new Set,next=[];for(let value of values){let normalized=value.trim();if(!normalized)continue;let lowered=normalized.toLowerCase();seen.has(lowered)||(seen.add(lowered),next.push(normalized))}return next}function normalizeCmsContentForWrite(content,fields){let normalized={};for(let field of fields)normalized[field.name]=normalizeFieldValueForPayload(field,content[field.name]);return normalized}function normalizeFieldValueForPayload(field,value){switch(field.type){case"date":if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}return value??null;case"number":if(typeof value=="string"){let parsed=Number.parseFloat(value.trim());return Number.isFinite(parsed)?field.ui?.number_kind==="integer"?Math.trunc(parsed):parsed:0}return value;case"bool":return!!value;case"multi_select":return normalizeStringArrayValue(value);case"image":case"file":return normalizeAssetValue(value);case"images":case"files":return normalizeAssetArrayValue(value);case"relation":return normalizeRelationId(value);case"relations":return normalizeRelationArrayValue(value);default:return typeof value=="string"?value:value??""}}function normalizeRelationId(value){if(typeof value=="string"){let normalized=value.trim();return normalized.length>0?normalized:null}if(value&&typeof value=="object"&&!Array.isArray(value)&&"id"in value){let id=value.id;return typeof id=="string"&&id.trim().length>0?id.trim():null}return null}function normalizeAssetValue(value){return value&&typeof value=="object"&&!Array.isArray(value)?value:null}function normalizeStringArrayValue(value){return Array.isArray(value)?value.map(item=>String(item)):typeof value=="string"?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function normalizeAssetArrayValue(value){return Array.isArray(value)?value.filter(item=>!!item&&typeof item=="object"&&!Array.isArray(item)):[]}function normalizeRelationArrayValue(value){return Array.isArray(value)?value.map(item=>normalizeRelationId(item)).filter(item=>!!item):[]}import{createHash}from"node:crypto";import{URL as URL2}from"node:url";var IMAGE_URL_ATTRS=["src","data-src","data-original","data-original-src","data-lazy-src"],IMAGE_SRCSET_ATTRS=["srcset","data-srcset"];function trimToUndefined(value){let normalized=value?.trim();return normalized||void 0}function normalizeUrl(value,baseUrl){let trimmed=trimToUndefined(value);if(trimmed)try{return baseUrl?new URL2(trimmed,baseUrl).toString():new URL2(trimmed).toString()}catch{return}}function isPlatformHostedAssetUrl(value){try{let parsed=new URL2(value);return/^\/assets\/[^/]+\/(original|variants\/[^/]+)$/.test(parsed.pathname)||parsed.pathname.startsWith("/api/tenant/assets/")}catch{return!1}}function inferMimeTypeFromUrl(value){if(!value)return;let pathname=(()=>{try{return new URL2(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg";if(pathname.endsWith(".avif"))return"image/avif"}function computeChecksum(content){return`sha256:${createHash("sha256").update(content).digest("hex")}`}function inferRemoteImageFileName(url,mimeType){let lastSegment=(()=>{try{return new URL2(url).pathname}catch{return url}})().split("/").filter(Boolean).at(-1);return lastSegment&&/\.[a-z0-9]{2,6}$/i.test(lastSegment)?decodeURIComponent(lastSegment):`remote-image.${(()=>{switch(mimeType){case"image/png":return"png";case"image/webp":return"webp";case"image/gif":return"gif";case"image/svg+xml":return"svg";case"image/avif":return"avif";case"image/jpeg":default:return"jpg"}})()}`}function buildTenantAssetReference(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function replaceImageAttributeUrls(html,replacementsByUrl,attribute2){let pattern=new RegExp(`(<img\\b[^>]*?\\s${attribute2}\\s*=\\s*)(["'])(.*?)\\2`,"gi");return html.replace(pattern,(fullMatch,prefix,quote,rawUrl)=>{let replacement=replacementsByUrl.get(rawUrl);return!replacement||replacement.finalUrl===rawUrl?fullMatch:`${prefix}${quote}${replacement.finalUrl}${quote}`})}function stripImageAttributes(html,attributes){let nextHtml=html;for(let attribute2 of attributes){let pattern=new RegExp(`\\s${attribute2}\\s*=\\s*(["']).*?\\1`,"gi");nextHtml=nextHtml.replace(pattern,"")}return nextHtml}async function fetchRemoteImageBinary(args){let response=await(args.fetchImpl??fetch)(args.url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u56FE\u7247\u62C9\u53D6\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let normalizedMimeType=String(response.headers.get("content-type")??"").split(";")[0]?.trim().toLowerCase()||inferMimeTypeFromUrl(args.url);if(!normalizedMimeType||!normalizedMimeType.startsWith("image/"))throw new Error("\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u53D7\u652F\u6301\u7684\u56FE\u7247\u7C7B\u578B");let content=new Uint8Array(await response.arrayBuffer()),maxBytes=args.maxBytes??20*1024*1024;if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");if(content.byteLength>maxBytes)throw new Error(`\u8FDC\u7A0B\u56FE\u7247\u8D85\u8FC7\u5927\u5C0F\u9650\u5236\uFF08${content.byteLength} bytes\uFF09`);return{content,mimeType:normalizedMimeType}}async function ingestRemoteImageCandidates(args){let uniqueCandidates=new Map;for(let candidate of args.candidates)uniqueCandidates.has(candidate.url)||uniqueCandidates.set(candidate.url,candidate);let resultsByUrl=new Map,resultsByChecksum=new Map,warnings=[];for(let candidate of uniqueCandidates.values())try{let{content,mimeType}=await fetchRemoteImageBinary({url:candidate.url,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),checksum3=computeChecksum(content),existingByChecksum=resultsByChecksum.get(checksum3);if(existingByChecksum){let reused={...existingByChecksum,originalUrl:candidate.url,status:"reused"};resultsByUrl.set(candidate.url,reused);continue}let fileName=inferRemoteImageFileName(candidate.url,mimeType),uploadedAsset=await args.sdk.createTenantAssetBinary({fileName,mimeType,content,title:candidate.title,...args.folderId?{folderId:args.folderId}:{}}),uploaded={originalUrl:candidate.url,finalUrl:uploadedAsset.original_url,asset:uploadedAsset,assetReference:buildTenantAssetReference(uploadedAsset),mimeType,checksum:checksum3,status:"uploaded"};resultsByUrl.set(candidate.url,uploaded),resultsByChecksum.set(checksum3,uploaded)}catch(error){let message=error instanceof Error?error.message:"\u5916\u94FE\u56FE\u7247\u8D44\u4EA7\u5316\u5931\u8D25";warnings.push(`\u56FE\u7247 \`${candidate.url}\` \u8D44\u4EA7\u5316\u5931\u8D25\uFF0C\u5DF2\u56DE\u9000\u539F\u94FE\u63A5\uFF1A${message}`),resultsByUrl.set(candidate.url,{originalUrl:candidate.url,finalUrl:candidate.url,mimeType:inferMimeTypeFromUrl(candidate.url),status:"fallback",warning:message})}return{resultsByUrl,warnings}}function collectExternalImageCandidatesFromHtml(args){let candidates=new Map;return args.html.replace(/<img\b[^>]*>/gi,tag=>{for(let attribute2 of IMAGE_URL_ATTRS){let rawUrl=tag.match(new RegExp(`(?:^|\\s)${attribute2}\\s*=\\s*(["'])(.*?)\\1`,"i"))?.[2],normalizedUrl=normalizeUrl(rawUrl,args.baseUrl);!normalizedUrl||normalizedUrl.startsWith("data:")||isPlatformHostedAssetUrl(normalizedUrl)||candidates.has(normalizedUrl)||candidates.set(normalizedUrl,{url:normalizedUrl,title:args.title,source:"body"})}return""}),[...candidates.values()]}async function assetizeExternalImagesInHtml(args){let bodyCandidates=collectExternalImageCandidatesFromHtml({html:args.html,baseUrl:args.baseUrl,title:args.bodyTitle}),normalizedCoverUrl=normalizeUrl(args.coverUrl,args.baseUrl),coverCandidate=normalizedCoverUrl&&!normalizedCoverUrl.startsWith("data:")&&!isPlatformHostedAssetUrl(normalizedCoverUrl)?{url:normalizedCoverUrl,title:args.coverTitle??args.bodyTitle,source:"cover"}:null,candidates=coverCandidate?[coverCandidate,...bodyCandidates]:bodyCandidates,{resultsByUrl,warnings}=await ingestRemoteImageCandidates({sdk:args.sdk,candidates,folderId:args.folderId,fetchImpl:args.fetchImpl,maxBytes:args.maxBytes}),html=args.html;for(let attribute2 of IMAGE_URL_ATTRS)html=replaceImageAttributeUrls(html,resultsByUrl,attribute2);html=stripImageAttributes(html,IMAGE_SRCSET_ATTRS);let replacements=[...resultsByUrl.values()].map(result=>({originalUrl:result.originalUrl,finalUrl:result.finalUrl,...result.asset?.asset.asset_id?{assetId:result.asset.asset.asset_id}:{},status:result.status}));if(!normalizedCoverUrl)return{html,cover:{mode:"none"},replacements,warnings};let coverResult=resultsByUrl.get(normalizedCoverUrl);return coverResult?.assetReference?{html,cover:{mode:"asset",value:coverResult.assetReference},replacements,warnings}:{html,cover:{mode:"remote",value:{title:args.coverTitle??args.bodyTitle??"Remote cover",...coverResult?.mimeType||args.coverMimeType?{mime_type:coverResult?.mimeType??args.coverMimeType}:{},original_url:normalizedCoverUrl}},replacements,warnings}}var PlatformApiError=class extends Error{status;code;detail;requestId;capability;category;remediation;constructor(message,status,code2,detail,requestId,capability,category,remediation){super(message),this.status=status,this.code=code2,this.detail=detail,this.requestId=requestId,this.capability=capability,this.category=category,this.remediation=remediation,this.name="PlatformApiError"}},BasePlatformSdk=class{options;fetchImpl;constructor(options){this.options=options,this.fetchImpl=options.fetchImpl??fetch}async request(path2,init={}){return this.requestUrl(new URL(path2,this.options.baseUrl),init)}async requestBinary(path2,init={}){return this.requestBinaryUrl(new URL(path2,this.options.baseUrl),init)}async requestVoid(path2,init={}){return this.requestVoidUrl(new URL(path2,this.options.baseUrl),init)}async requestUrl(url,init={}){let response=await this.fetchResponse(url,init),payload=await parseJsonResponse(response);if(!response.ok){let errorPayload=payload,error=errorPayload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??errorPayload.detail,errorPayload.request_id,error?.capability,error?.category,error?.remediation)}return payload}async requestBinaryUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}return new Uint8Array(await response.arrayBuffer())}async requestVoidUrl(url,init={}){let response=await this.fetchResponse(url,init);if(!response.ok){let payload=await parseJsonResponse(response),error=payload.error;throw new PlatformApiError(error?.message??`Request failed: ${response.status}`,response.status,error?.code,error?.detail??payload.detail,payload.request_id,error?.capability,error?.category,error?.remediation)}}async fetchResponse(url,init={}){let headers=new Headers(init.headers);!headers.has("Content-Type")&&init.body&&headers.set("Content-Type","application/json");let extraHeaders=await this.options.getHeaders?.();return extraHeaders&&new Headers(extraHeaders).forEach((value,key)=>{headers.set(key,value)}),this.fetchImpl(url,{...init,headers})}};async function parseJsonResponse(response){let text2=await response.text();if(text2.trim().length===0)return{};try{return JSON.parse(text2)}catch{if(response.ok)return{};throw new PlatformApiError(`Request failed with non-JSON response: ${response.status}`,response.status,"non_json_response",{content_type:response.headers.get("content-type")??void 0,body_preview:text2.replace(/\s+/g," ").slice(0,240)})}}var PlatformSdk=class extends BasePlatformSdk{notification;constructor(options){super(options),this.notification=new NotificationSdkNamespace(this)}async listNotificationInbox(filters={}){let url=new URL("/api/tenant/notification/inbox",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"inbox_type",filters.inbox_type),setOptionalSearchParam(url,"status",filters.status),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async updateNotificationInboxItemStatus(itemId,payload){return(await this.request(`/api/tenant/notification/inbox/${encodeURIComponent(itemId)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async batchUpdateNotificationInboxItemsStatus(payload){return this.request("/api/tenant/notification/inbox:batch",{method:"PATCH",body:JSON.stringify(payload)})}async listNotificationDeliveries(filters={}){let url=new URL("/api/tenant/notification/deliveries",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async announcePlatformNotification(payload){return(await this.request("/api/admin/notification/announcements/platform",{method:"POST",body:JSON.stringify(payload)})).item}async announceAppNotification(appId,payload){return(await this.request(`/api/tenant/notification/apps/${encodeURIComponent(appId)}/announcements`,{method:"POST",body:JSON.stringify(payload)})).item}async getAppNotificationConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/config`)}async listAppNotificationAnnouncements(appId,options={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,this.options.baseUrl);return typeof options.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async createAppNotificationAnnouncement(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements`,{method:"POST",body:JSON.stringify(payload)})}async archiveAppNotificationAnnouncement(appId,announcementId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/announcements/${encodeURIComponent(announcementId)}:archive`,{method:"POST"})}async publishEndUserNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/publish`,{method:"POST",body:JSON.stringify(payload)})}async createEndUserNotificationReminder(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/reminders`,{method:"POST",body:JSON.stringify(payload)})}async projectEndUserTaskNotification(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/task-projections`,{method:"POST",body:JSON.stringify(payload)})}async listEndUserNotificationInbox(appId,query){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/inbox`,this.options.baseUrl);return url.searchParams.set("end_user_id",query.end_user_id),setOptionalSearchParam(url,"status",query.status),setOptionalSearchParam(url,"inbox_type",query.inbox_type),typeof query.limit=="number"&&Number.isFinite(query.limit)&&url.searchParams.set("limit",String(query.limit)),this.request(`${url.pathname}${url.search}`)}async getEndUserNotificationUnreadCount(appId,endUserId){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/notification/agent/unread-count`,this.options.baseUrl);return url.searchParams.set("end_user_id",endUserId),this.request(`${url.pathname}${url.search}`)}async createWorkflowDefinition(payload){return(await this.request("/api/workflow/definitions",{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowTemplates(){return(await this.request("/api/workflow/templates")).items}async listWorkflowDefinitions(filters={}){let url=new URL("/api/workflow/definitions",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async listWorkflowBindings(filters={}){let url=new URL("/api/workflow/bindings",this.options.baseUrl);return setOptionalSearchParam(url,"target_id",filters.target_id),setOptionalSearchParam(url,"definition_key",filters.definition_key),(await this.request(`${url.pathname}${url.search}`)).items}async updateWorkflowDefinitionMetadata(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}`,{method:"PATCH",body:JSON.stringify(payload)})).item}async saveWorkflowRoleBindings(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/role-bindings`,{method:"POST",body:JSON.stringify(payload)})).items}async getWorkflowBindingOverride(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/binding-override`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).item}async saveWorkflowBindingOverride(payload){return(await this.request(`/api/workflow/definitions/${encodeURIComponent(payload.definition_key)}/binding-override`,{method:"POST",body:JSON.stringify(payload)})).item}async listWorkflowRoleBindings(args){let url=new URL(`/api/workflow/definitions/${encodeURIComponent(args.definition_key)}/role-bindings`,this.options.baseUrl);return setOptionalSearchParam(url,"target_scope",args.target_scope),setOptionalSearchParam(url,"target_id",args.target_id),(await this.request(`${url.pathname}${url.search}`)).items}async startWorkflow(payload){return(await this.request("/api/workflow/instances/start",{method:"POST",body:JSON.stringify(payload)})).item}async performWorkflowAction(instanceId,payload){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}/actions`,{method:"POST",body:JSON.stringify(payload)})).item}async getWorkflowInstance(instanceId){return(await this.request(`/api/workflow/instances/${encodeURIComponent(instanceId)}`)).item}async listWorkflowTasks(filters={}){let url=new URL("/api/workflow/tasks",this.options.baseUrl);return setOptionalSearchParam(url,"app_id",filters.app_id),setOptionalSearchParam(url,"status",filters.status),(await this.request(`${url.pathname}${url.search}`)).items}async getWhoAmI(){return this.request("/api/auth/whoami")}async getResolvedPermissions(){return this.request("/api/auth/permissions")}async switchTenantContext(payload){return this.request("/api/auth/context/switch-tenant",{method:"POST",body:JSON.stringify(payload)})}async listTenantWorkspaces(){return this.request("/api/auth/workspaces")}async ensurePersonalWorkspace(){return this.request("/api/auth/workspaces/ensure-personal",{method:"POST"})}async getAdminOverview(){return this.request("/api/admin/overview")}async listAdminWorkbenchEntries(){return this.request("/api/admin/workbench-entries")}async getAdminWorkbenchEntryDetail(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}`)}async updateAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"PUT",body:JSON.stringify(payload)})}async resetAdminWorkbenchEntryVisibility(entryKey){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility`,{method:"DELETE"})}async previewAdminWorkbenchEntryVisibility(entryKey,payload){return this.request(`/api/admin/workbench-entries/${encodeURIComponent(entryKey)}/visibility:preview`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAsset(payload){return this.request("/api/tenant/assets",{method:"POST",body:JSON.stringify(payload)})}async createTenantAssetBinary(args){let headers=new Headers({"Content-Type":args.mimeType,"X-Asset-File-Name":encodeURIComponent(args.fileName)});return args.title?.trim()&&headers.set("X-Asset-Title",encodeURIComponent(args.title.trim())),args.folderId?.trim()&&headers.set("X-Asset-Folder-Id",encodeURIComponent(args.folderId.trim())),this.request("/api/tenant/assets/upload",{method:"POST",headers,body:Buffer.from(args.content)})}async listTenantAssets(filters={}){let url=new URL("/api/tenant/assets",this.options.baseUrl);return setOptionalSearchParam(url,"q",filters.q),setOptionalSearchParam(url,"media_type",filters.media_type),setOptionalSearchParam(url,"mime_type",filters.mime_type),setOptionalSearchParam(url,"folder_id",filters.folder_id),setOptionalSearchParam(url,"tag_ids",filters.tag_ids?.join(",")),setOptionalSearchParam(url,"scene",filters.scene),setOptionalSearchParam(url,"objects",filters.objects?.join(",")),setOptionalSearchParam(url,"safety_flags",filters.safety_flags?.join(",")),setOptionalSearchParam(url,"orientation",filters.orientation),setOptionalBooleanSearchParam(url,"has_ocr",filters.has_ocr),setOptionalBooleanSearchParam(url,"has_person",filters.has_person),setOptionalBooleanSearchParam(url,"is_svg",filters.is_svg),typeof filters.page=="number"&&Number.isFinite(filters.page)&&url.searchParams.set("page",String(filters.page)),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`)}async deleteTenantAsset(assetId){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}`,{method:"DELETE"})}async batchUpdateTenantAssets(payload){return this.request("/api/tenant/assets/batch",{method:"POST",body:JSON.stringify(payload)})}async listTenantAssetFolders(){return this.request("/api/tenant/assets/folders")}async createTenantAssetFolder(payload){return this.request("/api/tenant/assets/folders",{method:"POST",body:JSON.stringify(payload)})}async updateTenantAssetFolderMetadata(folderId,payload){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAssetFolder(folderId){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}`,{method:"DELETE"})}async moveTenantAssetFolder(folderId,direction){return this.request(`/api/tenant/assets/folders/${encodeURIComponent(folderId)}/move-${direction}`,{method:"POST"})}async updateTenantAssetFolder(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/folder`,{method:"PATCH",body:JSON.stringify(payload)})}async updateTenantAssetMetadata(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/metadata`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAssetTags(options){let url=new URL("/api/tenant/assets/tags",this.options.baseUrl);return options?.assetId&&url.searchParams.set("asset_id",options.assetId),this.request(`${url.pathname}${url.search}`)}async addTenantAssetTag(assetId,payload){return this.request(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,{method:"POST",body:JSON.stringify(payload)})}async removeTenantAssetTag(assetId,label){let url=new URL(`/api/tenant/assets/${encodeURIComponent(assetId)}/tags`,this.options.baseUrl);return url.searchParams.set("label",label),this.request(`${url.pathname}${url.search}`,{method:"DELETE"})}async downloadTenantAssetOriginal(assetId){return this.requestBinary(`/api/tenant/assets/${encodeURIComponent(assetId)}/original`)}async downloadTenantAssetVariant(assetId,variantKind){return this.requestBinary(`/assets/${encodeURIComponent(assetId)}/variants/${encodeURIComponent(variantKind)}`)}async createTenantBlobUploadSession(payload){return this.request("/api/tenant/blobs/upload-sessions",{method:"POST",body:JSON.stringify(payload)})}async uploadTenantBlobBinary(uploadSessionId,payload){let url=resolveRelativeOrAbsoluteUrl(payload.upload_url??`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/content`,this.options.baseUrl),headers=new Headers(payload.headers);headers.set("Content-Type",payload.content_type?.trim()||"application/octet-stream"),await this.requestVoidUrl(url,{method:"PUT",headers,body:Buffer.from(payload.content)})}async completeTenantBlobUpload(uploadSessionId,payload={}){return this.request(`/api/tenant/blobs/upload-sessions/${encodeURIComponent(uploadSessionId)}/complete`,{method:"POST",body:JSON.stringify(payload)})}async createTenantBlobBinary(args){let contentType=args.contentType?.trim()||"application/octet-stream",session=await this.createTenantBlobUploadSession({original_filename:args.fileName,content_type:contentType,size_bytes:args.content.byteLength,...args.appId?.trim()?{app_id:args.appId.trim()}:{},...args.clientRequestId?.trim()?{client_request_id:args.clientRequestId.trim()}:{}});return await this.uploadTenantBlobBinary(session.upload_session_id,{content:args.content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}),this.completeTenantBlobUpload(session.upload_session_id,{size_bytes:args.content.byteLength,...args.sha256?.trim()?{sha256:args.sha256.trim()}:{}})}async listTenantBlobs(filters={}){let url=new URL("/api/tenant/blobs",this.options.baseUrl);return setOptionalSearchParam(url,"cursor",filters.cursor),setOptionalSearchParam(url,"app_id",filters.app_id??void 0),setOptionalSearchParam(url,"q",filters.q??void 0),typeof filters.limit=="number"&&Number.isFinite(filters.limit)&&url.searchParams.set("limit",String(filters.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantBlob(blobId){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}`)}async issueTenantBlobDownloadUrl(blobId,payload={}){return this.request(`/api/tenant/blobs/${encodeURIComponent(blobId)}/download-url`,{method:"POST",body:JSON.stringify(payload)})}async getTenantOverview(){return this.request("/api/tenant/overview")}async getTenantEffectiveState(){return this.request("/api/tenant/effective-state")}async getTenantWorkbenchNavigation(){return this.request("/api/tenant/workbench/navigation")}async createTenantApp(payload){return this.request("/api/tenant/apps",{method:"POST",body:JSON.stringify(payload)})}async updateTenantApp(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listAppTemplates(){return this.request("/api/tenant/app-templates")}async createAppTemplate(payload){return this.request("/api/tenant/app-templates",{method:"POST",body:JSON.stringify(payload)})}async getAppTemplate(templateId){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`)}async openAppTemplatePreview(templateId){return this.requestVoid(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/preview`)}async updateAppTemplateSettings(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteAppTemplate(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}`,{method:"DELETE",body:JSON.stringify(payload)})}async createAppTemplateInitializationTask(templateId,payload){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/initialization-tasks`,{method:"POST",body:JSON.stringify(payload)})}async getAppTemplateInitializationTask(taskId){return this.request(`/api/tenant/app-template-initialization-tasks/${encodeURIComponent(taskId)}`)}async createAppMarketSubmission(templateId,payload={}){return this.request(`/api/tenant/app-templates/${encodeURIComponent(templateId)}/market-submissions`,{method:"POST",body:JSON.stringify(payload)})}async cancelAppMarketSubmission(submissionId){return this.request(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/cancel`,{method:"POST"})}async listTenantAppMarketSubmissions(options){let url=new URL("/api/tenant/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async listAppMarketListings(options){let url=new URL("/api/tenant/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async listAdminAppMarketListings(options){let url=new URL("/api/admin/app-market/listings",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.tag&&url.searchParams.set("tag",options.tag),this.request(`${url.pathname}${url.search}`)}async getAppMarketListing(listingId){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}`)}async openAppMarketSubmissionPreview(submissionId){return this.requestVoid(`/api/tenant/app-market/submissions/${encodeURIComponent(submissionId)}/preview`)}async createAppMarketInstall(listingId,payload){return this.request(`/api/tenant/app-market/listings/${encodeURIComponent(listingId)}/installs`,{method:"POST",body:JSON.stringify(payload)})}async listAdminAppMarketSubmissions(options){let url=new URL("/api/admin/app-market/submissions",this.options.baseUrl);return options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async approveAppMarketSubmission(submissionId){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/approve`,{method:"POST"})}async rejectAppMarketSubmission(submissionId,payload={}){return this.request(`/api/admin/app-market/submissions/${encodeURIComponent(submissionId)}/reject`,{method:"POST",body:JSON.stringify(payload)})}async unlistAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/unlist`,{method:"POST",body:JSON.stringify(payload)})}async publishAppMarketListing(listingId,payload={}){return this.request(`/api/admin/app-market/listings/${encodeURIComponent(listingId)}/publish`,{method:"POST",body:JSON.stringify(payload)})}async listAdminLightAppLibraries(options){let url=new URL("/api/admin/light-app-library/libraries",this.options.baseUrl);return options?.visibility&&url.searchParams.set("visibility",options.visibility),this.request(`${url.pathname}${url.search}`)}async setAdminLightAppLibraryVisibility(libraryId,payload){return this.request(`/api/admin/light-app-library/libraries/${encodeURIComponent(libraryId)}/visibility`,{method:"POST",body:JSON.stringify(payload)})}async listLightAppLibraryEntries(options){let url=new URL("/api/tenant/light-app-library/entries",this.options.baseUrl);return options?.query&&url.searchParams.set("query",options.query),options?.status&&url.searchParams.set("status",options.status),options?.template_key&&url.searchParams.set("template_key",options.template_key),options?.tag&&url.searchParams.set("tag",options.tag),options?.visibility&&url.searchParams.set("visibility",options.visibility),typeof options?.include_public=="boolean"&&url.searchParams.set("include_public",String(options.include_public)),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntries(query){let url=new URL("/api/tenant/light-app-library/entries/search",this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async getLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`)}async createLightAppLibraryEntry(payload){return this.request("/api/tenant/light-app-library/entries",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppLibraryEntry(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async submitLightAppLibraryEntrySnapshot(entryId,payload){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/snapshots`,{method:"POST",body:JSON.stringify(payload)})}async publishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/publish`,{method:"POST"})}async unpublishLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/unpublish`,{method:"POST"})}async archiveLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/archive`,{method:"POST"})}async deleteLightAppLibraryEntry(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async getLightAppLibraryEntrySource(entryId){return this.request(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source`)}async readLightAppLibraryEntrySourceFile(entryId,path2){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/files`,this.options.baseUrl);return url.searchParams.set("path",path2),this.request(`${url.pathname}${url.search}`)}async searchLightAppLibraryEntrySource(entryId,query){let url=new URL(`/api/tenant/light-app-library/entries/${encodeURIComponent(entryId)}/source/search`,this.options.baseUrl);return url.searchParams.set("query",query),this.request(`${url.pathname}${url.search}`)}async listLightAppPrototypeEntries(options){let url=new URL("/api/tenant/prototypes",this.options.baseUrl);return options?.q&&url.searchParams.set("q",options.q),options?.status&&url.searchParams.set("status",options.status),this.request(`${url.pathname}${url.search}`)}async getLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`)}async createLightAppPrototypeEntry(payload){return this.request("/api/tenant/prototypes",{method:"POST",body:JSON.stringify(payload)})}async updateLightAppPrototypeEntry(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async copyLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/copy`,{method:"POST"})}async deleteLightAppPrototypeEntry(entryId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}`,{method:"DELETE"})}async saveLightAppPrototypeCurrentVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/current-version`,{method:"PUT",body:JSON.stringify(payload)})}async submitLightAppPrototypeVersion(entryId,payload){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions`,{method:"POST",body:JSON.stringify(payload)})}async getLightAppPrototypeVersion(entryId,versionId){return this.request(`/api/tenant/prototypes/entries/${encodeURIComponent(entryId)}/versions/${encodeURIComponent(versionId)}`)}async deleteTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}`,{method:"DELETE"})}async getTenantAppDeletePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/delete-preview`,{method:"POST"})}async getTenantAppDeleteJob(jobId){return this.request(`/api/tenant/app-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppUndeployPreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy-preview`,{method:"POST"})}async undeployTenantApp(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/undeploy`,{method:"POST"})}async getTenantAppUndeployJob(jobId){return this.request(`/api/tenant/app-undeploy-jobs/${encodeURIComponent(jobId)}`)}async createBuild(payload){return this.request("/api/builds",{method:"POST",body:JSON.stringify(payload)})}async listBuilds(appId,options){let url=new URL("/api/builds",this.options.baseUrl);return url.searchParams.set("app_id",appId),typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getBuildPrecheck(appId,args){let url=new URL("/api/builds/precheck",this.options.baseUrl);return url.searchParams.set("app_id",appId),url.searchParams.set("source_version_id",args.source_version_id),args.build_config?.dockerfile_path&&url.searchParams.set("dockerfile_path",args.build_config.dockerfile_path),args.build_config?.context_subdir&&url.searchParams.set("context_subdir",args.build_config.context_subdir),args.build_config?.target&&url.searchParams.set("target",args.build_config.target),this.request(`${url.pathname}${url.search}`)}async getBuild(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}`)}async listBuildEvents(buildId){return this.request(`/api/builds/${encodeURIComponent(buildId)}/events`)}async createLocalBuildSession(payload){return this.request("/api/builds/local-sessions",{method:"POST",body:JSON.stringify(payload)})}async completeLocalBuildSession(buildId,payload){return this.request(`/api/builds/${encodeURIComponent(buildId)}/local-complete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceWorkspace(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/source-workspace`,this.options.baseUrl);return options?.sourceVersionId&&url.searchParams.set("source_version_id",options.sourceVersionId),this.request(`${url.pathname}${url.search}`)}async getTenantAppDevWorkspace(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace`)}async pushTenantAppDevWorkspace(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/push`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)})}async createTenantAppDevWorkspacePreview(appId,payload={}){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDevWorkspacePreview(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/dev-workspace/preview`)}async listTenantAppSourceVersions(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`)}async updateTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}`,{method:"PATCH",body:JSON.stringify(payload)})}async getTenantAppEndUserAuthConfig(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/config`)}async getTenantAppEndUserAuthDiscovery(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/discovery`)}async getTenantAppEndUserAuthInspect(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/inspect`)}async configureTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/configure`,{method:"POST",body:JSON.stringify(payload)})}async bindTenantAppEndUserAuth(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/bind`,{method:"POST",body:JSON.stringify(payload)})}async listTenantAppEndUsers(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users`)}async listTenantAppEndUserRoles(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`)}async createTenantAppEndUserRole(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppEndUserRole(appId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`)}async updateTenantAppEndUserRole(appId,roleKey,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/roles/${encodeURIComponent(roleKey)}`,{method:"PATCH",body:JSON.stringify(payload)})}async listTenantAppUserRoles(appId,appUserId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`)}async assignTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles:assign`,{method:"POST",body:JSON.stringify(payload)})}async replaceTenantAppUserRoles(appId,appUserId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles`,{method:"PUT",body:JSON.stringify(payload)})}async removeTenantAppUserRole(appId,appUserId,roleKey){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/end-user-auth/app-users/${encodeURIComponent(appUserId)}/roles/${encodeURIComponent(roleKey)}`,{method:"DELETE"})}async discoverTenantCmsCollection(collection){let url=new URL("/api/tenant/cms/discover",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsCollections(){return this.request("/api/tenant/cms/collections")}async inspectTenantCmsSchema(collection){let url=new URL("/api/tenant/cms/inspect/schema",this.options.baseUrl);return url.searchParams.set("collection",collection),this.request(`${url.pathname}${url.search}`)}async listTenantCmsItems(args){let url=new URL("/api/tenant/cms/items",this.options.baseUrl);return url.searchParams.set("collection",args.collection),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"status",args.status),setOptionalSearchParam(url,"q",args.query),this.request(`${url.pathname}${url.search}`)}async getTenantCmsItem(args){let url=new URL(`/api/tenant/cms/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("collection",args.collection),this.request(`${url.pathname}${url.search}`)}async configureTenantCmsCollection(spec){return this.request("/api/tenant/cms/configure/collection",{method:"POST",body:JSON.stringify(spec)})}async configureTenantCmsItem(payload){return this.request("/api/tenant/cms/configure/item",{method:"POST",body:JSON.stringify(payload)})}async configureTenantCmsCategory(payload){return this.request("/api/tenant/cms/configure/category",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsSchema(payload){return this.request("/api/tenant/cms/apply/schema",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsCollectionStatus(payload){return this.request("/api/tenant/cms/apply/collection-status",{method:"POST",body:JSON.stringify(payload)})}async applyTenantCmsPublish(payload){return this.request("/api/tenant/cms/apply/publish",{method:"POST",body:JSON.stringify(payload)})}async listPublicCmsItems(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items`,this.options.baseUrl);url.searchParams.set("tenant_id",args.tenantId),typeof args.page=="number"&&Number.isFinite(args.page)&&url.searchParams.set("page",String(args.page)),typeof args.pageSize=="number"&&Number.isFinite(args.pageSize)&&url.searchParams.set("page_size",String(args.pageSize)),setOptionalSearchParam(url,"category_id",args.categoryId),setOptionalSearchParam(url,"sort_field",args.sortField),setOptionalSearchParam(url,"sort_direction",args.sortDirection);for(let tag of args.tags??[])url.searchParams.append("tag",tag);return this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemBySlug(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/by-slug/${encodeURIComponent(args.slug)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async getPublicCmsItemById(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/items/${encodeURIComponent(args.id)}`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listPublicCmsCategories(args){let url=new URL(`/api/public/cms/collections/${encodeURIComponent(args.collection)}/categories`,this.options.baseUrl);return url.searchParams.set("tenant_id",args.tenantId),this.request(`${url.pathname}${url.search}`)}async listTenantAppDeploymentTimeline(appId,options){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/deployments`,this.options.baseUrl);return typeof options?.limit=="number"&&Number.isFinite(options.limit)&&url.searchParams.set("limit",String(options.limit)),this.request(`${url.pathname}${url.search}`)}async getTenantAppPublishSettings(appId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`)}async updateTenantAppPublishSettings(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings`,{method:"PATCH",body:JSON.stringify(payload)})}async setTenantAppCurrentPublishedVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/publish-settings/current-version`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppPreview(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/previews`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersion(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions`,{method:"POST",body:JSON.stringify(payload)})}async createTenantAppSourceVersionFromTemplate(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions:from-template`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppReleaseDeletePreview(appId,releaseId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete-preview`,{method:"POST"})}async deleteTenantAppRelease(appId,releaseId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/releases/${encodeURIComponent(releaseId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppSourceVersionDeletePreview(appId,sourceVersionId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete-preview`,{method:"POST"})}async deleteTenantAppSourceVersion(appId,sourceVersionId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/source-versions/${encodeURIComponent(sourceVersionId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantVersionDeleteJob(jobId){return this.request(`/api/tenant/version-delete-jobs/${encodeURIComponent(jobId)}`)}async getTenantAppBuildDeletePreview(appId,buildId){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete-preview`,{method:"POST"})}async deleteTenantAppBuild(appId,buildId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/builds/${encodeURIComponent(buildId)}/delete`,{method:"POST",body:JSON.stringify(payload)})}async getTenantAppDbInstance(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbRuntimeBindings(appId,env="preview",purpose){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/runtime-bindings`,this.options.baseUrl);return url.searchParams.set("env",env),purpose&&url.searchParams.set("purpose",purpose),this.requestUrl(url)}async resolveDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/resolve",{method:"POST",body:JSON.stringify(payload)})}async revokeDevRuntimeBindings(payload){return this.request("/api/dev-runtime-bindings/revoke",{method:"POST",body:JSON.stringify(payload)})}async listTenantAppDbTables(appId,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableSchema(appId,tableName,env="preview"){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/schema`,this.options.baseUrl);return url.searchParams.set("env",env),this.requestUrl(url)}async getTenantAppDbTableRows(appId,tableName,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.page=="number"&&url.searchParams.set("page",String(args.page)),typeof args.page_size=="number"&&url.searchParams.set("page_size",String(args.page_size)),typeof args.sort_by=="string"&&args.sort_by.trim().length>0&&url.searchParams.set("sort_by",args.sort_by),args.sort_order==="desc"&&url.searchParams.set("sort_order","desc"),typeof args.filter_column=="string"&&args.filter_column.trim().length>0&&url.searchParams.set("filter_column",args.filter_column),typeof args.filter_value=="string"&&args.filter_value.length>0&&url.searchParams.set("filter_value",args.filter_value),typeof args.search_query=="string"&&args.search_query.trim().length>0&&url.searchParams.set("search_query",args.search_query),this.requestUrl(url)}async listTenantAppDbMigrationRuns(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/migrations`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async listTenantAppDbChangeAudits(appId,args={}){let url=new URL(`/api/tenant/apps/${encodeURIComponent(appId)}/db/audits`,this.options.baseUrl);return url.searchParams.set("env",args.env??"preview"),typeof args.table_name=="string"&&args.table_name.trim().length>0&&url.searchParams.set("table_name",args.table_name),typeof args.limit=="number"&&url.searchParams.set("limit",String(args.limit)),this.requestUrl(url)}async insertTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"POST",body:JSON.stringify(payload)})}async updateTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"PATCH",body:JSON.stringify(payload)})}async deleteTenantAppDbRow(appId,tableName,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/tables/${encodeURIComponent(tableName)}/rows`,{method:"DELETE",body:JSON.stringify(payload)})}async queryTenantAppDb(appId,payload){return this.request(`/api/tenant/apps/${encodeURIComponent(appId)}/db/query`,{method:"POST",body:JSON.stringify(payload)})}async createWorkspace(payload){return this.request("/api/admin/workspaces",{method:"POST",body:JSON.stringify(payload)})}async deleteWorkspace(workspaceId,payload){return this.request(`/api/admin/workspaces/${encodeURIComponent(workspaceId)}`,{method:"DELETE",...payload?{body:JSON.stringify(payload)}:{}})}async createApproval(payload){return this.request("/api/admin/resource-approvals",{method:"POST",body:JSON.stringify(payload)})}async listApprovals(filters){let url=new URL("/api/admin/resource-approvals",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.status&&url.searchParams.set("status",filters.status),filters?.operation&&url.searchParams.set("operation",filters.operation),this.requestUrl(url)}async decideApproval(approvalId,payload){return this.request(`/api/admin/resource-approvals/${approvalId}/decision`,{method:"POST",body:JSON.stringify(payload)})}async listResourceLocks(filters){let url=new URL("/api/admin/resource-locks",this.options.baseUrl);return filters?.tenant_id&&url.searchParams.set("tenant_id",filters.tenant_id),filters?.app_id&&url.searchParams.set("app_id",filters.app_id),filters?.env&&url.searchParams.set("env",filters.env),this.requestUrl(url)}async diffResources(payload){return this.request("/api/resources/diff",{method:"POST",body:JSON.stringify(payload)})}async applyResources(payload){return this.request("/api/resources/apply",{method:"POST",body:JSON.stringify(payload)})}async rollbackResources(payload){return this.request("/api/resources/rollback",{method:"POST",body:JSON.stringify(payload)})}async deployRelease(payload){return this.request("/api/releases/deploy",{method:"POST",body:JSON.stringify(payload)})}async rollbackRelease(payload){return this.request("/api/releases/rollback",{method:"POST",body:JSON.stringify(payload)})}async queryLogs(payload){return this.request("/api/logs/query",{method:"POST",body:JSON.stringify(payload)})}};function setOptionalSearchParam(url,key,value){typeof value=="string"&&value.trim().length>0&&url.searchParams.set(key,value)}function setOptionalBooleanSearchParam(url,key,value){typeof value=="boolean"&&url.searchParams.set(key,value?"true":"false")}function resolveRelativeOrAbsoluteUrl(pathOrUrl,baseUrl){return new URL(pathOrUrl,baseUrl)}function createPlatformSdk(options){return new PlatformSdk(options)}var NotificationSdkNamespace=class{sdk;endUser;constructor(sdk){this.sdk=sdk,this.endUser=new EndUserNotificationNamespace(sdk)}},EndUserNotificationNamespace=class{sdk;constructor(sdk){this.sdk=sdk}forApp(appId){return new EndUserNotificationAppClient(this.sdk,appId)}},EndUserNotificationAppClient=class{sdk;appId;announcements;constructor(sdk,appId){this.sdk=sdk,this.appId=appId,this.announcements=new EndUserNotificationAppAnnouncementsClient(sdk,appId)}listUsers(){return this.sdk.listTenantAppEndUsers(this.appId)}forUser(endUserId){return new EndUserNotificationUserClient(this.sdk,this.appId,endUserId)}listInbox(endUserId,query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:endUserId,...query})}getUnreadCount(endUserId){return this.sdk.getEndUserNotificationUnreadCount(this.appId,endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,input.end_user_id),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,input.end_user_id)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:buildDirectEndUserRecipientRef(this.appId,input.end_user_id),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,input.end_user_id)})}},EndUserNotificationAppAnnouncementsClient=class{sdk;appId;constructor(sdk,appId){this.sdk=sdk,this.appId=appId}getConfig(){return this.sdk.getAppNotificationConfig(this.appId)}list(limit){return this.sdk.listAppNotificationAnnouncements(this.appId,{limit})}create(input){return this.sdk.createAppNotificationAnnouncement(this.appId,input)}archive(announcementId){return this.sdk.archiveAppNotificationAnnouncement(this.appId,announcementId)}},EndUserNotificationUserClient=class{sdk;appId;endUserId;constructor(sdk,appId,endUserId){this.sdk=sdk,this.appId=appId,this.endUserId=endUserId}buildRecipientRef(){return buildDirectEndUserRecipientRef(this.appId,this.endUserId)}listInbox(query={}){return this.sdk.listEndUserNotificationInbox(this.appId,{end_user_id:this.endUserId,...query})}getUnreadCount(){return this.sdk.getEndUserNotificationUnreadCount(this.appId,this.endUserId)}publish(input){return this.sdk.publishEndUserNotification(this.appId,{recipient:this.buildRecipientRef(),title:input.title,body:input.body??null,notification_type:input.notification_type??"notification",object_ref:input.object_ref,action_ref:input.action_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("publish",this.appId,this.endUserId),deliver_to:input.deliver_to})}remind(input){return this.sdk.createEndUserNotificationReminder(this.appId,{recipient:this.buildRecipientRef(),remind_at:input.remind_at,title:input.title,body:input.body??null,object_ref:input.object_ref,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("reminder",this.appId,this.endUserId)})}projectTask(input){return this.sdk.projectEndUserTaskNotification(this.appId,{recipient:this.buildRecipientRef(),source_task_ref:input.source_task_ref,title:input.title,summary:input.summary??null,due_at:input.due_at??null,source_event_id:input.source_event_id??null,idempotency_key:input.idempotency_key??buildNotificationIdempotencyKey("task-projection",this.appId,this.endUserId)})}};function buildDirectEndUserRecipientRef(appId,endUserId){return{app_id:appId,end_user_id:endUserId,recipient_type:"direct_user"}}function buildNotificationIdempotencyKey(prefix,appId,endUserId){return`${prefix}:${appId}:${endUserId}:${Date.now()}`}var AUTH_PAGE_HTML=String.raw`<!doctype html>
3
3
  <html lang="zh-CN">
4
4
  <head>
5
5
  <meta charset="utf-8" />
@@ -2193,7 +2193,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2193
2193
  `}function buildPageRenderShellExampleSource(){return buildPageRenderShellSource()}function buildPageRenderArticleListTemplateSource(){return["<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," </head>",' <body class="min-h-screen bg-[linear-gradient(180deg,#f7f4ed_0%,#efebe3_100%)] text-slate-900">',' <div data-shell-slot="header"></div>',' <main class="mx-auto w-[min(1120px,calc(100%-32px))] px-0 py-6 pb-14">',' <section class="grid gap-4 rounded-[24px] border border-stone-300 bg-stone-50 px-7 py-7 shadow-[0_12px_32px_rgba(15,23,42,0.06)]">',' <div class="w-fit rounded-full bg-amber-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-amber-700">PAGE RENDER SAMPLE</div>',' <h1 class="m-0 text-[clamp(28px,4vw,44px)] font-extrabold leading-[1.1] tracking-tight text-slate-900">\u5185\u5BB9\u5217\u8868\u9875\u6A21\u677F</h1>',' <p class="m-0 text-base leading-7 text-slate-600">\u8FD9\u4E2A\u9875\u9762\u7531\u5E73\u53F0\u5728\u8BF7\u6C42\u65F6\u6309 CMS collection \u6E32\u67D3\u3002\u5217\u8868\u5361\u7247\u3001\u5206\u9875\u548C\u8BE6\u60C5\u8DF3\u8F6C\u90FD\u7531 `page-render` \u914D\u7F6E\u9A71\u52A8\u3002</p>'," </section>",' <form class="mt-6 grid grid-cols-[repeat(auto-fit,minmax(180px,1fr))] gap-3" method="get" action="">',' <input type="search" name="keyword" placeholder="\u6309\u5173\u952E\u5B57\u641C\u7D22" class="min-h-12 rounded-2xl border border-slate-300 bg-white/95 px-4 text-base text-slate-900 placeholder:text-slate-500">',' <input type="text" name="category" placeholder="\u6309\u5206\u7C7B slug \u8FC7\u6EE4" class="min-h-12 rounded-2xl border border-slate-300 bg-white/95 px-4 text-base text-slate-900 placeholder:text-slate-500">',' <button type="submit" class="min-h-12 rounded-2xl border border-slate-800 bg-slate-800 px-4 text-base font-bold text-slate-50">\u5237\u65B0\u5217\u8868</button>'," </form>",' <div data-render-list="article-list-main" class="mt-5 grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-[18px]">',' <article data-render-template="article-card" class="grid min-h-full gap-3.5 rounded-[22px] border border-slate-200 bg-white p-[18px] shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <img data-field="cover" alt="cover" class="aspect-[16/10] w-full rounded-2xl bg-stone-200 object-cover">',' <h2 data-field="title" class="m-0 text-[22px] font-bold leading-[1.3] text-slate-900">\u6587\u7AE0\u6807\u9898</h2>',' <p data-field="summary" class="m-0 text-base leading-7 text-slate-600">\u6587\u7AE0\u6458\u8981</p>',' <a data-field="link" class="inline-flex w-fit items-center gap-2 text-sm font-bold text-amber-700" href="#">\u67E5\u770B\u8BE6\u60C5</a>'," </article>"," </div>",' <nav data-render-pagination="article-list-main" class="mt-6 flex flex-wrap gap-2.5 [&>a]:inline-flex [&>a]:h-10 [&>a]:min-w-10 [&>a]:items-center [&>a]:justify-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-300 [&>a]:bg-white [&>a]:px-3 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900 [&>a.is-active]:border-slate-800 [&>a.is-active]:bg-slate-800 [&>a.is-active]:text-white"></nav>'," </main>",' <div data-shell-slot="footer"></div>',' <header data-shell-template="site-header" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-b border-slate-900/8 py-5">',' <strong class="text-[15px] font-bold text-slate-900">Page Render Sample</strong>',' <nav class="flex flex-wrap gap-3 [&>a]:inline-flex [&>a]:min-h-9 [&>a]:items-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-900/10 [&>a]:bg-white/80 [&>a]:px-3.5 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900">',' <a href="./app">App Home</a>',' <a href="./articles">Articles</a>',' <a href="./cms">CMS Page</a>'," </nav>"," </header>",' <footer data-shell-template="site-footer" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-t border-slate-900/8 py-5 text-sm text-slate-600">',' <span class="text-slate-600">On-demand rendered from CMS delivery data</span>',' <span class="text-slate-600">Progressive enhancement assets loaded from current app build</span>'," </footer>"," </body>","</html>",""].join(`
2194
2194
  `)}function buildPageRenderArticleDetailTemplateSource(){return["<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="UTF-8">',' <meta name="viewport" content="width=device-width, initial-scale=1.0">'," </head>",' <body class="min-h-screen bg-[radial-gradient(circle_at_top_left,rgba(15,118,110,0.12),transparent_30%),linear-gradient(180deg,#fdfaf3_0%,#f3efe7_100%)] text-slate-900">',' <div data-shell-slot="header"></div>',' <main class="mx-auto grid w-[min(1120px,calc(100%-32px))] gap-6 py-6 pb-14">',' <article data-render-detail="article-main" class="rounded-[24px] border border-stone-300 bg-stone-50 px-7 py-7 shadow-[0_12px_32px_rgba(15,23,42,0.06)]">',' <h1 data-field="title" class="mb-4 text-[clamp(30px,4vw,48px)] font-extrabold leading-[1.08] tracking-tight text-slate-900">\u6587\u7AE0\u6807\u9898</h1>',' <div data-field="body" class="article-content text-[15px] leading-8 text-slate-700"><p>\u8FD9\u91CC\u5C06\u7531\u5E73\u53F0\u6309 CMS \u8BE6\u60C5\u5185\u5BB9\u6E32\u67D3\u5BCC\u6587\u672C\u6B63\u6587\u3002</p></div>'," </article>",' <section class="rounded-[24px] border border-stone-300 bg-white px-6 py-6 shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <div class="mb-3 w-fit rounded-full bg-teal-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-teal-700">RELATED</div>',' <h2 class="m-0 text-2xl font-extrabold tracking-tight text-slate-900">\u63A8\u8350\u9605\u8BFB</h2>',' <p class="mb-5 mt-3 text-base leading-7 text-slate-600">\u8BE6\u60C5\u9875\u53EF\u4EE5\u540C\u65F6\u6302\u63A5\u5185\u5BB9\u8BE6\u60C5\u548C\u63A8\u8350\u5217\u8868\uFF0C\u4E0D\u9700\u8981\u5355\u72EC\u8D77\u5E94\u7528\u8FD0\u884C\u65F6\u3002</p>',' <div data-render-list="related-articles" class="grid grid-cols-[repeat(auto-fit,minmax(220px,1fr))] gap-4">',' <article data-render-template="related-card" class="grid min-h-full gap-2.5 rounded-[18px] border border-slate-200 bg-slate-50 p-[18px]">',' <h3 data-field="title" class="m-0 text-xl font-bold leading-[1.35] text-slate-900">\u63A8\u8350\u5185\u5BB9\u6807\u9898</h3>',' <p data-field="summary" class="m-0 text-sm leading-7 text-slate-600">\u63A8\u8350\u5185\u5BB9\u6458\u8981</p>',' <a data-field="link" class="inline-flex w-fit items-center gap-2 text-sm font-bold text-teal-700" href="#">\u7EE7\u7EED\u9605\u8BFB</a>'," </article>"," </div>"," </section>",' <section class="rounded-[24px] border border-stone-300 bg-white px-6 py-6 shadow-[0_10px_24px_rgba(15,23,42,0.05)]">',' <div class="mb-3 w-fit rounded-full bg-fuchsia-100 px-3 py-1 text-xs font-bold tracking-[0.12em] text-fuchsia-700">REACT ISLAND</div>',' <h2 class="m-0 text-2xl font-extrabold tracking-tight text-slate-900">\u6D3B\u52A8\u62A5\u540D\u8868\u5355</h2>',' <p class="mb-5 mt-3 text-base leading-7 text-slate-600">\u6B63\u6587\u548C\u63A8\u8350\u5185\u5BB9\u4ECD\u7531 HTML + CMS \u6E32\u67D3\uFF0C\u4E0B\u9762\u7684\u5B8C\u6574\u8868\u5355\u5219\u5728\u9875\u9762\u52A0\u8F7D\u540E\u7531\u5F53\u524D app bundle \u6302\u8F7D\uFF0C\u590D\u7528\u5DF2\u6709 shadcn/Data Form \u7EC4\u4EF6\u4F53\u7CFB\u3002</p>',' <div data-platform-react-island="event-signup-form"></div>'," </section>"," </main>",' <div data-shell-slot="footer"></div>',' <header data-shell-template="site-header" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-b border-slate-900/8 py-5">',' <strong class="text-[15px] font-bold text-slate-900">Page Render Sample</strong>',' <nav class="flex flex-wrap gap-3 [&>a]:inline-flex [&>a]:min-h-9 [&>a]:items-center [&>a]:rounded-full [&>a]:border [&>a]:border-slate-900/10 [&>a]:bg-white/80 [&>a]:px-3.5 [&>a]:text-sm [&>a]:font-semibold [&>a]:text-slate-900">',' <a href="./app">App Home</a>',' <a href="./articles">Articles</a>',' <a href="./cms">CMS Page</a>'," </nav>"," </header>",' <footer data-shell-template="site-footer" class="mx-auto flex w-[min(1120px,calc(100%-32px))] items-center justify-between gap-4 border-t border-slate-900/8 py-5 text-sm text-slate-600">',' <span class="text-slate-600">Detail template with progressive enhancement assets</span>',' <span class="text-slate-600">Rendered on demand from CMS delivery data</span>'," </footer>"," </body>","</html>",""].join(`
2195
2195
  `)}function buildPageRenderPostBuildScriptSource(){return['import { cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";','import { join, relative, resolve } from "node:path";',"","const appRoot = process.cwd();",'const sourceDir = resolve(appRoot, "page-render");','const registryPath = resolve(sourceDir, "registry.json");','const distDir = resolve(appRoot, "dist");','const distPageRenderDir = resolve(distDir, "page-render");',"","async function main() {"," if (!(await pathExists(registryPath))) {",' process.stdout.write("[page-render-postbuild] skipped: page-render/registry.json not found\\n");'," return;"," }"," if (!(await pathExists(distDir))) {",' throw new Error("dist directory not found; run vite build before page-render postbuild");'," }",""," await validateJsonFile(registryPath);"," const assetsManifest = await collectAssetsManifest(distDir);",""," await rm(distPageRenderDir, { recursive: true, force: true });"," await mkdir(distPageRenderDir, { recursive: true });"," await cp(sourceDir, distPageRenderDir, { recursive: true });"," await writeFile(",' join(distPageRenderDir, "assets-manifest.json"),',' JSON.stringify(assetsManifest, null, 2) + "\\n",',' "utf8"'," );","",' process.stdout.write("[page-render-postbuild] emitted dist/page-render assets manifest\\n");',"}","","async function collectAssetsManifest(distRoot) {",' const viteManifestPath = join(distRoot, ".vite", "manifest.json");',' const fallbackEntryHtmlPath = join(distRoot, "index.html");'," const css = [];"," const js = [];"," if (await pathExists(viteManifestPath)) {"," const manifest = await readJsonFile(viteManifestPath);"," const entryAssets = collectEntryAssetsFromViteManifest(manifest);"," css.push(...entryAssets.css);"," js.push(...entryAssets.js);"," } else if (await pathExists(fallbackEntryHtmlPath)) {"," const fallbackAssets = await collectAssetsFromHtmlEntry(fallbackEntryHtmlPath);"," css.push(...fallbackAssets.css);"," js.push(...fallbackAssets.js);"," }"," return {"," version: 1,",' mode: "progressive-enhancement",'," css: uniqueStable(css),"," js: uniqueStable(js)"," };","}","","function collectEntryAssetsFromViteManifest(manifest) {",' const entryKey = typeof manifest["index.html"] === "object" && manifest["index.html"] ? "index.html" : findFirstManifestEntryKey(manifest);'," if (!entryKey) {"," return { css: [], js: [] };"," }"," const css = [];"," const js = [];"," const visited = new Set();"," walkManifestEntry(manifest, entryKey, visited, { css, js }, true);"," return { css, js };","}","","function findFirstManifestEntryKey(manifest) {"," for (const [key, value] of Object.entries(manifest)) {",' if (value && typeof value === "object" && value.isEntry && typeof value.file === "string") {'," return key;"," }"," }"," return undefined;","}","","function walkManifestEntry(manifest, entryKey, visited, assets, includeJs) {"," if (visited.has(entryKey)) {"," return;"," }"," visited.add(entryKey);"," const entry = manifest[entryKey];",' if (!entry || typeof entry !== "object") {'," return;"," }",' if (includeJs && typeof entry.file === "string" && entry.file.endsWith(".js")) {'," assets.js.push(stripLeadingSlash(entry.file));"," }"," if (Array.isArray(entry.css)) {"," for (const cssFile of entry.css) {",' if (typeof cssFile === "string" && cssFile.endsWith(".css")) {'," assets.css.push(stripLeadingSlash(cssFile));"," }"," }"," }"," if (Array.isArray(entry.imports)) {"," for (const importKey of entry.imports) {",' if (typeof importKey === "string") {'," walkManifestEntry(manifest, importKey, visited, assets, false);"," }"," }"," }","}","","async function collectAssetsFromHtmlEntry(entryHtmlPath) {",' const html = await readFile(entryHtmlPath, "utf8");',` const css = Array.from(html.matchAll(/<link[^>]+rel=["']stylesheet["'][^>]+href=["']([^"']+)["']/gu)).map((match) => stripLeadingSlash(resolveAssetPath(match[1]))).filter(Boolean);`,` const js = Array.from(html.matchAll(/<script[^>]+type=["']module["'][^>]+src=["']([^"']+)["'][^>]*><\\/script>/gu)).map((match) => stripLeadingSlash(resolveAssetPath(match[1]))).filter(Boolean);`," return { css, js };","}","","function resolveAssetPath(value) {",' if (typeof value !== "string") {',' return "";'," }"," const trimmed = value.trim();",' if (!trimmed || /^https?:\\/\\//.test(trimmed) || trimmed.startsWith("data:")) {',' return "";'," }",' return trimmed.replace(/^\\.\\//, "");',"}","","function stripLeadingSlash(value) {",' return String(value).replace(/^\\/+/, "");',"}","","function uniqueStable(values) {"," const seen = new Set();"," return values.filter((value) => {"," if (!value || seen.has(value)) {"," return false;"," }"," seen.add(value);"," return true;"," });","}","","async function readJsonFile(filePath) {",' const raw = await readFile(filePath, "utf8");'," try {"," return JSON.parse(raw);"," } catch (error) {"," throw new Error(`invalid json file: ${relative(appRoot, filePath)} ${error instanceof Error ? error.message : String(error)}`);"," }","}","","async function validateJsonFile(filePath) {",' const raw = await readFile(filePath, "utf8");'," try {"," JSON.parse(raw);"," } catch (error) {"," throw new Error("," `invalid page-render json: ${relative(appRoot, filePath)} ${error instanceof Error ? error.message : String(error)}`"," );"," }","}","","async function pathExists(targetPath) {"," const target = await stat(targetPath).catch(() => null);"," return Boolean(target);","}","","main().catch((error) => {"," const message = error instanceof Error ? error.stack || error.message : String(error);"," process.stderr.write(`${message}\\n`);"," process.exit(1);","});",""].join(`
2196
- `)}function buildFrontendAppViteTemplateFiles(){let templatePackageName=DEFAULT_TEMPLATE_PACKAGE_NAME;return[{path:"app.yaml",content:buildAppYamlSource2(templatePackageName)},{path:"package.json",content:buildPackageJsonSource2(templatePackageName)},{path:"package-lock.json",content:buildPackageLockSource2(templatePackageName)},{path:"pnpm-workspace.yaml",content:buildPnpmWorkspaceSource()},{path:"README.md",content:buildReadmeSource2()},{path:".env.example",content:buildEnvExampleSource2(templatePackageName)},{path:"scripts/page-render-postbuild.mjs",content:buildPageRenderPostBuildScriptSource()},{path:"tsconfig.json",content:buildTsconfigSource2()},{path:"vite.config.ts",content:buildViteConfigSource2()},{path:"index.html",content:buildIndexHtmlSource2()},{path:"page-render/README.md",content:buildPageRenderReadmeSource()},{path:"page-render/registry.json",content:buildPageRenderRegistrySource()},{path:"page-render/registry.json.example",content:buildPageRenderRegistryExampleSource()},{path:"page-render/pages/article-list.page-render.json",content:buildPageRenderListConfigSource()},{path:"page-render/pages/article-list.page-render.json.example",content:buildPageRenderListExampleSource()},{path:"page-render/pages/article-detail.page-render.json",content:buildPageRenderDetailConfigSource()},{path:"page-render/pages/article-detail.page-render.json.example",content:buildPageRenderDetailExampleSource()},{path:"page-render/shells/default.shell.json",content:buildPageRenderShellSource()},{path:"page-render/shells/default.shell.json.example",content:buildPageRenderShellExampleSource()},{path:"public/site/article-list.html",content:buildPageRenderArticleListTemplateSource()},{path:"public/site/article-detail.html",content:buildPageRenderArticleDetailTemplateSource()},{path:"public/shared/shells/.gitkeep",content:""},{path:"public/shared/styles/.gitkeep",content:""},{path:"public/shared/scripts/.gitkeep",content:""},{path:"src/main.tsx",content:buildMainSource()},{path:"src/page-render/react-islands.tsx",content:buildReactIslandsSource()},...buildWebSharedPageFiles("src",{buildRouterAppSource,buildHomePageSource:()=>buildFrontendShowcaseHomePageSource(),buildFormPageSource,buildEventSignupFormSource,buildProtectedPageSource,buildCmsPageSource}),{path:"public/auth/index.html",content:buildAuthIndexHtmlSource()},{path:"public/__app/auth-ui.config.json",content:buildAuthUiConfigJsonSource()},{path:"public/__app/auth-ui.override.css",content:buildGeneratedAppAuthUiOverrideCssModuleSource()},{path:"src/styles/index.css",content:buildStylesSource()},{path:"src/styles/cms-content.css",content:buildCmsContentStylesSource()},{path:"src/vite-env.d.ts",content:buildViteEnvSource()},...buildWebSharedDataFormUiFiles("src"),{path:"resources/data-forms/README.md",content:buildDataFormsReadmeSource2()},{path:"resources/data-forms/0001_event_signup.yaml.example",content:buildDataFormExampleSource2()},...buildWebSharedPlatformFiles("src",{buildPlatformConfigSource,buildPlatformClientSource,buildPlatformErrorsSource,buildCapabilitiesIndexSource,buildCapabilitySource})]}function assembleFrontendAppViteTemplate(){let files=buildFrontendAppViteTemplateFiles(),manifest=buildPlatformBlocksManifestFromTemplateFiles("frontend-app-vite",files);return[...files,{path:".platform/platform-blocks.lock.json",content:stringifyPlatformBlocksLockfile(buildPlatformBlocksLockfile(manifest))}]}function getPlatformBlocksManifest(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return buildPlatformBlocksManifestFromTemplateFiles(templateKey,files)}import{mkdtempSync,readFileSync as readFileSync4,writeFileSync}from"node:fs";import{basename,extname,join,resolve as resolve2}from"node:path";import{tmpdir}from"node:os";import{spawn as nodeSpawn}from"node:child_process";import{readdir,readFile}from"node:fs/promises";import path from"node:path";import crossSpawn from"cross-spawn";import{zipSync}from"fflate";function spawnCrossPlatform(command,args,options={}){return crossSpawn(command,[...args],{...options,shell:!1})}async function terminateProcessTree(pid,options={}){if((options.platform??process.platform)==="win32"){let spawnImpl=options.spawnImpl??nodeSpawn;await new Promise((resolve17,reject)=>{let child;try{child=spawnImpl("taskkill.exe",["/PID",String(pid),"/T","/F"],{shell:!1,stdio:"ignore",windowsHide:!0})}catch(error){reject(error instanceof Error?error:new Error(String(error)));return}child.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.once("exit",(code2,signal)=>{if(signal){reject(new Error(`taskkill.exe was terminated by ${signal}`));return}if(code2!==0){reject(new Error(`taskkill.exe exited with status ${code2??"unknown"}`));return}resolve17()})});return}let killImpl=options.killImpl??process.kill.bind(process);try{killImpl(-pid,"SIGTERM")}catch(error){if(error.code==="ESRCH")return;throw error}}async function openExternal(target,options={}){let normalizedTarget=target.trim();if(!normalizedTarget)return{opened:!1,error:"Cannot open an empty target."};let platform=options.platform??process.platform,spawnImpl=options.spawnImpl??nodeSpawn,launcher=platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",normalizedTarget]}:platform==="darwin"?{command:"open",args:[normalizedTarget]}:{command:"xdg-open",args:[normalizedTarget]};return await new Promise(resolve17=>{let child;try{child=spawnImpl(launcher.command,launcher.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(error){resolve17({opened:!1,error:toErrorMessage(error)});return}child.once("error",error=>{resolve17({opened:!1,error:toErrorMessage(error)})}),child.once("spawn",()=>{child.unref(),resolve17({opened:!0})})})}async function createZipBuffer(directory){let archive=Object.create(null);return await addDirectoryToArchive(path.resolve(directory),"",archive),zipSync(archive,{level:6})}async function addDirectoryToArchive(directory,relativeDirectory,archive){let entries=await readdir(directory,{withFileTypes:!0});entries.sort((left,right)=>compareCodeUnits(left.name,right.name));for(let entry of entries){let absolutePath=path.join(directory,entry.name),relativePath=relativeDirectory?`${relativeDirectory}/${entry.name}`:entry.name;if(entry.isDirectory()){await addDirectoryToArchive(absolutePath,relativePath,archive);continue}if(entry.isSymbolicLink())throw new Error(`Cannot add symbolic link to portable ZIP archive: ${relativePath}`);if(!entry.isFile())throw new Error(`Cannot add unsupported filesystem entry to ZIP archive: ${relativePath}`);if(relativePath==="__proto__")throw new Error("Cannot add reserved root ZIP entry name: __proto__");archive[relativePath]=[await readFile(absolutePath),{mtime:new Date(1980,0,1,0,0,0)}]}}function compareCodeUnits(left,right){return left<right?-1:left>right?1:0}function toErrorMessage(error){return error instanceof Error?error.message:String(error)}async function runAssetCommand(args,deps){if(hasHelpFlag(args)||args.rest.length===0){printAssetHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runAssetUpload(args,deps);return}if(subcommand==="list"){await runAssetList(args,deps);return}if(subcommand==="folder"){await runAssetFolder(args,deps);return}if(subcommand==="get"){await runAssetGet(args,deps);return}if(subcommand==="move"){await runAssetMove(args,deps);return}if(subcommand==="update"){await runAssetUpdate(args,deps);return}if(subcommand==="analyze"){await runAssetAnalyze(args,deps);return}if(subcommand==="open"){await runAssetOpen(args,deps);return}if(subcommand==="download"){await runAssetDownload(args,deps);return}if(subcommand==="tag"){await runAssetTag(args,deps);return}throw new Error("`platform asset` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`move`\u3001`update`\u3001`analyze`\u3001`open`\u3001`download`\u3001`folder`\u3001`tag`\u3002")}function printAssetHelp(){process.stdout.write(["platform asset <command>","","Commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>] [--json]"," platform asset list [--q <keyword>] [--media-type image|video] [--mime-type <mime>] [--folder-id <folder-id>] [--tag-ids <id,id>] [--has-ocr true|false] [--has-person true|false] [--is-svg true|false] [--scene <scene>] [--objects <name,name>] [--safety-flags <flag,flag>] [--orientation landscape|portrait|square] [--page <n>] [--limit <n>] [--json]"," platform asset folder list [--json]"," platform asset folder create <name> [--parent-folder-id <folder-id>] [--json]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id>] [--root] [--json]"," platform asset get <asset-id> [--json]"," platform asset move <asset-id> [--folder-id <folder-id> | --root] [--json]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--summary <text>] [--caption <text>] [--scene <scene>] [--objects <name,name>] [--ocr <text>] [--colors <hex,hex>] [--safety-flags <flag,flag>] [--tags <label,label>] [--json]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>] [--json]"," platform asset tag add <asset-id> <label> [--json]"," platform asset tag remove <asset-id> <label> [--json]","","Notes:"," - \u7B2C\u4E00\u9636\u6BB5\u4EE5 tenant/workspace \u4E3A\u4E3B\uFF0C\u4E0D\u8981\u6C42 app/consumer \u4E0A\u4E0B\u6587"," - `list` \u652F\u6301\u7CBE\u786E\u68C0\u7D22 + \u7ED3\u6784\u5316\u8FC7\u6EE4\uFF1B\u4E0D\u5355\u72EC\u63D0\u4F9B `search` \u5B50\u547D\u4EE4"," - `update` \u4E00\u6B21\u547D\u4EE4\u53EF patch \u591A\u4E2A\u5143\u6570\u636E\u5B57\u6BB5\uFF1B\u4E0D\u66FF\u6362\u539F\u59CB\u6587\u4EF6"," - `analyze` \u4E0D\u8C03\u7528\u89C6\u89C9\u6A21\u578B\u3001\u4E0D\u4E0A\u4F20\u56FE\u7247\uFF1B\u4EC5\u6839\u636E\u5143\u6570\u636E\u7ED9\u51FA\u300C\u4E0B\u8F7D\u54EA\u4E00\u7248 + \u5982\u4F55 update\u300D\u7684\u5EFA\u8BAE\uFF1B`--json` \u8F93\u51FA\u540C\u4E0A\u7ED3\u6784\u4FBF\u4E8E\u811A\u672C\u89E3\u6790"," - `analyze` \u53EF\u7528\u4E8E\u7ED9\u4EBA\u5DE5\u6216\u52A9\u624B\u751F\u6210\u5206\u6790\u64CD\u4F5C\u63D0\u793A\uFF0C\u4E0D\u76F4\u63A5\u8BFB\u53D6\u50CF\u7D20\u5185\u5BB9"," - `open` \u4F1A\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6\uFF1B\u672A\u6307\u5B9A `--output` \u65F6\u4F1A\u5199\u5165\u4E34\u65F6\u76EE\u5F55\u5E76\u5C1D\u8BD5\u6253\u5F00"," - `download --variant` \u7528\u4E8E\u660E\u786E\u4E0B\u8F7D\u6307\u5B9A\u53D8\u4F53\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6253\u5F00",""].join(`
2196
+ `)}function buildFrontendAppViteTemplateFiles(){let templatePackageName=DEFAULT_TEMPLATE_PACKAGE_NAME;return[{path:"app.yaml",content:buildAppYamlSource2(templatePackageName)},{path:"package.json",content:buildPackageJsonSource2(templatePackageName)},{path:"package-lock.json",content:buildPackageLockSource2(templatePackageName)},{path:"pnpm-workspace.yaml",content:buildPnpmWorkspaceSource()},{path:"README.md",content:buildReadmeSource2()},{path:".env.example",content:buildEnvExampleSource2(templatePackageName)},{path:"scripts/page-render-postbuild.mjs",content:buildPageRenderPostBuildScriptSource()},{path:"tsconfig.json",content:buildTsconfigSource2()},{path:"vite.config.ts",content:buildViteConfigSource2()},{path:"index.html",content:buildIndexHtmlSource2()},{path:"page-render/README.md",content:buildPageRenderReadmeSource()},{path:"page-render/registry.json",content:buildPageRenderRegistrySource()},{path:"page-render/registry.json.example",content:buildPageRenderRegistryExampleSource()},{path:"page-render/pages/article-list.page-render.json",content:buildPageRenderListConfigSource()},{path:"page-render/pages/article-list.page-render.json.example",content:buildPageRenderListExampleSource()},{path:"page-render/pages/article-detail.page-render.json",content:buildPageRenderDetailConfigSource()},{path:"page-render/pages/article-detail.page-render.json.example",content:buildPageRenderDetailExampleSource()},{path:"page-render/shells/default.shell.json",content:buildPageRenderShellSource()},{path:"page-render/shells/default.shell.json.example",content:buildPageRenderShellExampleSource()},{path:"public/site/article-list.html",content:buildPageRenderArticleListTemplateSource()},{path:"public/site/article-detail.html",content:buildPageRenderArticleDetailTemplateSource()},{path:"public/shared/shells/.gitkeep",content:""},{path:"public/shared/styles/.gitkeep",content:""},{path:"public/shared/scripts/.gitkeep",content:""},{path:"src/main.tsx",content:buildMainSource()},{path:"src/page-render/react-islands.tsx",content:buildReactIslandsSource()},...buildWebSharedPageFiles("src",{buildRouterAppSource,buildHomePageSource:()=>buildFrontendShowcaseHomePageSource(),buildFormPageSource,buildEventSignupFormSource,buildProtectedPageSource,buildCmsPageSource}),{path:"public/auth/index.html",content:buildAuthIndexHtmlSource()},{path:"public/__app/auth-ui.config.json",content:buildAuthUiConfigJsonSource()},{path:"public/__app/auth-ui.override.css",content:buildGeneratedAppAuthUiOverrideCssModuleSource()},{path:"src/styles/index.css",content:buildStylesSource()},{path:"src/styles/cms-content.css",content:buildCmsContentStylesSource()},{path:"src/vite-env.d.ts",content:buildViteEnvSource()},...buildWebSharedDataFormUiFiles("src"),{path:"resources/data-forms/README.md",content:buildDataFormsReadmeSource2()},{path:"resources/data-forms/0001_event_signup.yaml.example",content:buildDataFormExampleSource2()},...buildWebSharedPlatformFiles("src",{buildPlatformConfigSource,buildPlatformClientSource,buildPlatformErrorsSource,buildCapabilitiesIndexSource,buildCapabilitySource})]}function assembleFrontendAppViteTemplate(){let files=buildFrontendAppViteTemplateFiles(),manifest=buildPlatformBlocksManifestFromTemplateFiles("frontend-app-vite",files);return[...files,{path:".platform/platform-blocks.lock.json",content:stringifyPlatformBlocksLockfile(buildPlatformBlocksLockfile(manifest))}]}function getPlatformBlocksManifest(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return buildPlatformBlocksManifestFromTemplateFiles(templateKey,files)}import{mkdtempSync,writeFileSync}from"node:fs";import{basename as basename2,extname as extname2,join,resolve as resolve3}from"node:path";import{tmpdir}from"node:os";import{readFileSync as readFileSync4}from"node:fs";import{basename,extname,resolve as resolve2}from"node:path";function inferAssetMimeType(fileName){switch(extname(fileName).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";default:throw new Error(`\u5F53\u524D\u4EC5\u652F\u6301\u5E38\u89C1\u56FE\u7247\u4E0E\u89C6\u9891\u6269\u5C55\u540D\uFF0C\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u7C7B\u578B: ${fileName}`)}}async function uploadTenantAssetBinary(sdk,input){let filePath=resolve2(input.filePath),fileName=basename(filePath);return sdk.createTenantAssetBinary({fileName,mimeType:inferAssetMimeType(fileName),content:new Uint8Array(readFileSync4(filePath)),...input.title?.trim()?{title:input.title.trim()}:{},...input.folderId?.trim()?{folderId:input.folderId.trim()}:{}})}import{spawn as nodeSpawn}from"node:child_process";import{readdir,readFile}from"node:fs/promises";import path from"node:path";import crossSpawn from"cross-spawn";import{zipSync}from"fflate";function spawnCrossPlatform(command,args,options={}){return crossSpawn(command,[...args],{...options,shell:!1})}async function terminateProcessTree(pid,options={}){if((options.platform??process.platform)==="win32"){let spawnImpl=options.spawnImpl??nodeSpawn;await new Promise((resolve19,reject)=>{let child;try{child=spawnImpl("taskkill.exe",["/PID",String(pid),"/T","/F"],{shell:!1,stdio:"ignore",windowsHide:!0})}catch(error){reject(error instanceof Error?error:new Error(String(error)));return}child.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.once("exit",(code2,signal)=>{if(signal){reject(new Error(`taskkill.exe was terminated by ${signal}`));return}if(code2!==0){reject(new Error(`taskkill.exe exited with status ${code2??"unknown"}`));return}resolve19()})});return}let killImpl=options.killImpl??process.kill.bind(process);try{killImpl(-pid,"SIGTERM")}catch(error){if(error.code==="ESRCH")return;throw error}}async function openExternal(target,options={}){let normalizedTarget=target.trim();if(!normalizedTarget)return{opened:!1,error:"Cannot open an empty target."};let platform=options.platform??process.platform,spawnImpl=options.spawnImpl??nodeSpawn,launcher=platform==="win32"?{command:"rundll32.exe",args:["url.dll,FileProtocolHandler",normalizedTarget]}:platform==="darwin"?{command:"open",args:[normalizedTarget]}:{command:"xdg-open",args:[normalizedTarget]};return await new Promise(resolve19=>{let child;try{child=spawnImpl(launcher.command,launcher.args,{detached:!0,stdio:"ignore",windowsHide:!0})}catch(error){resolve19({opened:!1,error:toErrorMessage(error)});return}child.once("error",error=>{resolve19({opened:!1,error:toErrorMessage(error)})}),child.once("spawn",()=>{child.unref(),resolve19({opened:!0})})})}async function createZipBuffer(directory){let archive=Object.create(null);return await addDirectoryToArchive(path.resolve(directory),"",archive),zipSync(archive,{level:6})}async function addDirectoryToArchive(directory,relativeDirectory,archive){let entries=await readdir(directory,{withFileTypes:!0});entries.sort((left,right)=>compareCodeUnits(left.name,right.name));for(let entry of entries){let absolutePath=path.join(directory,entry.name),relativePath=relativeDirectory?`${relativeDirectory}/${entry.name}`:entry.name;if(entry.isDirectory()){await addDirectoryToArchive(absolutePath,relativePath,archive);continue}if(entry.isSymbolicLink())throw new Error(`Cannot add symbolic link to portable ZIP archive: ${relativePath}`);if(!entry.isFile())throw new Error(`Cannot add unsupported filesystem entry to ZIP archive: ${relativePath}`);if(relativePath==="__proto__")throw new Error("Cannot add reserved root ZIP entry name: __proto__");archive[relativePath]=[await readFile(absolutePath),{mtime:new Date(1980,0,1,0,0,0)}]}}function compareCodeUnits(left,right){return left<right?-1:left>right?1:0}function toErrorMessage(error){return error instanceof Error?error.message:String(error)}async function runAssetCommand(args,deps){if(hasHelpFlag(args)||args.rest.length===0){printAssetHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runAssetUpload(args,deps);return}if(subcommand==="list"){await runAssetList(args,deps);return}if(subcommand==="folder"){await runAssetFolder(args,deps);return}if(subcommand==="get"){await runAssetGet(args,deps);return}if(subcommand==="move"){await runAssetMove(args,deps);return}if(subcommand==="update"){await runAssetUpdate(args,deps);return}if(subcommand==="analyze"){await runAssetAnalyze(args,deps);return}if(subcommand==="open"){await runAssetOpen(args,deps);return}if(subcommand==="download"){await runAssetDownload(args,deps);return}if(subcommand==="tag"){await runAssetTag(args,deps);return}throw new Error("`platform asset` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`move`\u3001`update`\u3001`analyze`\u3001`open`\u3001`download`\u3001`folder`\u3001`tag`\u3002")}function printAssetHelp(){process.stdout.write(["platform asset <command>","","Commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>] [--json]"," platform asset list [--q <keyword>] [--media-type image|video] [--mime-type <mime>] [--folder-id <folder-id>] [--tag-ids <id,id>] [--has-ocr true|false] [--has-person true|false] [--is-svg true|false] [--scene <scene>] [--objects <name,name>] [--safety-flags <flag,flag>] [--orientation landscape|portrait|square] [--page <n>] [--limit <n>] [--json]"," platform asset folder list [--json]"," platform asset folder create <name> [--parent-folder-id <folder-id>] [--json]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id>] [--root] [--json]"," platform asset get <asset-id> [--json]"," platform asset move <asset-id> [--folder-id <folder-id> | --root] [--json]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--summary <text>] [--caption <text>] [--scene <scene>] [--objects <name,name>] [--ocr <text>] [--colors <hex,hex>] [--safety-flags <flag,flag>] [--tags <label,label>] [--json]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>] [--json]"," platform asset tag add <asset-id> <label> [--json]"," platform asset tag remove <asset-id> <label> [--json]","","Notes:"," - \u7B2C\u4E00\u9636\u6BB5\u4EE5 tenant/workspace \u4E3A\u4E3B\uFF0C\u4E0D\u8981\u6C42 app/consumer \u4E0A\u4E0B\u6587"," - `list` \u652F\u6301\u7CBE\u786E\u68C0\u7D22 + \u7ED3\u6784\u5316\u8FC7\u6EE4\uFF1B\u4E0D\u5355\u72EC\u63D0\u4F9B `search` \u5B50\u547D\u4EE4"," - `update` \u4E00\u6B21\u547D\u4EE4\u53EF patch \u591A\u4E2A\u5143\u6570\u636E\u5B57\u6BB5\uFF1B\u4E0D\u66FF\u6362\u539F\u59CB\u6587\u4EF6"," - `analyze` \u4E0D\u8C03\u7528\u89C6\u89C9\u6A21\u578B\u3001\u4E0D\u4E0A\u4F20\u56FE\u7247\uFF1B\u4EC5\u6839\u636E\u5143\u6570\u636E\u7ED9\u51FA\u300C\u4E0B\u8F7D\u54EA\u4E00\u7248 + \u5982\u4F55 update\u300D\u7684\u5EFA\u8BAE\uFF1B`--json` \u8F93\u51FA\u540C\u4E0A\u7ED3\u6784\u4FBF\u4E8E\u811A\u672C\u89E3\u6790"," - `analyze` \u53EF\u7528\u4E8E\u7ED9\u4EBA\u5DE5\u6216\u52A9\u624B\u751F\u6210\u5206\u6790\u64CD\u4F5C\u63D0\u793A\uFF0C\u4E0D\u76F4\u63A5\u8BFB\u53D6\u50CF\u7D20\u5185\u5BB9"," - `open` \u4F1A\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6\uFF1B\u672A\u6307\u5B9A `--output` \u65F6\u4F1A\u5199\u5165\u4E34\u65F6\u76EE\u5F55\u5E76\u5C1D\u8BD5\u6253\u5F00"," - `download --variant` \u7528\u4E8E\u660E\u786E\u4E0B\u8F7D\u6307\u5B9A\u53D8\u4F53\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u6253\u5F00",""].join(`
2197
2197
  `))}async function runAssetList(args,deps){let response=await deps.sdk.listTenantAssets({...readStringOption(args,"q")?{q:readStringOption(args,"q")}:{},...readMediaTypeOption(args)?{media_type:readMediaTypeOption(args)}:{},...readStringOption(args,"mime-type")?{mime_type:readStringOption(args,"mime-type")}:{},...readStringOption(args,"folder-id")?{folder_id:readStringOption(args,"folder-id")}:{},...readCsvOption(args,"tag-ids").length>0?{tag_ids:readCsvOption(args,"tag-ids")}:{},...readBooleanOption(args,"has-ocr")!==void 0?{has_ocr:readBooleanOption(args,"has-ocr")}:{},...readBooleanOption(args,"has-person")!==void 0?{has_person:readBooleanOption(args,"has-person")}:{},...readBooleanOption(args,"is-svg")!==void 0?{is_svg:readBooleanOption(args,"is-svg")}:{},...readStringOption(args,"scene")?{scene:readStringOption(args,"scene")}:{},...readCsvOption(args,"objects").length>0?{objects:readCsvOption(args,"objects")}:{},...readCsvOption(args,"safety-flags").length>0?{safety_flags:readCsvOption(args,"safety-flags")}:{},...readOrientationOption(args)?{orientation:readOrientationOption(args)}:{},...readNumberOption(args,"page")!==void 0?{page:readNumberOption(args,"page")}:{},...readNumberOption(args,"limit")!==void 0?{limit:readNumberOption(args,"limit")}:{}}).catch(error=>{throw formatAssetError(error,"list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2198
2198
  `);return}process.stdout.write([`tenant/workspace: ${response.tenant_id}/${response.workspace_id}`,`assets: ${response.items.length}`,`page: ${response.page}/${Math.max(1,Math.ceil(response.total/Math.max(1,response.page_size)))}`,`page_size: ${response.page_size}`,`total: ${response.total}`,...response.items.map(item=>[item.asset.asset_id,item.asset.title,`mime=${item.asset.mime_type}`,`folder=${item.folder?.path??"/"}`,item.tags.length>0?`tags=${item.tags.map(tag=>tag.label).join(",")}`:"tags=-"].join(" ")),""].join(`
2199
2199
  `))}async function runAssetFolder(args,deps){let action=args.rest[1];if(action==="list"){let response=await deps.sdk.listTenantAssetFolders().catch(error=>{throw formatAssetError(error,"folder list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
@@ -2203,7 +2203,7 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2203
2203
  `);return}process.stdout.write(["\u7D20\u6750\u76EE\u5F55\u5DF2\u66F4\u65B0\u3002",`tenant: ${deps.tenantId}`,`folders: ${response.items.length}`,""].join(`
2204
2204
  `));return}if(action==="rename"){let folderId=args.rest[2],name=readStringOption(args,"name");if(!folderId||!name?.trim())throw new Error("`platform asset folder rename` \u9700\u8981 <folder-id> \u548C `--name <name>`\u3002");let parentFolderId=args.options.root===!0?null:readStringOption(args,"parent-folder-id"),response=await deps.sdk.updateTenantAssetFolderMetadata(folderId,{name:name.trim(),...args.options.root===!0||parentFolderId?{parent_folder_id:parentFolderId??null}:{}}).catch(error=>{throw formatAssetError(error,"folder rename")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2205
2205
  `);return}process.stdout.write(["\u7D20\u6750\u76EE\u5F55\u5DF2\u66F4\u65B0\u3002",`tenant: ${deps.tenantId}`,`folders: ${response.items.length}`,""].join(`
2206
- `));return}throw new Error("`platform asset folder` \u4EC5\u652F\u6301 `list`\u3001`create <name>`\u3001`rename <folder-id>`\u3002")}async function runAssetUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform asset upload` \u9700\u8981 <file-path>\u3002");let filePath=resolve2(filePathArg),fileName=basename(filePath),mimeType=inferMimeType(fileName),response=await deps.sdk.createTenantAssetBinary({fileName,mimeType,content:new Uint8Array(readFileSync4(filePath)),...readStringOption(args,"title")?{title:readStringOption(args,"title")}:{},...readStringOption(args,"folder-id")?{folderId:readStringOption(args,"folder-id")}:{}}).catch(error=>{throw formatAssetError(error,"upload")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2206
+ `));return}throw new Error("`platform asset folder` \u4EC5\u652F\u6301 `list`\u3001`create <name>`\u3001`rename <folder-id>`\u3002")}async function runAssetUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform asset upload` \u9700\u8981 <file-path>\u3002");let response=await uploadTenantAssetBinary(deps.sdk,{filePath:filePathArg,...readStringOption(args,"title")?{title:readStringOption(args,"title")}:{},...readStringOption(args,"folder-id")?{folderId:readStringOption(args,"folder-id")}:{}}).catch(error=>{throw formatAssetError(error,"upload")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2207
2207
  `);return}process.stdout.write(["\u7D20\u6750\u5DF2\u4E0A\u4F20\u3002",`tenant: ${deps.tenantId}`,`asset: ${response.asset.asset_id}`,`title: ${response.asset.title}`,`mime: ${response.asset.mime_type}`,`file: ${response.original_file.file_name}`,`size: ${response.original_file.size_bytes} bytes`,`original_url: ${response.original_url}`,...formatVariantLines(response.variant_urls),""].join(`
2208
2208
  `))}async function runAssetGet(args,deps){let assetId=args.rest[1]??readStringOption(args,"asset");if(!assetId)throw new Error("`platform asset get` \u9700\u8981 <asset-id>\u3002");let response=await deps.sdk.getTenantAsset(assetId).catch(error=>{throw formatAssetError(error,"get")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2209
2209
  `);return}process.stdout.write([`asset: ${response.asset.asset_id}`,`tenant/workspace: ${response.tenant_id}/${response.workspace_id}`,`title: ${response.asset.title}`,`media_type: ${response.asset.media_type}`,`mime_type: ${response.asset.mime_type}`,`status: ${response.asset.status}`,`folder: ${response.folder?.path??"/"}`,`original_file: ${response.original_file.file_name}`,`size: ${response.original_file.size_bytes} bytes`,`original_url: ${response.original_url}`,`variants: ${response.variants.length}`,...formatVariantLines(response.variant_urls),`tags: ${response.tags.length>0?response.tags.map(item=>item.label).join(", "):"-"}`,`ai_summary: ${response.ai_card.ai_summary??"-"}`,""].join(`
@@ -2220,13 +2220,13 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2220
2220
  `)+`
2221
2221
  `);return}if(action==="add"||action==="remove"){let assetId=args.rest[2],label=args.rest[3];if(!assetId||!label)throw new Error(`\`platform asset tag ${action}\` \u9700\u8981 <asset-id> <label>\u3002`);let response=action==="add"?await deps.sdk.addTenantAssetTag(assetId,{label}).catch(error=>{throw formatAssetError(error,"tag add")}):await deps.sdk.removeTenantAssetTag(assetId,label).catch(error=>{throw formatAssetError(error,"tag remove")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2222
2222
  `);return}process.stdout.write([action==="add"?"\u7D20\u6750\u6807\u7B7E\u5DF2\u6DFB\u52A0\u3002":"\u7D20\u6750\u6807\u7B7E\u5DF2\u79FB\u9664\u3002",`asset: ${response.asset.asset_id}`,`tags: ${response.tags.length>0?response.tags.map(item=>item.label).join(", "):"-"}`,""].join(`
2223
- `));return}throw new Error("`platform asset tag` \u4EC5\u652F\u6301 `list`\u3001`add <asset-id> <label>`\u3001`remove <asset-id> <label>`\u3002")}function readStringOption(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasOption(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function readCsvOption(args,key){return(readStringOption(args,key)??"").split(",").map(item=>item.trim()).filter(Boolean)}function readBooleanOption(args,key){let value=readStringOption(args,key);if(value!==void 0){if(value==="true")return!0;if(value==="false")return!1;throw new Error(`\`--${key}\` \u4EC5\u652F\u6301 true \u6216 false\u3002`)}}function readNumberOption(args,key){let value=readStringOption(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed))throw new Error(`\`--${key}\` \u9700\u8981\u6570\u5B57\u3002`);return Math.trunc(parsed)}function readMediaTypeOption(args){let value=readStringOption(args,"media-type");if(value){if(value==="image"||value==="video")return value;throw new Error("`--media-type` \u4EC5\u652F\u6301 image \u6216 video\u3002")}}function readOrientationOption(args){let value=readStringOption(args,"orientation");if(value){if(value==="landscape"||value==="portrait"||value==="square")return value;throw new Error("`--orientation` \u4EC5\u652F\u6301 landscape\u3001portrait\u3001square\u3002")}}function readVariantKindOption(args){let value=readStringOption(args,"variant");if(value){if(value==="thumbnail"||value==="sm"||value==="md"||value==="lg"||value==="cover")return value;throw new Error("`--variant` \u4EC5\u652F\u6301 thumbnail\u3001sm\u3001md\u3001lg\u3001cover\u3002")}}function pickRecommendedAnalysisSource(detail){let mdUrl=detail.variant_urls.md;if(mdUrl)return{kind:"md",url:mdUrl};let smUrl=detail.variant_urls.sm;if(smUrl)return{kind:"sm",url:smUrl};let thumbnailUrl=detail.variant_urls.thumbnail;return thumbnailUrl?{kind:"thumbnail",url:thumbnailUrl}:{kind:"original",url:detail.original_url}}function hasHelpFlag(args){return args.options.help===!0||args.options.h===!0}function inferMimeType(fileName){switch(extname(fileName).toLowerCase()){case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".webp":return"image/webp";case".gif":return"image/gif";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";default:throw new Error(`\u5F53\u524D\u4EC5\u652F\u6301\u5E38\u89C1\u56FE\u7247\u4E0E\u89C6\u9891\u6269\u5C55\u540D\uFF0C\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u7C7B\u578B: ${fileName}`)}}function formatVariantLines(variantUrls){let lines=Object.entries(variantUrls).filter(entry=>typeof entry[1]=="string"&&entry[1].length>0).map(([kind,url])=>`variant.${kind}: ${url}`);return lines.length>0?lines:["variant: -"]}function normalizeNullableCliText(value){let normalized=value?.trim()??"";return normalized||null}function buildAnalyzeUpdateTemplate(assetId){return[`platform asset update ${assetId} \\`,' --summary "..." \\',' --caption "..." \\',' --scene "..." \\',' --objects "..." \\',' --tags "..."'].join(`
2224
- `)}function flattenShellContinuation(template){return template.replace(/\s*\\\s*\n\s*/g," ").replace(/\s{2,}/g," ").trim()}function buildVariantFileName(originalFileName,variants,variantKind){let variant=variants.find(item=>item.variant_kind===variantKind),extension=variant?inferExtensionFromMimeType(variant.mime_type):extname(originalFileName)||".bin";return`${basename(originalFileName,extname(originalFileName))}.${variantKind}${extension}`}function inferExtensionFromMimeType(mimeType){switch(mimeType){case"image/jpeg":return".jpg";case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"video/mp4":return".mp4";case"video/webm":return".webm";default:return".bin"}}function resolveOutputPath(explicitOutputPath,fileName){if(explicitOutputPath)return resolve2(explicitOutputPath);let directory=mkdtempSync(join(tmpdir(),"platform-asset-"));return join(directory,fileName)}function formatAssetError(error,action){return error instanceof PlatformApiError?new Error([`\u7D20\u6750 ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
2223
+ `));return}throw new Error("`platform asset tag` \u4EC5\u652F\u6301 `list`\u3001`add <asset-id> <label>`\u3001`remove <asset-id> <label>`\u3002")}function readStringOption(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasOption(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function readCsvOption(args,key){return(readStringOption(args,key)??"").split(",").map(item=>item.trim()).filter(Boolean)}function readBooleanOption(args,key){let value=readStringOption(args,key);if(value!==void 0){if(value==="true")return!0;if(value==="false")return!1;throw new Error(`\`--${key}\` \u4EC5\u652F\u6301 true \u6216 false\u3002`)}}function readNumberOption(args,key){let value=readStringOption(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed))throw new Error(`\`--${key}\` \u9700\u8981\u6570\u5B57\u3002`);return Math.trunc(parsed)}function readMediaTypeOption(args){let value=readStringOption(args,"media-type");if(value){if(value==="image"||value==="video")return value;throw new Error("`--media-type` \u4EC5\u652F\u6301 image \u6216 video\u3002")}}function readOrientationOption(args){let value=readStringOption(args,"orientation");if(value){if(value==="landscape"||value==="portrait"||value==="square")return value;throw new Error("`--orientation` \u4EC5\u652F\u6301 landscape\u3001portrait\u3001square\u3002")}}function readVariantKindOption(args){let value=readStringOption(args,"variant");if(value){if(value==="thumbnail"||value==="sm"||value==="md"||value==="lg"||value==="cover")return value;throw new Error("`--variant` \u4EC5\u652F\u6301 thumbnail\u3001sm\u3001md\u3001lg\u3001cover\u3002")}}function pickRecommendedAnalysisSource(detail){let mdUrl=detail.variant_urls.md;if(mdUrl)return{kind:"md",url:mdUrl};let smUrl=detail.variant_urls.sm;if(smUrl)return{kind:"sm",url:smUrl};let thumbnailUrl=detail.variant_urls.thumbnail;return thumbnailUrl?{kind:"thumbnail",url:thumbnailUrl}:{kind:"original",url:detail.original_url}}function hasHelpFlag(args){return args.options.help===!0||args.options.h===!0}function formatVariantLines(variantUrls){let lines=Object.entries(variantUrls).filter(entry=>typeof entry[1]=="string"&&entry[1].length>0).map(([kind,url])=>`variant.${kind}: ${url}`);return lines.length>0?lines:["variant: -"]}function normalizeNullableCliText(value){let normalized=value?.trim()??"";return normalized||null}function buildAnalyzeUpdateTemplate(assetId){return[`platform asset update ${assetId} \\`,' --summary "..." \\',' --caption "..." \\',' --scene "..." \\',' --objects "..." \\',' --tags "..."'].join(`
2224
+ `)}function flattenShellContinuation(template){return template.replace(/\s*\\\s*\n\s*/g," ").replace(/\s{2,}/g," ").trim()}function buildVariantFileName(originalFileName,variants,variantKind){let variant=variants.find(item=>item.variant_kind===variantKind),extension=variant?inferExtensionFromMimeType(variant.mime_type):extname2(originalFileName)||".bin";return`${basename2(originalFileName,extname2(originalFileName))}.${variantKind}${extension}`}function inferExtensionFromMimeType(mimeType){switch(mimeType){case"image/jpeg":return".jpg";case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"video/mp4":return".mp4";case"video/webm":return".webm";default:return".bin"}}function resolveOutputPath(explicitOutputPath,fileName){if(explicitOutputPath)return resolve3(explicitOutputPath);let directory=mkdtempSync(join(tmpdir(),"platform-asset-"));return join(directory,fileName)}function formatAssetError(error,action){return error instanceof PlatformApiError?new Error([`\u7D20\u6750 ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
2225
2225
  `)):error instanceof Error?error:new Error(`\u7D20\u6750 ${action} \u5931\u8D25\u3002`)}function formatAppCreateCheckoutError(input){let causeMessage=input.cause instanceof Error?input.cause.message:String(input.cause),retryCommand=["platform app checkout","--tenant",quoteCliArgument(input.tenantId),"--app",quoteCliArgument(input.appId),...input.targetDir?["--dir",quoteCliArgument(input.targetDir)]:[]].join(" ");return new Error(["\u4E91\u7AEF\u5E94\u7528\u5DF2\u7ECF\u521B\u5EFA\uFF0C\u4F46\u672C\u5730 checkout \u5931\u8D25\uFF1B\u4E91\u7AEF\u5E94\u7528\u672A\u56DE\u6EDA\u3002",`tenant_id: ${input.tenantId}`,`app_id: ${input.appId}`,`\u672C\u5730\u9519\u8BEF: ${causeMessage}`,"\u53EF\u4FEE\u590D\u672C\u5730\u76EE\u5F55\u95EE\u9898\u540E\u91CD\u8BD5\uFF1A",` ${retryCommand}`].join(`
2226
- `))}function quoteCliArgument(value){return/^[A-Za-z0-9._:/-]+$/u.test(value)?value:JSON.stringify(value)}import{existsSync as existsSync9,mkdirSync as mkdirSync4,readdirSync as readdirSync3,readFileSync as readFileSync9,writeFileSync as writeFileSync5}from"node:fs";import{dirname as dirname6,join as join5,resolve as resolve6}from"node:path";import YAML2 from"yaml";import{createServer}from"node:http";import{createHash as createHash3,randomBytes}from"node:crypto";import{chmodSync,existsSync as existsSync7,mkdirSync as mkdirSync2,readFileSync as readFileSync7,writeFileSync as writeFileSync3}from"node:fs";import{existsSync as existsSync6,mkdirSync,writeFileSync as writeFileSync2}from"node:fs";import{homedir}from"node:os";import{dirname as dirname4,join as join3,resolve as resolve4}from"node:path";import{fileURLToPath as fileURLToPath4}from"node:url";import{existsSync as existsSync4,readFileSync as readFileSync5}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var AUTH_CLI_CLIENT_ID_KEYS=["AUTH_CLI_CLIENT_ID","LOGTO_CLI_APP_ID"],AUTH_CLI_REDIRECT_URI_KEYS=["AUTH_CLI_REDIRECT_URI","LOGTO_CLI_REDIRECT_URI"],AUTH_TENANT_CLIENT_ID_KEYS=["AUTH_TENANT_CLIENT_ID","LOGTO_TENANT_APP_ID","LOGTO_APP_ID"],AUTH_TENANT_REDIRECT_URI_KEYS=["AUTH_TENANT_REDIRECT_URI","LOGTO_TENANT_REDIRECT_URI"];function readTrimmedConfigValue(source,key){let value=source?.[key]?.trim();if(!(!value||/^<.+>$/.test(value)))return value}function readAuthConfigValue(keys,env=process.env){for(let key of keys){let fromEnv=readTrimmedConfigValue(env,key);if(fromEnv)return fromEnv}let defaults=getDistributionProfile().defaults??{};for(let key of keys){let fromDefaults=readTrimmedConfigValue(defaults,key);if(fromDefaults)return fromDefaults}}var defaultDeveloperProfile={name:"developer",defaults:{CONTROL_API_BASE_URL:"http://localhost:7001",PUBLIC_API_BASE_URL:"http://localhost:7007",RUNTIME_API_BASE_URL:"http://127.0.0.1.nip.io",OIDC_ISSUER:"http://localhost:3001/oidc",OIDC_AUDIENCE:"platform",LOGTO_CLI_REDIRECT_URI:"http://localhost:7300/callback",LOGTO_TENANT_REDIRECT_URI:"http://localhost:7102/callback"}},cachedProfile=null;function getDistributionProfile(){if(cachedProfile)return cachedProfile;let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return cachedProfile=defaultDeveloperProfile,cachedProfile;try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return cachedProfile=normalizeDistributionProfile(packageJson.platformDistributionProfile),cachedProfile}catch{return cachedProfile=defaultDeveloperProfile,cachedProfile}}function applyDistributionProfileDefaults(env=process.env){let profile=getDistributionProfile();for(let[key,value]of Object.entries(profile.defaults??{}))typeof value!="string"||value.trim().length===0||typeof env[key]=="string"&&env[key].trim().length>0||(env[key]=value);return profile}function getCliPackageVersion(){let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return"0.0.0";try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return typeof packageJson.version=="string"&&packageJson.version.trim().length>0?packageJson.version.trim():"0.0.0"}catch{return"0.0.0"}}function normalizeDistributionProfile(input){if(!input||input.name!=="developer"&&input.name!=="test-only"&&input.name!=="sandbox"&&input.name!=="nonprod"&&input.name!=="prod")return defaultDeveloperProfile;let defaults=input.name==="developer"?{...defaultDeveloperProfile.defaults}:{};for(let[key,value]of Object.entries(input.defaults??{}))typeof value=="string"&&value.trim().length>0&&(defaults[key]=value.trim());return{name:input.name,defaults}}function resolvePackageJsonPath(){let distDir=dirname2(fileURLToPath2(import.meta.url)),candidates=[join2(distDir,"..","package.json"),join2(distDir,"..","..","package.json")];for(let candidate of candidates)if(existsSync4(candidate))return candidate;return null}import{existsSync as existsSync5,readFileSync as readFileSync6,statSync as statSync2}from"node:fs";import{dirname as dirname3,resolve as resolve3}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function stripQuotes(value){return value.startsWith('"')&&value.endsWith('"')||value.startsWith("'")&&value.endsWith("'")?value.slice(1,-1):value}function hasWorkspaceMarker(directory){return existsSync5(resolve3(directory,"pnpm-workspace.yaml"))}function getInvocationCwd(){let candidates=[process.env.PLATFORM_INVOCATION_CWD,process.env.INIT_CWD,process.env.PWD,process.cwd()];for(let candidate of candidates){if(!candidate||candidate.trim().length===0)continue;let resolved=resolve3(candidate);if(existsSync5(resolved))try{if(statSync2(resolved).isDirectory())return resolved}catch{continue}}return resolve3(process.cwd())}function tryFindWorkspaceRoot(startDir=getInvocationCwd()){let current=resolve3(startDir);for(;;){if(hasWorkspaceMarker(current))return current;let parent=dirname3(current);if(parent===current)return null;current=parent}}function findWorkspaceRoot(startDir=getInvocationCwd()){return tryFindWorkspaceRoot(startDir)??resolve3(startDir)}function loadDotenvFiles(startDir=getInvocationCwd()){let workspaceRoot=findWorkspaceRoot(startDir),appRoot=resolve3(startDir),cliModuleRoot=resolve3(dirname3(fileURLToPath3(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot),developerLocalEnvFile=getDistributionProfile().name==="developer"?resolve3(process.env.PLATFORM_LOCAL_CLI_ENV_FILE?.trim()||resolve3(workspaceRoot,"TMP","local-cli.env")):null,candidates=[resolve3(workspaceRoot,".env"),resolve3(workspaceRoot,".env.local"),...developerLocalEnvFile?[developerLocalEnvFile]:[],resolve3(appRoot,".env"),resolve3(appRoot,".env.local"),resolve3(cliWorkspaceRoot,".env"),resolve3(cliWorkspaceRoot,".env.local"),resolve3(cliModuleRoot,".env"),resolve3(cliModuleRoot,".env.local")],visited=new Set;for(let filePath of candidates){if(visited.has(filePath)||(visited.add(filePath),!existsSync5(filePath)))continue;let lines=readFileSync6(filePath,"utf8").split(/\r?\n/u);for(let line of lines){let trimmed=line.trim();if(trimmed.length===0||trimmed.startsWith("#"))continue;let separatorIndex=trimmed.indexOf("=");if(separatorIndex<=0)continue;let key=trimmed.slice(0,separatorIndex).trim(),value=stripQuotes(trimmed.slice(separatorIndex+1).trim());process.env[key]||(process.env[key]=value)}}}var DEFAULT_STATE_DIR_NAME=".platform",LOCAL_DEVELOPER_STATE_DIR=join3("TMP","local-cli-state"),WORKSPACE_FALLBACK_STATE_DIR=join3("TMP","local-cli-state-fallback"),WORKSPACE_FALLBACK_MARKER=".state-fallback-active",activeFallbackStateDir=null,emittedFallbackWarnings=new Set,CliStateAccessError=class extends Error{operation;path;cause;constructor(operation,path2,cause){super([`\u65E0\u6CD5${operation} CLI \u672C\u5730\u72B6\u6001\u6587\u4EF6\uFF1A${path2}`,"\u8FD9\u901A\u5E38\u662F\u56E0\u4E3A\u5F53\u524D HOME / PLATFORM_STATE_DIR \u5BF9\u5E94\u76EE\u5F55\u4E0D\u53EF\u5199\uFF0C\u6216\u8FD0\u884C\u5728\u53D7\u9650\u6C99\u7BB1\u73AF\u5883\u4E2D\u3002","\u53EF\u5C1D\u8BD5\uFF1A","1. \u91CD\u65B0\u6267\u884C\u5E76\u786E\u8BA4\u5F53\u524D\u8D26\u53F7\u5BF9\u8BE5\u76EE\u5F55\u6709\u5199\u6743\u9650","2. \u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR` \u6307\u5411\u4E00\u4E2A\u53EF\u5199\u76EE\u5F55","3. \u82E5\u5728\u9694\u79BB\u73AF\u5883\u4E2D\u8FD0\u884C\uFF0C\u53EF\u4E3A\u8BE5\u73AF\u5883\u5355\u72EC\u914D\u7F6E `HOME` \u6216 `PLATFORM_STATE_DIR`"].join(`
2227
- `)),this.operation=operation,this.path=path2,this.cause=cause,this.name="CliStateAccessError"}};function resolveDeveloperStateDir(){let cliModuleRoot=resolve4(dirname4(fileURLToPath4(import.meta.url)),".."),workspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve4(workspaceRoot,LOCAL_DEVELOPER_STATE_DIR)}function resolveWorkspaceFallbackStateDir(startDir=getInvocationCwd()){let workspaceRoot=tryFindWorkspaceRoot(startDir);return workspaceRoot?resolve4(workspaceRoot,WORKSPACE_FALLBACK_STATE_DIR):null}function resolveCliStateLocation(options={}){let configured=options.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim()??"";if(configured)return{dir:resolve4(configured),source:"configured"};if(activeFallbackStateDir)return{dir:activeFallbackStateDir,source:"workspace-fallback"};if((options.distributionProfileName??getDistributionProfile().name)==="developer")return{dir:resolveDeveloperStateDir(),source:"developer"};let fallbackDir=resolveWorkspaceFallbackStateDir(options.startDir);return fallbackDir&&existsSync6(resolve4(fallbackDir,WORKSPACE_FALLBACK_MARKER))?{dir:fallbackDir,source:"workspace-fallback"}:{dir:join3(options.homeDir??homedir(),DEFAULT_STATE_DIR_NAME),source:"home"}}function isCliStateAccessFailure(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"&&["EACCES","EPERM","EROFS"].includes(error.code??"")}function activateWorkspaceFallback(startDir=getInvocationCwd()){let fallbackDir=resolveWorkspaceFallbackStateDir(startDir);return fallbackDir?(mkdirSync(fallbackDir,{recursive:!0}),writeFileSync2(resolve4(fallbackDir,WORKSPACE_FALLBACK_MARKER),`active
2226
+ `))}function quoteCliArgument(value){return/^[A-Za-z0-9._:/-]+$/u.test(value)?value:JSON.stringify(value)}import{existsSync as existsSync9,mkdirSync as mkdirSync4,readdirSync as readdirSync3,readFileSync as readFileSync9,writeFileSync as writeFileSync5}from"node:fs";import{dirname as dirname6,join as join5,resolve as resolve7}from"node:path";import YAML2 from"yaml";import{createServer}from"node:http";import{createHash as createHash3,randomBytes}from"node:crypto";import{chmodSync,existsSync as existsSync7,mkdirSync as mkdirSync2,readFileSync as readFileSync7,writeFileSync as writeFileSync3}from"node:fs";import{existsSync as existsSync6,mkdirSync,writeFileSync as writeFileSync2}from"node:fs";import{homedir}from"node:os";import{dirname as dirname4,join as join3,resolve as resolve5}from"node:path";import{fileURLToPath as fileURLToPath4}from"node:url";import{existsSync as existsSync4,readFileSync as readFileSync5}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";import{fileURLToPath as fileURLToPath2}from"node:url";var AUTH_CLI_CLIENT_ID_KEYS=["AUTH_CLI_CLIENT_ID","LOGTO_CLI_APP_ID"],AUTH_CLI_REDIRECT_URI_KEYS=["AUTH_CLI_REDIRECT_URI","LOGTO_CLI_REDIRECT_URI"],AUTH_TENANT_CLIENT_ID_KEYS=["AUTH_TENANT_CLIENT_ID","LOGTO_TENANT_APP_ID","LOGTO_APP_ID"],AUTH_TENANT_REDIRECT_URI_KEYS=["AUTH_TENANT_REDIRECT_URI","LOGTO_TENANT_REDIRECT_URI"];function readTrimmedConfigValue(source,key){let value=source?.[key]?.trim();if(!(!value||/^<.+>$/.test(value)))return value}function readAuthConfigValue(keys,env=process.env){for(let key of keys){let fromEnv=readTrimmedConfigValue(env,key);if(fromEnv)return fromEnv}let defaults=getDistributionProfile().defaults??{};for(let key of keys){let fromDefaults=readTrimmedConfigValue(defaults,key);if(fromDefaults)return fromDefaults}}var defaultDeveloperProfile={name:"developer",defaults:{CONTROL_API_BASE_URL:"http://localhost:7001",PUBLIC_API_BASE_URL:"http://localhost:7007",RUNTIME_API_BASE_URL:"http://127.0.0.1.nip.io",OIDC_ISSUER:"http://localhost:3001/oidc",OIDC_AUDIENCE:"platform",LOGTO_CLI_REDIRECT_URI:"http://localhost:7300/callback",LOGTO_TENANT_REDIRECT_URI:"http://localhost:7102/callback"}},cachedProfile=null;function getDistributionProfile(){if(cachedProfile)return cachedProfile;let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return cachedProfile=defaultDeveloperProfile,cachedProfile;try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return cachedProfile=normalizeDistributionProfile(packageJson.platformDistributionProfile),cachedProfile}catch{return cachedProfile=defaultDeveloperProfile,cachedProfile}}function applyDistributionProfileDefaults(env=process.env){let profile=getDistributionProfile();for(let[key,value]of Object.entries(profile.defaults??{}))typeof value!="string"||value.trim().length===0||typeof env[key]=="string"&&env[key].trim().length>0||(env[key]=value);return profile}function getCliPackageVersion(){let packageJsonPath=resolvePackageJsonPath();if(!packageJsonPath)return"0.0.0";try{let packageJson=JSON.parse(readFileSync5(packageJsonPath,"utf8"));return typeof packageJson.version=="string"&&packageJson.version.trim().length>0?packageJson.version.trim():"0.0.0"}catch{return"0.0.0"}}function normalizeDistributionProfile(input){if(!input||input.name!=="developer"&&input.name!=="test-only"&&input.name!=="sandbox"&&input.name!=="nonprod"&&input.name!=="prod")return defaultDeveloperProfile;let defaults=input.name==="developer"?{...defaultDeveloperProfile.defaults}:{};for(let[key,value]of Object.entries(input.defaults??{}))typeof value=="string"&&value.trim().length>0&&(defaults[key]=value.trim());return{name:input.name,defaults}}function resolvePackageJsonPath(){let distDir=dirname2(fileURLToPath2(import.meta.url)),candidates=[join2(distDir,"..","package.json"),join2(distDir,"..","..","package.json")];for(let candidate of candidates)if(existsSync4(candidate))return candidate;return null}import{existsSync as existsSync5,readFileSync as readFileSync6,statSync as statSync2}from"node:fs";import{dirname as dirname3,resolve as resolve4}from"node:path";import{fileURLToPath as fileURLToPath3}from"node:url";function stripQuotes(value){return value.startsWith('"')&&value.endsWith('"')||value.startsWith("'")&&value.endsWith("'")?value.slice(1,-1):value}function hasWorkspaceMarker(directory){return existsSync5(resolve4(directory,"pnpm-workspace.yaml"))}function getInvocationCwd(){let candidates=[process.env.PLATFORM_INVOCATION_CWD,process.env.INIT_CWD,process.env.PWD,process.cwd()];for(let candidate of candidates){if(!candidate||candidate.trim().length===0)continue;let resolved=resolve4(candidate);if(existsSync5(resolved))try{if(statSync2(resolved).isDirectory())return resolved}catch{continue}}return resolve4(process.cwd())}function tryFindWorkspaceRoot(startDir=getInvocationCwd()){let current=resolve4(startDir);for(;;){if(hasWorkspaceMarker(current))return current;let parent=dirname3(current);if(parent===current)return null;current=parent}}function findWorkspaceRoot(startDir=getInvocationCwd()){return tryFindWorkspaceRoot(startDir)??resolve4(startDir)}function loadDotenvFiles(startDir=getInvocationCwd()){let workspaceRoot=findWorkspaceRoot(startDir),appRoot=resolve4(startDir),cliModuleRoot=resolve4(dirname3(fileURLToPath3(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot),developerLocalEnvFile=getDistributionProfile().name==="developer"?resolve4(process.env.PLATFORM_LOCAL_CLI_ENV_FILE?.trim()||resolve4(workspaceRoot,"TMP","local-cli.env")):null,candidates=[resolve4(workspaceRoot,".env"),resolve4(workspaceRoot,".env.local"),...developerLocalEnvFile?[developerLocalEnvFile]:[],resolve4(appRoot,".env"),resolve4(appRoot,".env.local"),resolve4(cliWorkspaceRoot,".env"),resolve4(cliWorkspaceRoot,".env.local"),resolve4(cliModuleRoot,".env"),resolve4(cliModuleRoot,".env.local")],visited=new Set;for(let filePath of candidates){if(visited.has(filePath)||(visited.add(filePath),!existsSync5(filePath)))continue;let lines=readFileSync6(filePath,"utf8").split(/\r?\n/u);for(let line of lines){let trimmed=line.trim();if(trimmed.length===0||trimmed.startsWith("#"))continue;let separatorIndex=trimmed.indexOf("=");if(separatorIndex<=0)continue;let key=trimmed.slice(0,separatorIndex).trim(),value=stripQuotes(trimmed.slice(separatorIndex+1).trim());process.env[key]||(process.env[key]=value)}}}var DEFAULT_STATE_DIR_NAME=".platform",LOCAL_DEVELOPER_STATE_DIR=join3("TMP","local-cli-state"),WORKSPACE_FALLBACK_STATE_DIR=join3("TMP","local-cli-state-fallback"),WORKSPACE_FALLBACK_MARKER=".state-fallback-active",activeFallbackStateDir=null,emittedFallbackWarnings=new Set,CliStateAccessError=class extends Error{operation;path;cause;constructor(operation,path2,cause){super([`\u65E0\u6CD5${operation} CLI \u672C\u5730\u72B6\u6001\u6587\u4EF6\uFF1A${path2}`,"\u8FD9\u901A\u5E38\u662F\u56E0\u4E3A\u5F53\u524D HOME / PLATFORM_STATE_DIR \u5BF9\u5E94\u76EE\u5F55\u4E0D\u53EF\u5199\uFF0C\u6216\u8FD0\u884C\u5728\u53D7\u9650\u6C99\u7BB1\u73AF\u5883\u4E2D\u3002","\u53EF\u5C1D\u8BD5\uFF1A","1. \u91CD\u65B0\u6267\u884C\u5E76\u786E\u8BA4\u5F53\u524D\u8D26\u53F7\u5BF9\u8BE5\u76EE\u5F55\u6709\u5199\u6743\u9650","2. \u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR` \u6307\u5411\u4E00\u4E2A\u53EF\u5199\u76EE\u5F55","3. \u82E5\u5728\u9694\u79BB\u73AF\u5883\u4E2D\u8FD0\u884C\uFF0C\u53EF\u4E3A\u8BE5\u73AF\u5883\u5355\u72EC\u914D\u7F6E `HOME` \u6216 `PLATFORM_STATE_DIR`"].join(`
2227
+ `)),this.operation=operation,this.path=path2,this.cause=cause,this.name="CliStateAccessError"}};function resolveDeveloperStateDir(){let cliModuleRoot=resolve5(dirname4(fileURLToPath4(import.meta.url)),".."),workspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve5(workspaceRoot,LOCAL_DEVELOPER_STATE_DIR)}function resolveWorkspaceFallbackStateDir(startDir=getInvocationCwd()){let workspaceRoot=tryFindWorkspaceRoot(startDir);return workspaceRoot?resolve5(workspaceRoot,WORKSPACE_FALLBACK_STATE_DIR):null}function resolveCliStateLocation(options={}){let configured=options.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim()??"";if(configured)return{dir:resolve5(configured),source:"configured"};if(activeFallbackStateDir)return{dir:activeFallbackStateDir,source:"workspace-fallback"};if((options.distributionProfileName??getDistributionProfile().name)==="developer")return{dir:resolveDeveloperStateDir(),source:"developer"};let fallbackDir=resolveWorkspaceFallbackStateDir(options.startDir);return fallbackDir&&existsSync6(resolve5(fallbackDir,WORKSPACE_FALLBACK_MARKER))?{dir:fallbackDir,source:"workspace-fallback"}:{dir:join3(options.homeDir??homedir(),DEFAULT_STATE_DIR_NAME),source:"home"}}function isCliStateAccessFailure(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"&&["EACCES","EPERM","EROFS"].includes(error.code??"")}function activateWorkspaceFallback(startDir=getInvocationCwd()){let fallbackDir=resolveWorkspaceFallbackStateDir(startDir);return fallbackDir?(mkdirSync(fallbackDir,{recursive:!0}),writeFileSync2(resolve5(fallbackDir,WORKSPACE_FALLBACK_MARKER),`active
2228
2228
  `,"utf8"),activeFallbackStateDir=fallbackDir,fallbackDir):null}function emitFallbackWarning(originalPath,fallbackDir){emittedFallbackWarnings.has(fallbackDir)||(emittedFallbackWarnings.add(fallbackDir),console.warn([`\u68C0\u6D4B\u5230 CLI state \u9ED8\u8BA4\u76EE\u5F55\u4E0D\u53EF\u5199\uFF1A${originalPath}`,`\u5DF2\u81EA\u52A8\u5207\u6362\u5230\u4ED3\u5E93\u5185\u672C\u5730\u72B6\u6001\u76EE\u5F55\uFF1A${fallbackDir}`,"\u5982\u9700\u56FA\u5B9A\u8BE5\u884C\u4E3A\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_STATE_DIR`\u3002"].join(`
2229
- `)))}function withCliStateFileWriteFallback(args){let primary=resolveCliStateLocation(args.resolution),primaryPath=join3(primary.dir,args.fileName);try{return args.write({filePath:primaryPath,stateDir:primary.dir})}catch(error){if(!isCliStateAccessFailure(error))throw error;let configuredStateDir=args.resolution?.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim();if(primary.source!=="home"||configuredStateDir?.trim())throw new CliStateAccessError(args.operation,primaryPath,error);try{let fallbackDir=activateWorkspaceFallback(args.resolution?.startDir);if(!fallbackDir)throw new CliStateAccessError(args.operation,primaryPath,error);emitFallbackWarning(primaryPath,fallbackDir);let fallbackPath=join3(fallbackDir,args.fileName);try{return args.write({filePath:fallbackPath,stateDir:fallbackDir})}catch(fallbackError){throw isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,fallbackPath,fallbackError):fallbackError}}catch(fallbackError){throw fallbackError instanceof CliStateAccessError?fallbackError:isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,primaryPath,fallbackError):fallbackError}}}function resolveCliStateDir(options={}){return resolveCliStateLocation(options).dir}function resolveCliStateFilePath(fileName){return join3(resolveCliStateDir(),fileName)}var DEFAULT_CONTROL_API_BASE_URL="http://localhost:7001",DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES="end_user_auth,cms",runtimeEndpointCapabilities=["end_user_auth","workflow","end_user_notification"],publicEndpointCapabilities=["cms","asset_library"];function getControlApiBaseUrl(env=process.env){let configured=env.CONTROL_API_BASE_URL?.trim();if(configured&&configured.length>0)return configured;let profileDefault=getDistributionProfile().defaults?.CONTROL_API_BASE_URL?.trim();return profileDefault&&profileDefault.length>0?profileDefault:DEFAULT_CONTROL_API_BASE_URL}function resolveControlApiEndpoint(args={}){let env=args.env??process.env,controlApiBaseUrl=getControlApiBaseUrl(env),allowlist=readRuntimeEndpointCapabilityAllowlist(env);return(args.requestClass==="runtime"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl:args.requestClass==="public"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl:void 0)??controlApiBaseUrl}function listResolvedControlApiEndpoints(env=process.env){let controlApiBaseUrl=getControlApiBaseUrl(env),runtimeBaseUrl=readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl,publicBaseUrl=readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl,allowlist=parseRuntimeEndpointCapabilityAllowlist(readRuntimeEndpointCapabilityAllowlist(env)),runtimeCapabilities=filterAllowedEndpointCapabilities(runtimeEndpointCapabilities,allowlist),publicCapabilities=filterAllowedEndpointCapabilities(publicEndpointCapabilities,allowlist);return[{role:"control",baseUrl:controlApiBaseUrl,enabled:!0,capabilities:[],requestClass:"control"},{role:"runtime",baseUrl:runtimeBaseUrl,enabled:runtimeBaseUrl!=null&&runtimeCapabilities.length>0,capabilities:runtimeCapabilities,requestClass:"runtime",...runtimeBaseUrl==null?{reason:"not_configured"}:runtimeCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}},{role:"public",baseUrl:publicBaseUrl,enabled:publicBaseUrl!=null&&publicCapabilities.length>0,capabilities:publicCapabilities,requestClass:"public",...publicBaseUrl==null?{reason:"not_configured"}:publicCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}}]}function createControlApiSdk(args){return createPlatformSdk({baseUrl:args.baseUrl??resolveControlApiEndpoint({capability:args.capability,requestClass:args.requestClass}),getHeaders:()=>({Authorization:`Bearer ${args.accessToken}`,...args.tenantId?{"X-Tenant-Id":args.tenantId}:{},...Object.fromEntries(Object.entries(args.extraHeaders??{}).filter(([,value])=>value!=null))})})}function readOptionalBaseUrl(value){let trimmed=value?.trim();return trimmed&&trimmed.length>0?trimmed:void 0}function isRuntimeEndpointCapabilityEnabled(capability,rawAllowlist){if(!capability)return!1;let allowlist=parseRuntimeEndpointCapabilityAllowlist(rawAllowlist);return allowlist.has("*")||allowlist.has(capability)}function readRuntimeEndpointCapabilityAllowlist(env){return Object.prototype.hasOwnProperty.call(env,"CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES")?env.CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES:DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES}function parseRuntimeEndpointCapabilityAllowlist(value){return new Set((value??"").split(/[,\s]+/u).map(item=>item.trim()).filter(item=>item.length>0))}function filterAllowedEndpointCapabilities(capabilities,allowlist){return allowlist.has("*")?[...capabilities]:capabilities.filter(capability=>allowlist.has(capability))}var TOKEN_REFRESH_SKEW_MS=6e4,PAT_LOGIN_VALIDITY_MS=10080*60*1e3,CliSessionExpiredError=class extends Error{detail;constructor(detail){super(detail&&detail.trim().length>0?`CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF08${detail.trim()}\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C \`platform login\`\u3002`:"CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002"),this.detail=detail,this.name="CliSessionExpiredError"}};function sleep(ms){return new Promise(resolve17=>{setTimeout(resolve17,ms)})}function normalizeOidcGrantFailure(detail){let normalized=detail?.trim();return normalized&&(/(^|[\s:_-])(invalid_grant)([\s:_-]|$)/iu.test(normalized)||/grant request is invalid/iu.test(normalized))?normalized:null}function mapTokenFailureToAuthError(args){let detail=normalizeOidcGrantFailure(args.errorDescription)??normalizeOidcGrantFailure(args.error);return detail?new CliSessionExpiredError(detail):new Error(args.errorDescription??args.error??args.fallback)}function maybeWrapCredentialRefreshError(error){if(error instanceof CliSessionExpiredError)throw error;if(error instanceof Error){let detail=normalizeOidcGrantFailure(error.message);if(detail)throw new CliSessionExpiredError(detail)}throw error}function applyResource(params,audience){if(audience){if(/^[a-z][a-z0-9+.-]*:/iu.test(audience)){params.set("resource",audience);return}params.set("audience",audience)}}function normalizeAuthorizationPrompt(scopes,prompt){let normalized=(prompt??"").split(/\s+/u).map(item=>item.trim()).filter(Boolean);return scopes.includes("offline_access")&&!normalized.includes("consent")&&normalized.push("consent"),normalized.length>0?normalized.join(" "):void 0}function getLoginSuccessHtml(){return`<!DOCTYPE html>
2229
+ `)))}function withCliStateFileWriteFallback(args){let primary=resolveCliStateLocation(args.resolution),primaryPath=join3(primary.dir,args.fileName);try{return args.write({filePath:primaryPath,stateDir:primary.dir})}catch(error){if(!isCliStateAccessFailure(error))throw error;let configuredStateDir=args.resolution?.configuredStateDir??process.env.PLATFORM_STATE_DIR?.trim();if(primary.source!=="home"||configuredStateDir?.trim())throw new CliStateAccessError(args.operation,primaryPath,error);try{let fallbackDir=activateWorkspaceFallback(args.resolution?.startDir);if(!fallbackDir)throw new CliStateAccessError(args.operation,primaryPath,error);emitFallbackWarning(primaryPath,fallbackDir);let fallbackPath=join3(fallbackDir,args.fileName);try{return args.write({filePath:fallbackPath,stateDir:fallbackDir})}catch(fallbackError){throw isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,fallbackPath,fallbackError):fallbackError}}catch(fallbackError){throw fallbackError instanceof CliStateAccessError?fallbackError:isCliStateAccessFailure(fallbackError)?new CliStateAccessError(args.operation,primaryPath,fallbackError):fallbackError}}}function resolveCliStateDir(options={}){return resolveCliStateLocation(options).dir}function resolveCliStateFilePath(fileName){return join3(resolveCliStateDir(),fileName)}var DEFAULT_CONTROL_API_BASE_URL="http://localhost:7001",DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES="end_user_auth,cms",runtimeEndpointCapabilities=["end_user_auth","workflow","end_user_notification"],publicEndpointCapabilities=["cms","asset_library"];function getControlApiBaseUrl(env=process.env){let configured=env.CONTROL_API_BASE_URL?.trim();if(configured&&configured.length>0)return configured;let profileDefault=getDistributionProfile().defaults?.CONTROL_API_BASE_URL?.trim();return profileDefault&&profileDefault.length>0?profileDefault:DEFAULT_CONTROL_API_BASE_URL}function resolveControlApiEndpoint(args={}){let env=args.env??process.env,controlApiBaseUrl=getControlApiBaseUrl(env),allowlist=readRuntimeEndpointCapabilityAllowlist(env);return(args.requestClass==="runtime"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl:args.requestClass==="public"&&isRuntimeEndpointCapabilityEnabled(args.capability,allowlist)?readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl:void 0)??controlApiBaseUrl}function listResolvedControlApiEndpoints(env=process.env){let controlApiBaseUrl=getControlApiBaseUrl(env),runtimeBaseUrl=readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??controlApiBaseUrl,publicBaseUrl=readOptionalBaseUrl(env.PUBLIC_API_BASE_URL)??readOptionalBaseUrl(env.RUNTIME_API_BASE_URL)??controlApiBaseUrl,allowlist=parseRuntimeEndpointCapabilityAllowlist(readRuntimeEndpointCapabilityAllowlist(env)),runtimeCapabilities=filterAllowedEndpointCapabilities(runtimeEndpointCapabilities,allowlist),publicCapabilities=filterAllowedEndpointCapabilities(publicEndpointCapabilities,allowlist);return[{role:"control",baseUrl:controlApiBaseUrl,enabled:!0,capabilities:[],requestClass:"control"},{role:"runtime",baseUrl:runtimeBaseUrl,enabled:runtimeBaseUrl!=null&&runtimeCapabilities.length>0,capabilities:runtimeCapabilities,requestClass:"runtime",...runtimeBaseUrl==null?{reason:"not_configured"}:runtimeCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}},{role:"public",baseUrl:publicBaseUrl,enabled:publicBaseUrl!=null&&publicCapabilities.length>0,capabilities:publicCapabilities,requestClass:"public",...publicBaseUrl==null?{reason:"not_configured"}:publicCapabilities.length===0?{reason:"disabled_by_allowlist"}:{}}]}function createControlApiSdk(args){return createPlatformSdk({baseUrl:args.baseUrl??resolveControlApiEndpoint({capability:args.capability,requestClass:args.requestClass}),getHeaders:()=>({Authorization:`Bearer ${args.accessToken}`,...args.tenantId?{"X-Tenant-Id":args.tenantId}:{},...Object.fromEntries(Object.entries(args.extraHeaders??{}).filter(([,value])=>value!=null))})})}function readOptionalBaseUrl(value){let trimmed=value?.trim();return trimmed&&trimmed.length>0?trimmed:void 0}function isRuntimeEndpointCapabilityEnabled(capability,rawAllowlist){if(!capability)return!1;let allowlist=parseRuntimeEndpointCapabilityAllowlist(rawAllowlist);return allowlist.has("*")||allowlist.has(capability)}function readRuntimeEndpointCapabilityAllowlist(env){return Object.prototype.hasOwnProperty.call(env,"CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES")?env.CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES:DEFAULT_RUNTIME_ENDPOINT_CAPABILITIES}function parseRuntimeEndpointCapabilityAllowlist(value){return new Set((value??"").split(/[,\s]+/u).map(item=>item.trim()).filter(item=>item.length>0))}function filterAllowedEndpointCapabilities(capabilities,allowlist){return allowlist.has("*")?[...capabilities]:capabilities.filter(capability=>allowlist.has(capability))}var TOKEN_REFRESH_SKEW_MS=6e4,PAT_LOGIN_VALIDITY_MS=10080*60*1e3,CliSessionExpiredError=class extends Error{detail;constructor(detail){super(detail&&detail.trim().length>0?`CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF08${detail.trim()}\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C \`platform login\`\u3002`:"CLI \u4F1A\u8BDD\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002"),this.detail=detail,this.name="CliSessionExpiredError"}};function sleep(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}function normalizeOidcGrantFailure(detail){let normalized=detail?.trim();return normalized&&(/(^|[\s:_-])(invalid_grant)([\s:_-]|$)/iu.test(normalized)||/grant request is invalid/iu.test(normalized))?normalized:null}function mapTokenFailureToAuthError(args){let detail=normalizeOidcGrantFailure(args.errorDescription)??normalizeOidcGrantFailure(args.error);return detail?new CliSessionExpiredError(detail):new Error(args.errorDescription??args.error??args.fallback)}function maybeWrapCredentialRefreshError(error){if(error instanceof CliSessionExpiredError)throw error;if(error instanceof Error){let detail=normalizeOidcGrantFailure(error.message);if(detail)throw new CliSessionExpiredError(detail)}throw error}function applyResource(params,audience){if(audience){if(/^[a-z][a-z0-9+.-]*:/iu.test(audience)){params.set("resource",audience);return}params.set("audience",audience)}}function normalizeAuthorizationPrompt(scopes,prompt){let normalized=(prompt??"").split(/\s+/u).map(item=>item.trim()).filter(Boolean);return scopes.includes("offline_access")&&!normalized.includes("consent")&&normalized.push("consent"),normalized.length>0?normalized.join(" "):void 0}function getLoginSuccessHtml(){return`<!DOCTYPE html>
2230
2230
  <html lang="zh-CN">
2231
2231
  <head>
2232
2232
  <meta charset="utf-8" />
@@ -2362,10 +2362,10 @@ function inferUpstreamPath(pathname: string, routeBasePath: string): string {
2362
2362
  </body>
2363
2363
  </html>`}function escapeHtml(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function discoverOidcEndpoints(issuer){let discoveryUrl=`${issuer.endsWith("/")?issuer.slice(0,-1):issuer}/.well-known/openid-configuration`,response=await fetch(discoveryUrl);if(!response.ok)throw new Error(`\u83B7\u53D6 OIDC discovery \u5931\u8D25: ${response.status}`);let document=await response.json();if(!document.authorization_endpoint||!document.token_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11\u6388\u6743\u6216 token \u7AEF\u70B9");return{authorization_endpoint:document.authorization_endpoint,device_authorization_endpoint:document.device_authorization_endpoint,token_endpoint:document.token_endpoint}}function getCredentialPath(){return resolveCliStateFilePath("credentials.json")}function getCliContextPath(){return resolveCliStateFilePath("context.json")}function loadStoredCredentials(){let credentialsPath=getCredentialPath();return existsSync7(credentialsPath)?JSON.parse(readFileSync7(credentialsPath,"utf8")):null}function selectApiToken(credentials){return looksLikeJwt(credentials.access_token)?credentials.access_token:looksLikeJwt(credentials.id_token)?credentials.id_token:credentials.access_token}function loadStoredCliContext(){let cliContextPath=getCliContextPath();return existsSync7(cliContextPath)?JSON.parse(readFileSync7(cliContextPath,"utf8")):null}function persistCredentials(credentials){withCliStateFileWriteFallback({fileName:"credentials.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync2(stateDir,{recursive:!0}),writeFileSync3(filePath,`${JSON.stringify(credentials,null,2)}
2364
2364
  `,"utf8"),chmodSync(filePath,384)}})}function resolveStoredClientId(credentials){return credentials.client_id?.trim()||readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS)||readAuthConfigValue(AUTH_TENANT_CLIENT_ID_KEYS)}function readJwtExpiryMs(token){if(!looksLikeJwt(token))return null;try{let[,payload]=token.split("."),decoded=JSON.parse(Buffer.from(payload,"base64url").toString("utf8"));return typeof decoded.exp=="number"&&Number.isFinite(decoded.exp)?decoded.exp*1e3:null}catch{return null}}function isCredentialExpired(credentials,now=Date.now()){if(typeof credentials.expires_in=="number"&&Number.isFinite(credentials.expires_in)){let issuedAt=Date.parse(credentials.issued_at);if(Number.isFinite(issuedAt))return issuedAt+credentials.expires_in*1e3-TOKEN_REFRESH_SKEW_MS<=now}let jwtExpiry=readJwtExpiryMs(credentials.access_token)??readJwtExpiryMs(credentials.id_token);return typeof jwtExpiry=="number"?jwtExpiry-TOKEN_REFRESH_SKEW_MS<=now:!1}function canUsePatExchange(credentials,now=Date.now()){if(credentials.credential_mode!=="pat_exchange"||!credentials.exchange_subject_token||!credentials.exchange_subject_token_type||!resolveStoredClientId(credentials)||!credentials.mode_expires_at)return!1;let expiresAt=Date.parse(credentials.mode_expires_at);return Number.isFinite(expiresAt)&&expiresAt>now}async function refreshCredentials(credentials){let issuer=process.env.OIDC_ISSUER?.trim()||getDistributionProfile().defaults?.OIDC_ISSUER?.trim();if(!issuer)throw new Error("\u5F53\u524D\u73AF\u5883\u7F3A\u5C11 OIDC_ISSUER\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 CLI \u51ED\u636E\u3002");let clientId=resolveStoredClientId(credentials);if(!clientId)throw new Error("\u5F53\u524D\u51ED\u636E\u7F3A\u5C11 client_id\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 CLI \u51ED\u636E\u3002");if(!credentials.refresh_token)throw new Error("\u5F53\u524D\u51ED\u636E\u7F3A\u5C11 refresh_token\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`\u3002");let endpoints=await discoverOidcEndpoints(issuer),body=new URLSearchParams;body.set("grant_type","refresh_token"),body.set("client_id",clientId),body.set("refresh_token",credentials.refresh_token),applyResource(body,process.env.OIDC_AUDIENCE?.trim()||getDistributionProfile().defaults?.OIDC_AUDIENCE?.trim());let response=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),payload=await response.json();if(!response.ok)throw mapTokenFailureToAuthError({error:payload.error,errorDescription:payload.error_description,fallback:"\u5237\u65B0 CLI token \u5931\u8D25"});if(typeof payload.access_token!="string"||payload.access_token.length===0)throw new Error("\u5237\u65B0\u540E\u7684 token \u54CD\u5E94\u7F3A\u5C11 access_token");let nextCredentials={access_token:payload.access_token,id_token:typeof payload.id_token=="string"?payload.id_token:credentials.id_token,refresh_token:typeof payload.refresh_token=="string"?payload.refresh_token:credentials.refresh_token,client_id:clientId,token_type:payload.token_type??credentials.token_type,expires_in:typeof payload.expires_in=="number"?payload.expires_in:credentials.expires_in,scope:payload.scope??credentials.scope,issued_at:new Date().toISOString(),credential_mode:credentials.credential_mode??"interactive",exchange_subject_token:credentials.exchange_subject_token,exchange_subject_token_type:credentials.exchange_subject_token_type,mode_expires_at:credentials.mode_expires_at};return persistCredentials(nextCredentials),nextCredentials}async function exchangePatCredentials(credentials){let issuer=process.env.OIDC_ISSUER?.trim()||getDistributionProfile().defaults?.OIDC_ISSUER?.trim();if(!issuer)throw new Error("\u5F53\u524D\u73AF\u5883\u7F3A\u5C11 OIDC_ISSUER\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0 PAT \u51ED\u636E\u3002");let clientId=resolveStoredClientId(credentials);if(!clientId)throw new Error("\u5F53\u524D PAT \u51ED\u636E\u7F3A\u5C11 client_id\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5237\u65B0\u3002");if(!credentials.exchange_subject_token||!credentials.exchange_subject_token_type)throw new Error("\u5F53\u524D PAT \u51ED\u636E\u7F3A\u5C11 subject_token\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login --pat <token>`\u3002");if(credentials.mode_expires_at){let hardExpiry=Date.parse(credentials.mode_expires_at);if(Number.isFinite(hardExpiry)&&hardExpiry<=Date.now())throw new Error("\u5F53\u524D PAT \u767B\u5F55\u5DF2\u8D85\u8FC7 7 \u5929\u6709\u6548\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login --pat <token>`\u3002")}let endpoints=await discoverOidcEndpoints(issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",clientId),body.set("subject_token",credentials.exchange_subject_token),body.set("subject_token_type",credentials.exchange_subject_token_type),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),credentials.scope?.trim()&&body.set("scope",credentials.scope.trim()),applyResource(body,process.env.OIDC_AUDIENCE?.trim()||getDistributionProfile().defaults?.OIDC_AUDIENCE?.trim());let response=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),payload=await response.json();if(!response.ok)throw mapTokenFailureToAuthError({error:payload.error,errorDescription:payload.error_description,fallback:"PAT \u4EA4\u6362 access token \u5931\u8D25"});if(typeof payload.access_token!="string"||payload.access_token.length===0)throw new Error("PAT \u4EA4\u6362\u540E\u7684 token \u54CD\u5E94\u7F3A\u5C11 access_token");let nextCredentials={access_token:payload.access_token,id_token:typeof payload.id_token=="string"?payload.id_token:credentials.id_token,client_id:clientId,token_type:payload.token_type??credentials.token_type,expires_in:typeof payload.expires_in=="number"?payload.expires_in:credentials.expires_in,scope:payload.scope??credentials.scope,issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:credentials.exchange_subject_token,exchange_subject_token_type:credentials.exchange_subject_token_type,mode_expires_at:credentials.mode_expires_at};return persistCredentials(nextCredentials),nextCredentials}async function loadStoredCredentialsEnsuringFresh(options={}){let credentials=loadStoredCredentials();if(!credentials)return null;let expired=isCredentialExpired(credentials);if(!options.forceRefresh&&!expired)return credentials;if(credentials.refresh_token)try{return refreshCredentials(credentials)}catch(error){maybeWrapCredentialRefreshError(error)}if(canUsePatExchange(credentials))try{return exchangePatCredentials(credentials)}catch(error){maybeWrapCredentialRefreshError(error)}if(expired)throw new Error("\u5F53\u524D\u51ED\u636E\u5DF2\u8FC7\u671F\u4E14\u4E0D\u652F\u6301\u81EA\u52A8\u5237\u65B0\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login` \u6216 `platform login --pat <token>`\u3002");return credentials}function persistCliContext(context){withCliStateFileWriteFallback({fileName:"context.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync2(stateDir,{recursive:!0}),writeFileSync3(filePath,`${JSON.stringify({...context,updated_at:new Date().toISOString()},null,2)}
2365
- `,"utf8"),chmodSync(filePath,384)}})}async function performDeviceCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer);if(!endpoints.device_authorization_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9");let authBody=new URLSearchParams;authBody.set("client_id",config2.clientId),authBody.set("scope",config2.scopes.join(" ")),applyResource(authBody,config2.audience);let deviceResponse=await fetch(endpoints.device_authorization_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:authBody}),devicePayload=await deviceResponse.json();if(!deviceResponse.ok)throw new Error(devicePayload.error_description??devicePayload.error??"\u7533\u8BF7 device_code \u5931\u8D25");await config2.onPrompt?.({verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code,expiresIn:devicePayload.expires_in});let intervalSeconds=Math.max(devicePayload.interval??5,1),deadline=Date.now()+devicePayload.expires_in*1e3;for(;Date.now()<deadline;){await sleep(intervalSeconds*1e3);let tokenBody=new URLSearchParams;tokenBody.set("grant_type","urn:ietf:params:oauth:grant-type:device_code"),tokenBody.set("device_code",devicePayload.device_code),tokenBody.set("client_id",config2.clientId);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(tokenResponse.ok)return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code};if(tokenPayload.error!=="authorization_pending"){if(tokenPayload.error==="slow_down"){await sleep(intervalSeconds*1e3);continue}throw new Error(tokenPayload.error_description??tokenPayload.error??"\u8F6E\u8BE2 token \u5931\u8D25")}}throw new Error("Device Code \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`")}async function performAuthorizationCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),redirectUrl=new URL(config2.redirectUri);if(redirectUrl.protocol!=="http:")throw new Error("CLI \u6D4F\u89C8\u5668\u6388\u6743\u4EC5\u652F\u6301 http \u56DE\u8C03\u5730\u5740");let state=randomBytes(16).toString("base64url"),nonce=randomBytes(16).toString("base64url"),codeVerifier=randomBytes(32).toString("base64url"),codeChallenge=createHash3("sha256").update(codeVerifier).digest("base64url"),authorizationUrl=new URL(endpoints.authorization_endpoint);authorizationUrl.searchParams.set("client_id",config2.clientId),authorizationUrl.searchParams.set("redirect_uri",config2.redirectUri),authorizationUrl.searchParams.set("response_type","code"),authorizationUrl.searchParams.set("scope",config2.scopes.join(" ")),authorizationUrl.searchParams.set("state",state),authorizationUrl.searchParams.set("nonce",nonce),authorizationUrl.searchParams.set("code_challenge",codeChallenge),authorizationUrl.searchParams.set("code_challenge_method","S256");let normalizedPrompt=normalizeAuthorizationPrompt(config2.scopes,config2.prompt);normalizedPrompt&&authorizationUrl.searchParams.set("prompt",normalizedPrompt),applyResource(authorizationUrl.searchParams,config2.audience);let callbackResult=await new Promise((resolve17,reject)=>{let timeout=setTimeout(()=>{server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`"))},3e5),server=createServer((req,res)=>{let url=new URL(req.url??"/",config2.redirectUri);if(url.pathname!==redirectUrl.pathname){res.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Not Found");return}let returnedState=url.searchParams.get("state"),error=url.searchParams.get("error"),code2=url.searchParams.get("code");if(error){clearTimeout(timeout);let errMsg=url.searchParams.get("error_description")??error;res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml(errMsg)),server.close(()=>{}),reject(new Error(errMsg));return}if(!code2||returnedState!==state){clearTimeout(timeout),res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11\u6388\u6743\u7801\u6216 state \u4E0D\u5339\u914D\u3002")),server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11 code \u6216 state \u4E0D\u5339\u914D"));return}clearTimeout(timeout),res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginSuccessHtml()),server.close(()=>{}),resolve17({code:code2})});server.on("error",error=>{clearTimeout(timeout),reject(error)}),server.listen(Number(redirectUrl.port||80),redirectUrl.hostname,async()=>{try{await config2.onPrompt?.({authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri})}catch(error){clearTimeout(timeout),server.close(()=>{}),reject(error)}})}),tokenBody=new URLSearchParams;tokenBody.set("grant_type","authorization_code"),tokenBody.set("client_id",config2.clientId),tokenBody.set("code",callbackResult.code),tokenBody.set("redirect_uri",config2.redirectUri),tokenBody.set("code_verifier",codeVerifier),applyResource(tokenBody,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"\u6388\u6743\u7801\u6362\u53D6 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri}}async function performPatTokenExchangeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",config2.clientId),body.set("subject_token",config2.subjectToken),body.set("subject_token_type",config2.subjectTokenType??"urn:logto:token-type:personal_access_token"),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),config2.scopes.length>0&&body.set("scope",config2.scopes.join(" ")),applyResource(body,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"PAT \u4EA4\u6362 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:typeof tokenPayload.id_token=="string"?tokenPayload.id_token:void 0,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope??config2.scopes.join(" "),issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:config2.subjectToken,exchange_subject_token_type:config2.subjectTokenType??"urn:logto:token-type:personal_access_token",mode_expires_at:new Date(Date.now()+PAT_LOGIN_VALIDITY_MS).toISOString()}}async function fetchWhoAmI(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()}async function fetchTenantOverview(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"dashboard",requestClass:"control"}).getTenantOverview()}async function listTenantWorkspaces(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,capability:"auth",requestClass:"control"}).listTenantWorkspaces()}function looksLikeJwt(token){if(!token)return!1;let parts=token.split(".");return parts.length>=2&&parts.every(part=>part.length>0)}import{existsSync as existsSync8,mkdirSync as mkdirSync3,mkdtempSync as mkdtempSync2,readdirSync as readdirSync2,readFileSync as readFileSync8,renameSync,rmSync,statSync as statSync3,writeFileSync as writeFileSync4}from"node:fs";import{createServer as createNetServer}from"node:net";import{basename as basename2,dirname as dirname5,join as join4,relative,resolve as resolve5}from"node:path";import YAML from"yaml";var DEFAULT_APP_TEMPLATE_KEY="frontend-app-vite";function normalizeAppTemplateKey(value){if(typeof value>"u"||value.trim().length===0)return;let normalized=value.trim();if(normalized==="frontend-app-vite")return"frontend-app-vite";if(normalized==="backend-app-node")return"backend-app-node";throw new Error(`\u4E0D\u652F\u6301\u7684\u5E94\u7528\u6A21\u677F: ${normalized}\u3002\u5F53\u524D\u4EC5\u652F\u6301 \`frontend-app-vite\`\u3001\`backend-app-node\`\u3002\u65E7\u6A21\u677F\u5DF2\u4E0B\u7EBF\u3002`)}var PLATFORM_DIRECTORY=".platform",APP_MANIFEST_FILE="app.yaml",LEGACY_BINDING_FILE=join4(PLATFORM_DIRECTORY,"config.json"),SOURCE_CONTEXT_FILE=join4(PLATFORM_DIRECTORY,"source-context.json"),PLATFORM_BLOCKS_LOCKFILE=join4(PLATFORM_DIRECTORY,"platform-blocks.lock.json").replace(/\\/g,"/"),SOURCE_WORKSPACE_BYTES_LIMIT=50*1024*1024,SOURCE_WORKSPACE_ASSET_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".ico",".bmp",".avif",".mp4",".mp3",".wav",".ogg",".pdf",".woff",".woff2",".ttf",".otf",".eot",".zip",".gz"]);function ensureDirectory(directory){mkdirSync3(directory,{recursive:!0})}function writeFileIfMissing(path2,content){if(existsSync8(path2))throw new Error(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${path2}`);ensureDirectory(dirname5(path2)),writeFileSync4(path2,content,"utf8")}function listFilesRecursively(root,current=root){if(!existsSync8(current)||!statSync3(current).isDirectory())return[];let files=[];for(let entry of readdirSync2(current,{withFileTypes:!0})){let absolutePath=join4(current,entry.name);if(entry.isDirectory()){files.push(...listFilesRecursively(root,absolutePath));continue}entry.isFile()&&files.push(relative(root,absolutePath))}return files.sort((left,right)=>left.localeCompare(right))}function seedRuntimeSdkVendor(targetDir){let workspaceRoot=findWorkspaceRoot(),runtimeSdkDistDir=join4(workspaceRoot,"packages","runtime-sdk","dist");if(!existsSync8(runtimeSdkDistDir)||!statSync3(runtimeSdkDistDir).isDirectory())throw new Error(`\u7F3A\u5C11\u6D4F\u89C8\u5668\u4FA7 runtime-sdk \u6784\u5EFA\u4EA7\u7269\uFF1A${runtimeSdkDistDir}\u3002\u8BF7\u5148\u6267\u884C \`pnpm --filter @platform/runtime-sdk build\`\uFF0C\u518D\u91CD\u65B0\u521D\u59CB\u5316\u8F7B\u5E94\u7528\u6A21\u677F\u3002`);let created=[];for(let relativePath of listFilesRecursively(runtimeSdkDistDir)){let sourcePath=join4(runtimeSdkDistDir,relativePath),outputPath=join4(targetDir,"vendor","runtime-sdk",relativePath);writeFileIfMissing(outputPath,readFileSync8(sourcePath,"utf8")),created.push(relative(process.cwd(),outputPath))}return created}function normalizeAppManifest(input){let name=typeof input?.name=="string"&&input.name.trim().length>0?input.name.trim():"light-app",moduleName=typeof input?.module=="string"&&input.module.trim().length>0?input.module.trim():"light-app",templateKey=typeof input?.template_key=="string"&&input.template_key.trim().length>0?input.template_key.trim():DEFAULT_APP_TEMPLATE_KEY,normalizedEnvironments=Array.isArray(input?.environments)&&input.environments.length>0?input.environments.map(environment=>typeof environment?.name=="string"&&environment.name.trim().length>0?{name:environment.name.trim()}:null).filter(environment=>environment!==null):[];return{name,version:typeof input?.version=="string"&&input.version.trim().length>0?input.version.trim():"0.1.0",module:moduleName,template_key:templateKey,dev:{auto_restart:input?.dev?.auto_restart===!0},entry:{command:typeof input?.entry?.command=="string"&&input.entry.command.trim().length>0?input.entry.command.trim():"npm run dev",port:typeof input?.entry?.port=="number"&&Number.isFinite(input.entry.port)&&input.entry.port>0?input.entry.port:3e3,health_check:typeof input?.entry?.health_check=="string"&&input.entry.health_check.trim().length>0?input.entry.health_check.trim():"/healthz"},required_skills:Array.isArray(input?.required_skills)?input.required_skills.filter(Boolean):["db","auth"],permissions:Array.isArray(input?.permissions)?input.permissions.filter(Boolean):["app:read","app:write","app:publish"],env_vars:Array.isArray(input?.env_vars)?input.env_vars.filter(Boolean):["PORT","NODE_ENV","APP_ID","APP_ENV","TENANT_ID","DATABASE_URL","DATABASE_SCHEMA","CONTROL_API_BASE_URL"],runtime:{cpu:typeof input?.runtime?.cpu=="string"&&input.runtime.cpu.trim().length>0?input.runtime.cpu.trim():"250m",memory_mb:typeof input?.runtime?.memory_mb=="number"&&Number.isFinite(input.runtime.memory_mb)&&input.runtime.memory_mb>0?input.runtime.memory_mb:256},environments:normalizedEnvironments.length>0?normalizedEnvironments:[{name:"preview"},{name:"prod"}]}}function initProject(targetDir,_appName,templateKey=DEFAULT_APP_TEMPLATE_KEY){let absoluteTargetDir=resolve5(getInvocationCwd(),targetDir);ensureDirectory(absoluteTargetDir);let createdFiles=[],normalizedTemplateKey=normalizeAppTemplateKey(templateKey)??DEFAULT_APP_TEMPLATE_KEY,scaffoldFiles=normalizedTemplateKey==="frontend-app-vite"?assembleFrontendAppViteTemplate():normalizedTemplateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();for(let file of scaffoldFiles){let outputPath=join4(absoluteTargetDir,file.path);writeFileIfMissing(outputPath,file.content),createdFiles.push(relative(getInvocationCwd(),outputPath))}let vendorCreated=scaffoldFiles.some(file=>file.path.startsWith("vendor/runtime-sdk/")||file.path.startsWith("src/vendor/runtime-sdk/"))?[]:seedRuntimeSdkVendor(absoluteTargetDir);return[...createdFiles,...vendorCreated]}function scaffoldAppDebugSurface(startDir,scaffold){let appRoot=findAppRoot(startDir),appJsPath=join4(appRoot,"src","app.js");if(!existsSync8(appJsPath))throw new Error(`\u672A\u627E\u5230\u5E94\u7528\u5165\u53E3\u6587\u4EF6: ${appJsPath}`);let spec=getAppDebugScaffoldSpec(scaffold),createdFiles=[],updatedFiles=[],targetFilePath=join4(appRoot,spec.filePath);existsSync8(targetFilePath)||(ensureDirectory(dirname5(targetFilePath)),writeFileSync4(targetFilePath,spec.source,"utf8"),createdFiles.push(relative(appRoot,targetFilePath).replace(/\\/g,"/")));let appSource=readFileSync8(appJsPath,"utf8"),nextSource=injectDebugRouteIntoAppSource(appSource,spec);return nextSource!==appSource&&(writeFileSync4(appJsPath,nextSource,"utf8"),updatedFiles.push(relative(appRoot,appJsPath).replace(/\\/g,"/"))),{appRoot,createdFiles,updatedFiles,routePath:spec.routePath}}function readAppManifest(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),manifestPath=join4(appRoot,APP_MANIFEST_FILE),raw=readFileSync8(manifestPath,"utf8"),manifest=normalizeAppManifest(YAML.parse(raw));if(!manifest||typeof manifest!="object")throw new Error(`\u65E0\u6548\u7684 app.yaml: ${manifestPath}`);return{directory:appRoot,path:manifestPath,manifest}}function readLegacyBinding(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),bindingPath=join4(appRoot,LEGACY_BINDING_FILE);if(!existsSync8(bindingPath))return null;let raw=JSON.parse(readFileSync8(bindingPath,"utf8")),binding={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at??new Date(0).toISOString(),workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,validated_at:raw.validated_at};return{path:bindingPath,binding}}function readBinding(startDir=getInvocationCwd()){let sourceContext=readSourceContext(startDir);if(sourceContext?.sourceContext.tenant_id&&sourceContext.sourceContext.app_id){let context=sourceContext.sourceContext;return{path:sourceContext.path,binding:{schema_version:1,tenant_id:context.tenant_id,app_id:context.app_id,env:context.env||"preview",linked_at:context.linked_at??context.checked_out_at??context.updated_at,workspace_name:context.workspace_name,app_name:context.app_name,app_display_name:context.app_display_name,validated_at:context.validated_at}}}return readLegacyBinding(startDir)}function writeBinding(startDir,binding){let result=updateSourceContext(startDir,{tenant_id:binding.tenant_id,app_id:binding.app_id,env:binding.env,workspace_name:binding.workspace_name,app_name:binding.app_name,app_display_name:binding.app_display_name,validated_at:binding.validated_at,linked_at:new Date().toISOString()});return{appRoot:result.appRoot,path:result.path}}function readSourceContext(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),sourceContextPath=join4(appRoot,SOURCE_CONTEXT_FILE);if(!existsSync8(sourceContextPath))return null;let raw=JSON.parse(readFileSync8(sourceContextPath,"utf8")),sourceContext={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at,validated_at:raw.validated_at,workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,template_key:raw.template_key,default_directory:raw.default_directory,generated_from_template:typeof raw.generated_from_template=="boolean"?raw.generated_from_template:void 0,base_source_version_id:raw.base_source_version_id,checked_out_at:raw.checked_out_at,last_submitted_source_version_id:raw.last_submitted_source_version_id,last_submitted_at:raw.last_submitted_at,last_preview_source_version_id:raw.last_preview_source_version_id,last_preview_build_id:raw.last_preview_build_id,last_preview_generated_at:raw.last_preview_generated_at,control_plane:raw.control_plane&&typeof raw.control_plane=="object"?raw.control_plane:void 0,updated_at:raw.updated_at??new Date(0).toISOString()};return{path:sourceContextPath,sourceContext}}function writeSourceContext(startDir,sourceContext){let appRoot=findAppRoot(startDir),path2=join4(appRoot,SOURCE_CONTEXT_FILE);return ensureDirectory(dirname5(path2)),writeFileSync4(path2,`${JSON.stringify({schema_version:1,...sourceContext,updated_at:new Date().toISOString()},null,2)}
2366
- `,"utf8"),{appRoot,path:path2}}function updateSourceContext(startDir,patch){let appRoot=findAppRoot(startDir),existing=readSourceContext(appRoot)?.sourceContext,legacyBinding=readLegacyBinding(appRoot)?.binding;return writeSourceContext(appRoot,{tenant_id:patch.tenant_id??existing?.tenant_id??legacyBinding?.tenant_id??"",app_id:patch.app_id??existing?.app_id??legacyBinding?.app_id??"",env:patch.env??existing?.env??legacyBinding?.env??"preview",linked_at:patch.linked_at??existing?.linked_at??legacyBinding?.linked_at,validated_at:patch.validated_at??existing?.validated_at??legacyBinding?.validated_at,workspace_name:patch.workspace_name??existing?.workspace_name??legacyBinding?.workspace_name,app_name:patch.app_name??existing?.app_name??legacyBinding?.app_name,app_display_name:patch.app_display_name??existing?.app_display_name??legacyBinding?.app_display_name,template_key:patch.template_key??existing?.template_key,default_directory:patch.default_directory??existing?.default_directory,generated_from_template:typeof patch.generated_from_template=="boolean"?patch.generated_from_template:existing?.generated_from_template,base_source_version_id:patch.base_source_version_id??existing?.base_source_version_id,checked_out_at:patch.checked_out_at??existing?.checked_out_at,last_submitted_source_version_id:patch.last_submitted_source_version_id??existing?.last_submitted_source_version_id,last_submitted_at:patch.last_submitted_at??existing?.last_submitted_at,last_preview_source_version_id:patch.last_preview_source_version_id??existing?.last_preview_source_version_id,last_preview_build_id:patch.last_preview_build_id??existing?.last_preview_build_id,last_preview_generated_at:patch.last_preview_generated_at??existing?.last_preview_generated_at,control_plane:patch.control_plane??existing?.control_plane})}function checkoutSourceWorkspace(targetDir,files,sourceContext){let absoluteTargetDir=resolve5(getInvocationCwd(),targetDir);if(validatePortableWorkspacePaths(files),existsSync8(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF08\u5305\u62EC\u7A7A\u76EE\u5F55\uFF09: ${absoluteTargetDir}`);let parentDir=dirname5(absoluteTargetDir);ensureDirectory(parentDir);let stagingDir=mkdtempSync2(join4(parentDir,`.${basename2(absoluteTargetDir)}.platform-checkout-`));try{for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);writeFileIfMissing(join4(stagingDir,normalizedPath),file.content)}let now=new Date().toISOString();if(writeFileIfMissing(join4(stagingDir,SOURCE_CONTEXT_FILE),`${JSON.stringify({schema_version:1,...sourceContext,linked_at:sourceContext.linked_at??now,updated_at:now},null,2)}
2365
+ `,"utf8"),chmodSync(filePath,384)}})}async function performDeviceCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer);if(!endpoints.device_authorization_endpoint)throw new Error("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9");let authBody=new URLSearchParams;authBody.set("client_id",config2.clientId),authBody.set("scope",config2.scopes.join(" ")),applyResource(authBody,config2.audience);let deviceResponse=await fetch(endpoints.device_authorization_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:authBody}),devicePayload=await deviceResponse.json();if(!deviceResponse.ok)throw new Error(devicePayload.error_description??devicePayload.error??"\u7533\u8BF7 device_code \u5931\u8D25");await config2.onPrompt?.({verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code,expiresIn:devicePayload.expires_in});let intervalSeconds=Math.max(devicePayload.interval??5,1),deadline=Date.now()+devicePayload.expires_in*1e3;for(;Date.now()<deadline;){await sleep(intervalSeconds*1e3);let tokenBody=new URLSearchParams;tokenBody.set("grant_type","urn:ietf:params:oauth:grant-type:device_code"),tokenBody.set("device_code",devicePayload.device_code),tokenBody.set("client_id",config2.clientId);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(tokenResponse.ok)return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),verificationUri:devicePayload.verification_uri_complete??devicePayload.verification_uri??config2.issuer,userCode:devicePayload.user_code};if(tokenPayload.error!=="authorization_pending"){if(tokenPayload.error==="slow_down"){await sleep(intervalSeconds*1e3);continue}throw new Error(tokenPayload.error_description??tokenPayload.error??"\u8F6E\u8BE2 token \u5931\u8D25")}}throw new Error("Device Code \u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`")}async function performAuthorizationCodeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),redirectUrl=new URL(config2.redirectUri);if(redirectUrl.protocol!=="http:")throw new Error("CLI \u6D4F\u89C8\u5668\u6388\u6743\u4EC5\u652F\u6301 http \u56DE\u8C03\u5730\u5740");let state=randomBytes(16).toString("base64url"),nonce=randomBytes(16).toString("base64url"),codeVerifier=randomBytes(32).toString("base64url"),codeChallenge=createHash3("sha256").update(codeVerifier).digest("base64url"),authorizationUrl=new URL(endpoints.authorization_endpoint);authorizationUrl.searchParams.set("client_id",config2.clientId),authorizationUrl.searchParams.set("redirect_uri",config2.redirectUri),authorizationUrl.searchParams.set("response_type","code"),authorizationUrl.searchParams.set("scope",config2.scopes.join(" ")),authorizationUrl.searchParams.set("state",state),authorizationUrl.searchParams.set("nonce",nonce),authorizationUrl.searchParams.set("code_challenge",codeChallenge),authorizationUrl.searchParams.set("code_challenge_method","S256");let normalizedPrompt=normalizeAuthorizationPrompt(config2.scopes,config2.prompt);normalizedPrompt&&authorizationUrl.searchParams.set("prompt",normalizedPrompt),applyResource(authorizationUrl.searchParams,config2.audience);let callbackResult=await new Promise((resolve19,reject)=>{let timeout=setTimeout(()=>{server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C `platform login`"))},3e5),server=createServer((req,res)=>{let url=new URL(req.url??"/",config2.redirectUri);if(url.pathname!==redirectUrl.pathname){res.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),res.end("Not Found");return}let returnedState=url.searchParams.get("state"),error=url.searchParams.get("error"),code2=url.searchParams.get("code");if(error){clearTimeout(timeout);let errMsg=url.searchParams.get("error_description")??error;res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml(errMsg)),server.close(()=>{}),reject(new Error(errMsg));return}if(!code2||returnedState!==state){clearTimeout(timeout),res.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginFailureHtml("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11\u6388\u6743\u7801\u6216 state \u4E0D\u5339\u914D\u3002")),server.close(()=>{}),reject(new Error("\u6D4F\u89C8\u5668\u56DE\u8C03\u7F3A\u5C11 code \u6216 state \u4E0D\u5339\u914D"));return}clearTimeout(timeout),res.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),res.end(getLoginSuccessHtml()),server.close(()=>{}),resolve19({code:code2})});server.on("error",error=>{clearTimeout(timeout),reject(error)}),server.listen(Number(redirectUrl.port||80),redirectUrl.hostname,async()=>{try{await config2.onPrompt?.({authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri})}catch(error){clearTimeout(timeout),server.close(()=>{}),reject(error)}})}),tokenBody=new URLSearchParams;tokenBody.set("grant_type","authorization_code"),tokenBody.set("client_id",config2.clientId),tokenBody.set("code",callbackResult.code),tokenBody.set("redirect_uri",config2.redirectUri),tokenBody.set("code_verifier",codeVerifier),applyResource(tokenBody,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:tokenBody}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"\u6388\u6743\u7801\u6362\u53D6 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:tokenPayload.id_token,refresh_token:tokenPayload.refresh_token,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope,issued_at:new Date().toISOString(),authorizationUrl:authorizationUrl.toString(),redirectUri:config2.redirectUri}}async function performPatTokenExchangeLogin(config2){let endpoints=await discoverOidcEndpoints(config2.issuer),body=new URLSearchParams;body.set("grant_type","urn:ietf:params:oauth:grant-type:token-exchange"),body.set("client_id",config2.clientId),body.set("subject_token",config2.subjectToken),body.set("subject_token_type",config2.subjectTokenType??"urn:logto:token-type:personal_access_token"),body.set("requested_token_type","urn:ietf:params:oauth:token-type:access_token"),config2.scopes.length>0&&body.set("scope",config2.scopes.join(" ")),applyResource(body,config2.audience);let tokenResponse=await fetch(endpoints.token_endpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body}),tokenPayload=await tokenResponse.json();if(!tokenResponse.ok)throw new Error(tokenPayload.error_description??tokenPayload.error??"PAT \u4EA4\u6362 token \u5931\u8D25");return{access_token:tokenPayload.access_token,id_token:typeof tokenPayload.id_token=="string"?tokenPayload.id_token:void 0,client_id:config2.clientId,token_type:tokenPayload.token_type,expires_in:tokenPayload.expires_in,scope:tokenPayload.scope??config2.scopes.join(" "),issued_at:new Date().toISOString(),credential_mode:"pat_exchange",exchange_subject_token:config2.subjectToken,exchange_subject_token_type:config2.subjectTokenType??"urn:logto:token-type:personal_access_token",mode_expires_at:new Date(Date.now()+PAT_LOGIN_VALIDITY_MS).toISOString()}}async function fetchWhoAmI(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()}async function fetchTenantOverview(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,tenantId:args.tenantId,capability:"dashboard",requestClass:"control"}).getTenantOverview()}async function listTenantWorkspaces(args){return createControlApiSdk({baseUrl:args.baseUrl,accessToken:args.accessToken,capability:"auth",requestClass:"control"}).listTenantWorkspaces()}function looksLikeJwt(token){if(!token)return!1;let parts=token.split(".");return parts.length>=2&&parts.every(part=>part.length>0)}import{existsSync as existsSync8,mkdirSync as mkdirSync3,mkdtempSync as mkdtempSync2,readdirSync as readdirSync2,readFileSync as readFileSync8,renameSync,rmSync,statSync as statSync3,writeFileSync as writeFileSync4}from"node:fs";import{createServer as createNetServer}from"node:net";import{basename as basename3,dirname as dirname5,join as join4,relative,resolve as resolve6}from"node:path";import YAML from"yaml";var DEFAULT_APP_TEMPLATE_KEY="frontend-app-vite";function normalizeAppTemplateKey(value){if(typeof value>"u"||value.trim().length===0)return;let normalized=value.trim();if(normalized==="frontend-app-vite")return"frontend-app-vite";if(normalized==="backend-app-node")return"backend-app-node";throw new Error(`\u4E0D\u652F\u6301\u7684\u5E94\u7528\u6A21\u677F: ${normalized}\u3002\u5F53\u524D\u4EC5\u652F\u6301 \`frontend-app-vite\`\u3001\`backend-app-node\`\u3002\u65E7\u6A21\u677F\u5DF2\u4E0B\u7EBF\u3002`)}var PLATFORM_DIRECTORY=".platform",APP_MANIFEST_FILE="app.yaml",LEGACY_BINDING_FILE=join4(PLATFORM_DIRECTORY,"config.json"),SOURCE_CONTEXT_FILE=join4(PLATFORM_DIRECTORY,"source-context.json"),PLATFORM_BLOCKS_LOCKFILE=join4(PLATFORM_DIRECTORY,"platform-blocks.lock.json").replace(/\\/g,"/"),SOURCE_WORKSPACE_BYTES_LIMIT=50*1024*1024,SOURCE_WORKSPACE_ASSET_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".ico",".bmp",".avif",".mp4",".mp3",".wav",".ogg",".pdf",".woff",".woff2",".ttf",".otf",".eot",".zip",".gz"]);function ensureDirectory(directory){mkdirSync3(directory,{recursive:!0})}function writeFileIfMissing(path2,content){if(existsSync8(path2))throw new Error(`\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${path2}`);ensureDirectory(dirname5(path2)),writeFileSync4(path2,content,"utf8")}function listFilesRecursively(root,current=root){if(!existsSync8(current)||!statSync3(current).isDirectory())return[];let files=[];for(let entry of readdirSync2(current,{withFileTypes:!0})){let absolutePath=join4(current,entry.name);if(entry.isDirectory()){files.push(...listFilesRecursively(root,absolutePath));continue}entry.isFile()&&files.push(relative(root,absolutePath))}return files.sort((left,right)=>left.localeCompare(right))}function seedRuntimeSdkVendor(targetDir){let workspaceRoot=findWorkspaceRoot(),runtimeSdkDistDir=join4(workspaceRoot,"packages","runtime-sdk","dist");if(!existsSync8(runtimeSdkDistDir)||!statSync3(runtimeSdkDistDir).isDirectory())throw new Error(`\u7F3A\u5C11\u6D4F\u89C8\u5668\u4FA7 runtime-sdk \u6784\u5EFA\u4EA7\u7269\uFF1A${runtimeSdkDistDir}\u3002\u8BF7\u5148\u6267\u884C \`pnpm --filter @platform/runtime-sdk build\`\uFF0C\u518D\u91CD\u65B0\u521D\u59CB\u5316\u8F7B\u5E94\u7528\u6A21\u677F\u3002`);let created=[];for(let relativePath of listFilesRecursively(runtimeSdkDistDir)){let sourcePath=join4(runtimeSdkDistDir,relativePath),outputPath=join4(targetDir,"vendor","runtime-sdk",relativePath);writeFileIfMissing(outputPath,readFileSync8(sourcePath,"utf8")),created.push(relative(process.cwd(),outputPath))}return created}function normalizeAppManifest(input){let name=typeof input?.name=="string"&&input.name.trim().length>0?input.name.trim():"light-app",moduleName=typeof input?.module=="string"&&input.module.trim().length>0?input.module.trim():"light-app",templateKey=typeof input?.template_key=="string"&&input.template_key.trim().length>0?input.template_key.trim():DEFAULT_APP_TEMPLATE_KEY,normalizedEnvironments=Array.isArray(input?.environments)&&input.environments.length>0?input.environments.map(environment=>typeof environment?.name=="string"&&environment.name.trim().length>0?{name:environment.name.trim()}:null).filter(environment=>environment!==null):[];return{name,version:typeof input?.version=="string"&&input.version.trim().length>0?input.version.trim():"0.1.0",module:moduleName,template_key:templateKey,dev:{auto_restart:input?.dev?.auto_restart===!0},entry:{command:typeof input?.entry?.command=="string"&&input.entry.command.trim().length>0?input.entry.command.trim():"npm run dev",port:typeof input?.entry?.port=="number"&&Number.isFinite(input.entry.port)&&input.entry.port>0?input.entry.port:3e3,health_check:typeof input?.entry?.health_check=="string"&&input.entry.health_check.trim().length>0?input.entry.health_check.trim():"/healthz"},required_skills:Array.isArray(input?.required_skills)?input.required_skills.filter(Boolean):["db","auth"],permissions:Array.isArray(input?.permissions)?input.permissions.filter(Boolean):["app:read","app:write","app:publish"],env_vars:Array.isArray(input?.env_vars)?input.env_vars.filter(Boolean):["PORT","NODE_ENV","APP_ID","APP_ENV","TENANT_ID","DATABASE_URL","DATABASE_SCHEMA","CONTROL_API_BASE_URL"],runtime:{cpu:typeof input?.runtime?.cpu=="string"&&input.runtime.cpu.trim().length>0?input.runtime.cpu.trim():"250m",memory_mb:typeof input?.runtime?.memory_mb=="number"&&Number.isFinite(input.runtime.memory_mb)&&input.runtime.memory_mb>0?input.runtime.memory_mb:256},environments:normalizedEnvironments.length>0?normalizedEnvironments:[{name:"preview"},{name:"prod"}]}}function initProject(targetDir,_appName,templateKey=DEFAULT_APP_TEMPLATE_KEY){let absoluteTargetDir=resolve6(getInvocationCwd(),targetDir);ensureDirectory(absoluteTargetDir);let createdFiles=[],normalizedTemplateKey=normalizeAppTemplateKey(templateKey)??DEFAULT_APP_TEMPLATE_KEY,scaffoldFiles=normalizedTemplateKey==="frontend-app-vite"?assembleFrontendAppViteTemplate():normalizedTemplateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();for(let file of scaffoldFiles){let outputPath=join4(absoluteTargetDir,file.path);writeFileIfMissing(outputPath,file.content),createdFiles.push(relative(getInvocationCwd(),outputPath))}let vendorCreated=scaffoldFiles.some(file=>file.path.startsWith("vendor/runtime-sdk/")||file.path.startsWith("src/vendor/runtime-sdk/"))?[]:seedRuntimeSdkVendor(absoluteTargetDir);return[...createdFiles,...vendorCreated]}function scaffoldAppDebugSurface(startDir,scaffold){let appRoot=findAppRoot(startDir),appJsPath=join4(appRoot,"src","app.js");if(!existsSync8(appJsPath))throw new Error(`\u672A\u627E\u5230\u5E94\u7528\u5165\u53E3\u6587\u4EF6: ${appJsPath}`);let spec=getAppDebugScaffoldSpec(scaffold),createdFiles=[],updatedFiles=[],targetFilePath=join4(appRoot,spec.filePath);existsSync8(targetFilePath)||(ensureDirectory(dirname5(targetFilePath)),writeFileSync4(targetFilePath,spec.source,"utf8"),createdFiles.push(relative(appRoot,targetFilePath).replace(/\\/g,"/")));let appSource=readFileSync8(appJsPath,"utf8"),nextSource=injectDebugRouteIntoAppSource(appSource,spec);return nextSource!==appSource&&(writeFileSync4(appJsPath,nextSource,"utf8"),updatedFiles.push(relative(appRoot,appJsPath).replace(/\\/g,"/"))),{appRoot,createdFiles,updatedFiles,routePath:spec.routePath}}function readAppManifest(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),manifestPath=join4(appRoot,APP_MANIFEST_FILE),raw=readFileSync8(manifestPath,"utf8"),manifest=normalizeAppManifest(YAML.parse(raw));if(!manifest||typeof manifest!="object")throw new Error(`\u65E0\u6548\u7684 app.yaml: ${manifestPath}`);return{directory:appRoot,path:manifestPath,manifest}}function readLegacyBinding(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),bindingPath=join4(appRoot,LEGACY_BINDING_FILE);if(!existsSync8(bindingPath))return null;let raw=JSON.parse(readFileSync8(bindingPath,"utf8")),binding={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at??new Date(0).toISOString(),workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,validated_at:raw.validated_at};return{path:bindingPath,binding}}function readBinding(startDir=getInvocationCwd()){let sourceContext=readSourceContext(startDir);if(sourceContext?.sourceContext.tenant_id&&sourceContext.sourceContext.app_id){let context=sourceContext.sourceContext;return{path:sourceContext.path,binding:{schema_version:1,tenant_id:context.tenant_id,app_id:context.app_id,env:context.env||"preview",linked_at:context.linked_at??context.checked_out_at??context.updated_at,workspace_name:context.workspace_name,app_name:context.app_name,app_display_name:context.app_display_name,validated_at:context.validated_at}}}return readLegacyBinding(startDir)}function writeBinding(startDir,binding){let result=updateSourceContext(startDir,{tenant_id:binding.tenant_id,app_id:binding.app_id,env:binding.env,workspace_name:binding.workspace_name,app_name:binding.app_name,app_display_name:binding.app_display_name,validated_at:binding.validated_at,linked_at:new Date().toISOString()});return{appRoot:result.appRoot,path:result.path}}function readSourceContext(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),sourceContextPath=join4(appRoot,SOURCE_CONTEXT_FILE);if(!existsSync8(sourceContextPath))return null;let raw=JSON.parse(readFileSync8(sourceContextPath,"utf8")),sourceContext={schema_version:typeof raw.schema_version=="number"?raw.schema_version:1,tenant_id:raw.tenant_id??"",app_id:raw.app_id??"",env:raw.env??"preview",linked_at:raw.linked_at,validated_at:raw.validated_at,workspace_name:raw.workspace_name,app_name:raw.app_name,app_display_name:raw.app_display_name,template_key:raw.template_key,default_directory:raw.default_directory,generated_from_template:typeof raw.generated_from_template=="boolean"?raw.generated_from_template:void 0,base_source_version_id:raw.base_source_version_id,checked_out_at:raw.checked_out_at,last_submitted_source_version_id:raw.last_submitted_source_version_id,last_submitted_at:raw.last_submitted_at,last_preview_source_version_id:raw.last_preview_source_version_id,last_preview_build_id:raw.last_preview_build_id,last_preview_generated_at:raw.last_preview_generated_at,control_plane:raw.control_plane&&typeof raw.control_plane=="object"?raw.control_plane:void 0,updated_at:raw.updated_at??new Date(0).toISOString()};return{path:sourceContextPath,sourceContext}}function writeSourceContext(startDir,sourceContext){let appRoot=findAppRoot(startDir),path2=join4(appRoot,SOURCE_CONTEXT_FILE);return ensureDirectory(dirname5(path2)),writeFileSync4(path2,`${JSON.stringify({schema_version:1,...sourceContext,updated_at:new Date().toISOString()},null,2)}
2366
+ `,"utf8"),{appRoot,path:path2}}function updateSourceContext(startDir,patch){let appRoot=findAppRoot(startDir),existing=readSourceContext(appRoot)?.sourceContext,legacyBinding=readLegacyBinding(appRoot)?.binding;return writeSourceContext(appRoot,{tenant_id:patch.tenant_id??existing?.tenant_id??legacyBinding?.tenant_id??"",app_id:patch.app_id??existing?.app_id??legacyBinding?.app_id??"",env:patch.env??existing?.env??legacyBinding?.env??"preview",linked_at:patch.linked_at??existing?.linked_at??legacyBinding?.linked_at,validated_at:patch.validated_at??existing?.validated_at??legacyBinding?.validated_at,workspace_name:patch.workspace_name??existing?.workspace_name??legacyBinding?.workspace_name,app_name:patch.app_name??existing?.app_name??legacyBinding?.app_name,app_display_name:patch.app_display_name??existing?.app_display_name??legacyBinding?.app_display_name,template_key:patch.template_key??existing?.template_key,default_directory:patch.default_directory??existing?.default_directory,generated_from_template:typeof patch.generated_from_template=="boolean"?patch.generated_from_template:existing?.generated_from_template,base_source_version_id:patch.base_source_version_id??existing?.base_source_version_id,checked_out_at:patch.checked_out_at??existing?.checked_out_at,last_submitted_source_version_id:patch.last_submitted_source_version_id??existing?.last_submitted_source_version_id,last_submitted_at:patch.last_submitted_at??existing?.last_submitted_at,last_preview_source_version_id:patch.last_preview_source_version_id??existing?.last_preview_source_version_id,last_preview_build_id:patch.last_preview_build_id??existing?.last_preview_build_id,last_preview_generated_at:patch.last_preview_generated_at??existing?.last_preview_generated_at,control_plane:patch.control_plane??existing?.control_plane})}function checkoutSourceWorkspace(targetDir,files,sourceContext){let absoluteTargetDir=resolve6(getInvocationCwd(),targetDir);if(validatePortableWorkspacePaths(files),existsSync8(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6\uFF08\u5305\u62EC\u7A7A\u76EE\u5F55\uFF09: ${absoluteTargetDir}`);let parentDir=dirname5(absoluteTargetDir);ensureDirectory(parentDir);let stagingDir=mkdtempSync2(join4(parentDir,`.${basename3(absoluteTargetDir)}.platform-checkout-`));try{for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);writeFileIfMissing(join4(stagingDir,normalizedPath),file.content)}let now=new Date().toISOString();if(writeFileIfMissing(join4(stagingDir,SOURCE_CONTEXT_FILE),`${JSON.stringify({schema_version:1,...sourceContext,linked_at:sourceContext.linked_at??now,updated_at:now},null,2)}
2367
2367
  `),existsSync8(absoluteTargetDir))throw new Error(`\u76EE\u6807\u76EE\u5F55\u5728\u68C0\u51FA\u8FC7\u7A0B\u4E2D\u88AB\u521B\u5EFA\uFF0C\u62D2\u7EDD\u8986\u76D6: ${absoluteTargetDir}`);renameSync(stagingDir,absoluteTargetDir)}catch(error){throw rmSync(stagingDir,{recursive:!0,force:!0}),error}return files.map(file=>relative(getInvocationCwd(),join4(absoluteTargetDir,normalizePortableWorkspacePath(file.path))))}function validatePortableWorkspacePaths(files){let canonicalPaths=new Map;for(let file of files){let normalizedPath=normalizePortableWorkspacePath(file.path);if(normalizedPath.toLowerCase()===SOURCE_CONTEXT_FILE.replace(/\\/gu,"/").toLowerCase())throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5\uFF08CLI \u4FDD\u7559\u8DEF\u5F84\uFF09: ${file.path}`);let canonicalPath=normalizedPath.normalize("NFC").toLowerCase(),collision=canonicalPaths.get(canonicalPath);if(collision)throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u51B2\u7A81: ${collision} <-> ${file.path}`);canonicalPaths.set(canonicalPath,file.path)}for(let[canonicalPath,originalPath]of canonicalPaths){let segments=canonicalPath.split("/");for(let index=1;index<segments.length;index+=1){let parentPath=segments.slice(0,index).join("/"),parentOriginalPath=canonicalPaths.get(parentPath);if(parentOriginalPath)throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u51B2\u7A81\uFF08\u6587\u4EF6\u4E0E\u76EE\u5F55\u91CD\u540D\uFF09: ${parentOriginalPath} <-> ${originalPath}`)}}}function normalizePortableWorkspacePath(inputPath){let normalizedSeparators=inputPath.replace(/\\/gu,"/");if(!normalizedSeparators||normalizedSeparators.startsWith("/")||/^[A-Za-z]:/u.test(normalizedSeparators))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${inputPath}`);let segments=normalizedSeparators.split("/");for(let segment of segments){if(!segment||segment==="."||segment==="..")throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${inputPath}`);if(/[<>:"|?*\u0000-\u001F]/u.test(segment))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u5305\u542B Windows \u975E\u6CD5\u5B57\u7B26: ${inputPath}`);if(/[. ]$/u.test(segment))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u542B\u5C3E\u968F\u70B9\u6216\u7A7A\u683C: ${inputPath}`);let baseName=segment.split(".")[0]??segment;if(/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/iu.test(baseName))throw new Error(`\u4E91\u7AEF\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u4F7F\u7528 Windows \u4FDD\u7559\u540D: ${inputPath}`)}return segments.map(segment=>segment.normalize("NFC")).join("/")}function collectSourceWorkspaceFiles(startDir=getInvocationCwd()){let appRoot=findAppRoot(startDir),files=walkSourceWorkspace(appRoot,appRoot);return{appRoot,files}}function assertSourceWorkspaceCloudUploadPolicy(appRoot,commandLabel){let stats=scanSourceWorkspaceUploadPolicy(appRoot,appRoot);if(stats.sourceBytes>SOURCE_WORKSPACE_BYTES_LIMIT)throw new Error(`\u5F53\u524D\u6E90\u7801\u5305\u4F53\u79EF ${stats.sourceBytes} bytes\uFF0C\u8D85\u8FC7\u4E91\u7AEF\u6E90\u7801\u4E0A\u4F20\u4E0A\u9650 ${SOURCE_WORKSPACE_BYTES_LIMIT} bytes\u3002`);if(stats.assetHits.length>0)throw new Error([`\u68C0\u6D4B\u5230\u672C\u5730\u7D20\u6750\u8D44\u6E90\uFF0C\u5F53\u524D \`${commandLabel}\` \u4E0D\u8D1F\u8D23\u7D20\u6750\u4E0A\u4F20\u56DE\u5199\u3002`,"Agent \u8BF7\u5148\u53C2\u8003 Skill \u6587\u6863 `design-import.md` \u6267\u884C\u8BBE\u8BA1\u6E90\u7801\u9884\u5904\u7406\uFF0C\u5C06\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u7D20\u6750\u5E93\u5E76\u628A\u6E90\u7801\u6539\u5199\u4E3A\u7D20\u6750\u5E93\u5F15\u7528\u540E\u518D\u8BD5\u3002",`\u793A\u4F8B\u547D\u4E2D: ${stats.assetHits.slice(0,10).join(", ")}`].join(`
2368
- `));return stats}function detectPathBaseRuntimeViolations(files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_http_client",regex:/\baxios(?:\.(?:get|post|put|patch|delete|head|options))?\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let file of files){if(!textFilePattern.test(file.path)||/^README\.md$/i.test(file.path)||isPlatformDevSupportFile(file.path))continue;let lines=file.content.split(/\r?\n/);for(let index=0;index<lines.length;index+=1){let line=lines[index];for(let pattern of patterns)pattern.regex.lastIndex=0,pattern.regex.test(line)&&violations.push({path:file.path,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function isPlatformDevSupportFile(path2){return path2.startsWith("src/platform/dev/")||path2.startsWith("src/web/platform/dev/")||path2.startsWith("src/server/platform/dev/")}function scanSourceWorkspaceUploadPolicy(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),sourceBytes=0,assetHits=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,entry.isDirectory())){if(entry.isDirectory()){let nested=scanSourceWorkspaceUploadPolicy(appRoot,absolutePath);sourceBytes+=nested.sourceBytes,assetHits.push(...nested.assetHits);continue}entry.isFile()&&(sourceBytes+=statSync3(absolutePath).size,isSourceWorkspaceAssetPath(relativePath)&&assetHits.push(relativePath))}}return{sourceBytes,assetHits}}function shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(!normalized)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")?!0:new Set([".git",".platform","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)}function isSourceWorkspaceAssetPath(relativePath){let lower=relativePath.toLowerCase(),dotIndex=lower.lastIndexOf(".");return dotIndex<0?!1:SOURCE_WORKSPACE_ASSET_EXTENSIONS.has(lower.slice(dotIndex))}function walkSourceWorkspace(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),files=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspacePath(relativePath,entry.isDirectory())){if(entry.isDirectory()){files.push(...walkSourceWorkspace(appRoot,absolutePath));continue}entry.isFile()&&files.push({path:relativePath,content:readFileSync8(absolutePath,"utf8")})}}return files.sort((left,right)=>left.path.localeCompare(right.path))}function shouldIgnoreSourceWorkspacePath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(normalized.length===0)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")&&topLevel!==".platform"||new Set([".git","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)?!0:topLevel===".platform"?isDirectory?normalized===".platform/platform-blocks.history":normalized!==PLATFORM_BLOCKS_LOCKFILE:!!(!isDirectory&&new Set([".DS_Store",".env",".env.local",".env.dev",".env.ci"]).has(normalized))}function findAppRoot(startDir=getInvocationCwd()){let current=resolve5(getInvocationCwd(),startDir);for(;;){let manifestPath=join4(current,APP_MANIFEST_FILE);if(existsSync8(manifestPath)&&statSync3(manifestPath).isFile())return current;let parent=dirname5(current);if(parent===current)throw new Error("\u672A\u627E\u5230 app.yaml\u3002\u4F18\u5148\u5EFA\u8BAE\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u5F97\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u660E\u786E\u8981\u5728\u5F53\u524D\u7A7A\u76EE\u5F55\u521D\u59CB\u5316\uFF0C\u518D\u6267\u884C `platform init <project-name>`\u3002");current=parent}}function getAppDebugScaffoldSpec(scaffold){return scaffold==="auth-debug"?{kind:scaffold,routePath:"/debug/auth",filePath:"src/lib/debug-auth-page.js",importLine:'import { renderAuthDebugPage } from "./lib/debug-auth-page.js";',renderCall:"renderAuthDebugPage()",source:buildAuthDebugPageSource()}:scaffold==="cms-debug"?{kind:scaffold,routePath:"/debug/cms",filePath:"src/lib/debug-cms-page.js",importLine:'import { renderCmsDebugPage } from "./lib/debug-cms-page.js";',renderCall:"renderCmsDebugPage()",source:buildCmsDebugPageSource()}:scaffold==="db-debug"?{kind:scaffold,routePath:"/debug/db",filePath:"src/lib/debug-db-page.js",importLine:'import { renderDbDebugPage } from "./lib/debug-db-page.js";',renderCall:"renderDbDebugPage()",source:buildDbDebugPageSource(),extraRouteBlocks:[[' if (pathname === "/api/debug/db-context" && req.method === "GET") {'," sendJson(res, 200, {"," app_id: config.appId,"," tenant_id: config.tenantId || null,"," env: config.appEnv,"," request_id: requestId,"," database_ready: Boolean(config.databaseUrl),"," database_schema: config.databaseSchema || null,"," database_capability_version: process.env.DATABASE_CAPABILITY_VERSION || null,"," database_runtime_role: process.env.DATABASE_RUNTIME_ROLE || null,"," database_migrator_role: process.env.DATABASE_MIGRATOR_ROLE || null"," });"," return;"," }",""].join(`
2368
+ `));return stats}function detectPathBaseRuntimeViolations(files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_http_client",regex:/\baxios(?:\.(?:get|post|put|patch|delete|head|options))?\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let file of files){if(!textFilePattern.test(file.path)||/^README\.md$/i.test(file.path)||isPlatformDevSupportFile(file.path))continue;let lines=file.content.split(/\r?\n/);for(let index=0;index<lines.length;index+=1){let line=lines[index];for(let pattern of patterns)pattern.regex.lastIndex=0,pattern.regex.test(line)&&violations.push({path:file.path,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function isPlatformDevSupportFile(path2){return path2.startsWith("src/platform/dev/")||path2.startsWith("src/web/platform/dev/")||path2.startsWith("src/server/platform/dev/")}function scanSourceWorkspaceUploadPolicy(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),sourceBytes=0,assetHits=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,entry.isDirectory())){if(entry.isDirectory()){let nested=scanSourceWorkspaceUploadPolicy(appRoot,absolutePath);sourceBytes+=nested.sourceBytes,assetHits.push(...nested.assetHits);continue}entry.isFile()&&(sourceBytes+=statSync3(absolutePath).size,isSourceWorkspaceAssetPath(relativePath)&&assetHits.push(relativePath))}}return{sourceBytes,assetHits}}function shouldIgnoreSourceWorkspaceUploadPolicyPath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(!normalized)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")?!0:new Set([".git",".platform","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)}function isSourceWorkspaceAssetPath(relativePath){let lower=relativePath.toLowerCase(),dotIndex=lower.lastIndexOf(".");return dotIndex<0?!1:SOURCE_WORKSPACE_ASSET_EXTENSIONS.has(lower.slice(dotIndex))}function walkSourceWorkspace(appRoot,currentDir){let entries=readdirSync2(currentDir,{withFileTypes:!0}),files=[];for(let entry of entries){let absolutePath=join4(currentDir,entry.name),relativePath=relative(appRoot,absolutePath).replace(/\\/g,"/");if(!shouldIgnoreSourceWorkspacePath(relativePath,entry.isDirectory())){if(entry.isDirectory()){files.push(...walkSourceWorkspace(appRoot,absolutePath));continue}entry.isFile()&&files.push({path:relativePath,content:readFileSync8(absolutePath,"utf8")})}}return files.sort((left,right)=>left.path.localeCompare(right.path))}function shouldIgnoreSourceWorkspacePath(relativePath,isDirectory){let normalized=relativePath.replace(/^\.\/+/g,"");if(normalized.length===0)return!1;let topLevel=normalized.split("/")[0];return isDirectory&&topLevel.startsWith(".")&&topLevel!==".platform"||new Set([".git","node_modules","dist","coverage","evidence","Log","TMP"]).has(topLevel)?!0:topLevel===".platform"?isDirectory?normalized===".platform/platform-blocks.history":normalized!==PLATFORM_BLOCKS_LOCKFILE:!!(!isDirectory&&new Set([".DS_Store",".env",".env.local",".env.dev",".env.ci"]).has(normalized))}function findAppRoot(startDir=getInvocationCwd()){let current=resolve6(getInvocationCwd(),startDir);for(;;){let manifestPath=join4(current,APP_MANIFEST_FILE);if(existsSync8(manifestPath)&&statSync3(manifestPath).isFile())return current;let parent=dirname5(current);if(parent===current)throw new Error("\u672A\u627E\u5230 app.yaml\u3002\u4F18\u5148\u5EFA\u8BAE\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u5F97\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u660E\u786E\u8981\u5728\u5F53\u524D\u7A7A\u76EE\u5F55\u521D\u59CB\u5316\uFF0C\u518D\u6267\u884C `platform init <project-name>`\u3002");current=parent}}function getAppDebugScaffoldSpec(scaffold){return scaffold==="auth-debug"?{kind:scaffold,routePath:"/debug/auth",filePath:"src/lib/debug-auth-page.js",importLine:'import { renderAuthDebugPage } from "./lib/debug-auth-page.js";',renderCall:"renderAuthDebugPage()",source:buildAuthDebugPageSource()}:scaffold==="cms-debug"?{kind:scaffold,routePath:"/debug/cms",filePath:"src/lib/debug-cms-page.js",importLine:'import { renderCmsDebugPage } from "./lib/debug-cms-page.js";',renderCall:"renderCmsDebugPage()",source:buildCmsDebugPageSource()}:scaffold==="db-debug"?{kind:scaffold,routePath:"/debug/db",filePath:"src/lib/debug-db-page.js",importLine:'import { renderDbDebugPage } from "./lib/debug-db-page.js";',renderCall:"renderDbDebugPage()",source:buildDbDebugPageSource(),extraRouteBlocks:[[' if (pathname === "/api/debug/db-context" && req.method === "GET") {'," sendJson(res, 200, {"," app_id: config.appId,"," tenant_id: config.tenantId || null,"," env: config.appEnv,"," request_id: requestId,"," database_ready: Boolean(config.databaseUrl),"," database_schema: config.databaseSchema || null,"," database_capability_version: process.env.DATABASE_CAPABILITY_VERSION || null,"," database_runtime_role: process.env.DATABASE_RUNTIME_ROLE || null,"," database_migrator_role: process.env.DATABASE_MIGRATOR_ROLE || null"," });"," return;"," }",""].join(`
2369
2369
  `)]}:{kind:scaffold,routePath:"/debug/workflow",filePath:"src/lib/debug-workflow-page.js",importLine:'import { renderWorkflowDebugPage } from "./lib/debug-workflow-page.js";',renderCall:"renderWorkflowDebugPage()",source:buildWorkflowDebugPageSource()}}function injectDebugRouteIntoAppSource(source,spec){let next=source;if(!next.includes(spec.importLine)){let importMarker='import { readRuntimeAsset } from "./lib/runtime-assets.js";';if(!next.includes(importMarker))throw new Error("\u65E0\u6CD5\u5728 src/app.js \u4E2D\u627E\u5230 runtime-assets import\uFF0C\u6682\u65F6\u65E0\u6CD5\u81EA\u52A8\u6CE8\u5165 debug scaffold \u8DEF\u7531\u3002");next=next.replace(importMarker,`${spec.importLine}
2370
2370
  ${importMarker}`)}if(!next.includes(`pathname === "${spec.routePath}"`)){let routeMarker=' sendJsonError(res, requestId, 404, "not_found", "Route not found");';if(!next.includes(routeMarker))throw new Error("\u65E0\u6CD5\u5728 src/app.js \u4E2D\u627E\u5230 404 \u8DEF\u7531\u843D\u70B9\uFF0C\u6682\u65F6\u65E0\u6CD5\u81EA\u52A8\u6CE8\u5165 debug scaffold \u8DEF\u7531\u3002");let routeBlock=[` if (pathname === "${spec.routePath}" && req.method === "GET") {`,' res.setHeader("content-type", "text/html; charset=utf-8");'," res.writeHead(200);",` res.end(${spec.renderCall});`," return;"," }",""].join(`
2371
2371
  `);next=next.replace(routeMarker,`${routeBlock}
@@ -2376,19 +2376,19 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
2376
2376
  `)}function buildDbDebugPageSource(){return["export function renderDbDebugPage() {"," return `<!doctype html>",'<html lang="zh-CN">'," <head>",' <meta charset="utf-8" />',' <meta name="viewport" content="width=device-width, initial-scale=1" />'," <title>DB Debug</title>"," <style>",' :root { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color-scheme: light; }'," body { margin: 0; background: #f8fafc; color: #0f172a; }"," main { width: min(1080px, calc(100vw - 32px)); margin: 40px auto; padding: 32px; border-radius: 24px; background: #fff; border: 1px solid #e2e8f0; box-shadow: 0 24px 80px rgba(15,23,42,.08); }"," h1 { margin: 0 0 12px; font-size: 32px; }"," p { margin: 0 0 12px; color: #475569; line-height: 1.7; }"," .status { margin-top: 16px; padding: 12px 14px; border-radius: 14px; border: 1px solid #e2e8f0; background: #f8fafc; color: #334155; }"," .status-neutral { background: #f8fafc; border-color: #e2e8f0; color: #334155; }"," .status-success { background: #ecfdf5; border-color: #86efac; color: #166534; }"," .status-warning { background: #fffbeb; border-color: #fcd34d; color: #92400e; }"," .status-error { background: #fff1f2; border-color: #fecdd3; color: #be123c; }"," .grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 20px; }"," .card { border: 1px solid #e2e8f0; border-radius: 16px; padding: 16px; }"," .label { font-size: 12px; color: #64748b; }"," .value { margin-top: 8px; font-weight: 600; word-break: break-word; }"," .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }"," .actions { display: flex; gap: 12px; margin-top: 20px; flex-wrap: wrap; }"," button, a { border: 0; border-radius: 12px; padding: 12px 16px; font: inherit; font-weight: 600; cursor: pointer; background: #0f172a; color: #fff; text-decoration: none; display: inline-flex; align-items: center; }"," button.secondary, a.secondary { background: #fff; color: #0f172a; border: 1px solid #cbd5e1; }"," ul { margin: 0; padding-left: 20px; color: #334155; }"," li { margin: 8px 0; }"," pre { margin: 0; white-space: pre-wrap; word-break: break-word; }"," @media (max-width: 720px) { .grid { grid-template-columns: 1fr; } }"," </style>"," </head>"," <body>"," <main>"," <h1>DB \u6700\u5C0F\u8054\u8C03\u9875</h1>"," <p>\u8FD9\u4E2A\u9875\u9762\u53EA\u7528\u4E8E\u672C\u5730\u6216 preview \u8054\u8C03\u5E73\u53F0 DB \u7ED1\u5B9A\uFF0C\u4E0D\u5C5E\u4E8E\u6B63\u5F0F\u4E1A\u52A1\u9875\u9762\u3002\u5B83\u4F1A\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u7684 DB \u7ED1\u5B9A\u4E0A\u4E0B\u6587\uFF0C\u5E76\u63D0\u793A\u4F60\u7EE7\u7EED\u4F7F\u7528 `platform db` \u548C `platform dev --remote-bindings` \u9A8C\u8BC1\u771F\u5B9E\u8868\u7ED3\u6784\u4E0E\u67E5\u8BE2\u3002</p>",' <div class="status status-neutral" id="status">\u6B63\u5728\u8BFB\u53D6 DB \u7ED1\u5B9A\u4E0A\u4E0B\u6587...</div>',' <div class="grid">',' <div class="card"><div class="label">\u5F53\u524D\u79DF\u6237 / \u5E94\u7528 / \u73AF\u5883</div><div class="value mono" id="identity">-</div></div>',' <div class="card"><div class="label">DATABASE_URL \u6CE8\u5165\u72B6\u6001</div><div class="value mono" id="db-ready">-</div></div>',' <div class="card"><div class="label">DATABASE_SCHEMA</div><div class="value mono" id="db-schema">-</div></div>',' <div class="card"><div class="label">Capability Version</div><div class="value mono" id="db-capability">-</div></div>'," </div>",' <div class="card" style="margin-top:16px"><div class="label">\u540E\u7AEF\u8FD4\u56DE\u7684 DB \u4E0A\u4E0B\u6587</div><div class="value"><pre id="db-context">-</pre></div></div>',' <div class="card" style="margin-top:16px"><div class="label">\u4E0B\u4E00\u6B65\u5EFA\u8BAE</div><div class="value"><ul><li>\u5148\u8DD1 <code>platform db status</code> \u770B binding / schema / migration\u3002</li><li>\u518D\u8DD1 <code>platform db tables</code> \u6216 <code>platform db query --sql "SELECT ..."</code> \u786E\u8BA4\u771F\u5B9E\u8868\u7ED3\u6784\u3002</li><li>\u5982\u679C\u4F60\u8981\u9A8C\u8BC1\u5E94\u7528\u4EE3\u7801\u76F4\u8FDE DB\uFF0C\u4F7F\u7528 <code>platform dev --remote-bindings</code>\uFF0C\u4E0D\u8981\u53EA\u8DD1\u666E\u901A <code>platform dev</code>\u3002</li></ul></div></div>',' <div class="actions">',' <button id="refresh" type="button">\u5237\u65B0\u72B6\u6001</button>',' <a class="secondary" href="/app">\u8FD4\u56DE\u4E1A\u52A1\u9875</a>'," </div>"," </main>",' <script type="module">'," import { getRuntimeStatusFromError, applyRuntimeStatus } from '/assets/platform-runtime.js';"," const statusEl = document.getElementById('status');"," const identityEl = document.getElementById('identity');"," const dbReadyEl = document.getElementById('db-ready');"," const dbSchemaEl = document.getElementById('db-schema');"," const dbCapabilityEl = document.getElementById('db-capability');"," const dbContextEl = document.getElementById('db-context');"," const refreshEl = document.getElementById('refresh');"," async function refreshDbDebug() {"," applyRuntimeStatus(statusEl, { tone: 'neutral', message: '\u6B63\u5728\u8BFB\u53D6 DB \u8C03\u8BD5\u72B6\u6001...' });"," try {"," const [context, dbContext] = await Promise.all(["," fetch('/api/me').then((item) => item.json()).catch(() => null),"," fetch('/api/debug/db-context').then((item) => item.json()).catch(() => null)"," ]);"," identityEl.textContent = [dbContext?.tenant_id || context?.tenant_id || '-', dbContext?.app_id || context?.app_id || '-', dbContext?.env || context?.env || '-'].join(' / ');"," dbReadyEl.textContent = dbContext?.database_ready ? 'ready' : 'not_injected';"," dbSchemaEl.textContent = dbContext?.database_schema || '-';"," dbCapabilityEl.textContent = dbContext?.database_capability_version || '-';"," dbContextEl.textContent = dbContext ? JSON.stringify(dbContext, null, 2) : '-';"," applyRuntimeStatus(statusEl, dbContext?.database_ready"," ? { tone: 'success', message: '\u5DF2\u68C0\u6D4B\u5230 DATABASE_URL\u3002\u4E0B\u4E00\u6B65\u8BF7\u7528 platform db tables/query \u9A8C\u8BC1\u771F\u5B9E\u8868\u7ED3\u6784\u3002' }"," : { tone: 'warning', message: '\u5F53\u524D\u8FD8\u6CA1\u68C0\u6D4B\u5230 DATABASE_URL\u3002\u82E5\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u8BF7\u6539\u7528 platform dev --remote-bindings\u3002' });"," } catch (error) {"," applyRuntimeStatus(statusEl, getRuntimeStatusFromError(error, 'DB \u8C03\u8BD5\u9875\u521D\u59CB\u5316\u5931\u8D25\u3002'));"," }"," }"," refreshEl.addEventListener('click', () => { void refreshDbDebug(); });"," void refreshDbDebug();"," </script>"," </body>","</html>`;","}",""].join(`
2377
2377
  `)}function resolveWorkspaceDevTarget(target){if(!target)return null;let workspaceRoot=findWorkspaceRoot();return{command:`corepack pnpm --filter ${target.startsWith("@platform/")?target:`@platform/${target}`} dev`,cwd:workspaceRoot}}function buildDevEnvironment(binding,runtimeBindings={}){return{...process.env,PLATFORM_ACTIVE_TENANT_ID:binding?.tenant_id??"",PLATFORM_ACTIVE_APP_ID:binding?.app_id??"",PLATFORM_ACTIVE_ENV:binding?.env??"",PLATFORM_ACTIVE_APP_NAME:binding?.app_name??"",APP_ID:process.env.APP_ID??binding?.app_id??"",APP_ENV:process.env.APP_ENV??binding?.env??"preview",TENANT_ID:process.env.TENANT_ID??runtimeBindings.TENANT_ID??binding?.tenant_id??"",PUBLIC_APP_BASE_URL:process.env.PUBLIC_APP_BASE_URL??runtimeBindings.PUBLIC_APP_BASE_URL??"",CONTROL_API_BASE_URL:process.env.CONTROL_API_BASE_URL??runtimeBindings.CONTROL_API_BASE_URL??DEFAULT_CONTROL_API_BASE_URL,DATABASE_URL:process.env.DATABASE_URL??runtimeBindings.DATABASE_URL??"",DATABASE_SCHEMA:process.env.DATABASE_SCHEMA??runtimeBindings.DATABASE_SCHEMA??"",DATABASE_MIGRATOR_ROLE:process.env.DATABASE_MIGRATOR_ROLE??runtimeBindings.DATABASE_MIGRATOR_ROLE??"",DATABASE_RUNTIME_ROLE:process.env.DATABASE_RUNTIME_ROLE??runtimeBindings.DATABASE_RUNTIME_ROLE??"",DATABASE_CAPABILITY_VERSION:process.env.DATABASE_CAPABILITY_VERSION??runtimeBindings.DATABASE_CAPABILITY_VERSION??""}}function detectLocalDependencyInstallPlan(appDir){let packageJsonPath=join4(appDir,"package.json"),nodeModulesPath=join4(appDir,"node_modules");if(!existsSync8(packageJsonPath)||existsSync8(nodeModulesPath))return null;let npmCommand=process.platform==="win32"?"npm.cmd":"npm",corepackCommand=process.platform==="win32"?"corepack.cmd":"corepack",yarnCommand=process.platform==="win32"?"yarn.cmd":"yarn";return existsSync8(join4(appDir,"package-lock.json"))?{command:npmCommand,args:["install"],lockfile:"package-lock.json"}:existsSync8(join4(appDir,"pnpm-lock.yaml"))?{command:corepackCommand,args:["pnpm","install","--frozen-lockfile"],lockfile:"pnpm-lock.yaml"}:existsSync8(join4(appDir,"yarn.lock"))?{command:yarnCommand,args:["install","--frozen-lockfile"],lockfile:"yarn.lock"}:null}function detectRequestedRemoteBindings(startDir=process.cwd()){let capabilities=new Set;try{let appRoot=findAppRoot(startDir);workspaceHasEffectiveDbMigration(appRoot)&&capabilities.add("db")}catch{return[]}return[...capabilities]}function templatePrefersPlatformCapabilityBindings(templateKey){return templateKey==="frontend-app-vite"||templateKey==="backend-app-node"}function recommendDevCommandForTemplate(templateKey,options={}){return(options.requestedRemoteBindings??[]).includes("db")?"platform dev --remote-bindings=db":templatePrefersPlatformCapabilityBindings(templateKey)?"platform dev --remote-bindings":null}function workspaceHasEffectiveDbMigration(appRoot){let migrationsDir=join4(appRoot,"resources","db","migrations");if(!existsSync8(migrationsDir)||!statSync3(migrationsDir).isDirectory())return!1;for(let entry of readdirSync2(migrationsDir,{withFileTypes:!0})){if(!entry.isFile())continue;if(readFileSync8(join4(migrationsDir,entry.name),"utf8").split(`
2378
2378
  `).map(line=>line.replace(/--.*$/,"").trim()).filter(Boolean).join(`
2379
- `).trim().length>0)return!0}return!1}async function resolveAvailableLocalDevPort(preferredPort,options={}){let host=options.host;return await canBindPort(preferredPort,host)?{port:preferredPort,reusedPreferred:!0}:{port:await allocateEphemeralPort(host),reusedPreferred:!1}}async function canBindPort(port,host){return new Promise(resolve17=>{let server=createNetServer(),finish=available=>{server.removeAllListeners(),resolve17(available)};server.once("error",()=>{finish(!1)});let onListening=()=>{server.close(()=>finish(!0))};if(host){server.listen(port,host,onListening);return}server.listen(port,onListening)})}async function allocateEphemeralPort(host){return new Promise((resolve17,reject)=>{let server=createNetServer();server.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))});let onListening=()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u4E3A\u672C\u5730 dev \u5206\u914D\u56DE\u9000\u7AEF\u53E3\u3002")));return}let{port}=address;server.close(error=>{if(error){reject(error);return}resolve17(port)})};if(host){server.listen(0,host,onListening);return}server.listen(0,onListening)})}function collectDevPreflight(startDir=process.cwd(),target,runtimeBindings={}){let{manifest,directory}=readAppManifest(startDir),linked=readBinding(startDir);if(!linked?.binding.tenant_id||!linked.binding.app_id){let sourceContextPath=join4(directory,SOURCE_CONTEXT_FILE);throw new Error(existsSync8(sourceContextPath)?"\u5F53\u524D\u9879\u76EE\u672A\u7ED1\u5B9A tenant/app/env\u3002\u4F18\u5148\u5EFA\u8BAE\u6267\u884C `platform app create ...` \u6216 `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u53D6\u4E00\u4E2A\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u8981\u4FEE\u590D\u5F53\u524D\u76EE\u5F55\uFF0C\u518D\u624B\u52A8\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002":"\u5F53\u524D\u76EE\u5F55\u5DF2\u68C0\u6D4B\u5230 `app.yaml`\uFF0C\u4F46\u7F3A\u5C11 `.platform/source-context.json`\uFF0C\u770B\u8D77\u6765\u50CF\u4E00\u4E2A\u5DF2\u8FC1\u79FB\u6216\u672A\u91CD\u65B0\u7ED1\u5B9A\u7684\u5E94\u7528\u5DE5\u7A0B\u3002\u8BF7\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview` \u91CD\u65B0\u7ED1\u5B9A\u5F53\u524D\u76EE\u5F55\u3002")}let sourceContext=readSourceContext(startDir)?.sourceContext,workspaceTarget=resolveWorkspaceDevTarget(target),command=workspaceTarget?.command??manifest.entry.command,cwd=workspaceTarget?.cwd??directory,env=buildDevEnvironment(linked.binding,runtimeBindings),port=Number(env.PORT||manifest.entry.port||3e3);env.PUBLIC_APP_BASE_URL||(env.PUBLIC_APP_BASE_URL=`http://127.0.0.1:${port}`);let healthPath=manifest.entry.health_check||"/healthz",resolvedTemplateKey=typeof sourceContext?.template_key=="string"&&sourceContext.template_key.trim().length>0?sourceContext.template_key.trim():manifest.template_key,devCommandAnalysis=analyzeDevCommand(command,cwd),previewAddressMayChange=!manifest.dev.auto_restart&&devCommandAnalysis.portMayChange,warnings=["\u5F53\u524D\u9ED8\u8BA4\u8D70\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF1A\u672C\u5730\u5F00\u53D1\u4E0D\u8981\u6C42 registry\u3001kind\u3001ingress-nginx \u6216 build-runner\u3002",`\u5F53\u524D\u542F\u52A8\u547D\u4EE4\u6765\u81EA app.yaml \u7684 entry.command\uFF1A${command}`];return manifest.dev.auto_restart?warnings.push("\u5F53\u524D app.yaml \u5DF2\u914D\u7F6E `dev.auto_restart: true`\uFF1BCLI \u4F1A\u5728\u68C0\u6D4B\u5230\u6E90\u7801\u53D8\u66F4\u540E\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002"):devCommandAnalysis.managedByCommand?warnings.push(devCommandAnalysis.message):warnings.push("\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"),env.DATABASE_URL||warnings.push("\u672A\u68C0\u6D4B\u5230 DATABASE_URL\uFF1B\u672C\u5730\u6A21\u677F\u63A5\u53E3\u548C\u9875\u9762\u5F00\u53D1\u4ECD\u53EF\u7EE7\u7EED\u3002\u82E5\u4F60\u9700\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u518D\u6267\u884C `platform dev --remote-bindings` \u6216\u624B\u52A8\u8BBE\u7F6E\u672C\u5730\u73AF\u5883\u53D8\u91CF\u3002"),templatePrefersPlatformCapabilityBindings(resolvedTemplateKey)&&warnings.push("\u5F53\u524D\u5B98\u65B9\u6A21\u677F\u9ED8\u8BA4\u5E26 Auth / CMS / Data Form \u793A\u4F8B\u9875\u3002\u82E5\u4F60\u8981\u8054\u8C03\u8FD9\u4E9B\u771F\u5B9E\u5E73\u53F0\u80FD\u529B\uFF0C\u5EFA\u8BAE\u76F4\u63A5\u6267\u884C `platform dev --remote-bindings`\u3002"),!process.env.PUBLIC_APP_BASE_URL&&!runtimeBindings.PUBLIC_APP_BASE_URL&&warnings.push(`\u672A\u663E\u5F0F\u914D\u7F6E PUBLIC_APP_BASE_URL\uFF1B\u672C\u5730 dev \u5DF2\u4E34\u65F6\u56DE\u9000\u4E3A ${env.PUBLIC_APP_BASE_URL}\u3002`),resolvedTemplateKey&&resolvedTemplateKey!=="frontend-app-vite"&&resolvedTemplateKey!=="backend-app-node"&&warnings.push(`\u5F53\u524D\u6A21\u677F\u4E3A ${resolvedTemplateKey}\uFF0C\u8BF7\u786E\u8BA4\u5165\u53E3\u547D\u4EE4\u4E0E\u5065\u5EB7\u68C0\u67E5\u8DEF\u5F84\u5DF2\u7ECF\u548C app.yaml \u5BF9\u9F50\u3002`),{binding:linked.binding,manifest,templateKey:resolvedTemplateKey,directory,command,cwd,env,healthcheckUrl:`http://localhost:${port}${healthPath}`,previewAddressMayChange,warnings}}function analyzeDevCommand(command,cwd){if(/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch)/iu.test(command))return{managedByCommand:!0,portMayChange:/\bvite\b/iu.test(command),message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u5DF2\u5305\u542B watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"};let npmScriptMatch=command.trim().match(/^(?:npm|pnpm|yarn)\s+run\s+([a-zA-Z0-9:_-]+)|^corepack\s+pnpm\s+run\s+([a-zA-Z0-9:_-]+)/u),scriptName=npmScriptMatch?.[1]??npmScriptMatch?.[2];if(!scriptName)return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};let packageJsonPath=join4(cwd,"package.json");if(!existsSync8(packageJsonPath))return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};try{let scriptCommand=JSON.parse(readFileSync8(packageJsonPath,"utf8")).scripts?.[scriptName];if(typeof scriptCommand=="string"&&/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch|scripts\/dev\.mjs|scripts\\dev\.mjs)/iu.test(scriptCommand))return{managedByCommand:!0,portMayChange:/\bvite\b|scripts\/dev\.mjs|scripts\\dev\.mjs/iu.test(scriptCommand),message:scriptCommand.includes("scripts/dev.mjs")?"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7\u6A21\u677F\u81EA\u5E26\u7684\u672C\u5730 dev \u7F16\u6392\u811A\u672C\u542F\u52A8\uFF1B\u524D\u7AEF\u70ED\u66F4\u65B0\u4E0E\u670D\u52A1\u7AEF\u81EA\u52A8\u91CD\u542F\u7531\u6A21\u677F\u81EA\u5DF1\u7BA1\u7406\uFF0CCLI \u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002":"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7 package.json script \u81EA\u5E26 watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"}}catch{return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}async function runAppLibraryCommand(args,deps={}){let subcommand=args.rest[0];if(hasHelpFlag2(args)||args.rest.length===0||subcommand==="help"){printAppLibraryHelp();return}let sdk=deps.sdk,tenantId=deps.tenantId;if(!sdk||!tenantId){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");if(tenantId=deps.tenantId??resolveTenantId(args),!tenantId)throw new Error("`platform app-library` \u9700\u8981 tenant \u4E0A\u4E0B\u6587\u3002\u8BF7\u5148\u5728\u5F53\u524D\u9879\u76EE\u7ED1\u5B9A tenant/app\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant`\u3002");sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"dashboard",requestClass:"control"})}switch(subcommand){case"list":await runList(args,sdk);return;case"search":await runSearch(args,sdk);return;case"inspect":await runInspect(args,sdk);return;case"source":await runSource(args,sdk);return;case"config":await runConfig(args);return;case"open":await runOpen(args,deps);return;case"checkout":await runCheckout(args,sdk);return;case"create":await runCreate(args,sdk);return;case"update":await runUpdate(args,sdk);return;case"submit":await runSubmit(args,sdk,deps);return;case"publish":await runStateAction(args,sdk,"publish");return;case"unpublish":await runStateAction(args,sdk,"unpublish");return;case"archive":await runStateAction(args,sdk,"archive");return;case"delete":await runDelete(args,sdk);return;default:throw new Error("`platform app-library` \u4EC5\u652F\u6301 `list`\u3001`search`\u3001`inspect`\u3001`source`\u3001`config`\u3001`open`\u3001`checkout`\u3001`create`\u3001`update`\u3001`submit`\u3001`publish`\u3001`unpublish`\u3001`archive`\u3001`delete`\u3002")}}function printAppLibraryHelp(){process.stdout.write(["platform app-library <command>","","Commands:"," platform app-library list [--query <keyword>] [--status draft|published|unpublished|archived] [--tag <tag>] [--template-key <key>] [--visibility private|public] [--full] [--json]"," platform app-library search <keyword> [--status draft|published|unpublished|archived] [--full] [--json]"," platform app-library inspect <entry-id> [--json]"," platform app-library source tree <entry-id> [--json]"," platform app-library source read <entry-id> <path> [--json]"," platform app-library source search <entry-id> <query> [--json]"," platform app-library config init [--file app-library.yaml] [--force]"," platform app-library config validate [--file app-library.yaml] [--json]"," platform app-library open <entry-id> [--no-browser]"," platform app-library checkout <entry-id> [--dir <target-dir>] [--write-config] [--no-config] [--json]"," platform app-library create [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library update <entry-id> [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library submit <entry-id> [--file app-library.yaml] [--json]"," platform app-library publish <entry-id> [--json]"," platform app-library unpublish <entry-id> [--json]"," platform app-library archive <entry-id> [--json]"," platform app-library delete <entry-id> [--json]","","Notes:"," - \u521D\u671F\u4EC5\u652F\u6301 `example-app` \u6761\u76EE"," - `list` / `search` \u9ED8\u8BA4\u8FD4\u56DE\u8F7B\u6458\u8981\uFF1B\u5982\u9700\u5B8C\u6574\u5B57\u6BB5\u8BF7\u663E\u5F0F\u4F20 `--full`\uFF0C\u6216\u8FDB\u4E00\u6B65\u6267\u884C `inspect`"," - `list` / `search` \u9ED8\u8BA4\u4F1A\u67E5\u8BE2\u672C\u79DF\u6237 + \u8DE8\u79DF\u6237\u5DF2\u53D1\u5E03\u6761\u76EE\uFF1B\u5982\u663E\u5F0F\u4F20 `--status draft|unpublished|archived`\uFF0C\u5219\u4EC5\u67E5\u8BE2\u672C\u79DF\u6237\u6761\u76EE"," - `submit` \u9700\u8981\u5728\u672C\u5730\u8F7B\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u4F1A\u8BFB\u53D6\u5F53\u524D\u6E90\u7801\u5DE5\u4F5C\u533A\u5E76\u4E0A\u4F20\u4E3A\u5F53\u524D\u5FEB\u7167"," - \u5143\u6570\u636E\u9ED8\u8BA4\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u6839\u76EE\u5F55\u4E0B\u7684 `app-library.yaml`\uFF0CCLI flags \u53EF\u8986\u76D6\u540C\u540D\u5B57\u6BB5"," - `create` / `update` \u5728\u68C0\u6D4B\u5230\u73B0\u6709\u914D\u7F6E\u6587\u4EF6\u6216\u663E\u5F0F\u4F20\u5165 `--write-config` \u65F6\uFF0C\u4F1A\u628A\u6700\u65B0\u5143\u6570\u636E\u56DE\u5199\u5230 `app-library.yaml`"," - `checkout` \u9ED8\u8BA4\u5728\u76EE\u6807\u6E90\u7801\u4E0D\u5305\u542B `app-library.yaml` \u65F6\u81EA\u52A8\u751F\u6210\u4E00\u4EFD\uFF1B\u53EF\u7528 `--write-config` \u5F3A\u5236\u8986\u76D6\uFF0C`--no-config` \u8DF3\u8FC7"," - `open` \u9ED8\u8BA4\u6253\u5F00\u672C\u5730 tenant-workbench \u7684 `#app-library/<entry-id>` \u8DEF\u7531"," - `source tree/read/search` \u7528\u4E8E\u4E0D checkout \u7684\u4E91\u7AEF\u6E90\u7801\u7406\u89E3",""].join(`
2379
+ `).trim().length>0)return!0}return!1}async function resolveAvailableLocalDevPort(preferredPort,options={}){let host=options.host;return await canBindPort(preferredPort,host)?{port:preferredPort,reusedPreferred:!0}:{port:await allocateEphemeralPort(host),reusedPreferred:!1}}async function canBindPort(port,host){return new Promise(resolve19=>{let server=createNetServer(),finish=available=>{server.removeAllListeners(),resolve19(available)};server.once("error",()=>{finish(!1)});let onListening=()=>{server.close(()=>finish(!0))};if(host){server.listen(port,host,onListening);return}server.listen(port,onListening)})}async function allocateEphemeralPort(host){return new Promise((resolve19,reject)=>{let server=createNetServer();server.once("error",error=>{reject(error instanceof Error?error:new Error(String(error)))});let onListening=()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u4E3A\u672C\u5730 dev \u5206\u914D\u56DE\u9000\u7AEF\u53E3\u3002")));return}let{port}=address;server.close(error=>{if(error){reject(error);return}resolve19(port)})};if(host){server.listen(0,host,onListening);return}server.listen(0,onListening)})}function collectDevPreflight(startDir=process.cwd(),target,runtimeBindings={}){let{manifest,directory}=readAppManifest(startDir),linked=readBinding(startDir);if(!linked?.binding.tenant_id||!linked.binding.app_id){let sourceContextPath=join4(directory,SOURCE_CONTEXT_FILE);throw new Error(existsSync8(sourceContextPath)?"\u5F53\u524D\u9879\u76EE\u672A\u7ED1\u5B9A tenant/app/env\u3002\u4F18\u5148\u5EFA\u8BAE\u6267\u884C `platform app create ...` \u6216 `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>` \u83B7\u53D6\u4E00\u4E2A\u5DF2\u7ED1\u5B9A\u76EE\u5F55\uFF1B\u82E5\u4F60\u8981\u4FEE\u590D\u5F53\u524D\u76EE\u5F55\uFF0C\u518D\u624B\u52A8\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002":"\u5F53\u524D\u76EE\u5F55\u5DF2\u68C0\u6D4B\u5230 `app.yaml`\uFF0C\u4F46\u7F3A\u5C11 `.platform/source-context.json`\uFF0C\u770B\u8D77\u6765\u50CF\u4E00\u4E2A\u5DF2\u8FC1\u79FB\u6216\u672A\u91CD\u65B0\u7ED1\u5B9A\u7684\u5E94\u7528\u5DE5\u7A0B\u3002\u8BF7\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview` \u91CD\u65B0\u7ED1\u5B9A\u5F53\u524D\u76EE\u5F55\u3002")}let sourceContext=readSourceContext(startDir)?.sourceContext,workspaceTarget=resolveWorkspaceDevTarget(target),command=workspaceTarget?.command??manifest.entry.command,cwd=workspaceTarget?.cwd??directory,env=buildDevEnvironment(linked.binding,runtimeBindings),port=Number(env.PORT||manifest.entry.port||3e3);env.PUBLIC_APP_BASE_URL||(env.PUBLIC_APP_BASE_URL=`http://127.0.0.1:${port}`);let healthPath=manifest.entry.health_check||"/healthz",resolvedTemplateKey=typeof sourceContext?.template_key=="string"&&sourceContext.template_key.trim().length>0?sourceContext.template_key.trim():manifest.template_key,devCommandAnalysis=analyzeDevCommand(command,cwd),previewAddressMayChange=!manifest.dev.auto_restart&&devCommandAnalysis.portMayChange,warnings=["\u5F53\u524D\u9ED8\u8BA4\u8D70\u8F7B\u91CF\u5F00\u53D1\u6A21\u5F0F\uFF1A\u672C\u5730\u5F00\u53D1\u4E0D\u8981\u6C42 registry\u3001kind\u3001ingress-nginx \u6216 build-runner\u3002",`\u5F53\u524D\u542F\u52A8\u547D\u4EE4\u6765\u81EA app.yaml \u7684 entry.command\uFF1A${command}`];return manifest.dev.auto_restart?warnings.push("\u5F53\u524D app.yaml \u5DF2\u914D\u7F6E `dev.auto_restart: true`\uFF1BCLI \u4F1A\u5728\u68C0\u6D4B\u5230\u6E90\u7801\u53D8\u66F4\u540E\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002"):devCommandAnalysis.managedByCommand?warnings.push(devCommandAnalysis.message):warnings.push("\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"),env.DATABASE_URL||warnings.push("\u672A\u68C0\u6D4B\u5230 DATABASE_URL\uFF1B\u672C\u5730\u6A21\u677F\u63A5\u53E3\u548C\u9875\u9762\u5F00\u53D1\u4ECD\u53EF\u7EE7\u7EED\u3002\u82E5\u4F60\u9700\u8981\u8054\u8C03\u5E73\u53F0 DB\uFF0C\u518D\u6267\u884C `platform dev --remote-bindings` \u6216\u624B\u52A8\u8BBE\u7F6E\u672C\u5730\u73AF\u5883\u53D8\u91CF\u3002"),templatePrefersPlatformCapabilityBindings(resolvedTemplateKey)&&warnings.push("\u5F53\u524D\u5B98\u65B9\u6A21\u677F\u9ED8\u8BA4\u5E26 Auth / CMS / Data Form \u793A\u4F8B\u9875\u3002\u82E5\u4F60\u8981\u8054\u8C03\u8FD9\u4E9B\u771F\u5B9E\u5E73\u53F0\u80FD\u529B\uFF0C\u5EFA\u8BAE\u76F4\u63A5\u6267\u884C `platform dev --remote-bindings`\u3002"),!process.env.PUBLIC_APP_BASE_URL&&!runtimeBindings.PUBLIC_APP_BASE_URL&&warnings.push(`\u672A\u663E\u5F0F\u914D\u7F6E PUBLIC_APP_BASE_URL\uFF1B\u672C\u5730 dev \u5DF2\u4E34\u65F6\u56DE\u9000\u4E3A ${env.PUBLIC_APP_BASE_URL}\u3002`),resolvedTemplateKey&&resolvedTemplateKey!=="frontend-app-vite"&&resolvedTemplateKey!=="backend-app-node"&&warnings.push(`\u5F53\u524D\u6A21\u677F\u4E3A ${resolvedTemplateKey}\uFF0C\u8BF7\u786E\u8BA4\u5165\u53E3\u547D\u4EE4\u4E0E\u5065\u5EB7\u68C0\u67E5\u8DEF\u5F84\u5DF2\u7ECF\u548C app.yaml \u5BF9\u9F50\u3002`),{binding:linked.binding,manifest,templateKey:resolvedTemplateKey,directory,command,cwd,env,healthcheckUrl:`http://localhost:${port}${healthPath}`,previewAddressMayChange,warnings}}function analyzeDevCommand(command,cwd){if(/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch)/iu.test(command))return{managedByCommand:!0,portMayChange:/\bvite\b/iu.test(command),message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u5DF2\u5305\u542B watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"};let npmScriptMatch=command.trim().match(/^(?:npm|pnpm|yarn)\s+run\s+([a-zA-Z0-9:_-]+)|^corepack\s+pnpm\s+run\s+([a-zA-Z0-9:_-]+)/u),scriptName=npmScriptMatch?.[1]??npmScriptMatch?.[2];if(!scriptName)return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};let packageJsonPath=join4(cwd,"package.json");if(!existsSync8(packageJsonPath))return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"};try{let scriptCommand=JSON.parse(readFileSync8(packageJsonPath,"utf8")).scripts?.[scriptName];if(typeof scriptCommand=="string"&&/(--watch|\bwatch\b|nodemon|vite|next dev|webpack serve|tsx watch|scripts\/dev\.mjs|scripts\\dev\.mjs)/iu.test(scriptCommand))return{managedByCommand:!0,portMayChange:/\bvite\b|scripts\/dev\.mjs|scripts\\dev\.mjs/iu.test(scriptCommand),message:scriptCommand.includes("scripts/dev.mjs")?"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7\u6A21\u677F\u81EA\u5E26\u7684\u672C\u5730 dev \u7F16\u6392\u811A\u672C\u542F\u52A8\uFF1B\u524D\u7AEF\u70ED\u66F4\u65B0\u4E0E\u670D\u52A1\u7AEF\u81EA\u52A8\u91CD\u542F\u7531\u6A21\u677F\u81EA\u5DF1\u7BA1\u7406\uFF0CCLI \u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002":"\u5F53\u524D\u547D\u4EE4\u901A\u8FC7 package.json script \u81EA\u5E26 watch / \u70ED\u66F4\u65B0\u80FD\u529B\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u989D\u5916\u63A5\u7BA1\u81EA\u52A8\u91CD\u542F\u3002"}}catch{return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}return{managedByCommand:!1,portMayChange:!1,message:"\u5F53\u524D\u547D\u4EE4\u81EA\u8EAB\u4E0D\u5E26\u70ED\u66F4\u65B0\uFF1BCLI \u9ED8\u8BA4\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u3002\u82E5\u4F60\u9700\u8981\u81EA\u52A8\u91CD\u542F\uFF0C\u8BF7\u5728 app.yaml \u4E2D\u663E\u5F0F\u914D\u7F6E `dev.auto_restart: true`\u3002"}}async function runAppLibraryCommand(args,deps={}){let subcommand=args.rest[0];if(hasHelpFlag2(args)||args.rest.length===0||subcommand==="help"){printAppLibraryHelp();return}let sdk=deps.sdk,tenantId=deps.tenantId;if(!sdk||!tenantId){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");if(tenantId=deps.tenantId??resolveTenantId(args),!tenantId)throw new Error("`platform app-library` \u9700\u8981 tenant \u4E0A\u4E0B\u6587\u3002\u8BF7\u5148\u5728\u5F53\u524D\u9879\u76EE\u7ED1\u5B9A tenant/app\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant`\u3002");sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"dashboard",requestClass:"control"})}switch(subcommand){case"list":await runList(args,sdk);return;case"search":await runSearch(args,sdk);return;case"inspect":await runInspect(args,sdk);return;case"source":await runSource(args,sdk);return;case"config":await runConfig(args);return;case"open":await runOpen(args,deps);return;case"checkout":await runCheckout(args,sdk);return;case"create":await runCreate(args,sdk);return;case"update":await runUpdate(args,sdk);return;case"submit":await runSubmit(args,sdk,deps);return;case"publish":await runStateAction(args,sdk,"publish");return;case"unpublish":await runStateAction(args,sdk,"unpublish");return;case"archive":await runStateAction(args,sdk,"archive");return;case"delete":await runDelete(args,sdk);return;default:throw new Error("`platform app-library` \u4EC5\u652F\u6301 `list`\u3001`search`\u3001`inspect`\u3001`source`\u3001`config`\u3001`open`\u3001`checkout`\u3001`create`\u3001`update`\u3001`submit`\u3001`publish`\u3001`unpublish`\u3001`archive`\u3001`delete`\u3002")}}function printAppLibraryHelp(){process.stdout.write(["platform app-library <command>","","Commands:"," platform app-library list [--query <keyword>] [--status draft|published|unpublished|archived] [--tag <tag>] [--template-key <key>] [--visibility private|public] [--full] [--json]"," platform app-library search <keyword> [--status draft|published|unpublished|archived] [--full] [--json]"," platform app-library inspect <entry-id> [--json]"," platform app-library source tree <entry-id> [--json]"," platform app-library source read <entry-id> <path> [--json]"," platform app-library source search <entry-id> <query> [--json]"," platform app-library config init [--file app-library.yaml] [--force]"," platform app-library config validate [--file app-library.yaml] [--json]"," platform app-library open <entry-id> [--no-browser]"," platform app-library checkout <entry-id> [--dir <target-dir>] [--write-config] [--no-config] [--json]"," platform app-library create [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library update <entry-id> [--file app-library.yaml] [--name <name>] [--summary <text>] [--tags a,b] [--template-key <key>] [--write-config] [--json]"," platform app-library submit <entry-id> [--file app-library.yaml] [--json]"," platform app-library publish <entry-id> [--json]"," platform app-library unpublish <entry-id> [--json]"," platform app-library archive <entry-id> [--json]"," platform app-library delete <entry-id> [--json]","","Notes:"," - \u521D\u671F\u4EC5\u652F\u6301 `example-app` \u6761\u76EE"," - `list` / `search` \u9ED8\u8BA4\u8FD4\u56DE\u8F7B\u6458\u8981\uFF1B\u5982\u9700\u5B8C\u6574\u5B57\u6BB5\u8BF7\u663E\u5F0F\u4F20 `--full`\uFF0C\u6216\u8FDB\u4E00\u6B65\u6267\u884C `inspect`"," - `list` / `search` \u9ED8\u8BA4\u4F1A\u67E5\u8BE2\u672C\u79DF\u6237 + \u8DE8\u79DF\u6237\u5DF2\u53D1\u5E03\u6761\u76EE\uFF1B\u5982\u663E\u5F0F\u4F20 `--status draft|unpublished|archived`\uFF0C\u5219\u4EC5\u67E5\u8BE2\u672C\u79DF\u6237\u6761\u76EE"," - `submit` \u9700\u8981\u5728\u672C\u5730\u8F7B\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u4F1A\u8BFB\u53D6\u5F53\u524D\u6E90\u7801\u5DE5\u4F5C\u533A\u5E76\u4E0A\u4F20\u4E3A\u5F53\u524D\u5FEB\u7167"," - \u5143\u6570\u636E\u9ED8\u8BA4\u8BFB\u53D6\u5F53\u524D\u5E94\u7528\u6839\u76EE\u5F55\u4E0B\u7684 `app-library.yaml`\uFF0CCLI flags \u53EF\u8986\u76D6\u540C\u540D\u5B57\u6BB5"," - `create` / `update` \u5728\u68C0\u6D4B\u5230\u73B0\u6709\u914D\u7F6E\u6587\u4EF6\u6216\u663E\u5F0F\u4F20\u5165 `--write-config` \u65F6\uFF0C\u4F1A\u628A\u6700\u65B0\u5143\u6570\u636E\u56DE\u5199\u5230 `app-library.yaml`"," - `checkout` \u9ED8\u8BA4\u5728\u76EE\u6807\u6E90\u7801\u4E0D\u5305\u542B `app-library.yaml` \u65F6\u81EA\u52A8\u751F\u6210\u4E00\u4EFD\uFF1B\u53EF\u7528 `--write-config` \u5F3A\u5236\u8986\u76D6\uFF0C`--no-config` \u8DF3\u8FC7"," - `open` \u9ED8\u8BA4\u6253\u5F00\u672C\u5730 tenant-workbench \u7684 `#app-library/<entry-id>` \u8DEF\u7531"," - `source tree/read/search` \u7528\u4E8E\u4E0D checkout \u7684\u4E91\u7AEF\u6E90\u7801\u7406\u89E3",""].join(`
2380
2380
  `))}async function runList(args,sdk){let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query:readStringOption2(args,"query"),status,template_key:readStringOption2(args,"template-key"),tag:readStringOption2(args,"tag"),visibility:readVisibilityOption(args,"visibility"),include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"list")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runSearch(args,sdk){let query=args.rest[1]?.trim();if(!query)throw new Error("`platform app-library search` \u9700\u8981 <keyword>\u3002");let status=readStatusOption(args,"status")??"published",includePublic=status==="published",response=await sdk.listLightAppLibraryEntries({query,status,include_public:includePublic}).catch(error=>{throw formatAppLibraryError(error,"search")}),full=args.options.full===!0;writeJsonOrText(args.options.json===!0,full?response:toEntryListBriefPayload(response),[`query: ${query}`,`items: ${response.items.length}`,...response.items.flatMap((item,index)=>formatEntrySummary(item,index+1,full))])}async function runInspect(args,sdk){let config2=loadAppLibraryConfigOptional(),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library inspect` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let[entry,source]=await Promise.all([sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect")}),sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"inspect(source)")})]);writeJsonOrText(args.options.json===!0,{entry,source},[`entry_id: ${entry.entry_id}`,`name: ${entry.name}`,`type: ${entry.type==="example_app"?"example-app":entry.type}`,`status: ${entry.status}`,`library: ${entry.library.name} (${entry.library.visibility})`,`summary: ${entry.summary?.trim()||"-"}`,`tags: ${entry.tags.length?entry.tags.join(", "):"-"}`,`template_key: ${entry.template_key??"-"}`,`capabilities: ${entry.capability_dependencies.length?entry.capability_dependencies.map(item=>item.minVersion?`${item.capability}@${item.minVersion}`:item.capability).join(", "):"-"}`,`current_snapshot_id: ${entry.current_snapshot_id??"-"}`,`source_files: ${source.files.length}`,`key_files: ${source.files.filter(file=>file.is_key_file).slice(0,8).map(file=>file.path).join(", ")||"-"}`,`next.inspect: platform app-library inspect ${entry.entry_id} --json`,`next.checkout: platform app-library checkout ${entry.entry_id} --dir ./${sanitizeDirectoryName(entry.name||entry.entry_id)}`])}async function runSource(args,sdk){let action=args.rest[1];if(action==="tree"){await runSourceTree(args,sdk);return}if(action==="read"){await runSourceRead(args,sdk);return}if(action==="search"){await runSourceSearch(args,sdk);return}throw new Error("`platform app-library source` \u4EC5\u652F\u6301 `tree`\u3001`read`\u3001`search`\u3002")}async function runConfig(args){let action=args.rest[1];if(action==="init"){runConfigInit(args);return}if(action==="validate"){runConfigValidate(args);return}throw new Error("`platform app-library config` \u4EC5\u652F\u6301 `init`\u3001`validate`\u3002")}async function runSourceTree(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source tree` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"source(tree)")});writeJsonOrText(args.options.json===!0,source,[`entry_id: ${entryId}`,`snapshot_id: ${source.snapshot_id}`,`files: ${source.files.length}`,...source.files.map(file=>{let markers=[file.is_key_file?"key":null,file.is_text?"text":"binary",file.ext||"-"].filter(Boolean).join(", ");return`- ${file.path} [${markers}]`})])}async function runSourceRead(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source read` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let path2=args.rest[3]?.trim()||readStringOption2(args,"path");if(!path2)throw new Error("`platform app-library source read` \u9700\u8981 <path>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--path`\u3002");let response=await sdk.readLightAppLibraryEntrySourceFile(entryId,path2).catch(error=>{throw formatAppLibraryError(error,"source(read)")});if(args.options.json===!0){writeJsonOrText(!0,response,[]);return}process.stdout.write(`# ${response.file.path}
2381
2381
 
2382
2382
  `),process.stdout.write(`${response.file.content}${response.file.content.endsWith(`
2383
2383
  `)?"":`
2384
- `}`)}async function runSourceSearch(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source search` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let query=args.rest[3]?.trim()||readStringOption2(args,"query");if(!query)throw new Error("`platform app-library source search` \u9700\u8981 <query>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--query`\u3002");let response=await sdk.searchLightAppLibraryEntrySource(entryId,query).catch(error=>{throw formatAppLibraryError(error,"source(search)")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`query: ${query}`,`items: ${response.items.length}`,...response.items.map(item=>`- ${item.path}${item.excerpt?` :: ${item.excerpt}`:""}`)])}async function runCreate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),payload=buildCreatePayload(args,config2);if(!payload.name?.trim())throw new Error("`platform app-library create` \u9700\u8981\u540D\u79F0\u3002\u8BF7\u5728 `app-library.yaml` \u4E2D\u8BBE\u7F6E `name`\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--name`\u3002");let response=await sdk.createLightAppLibraryEntry(payload).catch(error=>{throw formatAppLibraryError(error,"create")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u8349\u7A3F\u5DF2\u521B\u5EFA\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runUpdate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library update` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"update")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u5DF2\u66F4\u65B0\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runSubmit(args,sdk,deps){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library submit` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");if(config2){let updatedEntry=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"submit(update-metadata)")});maybeWriteConfig(configPath,config2,updatedEntry,args)}let{files,appRoot}=(deps.collectWorkspaceFiles??collectSourceWorkspaceFiles)(process.cwd()),response=await sdk.submitLightAppLibraryEntrySnapshot(entryId,{files}).catch(error=>{throw formatAppLibraryError(error,"submit")});writeJsonOrText(args.options.json===!0,{snapshot:response,app_root:appRoot},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5FEB\u7167\u5DF2\u63D0\u4EA4\u3002",`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`files: ${response.files_count}`,`bytes: ${response.content_bytes}`,`app_root: ${appRoot}`])}async function runStateAction(args,sdk,action){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error(`\`platform app-library ${action}\` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 \`app-library.yaml\` \u4E2D\u63D0\u4F9B \`entry_id\`\u3002`);let response=action==="publish"?await sdk.publishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"publish")}):action==="unpublish"?await sdk.unpublishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"unpublish")}):await sdk.archiveLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"archive")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${response.entry_id}`,`status: ${response.status}`])}async function runDelete(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library delete` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.deleteLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"delete")});writeJsonOrText(args.options.json===!0,response,[`\u5DF2\u5220\u9664\u6761\u76EE ${response.entry_id}`])}async function runCheckout(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library checkout` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let entry=await sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(entry)")}),source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(source)")}),targetDir=readStringOption2(args,"dir")??sanitizeDirectoryName(entry.name||entry.entry_id),absoluteTargetDir=resolve6(process.cwd(),targetDir);ensureEmptyDirectory(absoluteTargetDir);let sourceIncludesConfig=!1;for(let file of source.files){file.path==="app-library.yaml"&&(sourceIncludesConfig=!0);let payload=await sdk.readLightAppLibraryEntrySourceFile(entryId,file.path).catch(error=>{throw formatAppLibraryError(error,`checkout(file:${file.path})`)});writeWorkspaceFile(absoluteTargetDir,payload.file.path,payload.file.content)}let generatedConfigPath=join5(absoluteTargetDir,"app-library.yaml");args.options["no-config"]!==!0&&(args.options["write-config"]===!0||!sourceIncludesConfig)&&saveAppLibraryConfig(generatedConfigPath,materializeConfig(null,entry)),writeJsonOrText(args.options.json===!0,{entry_id:entryId,dir:absoluteTargetDir,files:source.files.length},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5DF2 checkout \u5230\u672C\u5730\u76EE\u5F55\u3002",`entry_id: ${entryId}`,`dir: ${absoluteTargetDir}`,`files: ${source.files.length}`,...args.options["no-config"]===!0?[]:args.options["write-config"]===!0||!sourceIncludesConfig?[`config: ${generatedConfigPath}`]:[]])}async function runOpen(args,deps){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library open` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let url=`http://127.0.0.1:${process.env.TENANT_WORKBENCH_PORT?.trim()||"7102"}/#app-library/${encodeURIComponent(entryId)}`,opened=args.options["no-browser"]===!0?!1:await(deps.openBrowser??tryOpenBrowser)(url);process.stdout.write(`${url}
2384
+ `}`)}async function runSourceSearch(args,sdk){let entryId=resolvePositionalOrConfigEntryId(args,2);if(!entryId)throw new Error("`platform app-library source search` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let query=args.rest[3]?.trim()||readStringOption2(args,"query");if(!query)throw new Error("`platform app-library source search` \u9700\u8981 <query>\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--query`\u3002");let response=await sdk.searchLightAppLibraryEntrySource(entryId,query).catch(error=>{throw formatAppLibraryError(error,"source(search)")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`query: ${query}`,`items: ${response.items.length}`,...response.items.map(item=>`- ${item.path}${item.excerpt?` :: ${item.excerpt}`:""}`)])}async function runCreate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),payload=buildCreatePayload(args,config2);if(!payload.name?.trim())throw new Error("`platform app-library create` \u9700\u8981\u540D\u79F0\u3002\u8BF7\u5728 `app-library.yaml` \u4E2D\u8BBE\u7F6E `name`\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--name`\u3002");let response=await sdk.createLightAppLibraryEntry(payload).catch(error=>{throw formatAppLibraryError(error,"create")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u8349\u7A3F\u5DF2\u521B\u5EFA\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runUpdate(args,sdk){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library update` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"update")});maybeWriteConfig(configPath,config2,response,args),writeJsonOrText(args.options.json===!0,response,["\u8F7B\u5E94\u7528\u8D44\u4EA7\u5DF2\u66F4\u65B0\u3002",`entry_id: ${response.entry_id}`,`name: ${response.name}`,`status: ${response.status}`])}async function runSubmit(args,sdk,deps){let configPath=resolveAppLibraryConfigPath(readStringOption2(args,"file")),config2=loadAppLibraryConfigOptional(readStringOption2(args,"file")),entryId=resolveEntryId(args,config2);if(!entryId)throw new Error("`platform app-library submit` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");if(config2){let updatedEntry=await sdk.updateLightAppLibraryEntry(entryId,buildUpdatePayload(args,config2)).catch(error=>{throw formatAppLibraryError(error,"submit(update-metadata)")});maybeWriteConfig(configPath,config2,updatedEntry,args)}let{files,appRoot}=(deps.collectWorkspaceFiles??collectSourceWorkspaceFiles)(process.cwd()),response=await sdk.submitLightAppLibraryEntrySnapshot(entryId,{files}).catch(error=>{throw formatAppLibraryError(error,"submit")});writeJsonOrText(args.options.json===!0,{snapshot:response,app_root:appRoot},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5FEB\u7167\u5DF2\u63D0\u4EA4\u3002",`entry_id: ${entryId}`,`snapshot_id: ${response.snapshot_id}`,`files: ${response.files_count}`,`bytes: ${response.content_bytes}`,`app_root: ${appRoot}`])}async function runStateAction(args,sdk,action){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error(`\`platform app-library ${action}\` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 \`app-library.yaml\` \u4E2D\u63D0\u4F9B \`entry_id\`\u3002`);let response=action==="publish"?await sdk.publishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"publish")}):action==="unpublish"?await sdk.unpublishLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"unpublish")}):await sdk.archiveLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"archive")});writeJsonOrText(args.options.json===!0,response,[`entry_id: ${response.entry_id}`,`status: ${response.status}`])}async function runDelete(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library delete` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let response=await sdk.deleteLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"delete")});writeJsonOrText(args.options.json===!0,response,[`\u5DF2\u5220\u9664\u6761\u76EE ${response.entry_id}`])}async function runCheckout(args,sdk){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library checkout` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let entry=await sdk.getLightAppLibraryEntry(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(entry)")}),source=await sdk.getLightAppLibraryEntrySource(entryId).catch(error=>{throw formatAppLibraryError(error,"checkout(source)")}),targetDir=readStringOption2(args,"dir")??sanitizeDirectoryName(entry.name||entry.entry_id),absoluteTargetDir=resolve7(process.cwd(),targetDir);ensureEmptyDirectory(absoluteTargetDir);let sourceIncludesConfig=!1;for(let file of source.files){file.path==="app-library.yaml"&&(sourceIncludesConfig=!0);let payload=await sdk.readLightAppLibraryEntrySourceFile(entryId,file.path).catch(error=>{throw formatAppLibraryError(error,`checkout(file:${file.path})`)});writeWorkspaceFile(absoluteTargetDir,payload.file.path,payload.file.content)}let generatedConfigPath=join5(absoluteTargetDir,"app-library.yaml");args.options["no-config"]!==!0&&(args.options["write-config"]===!0||!sourceIncludesConfig)&&saveAppLibraryConfig(generatedConfigPath,materializeConfig(null,entry)),writeJsonOrText(args.options.json===!0,{entry_id:entryId,dir:absoluteTargetDir,files:source.files.length},["\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u5DF2 checkout \u5230\u672C\u5730\u76EE\u5F55\u3002",`entry_id: ${entryId}`,`dir: ${absoluteTargetDir}`,`files: ${source.files.length}`,...args.options["no-config"]===!0?[]:args.options["write-config"]===!0||!sourceIncludesConfig?[`config: ${generatedConfigPath}`]:[]])}async function runOpen(args,deps){let entryId=resolveEntryId(args,loadAppLibraryConfigOptional());if(!entryId)throw new Error("`platform app-library open` \u9700\u8981 <entry-id>\uFF0C\u6216\u5728 `app-library.yaml` \u4E2D\u63D0\u4F9B `entry_id`\u3002");let url=`http://127.0.0.1:${process.env.TENANT_WORKBENCH_PORT?.trim()||"7102"}/#app-library/${encodeURIComponent(entryId)}`,opened=args.options["no-browser"]===!0?!1:await(deps.openBrowser??tryOpenBrowser)(url);process.stdout.write(`${url}
2385
2385
  `),!opened&&args.options["no-browser"]!==!0&&process.stdout.write(`\u672A\u80FD\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE\u4E0A\u9762\u7684 URL\u3002
2386
2386
  `),process.stdout.write(`inspect: platform app-library inspect ${entryId}
2387
2387
  `),process.stdout.write(`checkout: platform app-library checkout ${entryId} --dir ./${sanitizeDirectoryName(entryId)}
2388
- `)}function resolveTenantId(args){let binding=tryReadBinding(),context=loadStoredCliContext();return readStringOption2(args,"tenant")??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id}function resolveEntryId(args,config2){return args.rest[1]?.trim()||readStringOption2(args,"entry")||config2?.entry_id?.trim()}function resolvePositionalOrConfigEntryId(args,positionalIndex){return args.rest[positionalIndex]?.trim()||readStringOption2(args,"entry")||loadAppLibraryConfigOptional()?.entry_id?.trim()}function loadAppLibraryConfigOptional(filePath){let resolvedPath=resolveAppLibraryConfigPath(filePath);if(!resolvedPath||!existsSync9(resolvedPath))return null;let parsed=YAML2.parse(readFileSync9(resolvedPath,"utf8"));return parsed&&typeof parsed=="object"?parsed:null}function resolveAppLibraryConfigPath(filePath){if(filePath?.trim())return resolve6(process.cwd(),filePath.trim());try{return join5(findAppRoot(process.cwd()),"app-library.yaml")}catch{return null}}function resolveWritableAppLibraryConfigPath(filePath){return filePath?.trim()?resolve6(process.cwd(),filePath.trim()):resolveAppLibraryConfigPath()??join5(process.cwd(),"app-library.yaml")}function buildCreatePayload(args,config2){return{name:readStringOption2(args,"name")??config2?.name??"",...readStringOption2(args,"summary")??config2?.summary?{summary:readStringOption2(args,"summary")??config2?.summary}:{},...readTagsOption(args,config2)?.length?{tags:readTagsOption(args,config2)}:{},...readStringOption2(args,"readme")??config2?.readme?{readme:readStringOption2(args,"readme")??config2?.readme}:{},...readStringOption2(args,"template-key")??config2?.template_key?{template_key:readStringOption2(args,"template-key")??config2?.template_key}:{},...config2?.capability_dependencies?.length?{capability_dependencies:config2.capability_dependencies}:{},...readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id}:{},...readStringOption2(args,"source-app-id")??config2?.source_app_id?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id}:{},...readStringOption2(args,"source-version-id")??config2?.source_version_id?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id}:{},...readStringOption2(args,"created-from")??config2?.created_from?{created_from:readStringOption2(args,"created-from")??config2?.created_from}:{}}}function buildUpdatePayload(args,config2){return{...readStringOption2(args,"name")??config2?.name?{name:readStringOption2(args,"name")??config2?.name}:{},...hasOption2(args,"summary")||config2?.summary!==void 0?{summary:readStringOption2(args,"summary")??config2?.summary??null}:{},...hasOption2(args,"tags")||config2?.tags?{tags:readTagsOption(args,config2)??[]}:{},...hasOption2(args,"readme")||config2?.readme!==void 0?{readme:readStringOption2(args,"readme")??config2?.readme??null}:{},...hasOption2(args,"template-key")||config2?.template_key!==void 0?{template_key:readStringOption2(args,"template-key")??config2?.template_key??null}:{},...config2?.capability_dependencies?{capability_dependencies:config2.capability_dependencies}:{},...hasOption2(args,"screenshot-asset-id")||config2?.screenshot_asset_id!==void 0?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id??null}:{},...hasOption2(args,"source-app-id")||config2?.source_app_id!==void 0?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id??null}:{},...hasOption2(args,"source-version-id")||config2?.source_version_id!==void 0?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id??null}:{},...hasOption2(args,"created-from")||config2?.created_from!==void 0?{created_from:readStringOption2(args,"created-from")??config2?.created_from??null}:{}}}function readTagsOption(args,config2){let explicit=readCsvOption2(args,"tags");return explicit.length>0?explicit:config2?.tags}function readStringOption2(args,key){let value=args.options[key];return typeof value=="string"&&value.trim()||void 0}function readCsvOption2(args,key){let value=readStringOption2(args,key);return value?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function readStatusOption(args,key){let value=readStringOption2(args,key);return value==="draft"||value==="published"||value==="unpublished"||value==="archived"?value:void 0}function readVisibilityOption(args,key){let value=readStringOption2(args,key);return value==="private"||value==="public"?value:void 0}function hasOption2(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function hasHelpFlag2(args){return args.options.help===!0||args.options.h===!0}function tryReadBinding(){try{return readBinding(process.cwd())?.binding}catch{return null}}function ensureEmptyDirectory(directory){if(existsSync9(directory)){if(readdirSync3(directory).length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6: ${directory}`);return}mkdirSync4(directory,{recursive:!0})}function writeWorkspaceFile(root,relativePath,content){let normalizedPath=relativePath.replace(/^\/+/g,"");if(!normalizedPath||normalizedPath.startsWith("..")||normalizedPath.includes("../")||normalizedPath.includes("..\\"))throw new Error(`\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${relativePath}`);let outputPath=join5(root,normalizedPath);mkdirSync4(dirname6(outputPath),{recursive:!0}),writeFileSync5(outputPath,content,"utf8")}function sanitizeDirectoryName(value){return value.trim().toLowerCase().replace(/[^\p{L}\p{N}._-]+/gu,"-").replace(/^-+|-+$/g,"")||"light-app-library-entry"}function maybeWriteConfig(configPath,currentConfig,entry,args){configPath&&(!currentConfig&&args.options["write-config"]!==!0||saveAppLibraryConfig(configPath,materializeConfig(currentConfig,entry)))}function saveAppLibraryConfig(path2,config2){mkdirSync4(dirname6(path2),{recursive:!0}),writeFileSync5(path2,YAML2.stringify(config2),"utf8")}function runConfigInit(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(existsSync9(configPath)&&args.options.force!==!0)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${configPath}\u3002\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u5165 --force\u3002`);saveAppLibraryConfig(configPath,{name:"",summary:"",tags:[],readme:"",capability_dependencies:[]}),writeJsonOrText(args.options.json===!0,{path:configPath,created:!0},["\u5DF2\u751F\u6210\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93\u914D\u7F6E\u6A21\u677F\u3002",`path: ${configPath}`,"next: \u7F16\u8F91 app-library.yaml \u540E\uFF0C\u53EF\u6267\u884C `platform app-library config validate` \u6216 `platform app-library create`\u3002"])}function runConfigValidate(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(!existsSync9(configPath))throw new Error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);let raw=loadAppLibraryConfigOptional(configPath);if(!raw)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E3A\u7A7A\u6216\u683C\u5F0F\u975E\u6CD5: ${configPath}`);let normalized=validateAppLibraryConfig(raw,configPath);writeJsonOrText(args.options.json===!0,{path:configPath,config:normalized,valid:!0},["app-library.yaml \u6821\u9A8C\u901A\u8FC7\u3002",`path: ${configPath}`,`name: ${normalized.name}`,`tags: ${normalized.tags?.length??0}`,`capability_dependencies: ${normalized.capability_dependencies?.length??0}`])}function validateAppLibraryConfig(config2,configPath){let fail=message=>{throw new Error(`app-library.yaml \u6821\u9A8C\u5931\u8D25: ${message} (${configPath})`)},rawName=config2.name,normalizedName=typeof rawName=="string"?rawName.trim():"";return normalizedName||fail("`name` \u5FC5\u586B\u4E14\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.summary!==void 0&&typeof config2.summary!="string"&&fail("`summary` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.readme!==void 0&&typeof config2.readme!="string"&&fail("`readme` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.template_key!==void 0&&typeof config2.template_key!="string"&&fail("`template_key` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.entry_id!==void 0&&typeof config2.entry_id!="string"&&fail("`entry_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.screenshot_asset_id!==void 0&&typeof config2.screenshot_asset_id!="string"&&fail("`screenshot_asset_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_app_id!==void 0&&typeof config2.source_app_id!="string"&&fail("`source_app_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_version_id!==void 0&&typeof config2.source_version_id!="string"&&fail("`source_version_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.created_from!==void 0&&typeof config2.created_from!="string"&&fail("`created_from` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.tags!==void 0&&!Array.isArray(config2.tags)&&fail("`tags` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4"),config2.tags?.some(item=>typeof item!="string"||!item.trim())&&fail("`tags` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.capability_dependencies!==void 0&&!Array.isArray(config2.capability_dependencies)&&fail("`capability_dependencies` \u5FC5\u987B\u4E3A\u6570\u7EC4"),config2.capability_dependencies?.some(item=>!item||typeof item!="object"||typeof item.capability!="string"||!item.capability.trim())&&fail("`capability_dependencies` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u5305\u542B\u975E\u7A7A\u5B57\u7B26\u4E32 `capability`"),config2.capability_dependencies?.some(item=>item.minVersion!==void 0&&typeof item.minVersion!="string")&&fail("`capability_dependencies[].minVersion` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),{entry_id:config2.entry_id?.trim()||void 0,name:normalizedName,summary:config2.summary??"",tags:config2.tags?.map(item=>item.trim()).filter(Boolean)??[],readme:config2.readme??"",template_key:config2.template_key?.trim()||void 0,capability_dependencies:config2.capability_dependencies?.map(item=>({capability:item.capability.trim(),...item.minVersion?.trim()?{minVersion:item.minVersion.trim()}:{}}))??[],screenshot_asset_id:config2.screenshot_asset_id?.trim()||void 0,source_app_id:config2.source_app_id?.trim()||void 0,source_version_id:config2.source_version_id?.trim()||void 0,created_from:config2.created_from?.trim()||void 0}}function materializeConfig(currentConfig,entry){return{...currentConfig,entry_id:entry.entry_id,name:entry.name,summary:entry.summary??"",tags:entry.tags??[],readme:entry.readme??"",template_key:entry.template_key??void 0,screenshot_asset_id:entry.screenshot_asset_id??void 0,source_app_id:entry.source_app_id??void 0,source_version_id:entry.source_version_id??void 0,created_from:entry.created_from??void 0,capability_dependencies:entry.capability_dependencies??[]}}function writeJsonOrText(json,payload,lines){if(json){process.stdout.write(`${JSON.stringify(payload,null,2)}
2388
+ `)}function resolveTenantId(args){let binding=tryReadBinding(),context=loadStoredCliContext();return readStringOption2(args,"tenant")??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id}function resolveEntryId(args,config2){return args.rest[1]?.trim()||readStringOption2(args,"entry")||config2?.entry_id?.trim()}function resolvePositionalOrConfigEntryId(args,positionalIndex){return args.rest[positionalIndex]?.trim()||readStringOption2(args,"entry")||loadAppLibraryConfigOptional()?.entry_id?.trim()}function loadAppLibraryConfigOptional(filePath){let resolvedPath=resolveAppLibraryConfigPath(filePath);if(!resolvedPath||!existsSync9(resolvedPath))return null;let parsed=YAML2.parse(readFileSync9(resolvedPath,"utf8"));return parsed&&typeof parsed=="object"?parsed:null}function resolveAppLibraryConfigPath(filePath){if(filePath?.trim())return resolve7(process.cwd(),filePath.trim());try{return join5(findAppRoot(process.cwd()),"app-library.yaml")}catch{return null}}function resolveWritableAppLibraryConfigPath(filePath){return filePath?.trim()?resolve7(process.cwd(),filePath.trim()):resolveAppLibraryConfigPath()??join5(process.cwd(),"app-library.yaml")}function buildCreatePayload(args,config2){return{name:readStringOption2(args,"name")??config2?.name??"",...readStringOption2(args,"summary")??config2?.summary?{summary:readStringOption2(args,"summary")??config2?.summary}:{},...readTagsOption(args,config2)?.length?{tags:readTagsOption(args,config2)}:{},...readStringOption2(args,"readme")??config2?.readme?{readme:readStringOption2(args,"readme")??config2?.readme}:{},...readStringOption2(args,"template-key")??config2?.template_key?{template_key:readStringOption2(args,"template-key")??config2?.template_key}:{},...config2?.capability_dependencies?.length?{capability_dependencies:config2.capability_dependencies}:{},...readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id}:{},...readStringOption2(args,"source-app-id")??config2?.source_app_id?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id}:{},...readStringOption2(args,"source-version-id")??config2?.source_version_id?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id}:{},...readStringOption2(args,"created-from")??config2?.created_from?{created_from:readStringOption2(args,"created-from")??config2?.created_from}:{}}}function buildUpdatePayload(args,config2){return{...readStringOption2(args,"name")??config2?.name?{name:readStringOption2(args,"name")??config2?.name}:{},...hasOption2(args,"summary")||config2?.summary!==void 0?{summary:readStringOption2(args,"summary")??config2?.summary??null}:{},...hasOption2(args,"tags")||config2?.tags?{tags:readTagsOption(args,config2)??[]}:{},...hasOption2(args,"readme")||config2?.readme!==void 0?{readme:readStringOption2(args,"readme")??config2?.readme??null}:{},...hasOption2(args,"template-key")||config2?.template_key!==void 0?{template_key:readStringOption2(args,"template-key")??config2?.template_key??null}:{},...config2?.capability_dependencies?{capability_dependencies:config2.capability_dependencies}:{},...hasOption2(args,"screenshot-asset-id")||config2?.screenshot_asset_id!==void 0?{screenshot_asset_id:readStringOption2(args,"screenshot-asset-id")??config2?.screenshot_asset_id??null}:{},...hasOption2(args,"source-app-id")||config2?.source_app_id!==void 0?{source_app_id:readStringOption2(args,"source-app-id")??config2?.source_app_id??null}:{},...hasOption2(args,"source-version-id")||config2?.source_version_id!==void 0?{source_version_id:readStringOption2(args,"source-version-id")??config2?.source_version_id??null}:{},...hasOption2(args,"created-from")||config2?.created_from!==void 0?{created_from:readStringOption2(args,"created-from")??config2?.created_from??null}:{}}}function readTagsOption(args,config2){let explicit=readCsvOption2(args,"tags");return explicit.length>0?explicit:config2?.tags}function readStringOption2(args,key){let value=args.options[key];return typeof value=="string"&&value.trim()||void 0}function readCsvOption2(args,key){let value=readStringOption2(args,key);return value?value.split(",").map(item=>item.trim()).filter(Boolean):[]}function readStatusOption(args,key){let value=readStringOption2(args,key);return value==="draft"||value==="published"||value==="unpublished"||value==="archived"?value:void 0}function readVisibilityOption(args,key){let value=readStringOption2(args,key);return value==="private"||value==="public"?value:void 0}function hasOption2(args,key){return Object.prototype.hasOwnProperty.call(args.options,key)}function hasHelpFlag2(args){return args.options.help===!0||args.options.h===!0}function tryReadBinding(){try{return readBinding(process.cwd())?.binding}catch{return null}}function ensureEmptyDirectory(directory){if(existsSync9(directory)){if(readdirSync3(directory).length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u975E\u7A7A\uFF0C\u62D2\u7EDD\u8986\u76D6: ${directory}`);return}mkdirSync4(directory,{recursive:!0})}function writeWorkspaceFile(root,relativePath,content){let normalizedPath=relativePath.replace(/^\/+/g,"");if(!normalizedPath||normalizedPath.startsWith("..")||normalizedPath.includes("../")||normalizedPath.includes("..\\"))throw new Error(`\u8F7B\u5E94\u7528\u8D44\u4EA7\u6E90\u7801\u6587\u4EF6\u8DEF\u5F84\u975E\u6CD5: ${relativePath}`);let outputPath=join5(root,normalizedPath);mkdirSync4(dirname6(outputPath),{recursive:!0}),writeFileSync5(outputPath,content,"utf8")}function sanitizeDirectoryName(value){return value.trim().toLowerCase().replace(/[^\p{L}\p{N}._-]+/gu,"-").replace(/^-+|-+$/g,"")||"light-app-library-entry"}function maybeWriteConfig(configPath,currentConfig,entry,args){configPath&&(!currentConfig&&args.options["write-config"]!==!0||saveAppLibraryConfig(configPath,materializeConfig(currentConfig,entry)))}function saveAppLibraryConfig(path2,config2){mkdirSync4(dirname6(path2),{recursive:!0}),writeFileSync5(path2,YAML2.stringify(config2),"utf8")}function runConfigInit(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(existsSync9(configPath)&&args.options.force!==!0)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u62D2\u7EDD\u8986\u76D6: ${configPath}\u3002\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u5165 --force\u3002`);saveAppLibraryConfig(configPath,{name:"",summary:"",tags:[],readme:"",capability_dependencies:[]}),writeJsonOrText(args.options.json===!0,{path:configPath,created:!0},["\u5DF2\u751F\u6210\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93\u914D\u7F6E\u6A21\u677F\u3002",`path: ${configPath}`,"next: \u7F16\u8F91 app-library.yaml \u540E\uFF0C\u53EF\u6267\u884C `platform app-library config validate` \u6216 `platform app-library create`\u3002"])}function runConfigValidate(args){let configPath=resolveWritableAppLibraryConfigPath(readStringOption2(args,"file"));if(!existsSync9(configPath))throw new Error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6: ${configPath}`);let raw=loadAppLibraryConfigOptional(configPath);if(!raw)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u5185\u5BB9\u4E3A\u7A7A\u6216\u683C\u5F0F\u975E\u6CD5: ${configPath}`);let normalized=validateAppLibraryConfig(raw,configPath);writeJsonOrText(args.options.json===!0,{path:configPath,config:normalized,valid:!0},["app-library.yaml \u6821\u9A8C\u901A\u8FC7\u3002",`path: ${configPath}`,`name: ${normalized.name}`,`tags: ${normalized.tags?.length??0}`,`capability_dependencies: ${normalized.capability_dependencies?.length??0}`])}function validateAppLibraryConfig(config2,configPath){let fail=message=>{throw new Error(`app-library.yaml \u6821\u9A8C\u5931\u8D25: ${message} (${configPath})`)},rawName=config2.name,normalizedName=typeof rawName=="string"?rawName.trim():"";return normalizedName||fail("`name` \u5FC5\u586B\u4E14\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.summary!==void 0&&typeof config2.summary!="string"&&fail("`summary` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.readme!==void 0&&typeof config2.readme!="string"&&fail("`readme` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.template_key!==void 0&&typeof config2.template_key!="string"&&fail("`template_key` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.entry_id!==void 0&&typeof config2.entry_id!="string"&&fail("`entry_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.screenshot_asset_id!==void 0&&typeof config2.screenshot_asset_id!="string"&&fail("`screenshot_asset_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_app_id!==void 0&&typeof config2.source_app_id!="string"&&fail("`source_app_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.source_version_id!==void 0&&typeof config2.source_version_id!="string"&&fail("`source_version_id` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.created_from!==void 0&&typeof config2.created_from!="string"&&fail("`created_from` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),config2.tags!==void 0&&!Array.isArray(config2.tags)&&fail("`tags` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32\u6570\u7EC4"),config2.tags?.some(item=>typeof item!="string"||!item.trim())&&fail("`tags` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32"),config2.capability_dependencies!==void 0&&!Array.isArray(config2.capability_dependencies)&&fail("`capability_dependencies` \u5FC5\u987B\u4E3A\u6570\u7EC4"),config2.capability_dependencies?.some(item=>!item||typeof item!="object"||typeof item.capability!="string"||!item.capability.trim())&&fail("`capability_dependencies` \u4E2D\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u5305\u542B\u975E\u7A7A\u5B57\u7B26\u4E32 `capability`"),config2.capability_dependencies?.some(item=>item.minVersion!==void 0&&typeof item.minVersion!="string")&&fail("`capability_dependencies[].minVersion` \u5FC5\u987B\u4E3A\u5B57\u7B26\u4E32"),{entry_id:config2.entry_id?.trim()||void 0,name:normalizedName,summary:config2.summary??"",tags:config2.tags?.map(item=>item.trim()).filter(Boolean)??[],readme:config2.readme??"",template_key:config2.template_key?.trim()||void 0,capability_dependencies:config2.capability_dependencies?.map(item=>({capability:item.capability.trim(),...item.minVersion?.trim()?{minVersion:item.minVersion.trim()}:{}}))??[],screenshot_asset_id:config2.screenshot_asset_id?.trim()||void 0,source_app_id:config2.source_app_id?.trim()||void 0,source_version_id:config2.source_version_id?.trim()||void 0,created_from:config2.created_from?.trim()||void 0}}function materializeConfig(currentConfig,entry){return{...currentConfig,entry_id:entry.entry_id,name:entry.name,summary:entry.summary??"",tags:entry.tags??[],readme:entry.readme??"",template_key:entry.template_key??void 0,screenshot_asset_id:entry.screenshot_asset_id??void 0,source_app_id:entry.source_app_id??void 0,source_version_id:entry.source_version_id??void 0,created_from:entry.created_from??void 0,capability_dependencies:entry.capability_dependencies??[]}}function writeJsonOrText(json,payload,lines){if(json){process.stdout.write(`${JSON.stringify(payload,null,2)}
2389
2389
  `);return}process.stdout.write(`${lines.join(`
2390
2390
  `)}
2391
- `)}function formatEntrySummary(item,index,full){let typeLabel=item.type==="example_app"?"example-app":item.type,tenantLabel=item.library?.tenant_id??"-",tags=item.tags.length?item.tags.slice(0,3).join(", "):"-",capabilities=item.capability_dependencies?.length?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";if(!full)return[`[${index}] ${item.name} (${item.entry_id})`,` ${item.status} \xB7 ${typeLabel} \xB7 ${item.template_key??"-"} \xB7 tenant=${tenantLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${tags}`,` capabilities: ${capabilities}`];let fullCapabilities=item.capability_dependencies?.length?item.capability_dependencies.map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";return[`[${index}] ${item.name} (${item.entry_id})`,` status: ${item.status} type: ${typeLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${item.tags.length?item.tags.join(", "):"-"}`,` template: ${item.template_key??"-"} snapshot: ${item.current_snapshot_id??"-"}`,` capabilities: ${fullCapabilities}`]}function toEntryListBriefPayload(response){return{items:response.items.map(item=>({entry_id:item.entry_id,name:item.name,summary:item.summary??"",status:item.status,type:item.type,template_key:item.template_key??null,tags:Array.isArray(item.tags)?item.tags.slice(0,3):[],capability_dependencies:Array.isArray(item.capability_dependencies)?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability):[],library:item.library?{tenant_id:item.library.tenant_id,visibility:item.library.visibility}:void 0}))}}function formatAppLibraryError(error,stage){return error instanceof PlatformApiError?new Error(`app-library ${stage} failed: ${error.message}${error.code?` (${error.code})`:""}`):error instanceof Error?error:new Error(`app-library ${stage} failed`)}async function tryOpenBrowser(url){return(await openExternal(url)).opened}import{execFileSync}from"node:child_process";import{existsSync as existsSync13,mkdirSync as mkdirSync7,readFileSync as readFileSync13,unlinkSync,writeFileSync as writeFileSync8}from"node:fs";import{dirname as dirname9,isAbsolute,join as join9,resolve as resolve7,sep}from"node:path";import{createHash as createHash4}from"node:crypto";import{existsSync as existsSync10,readFileSync as readFileSync10}from"node:fs";import{join as join6}from"node:path";function inspectPlatformBlocksAdoptability(appRoot,manifest){let files=manifest.managed_files.map(file=>{let current=readCurrentSha(appRoot,file.path);return current?current===file.content_sha256?{path:file.path,status:"match"}:{path:file.path,status:"drift"}:{path:file.path,status:"missing"}});return{adoptable:files.every(file=>file.status==="match"),files}}function computePlatformBlocksDiff(appRoot,manifest,lockfile){let lockFiles=new Map(lockfile.managed_files.map(file=>[file.path,file])),targetFiles=new Map(manifest.managed_files.map(file=>[file.path,file])),targetDiff=manifest.managed_files.map(file=>{let current_sha256=readCurrentSha(appRoot,file.path),lock_sha256=lockFiles.get(file.path)?.applied_sha256??null;return current_sha256===file.content_sha256?{path:file.path,status:lock_sha256===file.content_sha256?"noop":"lock_refresh",current_sha256,lock_sha256,target_sha256:file.content_sha256}:current_sha256===null||current_sha256===lock_sha256?{path:file.path,status:"safe_update",current_sha256,lock_sha256,target_sha256:file.content_sha256}:{path:file.path,status:"conflict",current_sha256,lock_sha256,target_sha256:file.content_sha256}}),removedDiff=lockfile.managed_files.filter(file=>!targetFiles.has(file.path)).map(file=>{let current_sha256=readCurrentSha(appRoot,file.path);return current_sha256===null?{path:file.path,status:"lock_refresh",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}:{path:file.path,status:current_sha256===file.applied_sha256?"safe_remove":"conflict",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}});return[...targetDiff,...removedDiff]}function determinePlatformBlocksApplyOutcome(diff){return diff.some(file=>file.status==="conflict")?"conflict":diff.some(file=>file.status==="safe_update"||file.status==="safe_remove")?"updated":diff.some(file=>file.status==="lock_refresh")?"lock_refreshed":"noop"}function checksumContent(content){return`sha256-${createHash4("sha256").update(content).digest("hex")}`}function readCurrentSha(appRoot,relativePath){let absolutePath=join6(appRoot,relativePath);return existsSync10(absolutePath)?checksumContent(readFileSync10(absolutePath,"utf8")):null}import{existsSync as existsSync12,mkdirSync as mkdirSync6,readFileSync as readFileSync12,readdirSync as readdirSync4,rmSync as rmSync2,writeFileSync as writeFileSync7}from"node:fs";import{dirname as dirname8,join as join8,relative as relative2}from"node:path";import{dirname as dirname7,join as join7}from"node:path";import{existsSync as existsSync11,mkdirSync as mkdirSync5,readFileSync as readFileSync11,writeFileSync as writeFileSync6}from"node:fs";var PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH=".platform/platform-blocks.lock.json";function getPlatformBlocksLockfilePath(appRoot){return join7(appRoot,PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH)}function readPlatformBlocksLockfile(startDir){let{directory:appRoot}=readAppManifest(startDir),path2=getPlatformBlocksLockfilePath(appRoot);if(!existsSync11(path2))return null;let raw=readFileSync11(path2,"utf8"),lockfile=JSON.parse(raw);return{appRoot,path:path2,lockfile,raw}}function writePlatformBlocksLockfile(appRoot,content){let path2=getPlatformBlocksLockfilePath(appRoot);mkdirSync5(dirname7(path2),{recursive:!0});let serialized=typeof content=="string"?content:`${JSON.stringify(content,null,2)}
2391
+ `)}function formatEntrySummary(item,index,full){let typeLabel=item.type==="example_app"?"example-app":item.type,tenantLabel=item.library?.tenant_id??"-",tags=item.tags.length?item.tags.slice(0,3).join(", "):"-",capabilities=item.capability_dependencies?.length?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";if(!full)return[`[${index}] ${item.name} (${item.entry_id})`,` ${item.status} \xB7 ${typeLabel} \xB7 ${item.template_key??"-"} \xB7 tenant=${tenantLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${tags}`,` capabilities: ${capabilities}`];let fullCapabilities=item.capability_dependencies?.length?item.capability_dependencies.map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability).join(", "):"-";return[`[${index}] ${item.name} (${item.entry_id})`,` status: ${item.status} type: ${typeLabel}`,` summary: ${item.summary?.trim()||"-"}`,` tags: ${item.tags.length?item.tags.join(", "):"-"}`,` template: ${item.template_key??"-"} snapshot: ${item.current_snapshot_id??"-"}`,` capabilities: ${fullCapabilities}`]}function toEntryListBriefPayload(response){return{items:response.items.map(item=>({entry_id:item.entry_id,name:item.name,summary:item.summary??"",status:item.status,type:item.type,template_key:item.template_key??null,tags:Array.isArray(item.tags)?item.tags.slice(0,3):[],capability_dependencies:Array.isArray(item.capability_dependencies)?item.capability_dependencies.slice(0,3).map(dependency=>dependency.minVersion?`${dependency.capability}@${dependency.minVersion}`:dependency.capability):[],library:item.library?{tenant_id:item.library.tenant_id,visibility:item.library.visibility}:void 0}))}}function formatAppLibraryError(error,stage){return error instanceof PlatformApiError?new Error(`app-library ${stage} failed: ${error.message}${error.code?` (${error.code})`:""}`):error instanceof Error?error:new Error(`app-library ${stage} failed`)}async function tryOpenBrowser(url){return(await openExternal(url)).opened}import{execFileSync}from"node:child_process";import{existsSync as existsSync13,mkdirSync as mkdirSync7,readFileSync as readFileSync13,unlinkSync,writeFileSync as writeFileSync8}from"node:fs";import{dirname as dirname9,isAbsolute,join as join9,resolve as resolve8,sep}from"node:path";import{createHash as createHash4}from"node:crypto";import{existsSync as existsSync10,readFileSync as readFileSync10}from"node:fs";import{join as join6}from"node:path";function inspectPlatformBlocksAdoptability(appRoot,manifest){let files=manifest.managed_files.map(file=>{let current=readCurrentSha(appRoot,file.path);return current?current===file.content_sha256?{path:file.path,status:"match"}:{path:file.path,status:"drift"}:{path:file.path,status:"missing"}});return{adoptable:files.every(file=>file.status==="match"),files}}function computePlatformBlocksDiff(appRoot,manifest,lockfile){let lockFiles=new Map(lockfile.managed_files.map(file=>[file.path,file])),targetFiles=new Map(manifest.managed_files.map(file=>[file.path,file])),targetDiff=manifest.managed_files.map(file=>{let current_sha256=readCurrentSha(appRoot,file.path),lock_sha256=lockFiles.get(file.path)?.applied_sha256??null;return current_sha256===file.content_sha256?{path:file.path,status:lock_sha256===file.content_sha256?"noop":"lock_refresh",current_sha256,lock_sha256,target_sha256:file.content_sha256}:current_sha256===null||current_sha256===lock_sha256?{path:file.path,status:"safe_update",current_sha256,lock_sha256,target_sha256:file.content_sha256}:{path:file.path,status:"conflict",current_sha256,lock_sha256,target_sha256:file.content_sha256}}),removedDiff=lockfile.managed_files.filter(file=>!targetFiles.has(file.path)).map(file=>{let current_sha256=readCurrentSha(appRoot,file.path);return current_sha256===null?{path:file.path,status:"lock_refresh",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}:{path:file.path,status:current_sha256===file.applied_sha256?"safe_remove":"conflict",current_sha256,lock_sha256:file.applied_sha256,target_sha256:null}});return[...targetDiff,...removedDiff]}function determinePlatformBlocksApplyOutcome(diff){return diff.some(file=>file.status==="conflict")?"conflict":diff.some(file=>file.status==="safe_update"||file.status==="safe_remove")?"updated":diff.some(file=>file.status==="lock_refresh")?"lock_refreshed":"noop"}function checksumContent(content){return`sha256-${createHash4("sha256").update(content).digest("hex")}`}function readCurrentSha(appRoot,relativePath){let absolutePath=join6(appRoot,relativePath);return existsSync10(absolutePath)?checksumContent(readFileSync10(absolutePath,"utf8")):null}import{existsSync as existsSync12,mkdirSync as mkdirSync6,readFileSync as readFileSync12,readdirSync as readdirSync4,rmSync as rmSync2,writeFileSync as writeFileSync7}from"node:fs";import{dirname as dirname8,join as join8,relative as relative2}from"node:path";import{dirname as dirname7,join as join7}from"node:path";import{existsSync as existsSync11,mkdirSync as mkdirSync5,readFileSync as readFileSync11,writeFileSync as writeFileSync6}from"node:fs";var PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH=".platform/platform-blocks.lock.json";function getPlatformBlocksLockfilePath(appRoot){return join7(appRoot,PLATFORM_BLOCKS_LOCKFILE_RELATIVE_PATH)}function readPlatformBlocksLockfile(startDir){let{directory:appRoot}=readAppManifest(startDir),path2=getPlatformBlocksLockfilePath(appRoot);if(!existsSync11(path2))return null;let raw=readFileSync11(path2,"utf8"),lockfile=JSON.parse(raw);return{appRoot,path:path2,lockfile,raw}}function writePlatformBlocksLockfile(appRoot,content){let path2=getPlatformBlocksLockfilePath(appRoot);mkdirSync5(dirname7(path2),{recursive:!0});let serialized=typeof content=="string"?content:`${JSON.stringify(content,null,2)}
2392
2392
  `;return writeFileSync6(path2,serialized,"utf8"),path2}function resolvePlatformBlocksTemplateKey(startDir){let{directory:appRoot}=readAppManifest(startDir),sourceContextTemplateKey=normalizeAppTemplateKey(readSourceContext(appRoot)?.sourceContext.template_key);if(sourceContextTemplateKey)return sourceContextTemplateKey;let lockfileTemplateKey=normalizeAppTemplateKey(readPlatformBlocksLockfile(appRoot)?.lockfile.template_key);if(lockfileTemplateKey)return lockfileTemplateKey;throw new Error("\u65E0\u6CD5\u8BC6\u522B\u5F53\u524D\u5DE5\u7A0B\u7684\u6A21\u677F\u3002\u8BF7\u5148\u901A\u8FC7 checkout/\u7ED1\u5B9A\u4E0A\u4E0B\u6587\u8FDB\u5165\u53D7\u652F\u6301\u7684 frontend/backend app \u5DE5\u7A0B\u3002")}var HISTORY_LAST_RELATIVE_DIR=".platform/platform-blocks.history/last";function getPlatformBlocksHistoryLastDir(appRoot){return join8(appRoot,HISTORY_LAST_RELATIVE_DIR)}function writeLastPlatformBlocksHistory(appRoot,args){let historyDir=getPlatformBlocksHistoryLastDir(appRoot);rmSync2(historyDir,{recursive:!0,force:!0}),mkdirSync6(join8(historyDir,"files"),{recursive:!0});for(let file of args.files){if(!file.existed_before||typeof file.content!="string")continue;let snapshotPath=join8(historyDir,"files",file.path);mkdirSync6(dirname8(snapshotPath),{recursive:!0}),writeFileSync7(snapshotPath,file.content,"utf8")}writeFileSync7(join8(historyDir,"lockfile.before.json"),args.lockfileBefore,"utf8"),writeFileSync7(join8(historyDir,"lockfile.after.json"),args.lockfileAfter,"utf8");let metadata={template_key:args.templateKey,platform_blocks_revision_before:args.revisionBefore,platform_blocks_revision_after:args.revisionAfter,managed_files_overwritten:args.files.map(file=>({path:file.path,existed_before:file.existed_before})),lockfile_before_path:"lockfile.before.json",lockfile_after_path:"lockfile.after.json",created_at:new Date().toISOString()};return writeFileSync7(join8(historyDir,"metadata.json"),`${JSON.stringify(metadata,null,2)}
2393
2393
  `,"utf8"),historyDir}function restoreLastPlatformBlocksHistory(appRoot){let historyDir=getPlatformBlocksHistoryLastDir(appRoot),metadataPath=join8(historyDir,"metadata.json");if(!existsSync12(metadataPath))throw new Error("\u65E0\u53EF\u56DE\u9000\u7684\u6700\u8FD1\u4E00\u6B21 apply\u3002");let metadata=JSON.parse(readFileSync12(metadataPath,"utf8")),restoredFiles=[],removedFiles=[];for(let file of metadata.managed_files_overwritten){let targetPath=join8(appRoot,file.path);if(!file.existed_before){rmSync2(targetPath,{force:!0}),removedFiles.push(file.path);continue}let snapshotPath=join8(historyDir,"files",file.path),content=readFileSync12(snapshotPath,"utf8");mkdirSync6(dirname8(targetPath),{recursive:!0}),writeFileSync7(targetPath,content,"utf8"),restoredFiles.push(file.path)}let lockfilePath=getPlatformBlocksLockfilePath(appRoot);return mkdirSync6(dirname8(lockfilePath),{recursive:!0}),writeFileSync7(lockfilePath,readFileSync12(join8(historyDir,metadata.lockfile_before_path),"utf8"),"utf8"),{restoredFiles,removedFiles,lockfilePath:relative2(appRoot,lockfilePath).replace(/\\/g,"/")}}function hasLastPlatformBlocksHistory(appRoot){return existsSync12(join8(getPlatformBlocksHistoryLastDir(appRoot),"metadata.json"))}var CLI_TOOL_VERSION=`@voobase/cli@${getCliPackageVersion()}`;function runAppSyncPlatformBlocksCommand(args){let{directory:appRoot}=readAppManifest(args.cwd);if(args.rollbackLast){let restored=restoreLastPlatformBlocksHistory(appRoot);return{mode:"rollback",appRoot,restoredFiles:restored.restoredFiles,removedFiles:restored.removedFiles,lockfilePath:restored.lockfilePath}}let templateKey=resolvePlatformBlocksTemplateKey(appRoot),manifest=getPlatformBlocksManifest(templateKey),templateFiles=buildTemplateFileMap(templateKey),lockRecord=readPlatformBlocksLockfile(appRoot);if(args.adopt){if(lockRecord)return{mode:"adopt",appRoot,templateKey,status:"already_managed",targetRevision:manifest.platform_blocks_revision,lockfilePath:lockRecord.path};let adopt=inspectPlatformBlocksAdoptability(appRoot,manifest);if(!adopt.adoptable){let problems=adopt.files.filter(file=>file.status!=="match").map(file=>`${file.path}=${file.status}`).join(", ");throw new Error(`\u5F53\u524D\u5DE5\u7A0B\u5C1A\u672A\u8FBE\u5230 adopt \u6761\u4EF6\uFF1A${problems}`)}let nextLockfile=buildPlatformBlocksLockfile(manifest,{mode:"adopt",toolVersion:CLI_TOOL_VERSION}),lockfilePath=writePlatformBlocksLockfile(appRoot,stringifyPlatformBlocksLockfile(nextLockfile));return{mode:"adopt",appRoot,templateKey,status:"adopted",targetRevision:manifest.platform_blocks_revision,lockfilePath}}if(args.apply){if(!lockRecord)throw new Error("\u7F3A\u5C11 `.platform/platform-blocks.lock.json`\uFF0C\u8BF7\u5148\u6267\u884C `platform app sync-platform-blocks --adopt`\u3002");let diff2=computePlatformBlocksDiff(appRoot,manifest,lockRecord.lockfile),outcome=determinePlatformBlocksApplyOutcome(diff2);if(outcome==="conflict"){let conflictList=diff2.filter(file=>file.status==="conflict").map(file=>file.path).join(", ");throw new Error(`\u68C0\u6D4B\u5230\u5E73\u53F0\u5757\u51B2\u7A81\uFF0C\u5DF2\u62D2\u7EDD apply\uFF1A${conflictList}`)}let nextLockfile=buildPlatformBlocksLockfile(manifest,{mode:outcome==="lock_refreshed"?"lock_refreshed":"apply",toolVersion:CLI_TOOL_VERSION}),nextLockfileRaw=stringifyPlatformBlocksLockfile(nextLockfile);if(outcome==="updated"){for(let file of diff2.filter(item=>item.status==="safe_remove"))assertSafeManagedRemovalPath(appRoot,templateKey,file.path);let snapshots=diff2.filter(file=>file.status==="safe_update"||file.status==="safe_remove").map(file=>buildHistorySnapshot(appRoot,file.path));for(let file of diff2.filter(item=>item.status==="safe_update")){let target=templateFiles.get(file.path);if(typeof target!="string")throw new Error(`\u6A21\u677F\u7F3A\u5C11\u76EE\u6807\u6587\u4EF6\uFF1A${file.path}`);writeManagedFile(appRoot,file.path,target)}for(let file of diff2.filter(item=>item.status==="safe_remove"))removeManagedFile(appRoot,file.path);writePlatformBlocksLockfile(appRoot,nextLockfileRaw),writeLastPlatformBlocksHistory(appRoot,{templateKey,revisionBefore:lockRecord.lockfile.platform_blocks_revision,revisionAfter:manifest.platform_blocks_revision,files:snapshots,lockfileBefore:lockRecord.raw,lockfileAfter:nextLockfileRaw});let verify2=args.verify?runPlatformBlocksVerify(appRoot):void 0;return{mode:"apply",appRoot,templateKey,status:outcome,targetRevision:manifest.platform_blocks_revision,updatedFiles:diff2.filter(file=>file.status==="safe_update").map(file=>file.path),removedFiles:diff2.filter(file=>file.status==="safe_remove").map(file=>file.path),lockfilePath:lockRecord.path,historyUpdated:!0,verify:verify2}}if(outcome==="lock_refreshed"){writePlatformBlocksLockfile(appRoot,nextLockfileRaw);let verify2=args.verify?runPlatformBlocksVerify(appRoot):void 0;return{mode:"apply",appRoot,templateKey,status:outcome,targetRevision:manifest.platform_blocks_revision,updatedFiles:[],removedFiles:[],lockfilePath:lockRecord.path,historyUpdated:!1,verify:verify2}}let verify=args.verify?runPlatformBlocksVerify(appRoot):void 0;return{mode:"apply",appRoot,templateKey,status:"noop",targetRevision:manifest.platform_blocks_revision,updatedFiles:[],removedFiles:[],lockfilePath:lockRecord.path,historyUpdated:!1,verify}}if(!lockRecord){let adopt=inspectPlatformBlocksAdoptability(appRoot,manifest);return{mode:"dry-run",appRoot,templateKey,targetRevision:manifest.platform_blocks_revision,managedFiles:manifest.managed_files.length,lockfilePresent:!1,adoptable:adopt.adoptable}}let diff=computePlatformBlocksDiff(appRoot,manifest,lockRecord.lockfile);return{mode:"dry-run",appRoot,templateKey,targetRevision:manifest.platform_blocks_revision,managedFiles:manifest.managed_files.length,lockfilePresent:!0,safeUpdates:diff.filter(file=>file.status==="safe_update").length,safeRemovals:diff.filter(file=>file.status==="safe_remove").length,lockRefreshes:diff.filter(file=>file.status==="lock_refresh").length,conflicts:diff.filter(file=>file.status==="conflict").length,noopFiles:diff.filter(file=>file.status==="noop").length}}function formatAppSyncPlatformBlocksResult(result){return result.mode==="rollback"?["\u5E73\u53F0\u5757\u5DF2\u56DE\u9000\u5230\u6700\u8FD1\u4E00\u6B21\u5FEB\u7167\u3002",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,result.restoredFiles.length>0?`\u6062\u590D\u6587\u4EF6:
2394
2394
  - ${result.restoredFiles.join(`
@@ -2402,33 +2402,34 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
2402
2402
  - ${result.removedFiles.join(`
2403
2403
  - `)}`:"\u5220\u9664\u6587\u4EF6: -",`lockfile: ${result.lockfilePath}`,`history: ${result.historyUpdated?"updated":"unchanged"}`,result.verify?formatPlatformBlocksVerifySummary(result.verify.output):"",""].join(`
2404
2404
  `):["\u5E73\u53F0\u5757 dry-run \u7ED3\u679C",`\u5E94\u7528\u76EE\u5F55: ${result.appRoot}`,`\u6A21\u677F: ${result.templateKey}`,`target revision: ${result.targetRevision}`,`managed files: ${result.managedFiles}`,`lockfile: ${result.lockfilePresent?"present":"missing"}`,typeof result.adoptable=="boolean"?`adoptable: ${result.adoptable?"yes":"no"}`:"",typeof result.safeUpdates=="number"?`safe updates: ${result.safeUpdates}`:"",typeof result.safeRemovals=="number"?`safe removals: ${result.safeRemovals}`:"",typeof result.lockRefreshes=="number"?`lock refreshes: ${result.lockRefreshes}`:"",typeof result.conflicts=="number"?`conflicts: ${result.conflicts}`:"",typeof result.noopFiles=="number"?`noop files: ${result.noopFiles}`:"",hasLastPlatformBlocksHistory(result.appRoot)?"rollback last: available":"rollback last: unavailable",""].filter(Boolean).join(`
2405
- `)}function buildTemplateFileMap(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return new Map(files.map(file=>[file.path,file.content]))}function buildHistorySnapshot(appRoot,relativePath){let absolutePath=join9(appRoot,relativePath);return existsSync13(absolutePath)?{path:relativePath,existed_before:!0,content:readFileSync13(absolutePath,"utf8")}:{path:relativePath,existed_before:!1}}function writeManagedFile(appRoot,relativePath,content){let absolutePath=join9(appRoot,relativePath);mkdirSync7(dirname9(absolutePath),{recursive:!0}),writeFileSync8(absolutePath,content,"utf8")}function removeManagedFile(appRoot,relativePath){let absolutePath=resolve7(appRoot,relativePath);existsSync13(absolutePath)&&unlinkSync(absolutePath)}function assertSafeManagedRemovalPath(appRoot,templateKey,relativePath){let normalizedRoot=resolve7(appRoot),insideAppRoot=resolve7(normalizedRoot,relativePath).startsWith(`${normalizedRoot}${sep}`);if(isAbsolute(relativePath)||!insideAppRoot||!isManagedPlatformFilePath(templateKey,relativePath))throw new Error(`\u9501\u6587\u4EF6\u5305\u542B\u975E\u6CD5\u7684\u6258\u7BA1\u5220\u9664\u8DEF\u5F84\uFF0C\u5DF2\u62D2\u7EDD apply\uFF1A${relativePath}`)}function runPlatformBlocksVerify(appRoot){let workspaceRoot=findWorkspaceRoot(appRoot),scriptPath=process.env.PLATFORM_BLOCKS_VERIFY_SCRIPT?.trim()||join9(workspaceRoot,"scripts","validation","url","local-url-gate.sh");try{return{status:"passed",output:execFileSync("bash",[scriptPath,"--mode","inspect"],{cwd:workspaceRoot,encoding:"utf8",env:process.env,maxBuffer:4194304}).trim()}}catch(error){let detail=error instanceof Error?error.message:String(error);throw new Error(`\u5E73\u53F0\u5757 verify \u5931\u8D25\uFF1A${detail}`)}}function formatPlatformBlocksVerifySummary(output){try{let parsed=JSON.parse(output),checks=Array.isArray(parsed.checks)?parsed.checks:[],passed=checks.filter(check=>check.status==="passed").length;return`verify: ${parsed.status??"passed"} mode=${parsed.mode??"inspect"} checks=${passed}/${checks.length}`}catch{return"verify: passed"}}import{cpSync,existsSync as existsSync15,mkdirSync as mkdirSync8,readFileSync as readFileSync15,rmSync as rmSync3,statSync as statSync4,writeFileSync as writeFileSync9}from"node:fs";import{join as join11,resolve as resolve8}from"node:path";import{existsSync as existsSync14,readFileSync as readFileSync14}from"node:fs";import{join as join10}from"node:path";var SOURCE_CONTEXT_PATH=join10(".platform","source-context.json");function readJsonIfExists(filePath){return existsSync14(filePath)?JSON.parse(readFileSync14(filePath,"utf8")):null}function detectTemplateKeyFromWorkspace(workspaceDir){let sourceContext=readJsonIfExists(join10(workspaceDir,SOURCE_CONTEXT_PATH));if(sourceContext?.template_key){let normalized=normalizeAppTemplateKey(sourceContext.template_key);if(normalized==="frontend-app-vite"||normalized==="backend-app-node")return normalized}return existsSync14(join10(workspaceDir,"src","web","app.tsx"))||existsSync14(join10(workspaceDir,"src","server","entry.ts"))?"backend-app-node":(existsSync14(join10(workspaceDir,"src","app.tsx"))||existsSync14(join10(workspaceDir,"src","main.tsx")),"frontend-app-vite")}function resolveAppImportLayout(workspaceDir){let templateKey=detectTemplateKeyFromWorkspace(workspaceDir),frontendRoot=templateKey==="backend-app-node"?"src/web":"src",importedUpstreamRoot=join10(frontendRoot,"imported-upstream").replace(/\\/g,"/"),preservedWorkspaceFiles=["app.yaml","package.json","vite.config.ts","index.html",`${frontendRoot}/main.tsx`,`${frontendRoot}/app.tsx`,`${frontendRoot}/platform`,"public/auth/index.html","public/__app"];return templateKey==="backend-app-node"&&preservedWorkspaceFiles.push("Dockerfile","src/server"),{template_key:templateKey,frontend_root:frontendRoot,imported_upstream_root:importedUpstreamRoot,preserved_workspace_files:preservedWorkspaceFiles}}var REQUIRED_WORKSPACE_FILES=["app.yaml","package.json"],FRONTEND_MERGEABLE_SOURCE_DIRS=["pages","components","styles","lib","imports"];function printAppImportMergeUsage(){process.stdout.write(["platform app import merge","","\u7528\u6CD5\uFF1A"," platform app import merge [--workspace-dir <template-workspace-dir>] [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06 `.design-import/upstream-clean-source/` \u7684\u53EF\u8FC1\u79FB\u76EE\u5F55\u5B89\u5168\u5E76\u5165\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 imported-upstream \u843D\u70B9\uFF0C\u4FDD\u7559\u6A21\u677F\u5165\u53E3\u4E0E\u5E73\u53F0\u5951\u7EA6\u6587\u4EF6\u7531\u6A21\u677F\u4E3B\u5BFC\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",""].join(`
2405
+ `)}function buildTemplateFileMap(templateKey){let files=templateKey==="backend-app-node"?assembleBackendAppNodeTemplate():assembleFrontendAppViteTemplate();return new Map(files.map(file=>[file.path,file.content]))}function buildHistorySnapshot(appRoot,relativePath){let absolutePath=join9(appRoot,relativePath);return existsSync13(absolutePath)?{path:relativePath,existed_before:!0,content:readFileSync13(absolutePath,"utf8")}:{path:relativePath,existed_before:!1}}function writeManagedFile(appRoot,relativePath,content){let absolutePath=join9(appRoot,relativePath);mkdirSync7(dirname9(absolutePath),{recursive:!0}),writeFileSync8(absolutePath,content,"utf8")}function removeManagedFile(appRoot,relativePath){let absolutePath=resolve8(appRoot,relativePath);existsSync13(absolutePath)&&unlinkSync(absolutePath)}function assertSafeManagedRemovalPath(appRoot,templateKey,relativePath){let normalizedRoot=resolve8(appRoot),insideAppRoot=resolve8(normalizedRoot,relativePath).startsWith(`${normalizedRoot}${sep}`);if(isAbsolute(relativePath)||!insideAppRoot||!isManagedPlatformFilePath(templateKey,relativePath))throw new Error(`\u9501\u6587\u4EF6\u5305\u542B\u975E\u6CD5\u7684\u6258\u7BA1\u5220\u9664\u8DEF\u5F84\uFF0C\u5DF2\u62D2\u7EDD apply\uFF1A${relativePath}`)}function runPlatformBlocksVerify(appRoot){let workspaceRoot=findWorkspaceRoot(appRoot),scriptPath=process.env.PLATFORM_BLOCKS_VERIFY_SCRIPT?.trim()||join9(workspaceRoot,"scripts","validation","url","local-url-gate.sh");try{return{status:"passed",output:execFileSync("bash",[scriptPath,"--mode","inspect"],{cwd:workspaceRoot,encoding:"utf8",env:process.env,maxBuffer:4194304}).trim()}}catch(error){let detail=error instanceof Error?error.message:String(error);throw new Error(`\u5E73\u53F0\u5757 verify \u5931\u8D25\uFF1A${detail}`)}}function formatPlatformBlocksVerifySummary(output){try{let parsed=JSON.parse(output),checks=Array.isArray(parsed.checks)?parsed.checks:[],passed=checks.filter(check=>check.status==="passed").length;return`verify: ${parsed.status??"passed"} mode=${parsed.mode??"inspect"} checks=${passed}/${checks.length}`}catch{return"verify: passed"}}import{cpSync,existsSync as existsSync15,mkdirSync as mkdirSync8,readFileSync as readFileSync15,rmSync as rmSync3,statSync as statSync4,writeFileSync as writeFileSync9}from"node:fs";import{join as join11,resolve as resolve9}from"node:path";import{existsSync as existsSync14,readFileSync as readFileSync14}from"node:fs";import{join as join10}from"node:path";var SOURCE_CONTEXT_PATH=join10(".platform","source-context.json");function readJsonIfExists(filePath){return existsSync14(filePath)?JSON.parse(readFileSync14(filePath,"utf8")):null}function detectTemplateKeyFromWorkspace(workspaceDir){let sourceContext=readJsonIfExists(join10(workspaceDir,SOURCE_CONTEXT_PATH));if(sourceContext?.template_key){let normalized=normalizeAppTemplateKey(sourceContext.template_key);if(normalized==="frontend-app-vite"||normalized==="backend-app-node")return normalized}return existsSync14(join10(workspaceDir,"src","web","app.tsx"))||existsSync14(join10(workspaceDir,"src","server","entry.ts"))?"backend-app-node":(existsSync14(join10(workspaceDir,"src","app.tsx"))||existsSync14(join10(workspaceDir,"src","main.tsx")),"frontend-app-vite")}function resolveAppImportLayout(workspaceDir){let templateKey=detectTemplateKeyFromWorkspace(workspaceDir),frontendRoot=templateKey==="backend-app-node"?"src/web":"src",importedUpstreamRoot=join10(frontendRoot,"imported-upstream").replace(/\\/g,"/"),preservedWorkspaceFiles=["app.yaml","package.json","vite.config.ts","index.html",`${frontendRoot}/main.tsx`,`${frontendRoot}/app.tsx`,`${frontendRoot}/platform`,"public/auth/index.html","public/__app"];return templateKey==="backend-app-node"&&preservedWorkspaceFiles.push("Dockerfile","src/server"),{template_key:templateKey,frontend_root:frontendRoot,imported_upstream_root:importedUpstreamRoot,preserved_workspace_files:preservedWorkspaceFiles}}var REQUIRED_WORKSPACE_FILES=["app.yaml","package.json"],FRONTEND_MERGEABLE_SOURCE_DIRS=["pages","components","styles","lib","imports"];function printAppImportMergeUsage(){process.stdout.write(["platform app import merge","","\u7528\u6CD5\uFF1A"," platform app import merge [--workspace-dir <template-workspace-dir>] [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06 `.design-import/upstream-clean-source/` \u7684\u53EF\u8FC1\u79FB\u76EE\u5F55\u5B89\u5168\u5E76\u5165\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 imported-upstream \u843D\u70B9\uFF0C\u4FDD\u7559\u6A21\u677F\u5165\u53E3\u4E0E\u5E73\u53F0\u5951\u7EA6\u6587\u4EF6\u7531\u6A21\u677F\u4E3B\u5BFC\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",""].join(`
2406
2406
  `))}function parseArgs(argv){let result={workspaceDir:"",dryRun:!1,json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJson(filePath){return JSON.parse(readFileSync15(filePath,"utf8"))}function writeJson(filePath,payload){writeFileSync9(filePath,`${JSON.stringify(payload,null,2)}
2407
- `,"utf8")}function assertDirectory(pathValue,label){let stats=statSync4(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace(workspaceDir){assertDirectory(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES.filter(file=>!existsSync15(join11(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function buildMergeSummary(args,payload){let sourcePreprocessExecutionMode=payload.importSummary.source_preprocess_execution_mode||payload.importManifest.execution_mode||"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D merge \u6765\u6E90\u4E8E dry-run \u9884\u5904\u7406\u4EA7\u7269\uFF1Bsrc/imported-upstream/ \u4E2D\u4ECD\u53EF\u80FD\u5305\u542B\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"merge-imported-upstream",version:1,mode:"merge-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,import_summary:payload.importSummaryPath,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,upstream_clean_source_dir:payload.upstreamCleanSourceDir,merged_target_dir:payload.mergedTargetDir,merge_required:payload.mergeRequired,merged_paths:payload.mergedPaths,skipped_paths:payload.skippedPaths,preserved_workspace_files:payload.importSummary.preserved_workspace_files??[],warnings,next_steps:[`\u5728 ${payload.layout.imported_upstream_root}/ \u4E2D\u5BA1\u67E5\u4E0A\u6E38\u9875\u9762\u3001components\u3001styles\u3001lib\u3001imports`,payload.layout.template_key==="backend-app-node"?"\u4ECE src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC":"\u4ECE src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC","\u9010\u6B65\u628A\u9700\u8981\u7684\u5E73\u53F0\u80FD\u529B\u63A5\u5165\u5230\u6A21\u677F\u4E3B\u5BFC\u7684\u8FD0\u884C\u5165\u53E3\u4E2D","\u5B8C\u6210\u63A5\u7EBF\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}async function runAppImportMergeCli(argv){let args=parseArgs(argv);if(args.help){printAppImportMergeUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve8(args.workspaceDir);validateWorkspace(workspaceDir);let designImportRoot=join11(workspaceDir,".design-import"),importSummaryPath=join11(designImportRoot,"import-summary.json"),importManifestPath=join11(designImportRoot,"reports","import-manifest.json"),upstreamCleanSourceDir=join11(designImportRoot,"upstream-clean-source");assertDirectory(designImportRoot,".design-import"),assertDirectory(upstreamCleanSourceDir,"upstream-clean-source");let importSummary=readJson(importSummaryPath),importManifest=existsSync15(importManifestPath)?readJson(importManifestPath):{},layout=resolveAppImportLayout(workspaceDir),mergedTargetDir=join11(workspaceDir,...layout.imported_upstream_root.split("/")),upstreamSrcDir=join11(upstreamCleanSourceDir,"src"),upstreamPublicDir=join11(upstreamCleanSourceDir,"public"),mergedPublicTargetDir=join11(workspaceDir,"public","imported-upstream"),mergeRequired=!0,upstreamSrcExists=!!statSync4(upstreamSrcDir,{throwIfNoEntry:!1})?.isDirectory(),upstreamPublicExists=!!statSync4(upstreamPublicDir,{throwIfNoEntry:!1})?.isDirectory();importSummary.source_detected_type==="frontend-app"&&assertDirectory(upstreamSrcDir,"upstream clean-source/src");let mergedPaths=[],skippedPaths=[];if(args.dryRun||(rmSync3(mergedTargetDir,{recursive:!0,force:!0}),rmSync3(mergedPublicTargetDir,{recursive:!0,force:!0}),mkdirSync8(mergedTargetDir,{recursive:!0})),importSummary.source_detected_type==="frontend-app"&&upstreamSrcExists)for(let name of FRONTEND_MERGEABLE_SOURCE_DIRS){let sourcePath=join11(upstreamSrcDir,name),sourceStats=statSync4(sourcePath,{throwIfNoEntry:!1});if(!sourceStats||!sourceStats.isDirectory()){skippedPaths.push(`src/${name}`);continue}let targetPath=join11(mergedTargetDir,name);mergedPaths.push({source:`src/${name}`,target:`${layout.imported_upstream_root}/${name}`}),args.dryRun||cpSync(sourcePath,targetPath,{recursive:!0})}else importSummary.source_detected_type==="frontend-app"?skippedPaths.push("src/: upstream clean-source does not contain mergeable frontend source"):skippedPaths.push("src/: static-site upstream does not require frontend source merge");upstreamPublicExists?(mergedPaths.push({source:"public",target:"public/imported-upstream"}),args.dryRun||(mkdirSync8(join11(workspaceDir,"public"),{recursive:!0}),cpSync(upstreamPublicDir,mergedPublicTargetDir,{recursive:!0}))):skippedPaths.push("public");let summary=buildMergeSummary(args,{workspaceDir,importSummaryPath,importSummary,importManifest,layout,upstreamCleanSourceDir,mergedTargetDir,mergeRequired,mergedPaths,skippedPaths});if(args.dryRun||writeJson(join11(designImportRoot,"merge-summary.json"),summary),args.json){process.stdout.write(`${JSON.stringify(summary,null,2)}
2407
+ `,"utf8")}function assertDirectory(pathValue,label){let stats=statSync4(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace(workspaceDir){assertDirectory(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES.filter(file=>!existsSync15(join11(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function buildMergeSummary(args,payload){let sourcePreprocessExecutionMode=payload.importSummary.source_preprocess_execution_mode||payload.importManifest.execution_mode||"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D merge \u6765\u6E90\u4E8E dry-run \u9884\u5904\u7406\u4EA7\u7269\uFF1Bsrc/imported-upstream/ \u4E2D\u4ECD\u53EF\u80FD\u5305\u542B\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"merge-imported-upstream",version:1,mode:"merge-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,import_summary:payload.importSummaryPath,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,upstream_clean_source_dir:payload.upstreamCleanSourceDir,merged_target_dir:payload.mergedTargetDir,merge_required:payload.mergeRequired,merged_paths:payload.mergedPaths,skipped_paths:payload.skippedPaths,preserved_workspace_files:payload.importSummary.preserved_workspace_files??[],warnings,next_steps:[`\u5728 ${payload.layout.imported_upstream_root}/ \u4E2D\u5BA1\u67E5\u4E0A\u6E38\u9875\u9762\u3001components\u3001styles\u3001lib\u3001imports`,payload.layout.template_key==="backend-app-node"?"\u4ECE src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC":"\u4ECE src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9\uFF0C\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC","\u9010\u6B65\u628A\u9700\u8981\u7684\u5E73\u53F0\u80FD\u529B\u63A5\u5165\u5230\u6A21\u677F\u4E3B\u5BFC\u7684\u8FD0\u884C\u5165\u53E3\u4E2D","\u5B8C\u6210\u63A5\u7EBF\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}async function runAppImportMergeCli(argv){let args=parseArgs(argv);if(args.help){printAppImportMergeUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve9(args.workspaceDir);validateWorkspace(workspaceDir);let designImportRoot=join11(workspaceDir,".design-import"),importSummaryPath=join11(designImportRoot,"import-summary.json"),importManifestPath=join11(designImportRoot,"reports","import-manifest.json"),upstreamCleanSourceDir=join11(designImportRoot,"upstream-clean-source");assertDirectory(designImportRoot,".design-import"),assertDirectory(upstreamCleanSourceDir,"upstream-clean-source");let importSummary=readJson(importSummaryPath),importManifest=existsSync15(importManifestPath)?readJson(importManifestPath):{},layout=resolveAppImportLayout(workspaceDir),mergedTargetDir=join11(workspaceDir,...layout.imported_upstream_root.split("/")),upstreamSrcDir=join11(upstreamCleanSourceDir,"src"),upstreamPublicDir=join11(upstreamCleanSourceDir,"public"),mergedPublicTargetDir=join11(workspaceDir,"public","imported-upstream"),mergeRequired=!0,upstreamSrcExists=!!statSync4(upstreamSrcDir,{throwIfNoEntry:!1})?.isDirectory(),upstreamPublicExists=!!statSync4(upstreamPublicDir,{throwIfNoEntry:!1})?.isDirectory();importSummary.source_detected_type==="frontend-app"&&assertDirectory(upstreamSrcDir,"upstream clean-source/src");let mergedPaths=[],skippedPaths=[];if(args.dryRun||(rmSync3(mergedTargetDir,{recursive:!0,force:!0}),rmSync3(mergedPublicTargetDir,{recursive:!0,force:!0}),mkdirSync8(mergedTargetDir,{recursive:!0})),importSummary.source_detected_type==="frontend-app"&&upstreamSrcExists)for(let name of FRONTEND_MERGEABLE_SOURCE_DIRS){let sourcePath=join11(upstreamSrcDir,name),sourceStats=statSync4(sourcePath,{throwIfNoEntry:!1});if(!sourceStats||!sourceStats.isDirectory()){skippedPaths.push(`src/${name}`);continue}let targetPath=join11(mergedTargetDir,name);mergedPaths.push({source:`src/${name}`,target:`${layout.imported_upstream_root}/${name}`}),args.dryRun||cpSync(sourcePath,targetPath,{recursive:!0})}else importSummary.source_detected_type==="frontend-app"?skippedPaths.push("src/: upstream clean-source does not contain mergeable frontend source"):skippedPaths.push("src/: static-site upstream does not require frontend source merge");upstreamPublicExists?(mergedPaths.push({source:"public",target:"public/imported-upstream"}),args.dryRun||(mkdirSync8(join11(workspaceDir,"public"),{recursive:!0}),cpSync(upstreamPublicDir,mergedPublicTargetDir,{recursive:!0}))):skippedPaths.push("public");let summary=buildMergeSummary(args,{workspaceDir,importSummaryPath,importSummary,importManifest,layout,upstreamCleanSourceDir,mergedTargetDir,mergeRequired,mergedPaths,skippedPaths});if(args.dryRun||writeJson(join11(designImportRoot,"merge-summary.json"),summary),args.json){process.stdout.write(`${JSON.stringify(summary,null,2)}
2408
2408
  `);return}process.stdout.write(["third-party design merge stage completed",`execution_mode: ${summary.execution_mode}`,`workspace_dir: ${summary.workspace_dir}`,`merged_target_dir: ${summary.merged_target_dir}`,`merged_paths: ${summary.merged_paths.length}`,`skipped_paths: ${summary.skipped_paths.length}`,`warnings: ${summary.warnings.length}`].join(`
2409
2409
  `)+`
2410
- `)}import{createHash as createHash5}from"node:crypto";import{cpSync as cpSync2,existsSync as existsSync16,mkdtempSync as mkdtempSync3,mkdirSync as mkdirSync9,readFileSync as readFileSync16,readdirSync as readdirSync5,rmSync as rmSync4,statSync as statSync5,unlinkSync as unlinkSync2,writeFileSync as writeFileSync10}from"node:fs";import{spawn,spawnSync}from"node:child_process";import{basename as basename3,dirname as dirname10,extname as extname2,join as join12,relative as relative3,resolve as resolve9}from"node:path";import{tmpdir as tmpdir2}from"node:os";var DEFAULT_INCLUDE_EXTENSIONS=new Set([".html",".css",".js",".jsx",".ts",".tsx",".vue",".svelte"]),DEFAULT_SKIP_DIRS=new Set([".git","node_modules","dist","build",".next",".nuxt","coverage",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]),IMAGE_HOST_HINTS=["unsplash.com","images.unsplash.com","googleusercontent.com","lh3.googleusercontent.com"],IMAGE_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".avif",".bmp",".ico"]),VIDEO_EXTENSIONS=new Set([".mp4",".webm",".mov",".m4v",".avi",".mkv"]),HTTPS_FORCE_HOST_SUFFIXES=["21epub.com"],URL_PATTERN=/https?:\/\/[^\s"'`)>\]]+/giu,LOCAL_ASSET_REF_PATTERN=/["'`](\.{1,2}\/[^"'`]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))["'`]/giu,CSS_URL_PATTERN=/url\((['"]?)(\.{1,2}\/[^)'"]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\1\)/giu,IMPORT_LOCAL_ASSET_PATTERN=/^(\s*)import\s+([A-Za-z_$][\w$]*)\s+from\s+(["'])(\.{1,2}\/[^"'`\n]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\3;?(\s*)$/gmu,LOCAL_IMAGE_UPLOAD_MAX_WIDTH=2048,PREFLIGHT_LOCAL_ASSET_WARN_BYTES=5*1024*1024,CACHE_VERSION=1,REMOTE_IMAGE_CONCURRENCY=3;function logProgress(message){process.stderr.write(`[app import preprocess] ${message}
2410
+ `)}import{createHash as createHash5}from"node:crypto";import{copyFileSync,existsSync as existsSync16,lstatSync,mkdtempSync as mkdtempSync3,mkdirSync as mkdirSync9,readFileSync as readFileSync16,readdirSync as readdirSync5,rmSync as rmSync4,statSync as statSync5,unlinkSync as unlinkSync2,writeFileSync as writeFileSync10}from"node:fs";import{spawn}from"node:child_process";import{basename as basename4,dirname as dirname10,extname as extname3,join as join12,relative as relative3,resolve as resolve10}from"node:path";import{tmpdir as tmpdir2}from"node:os";var DEFAULT_INCLUDE_EXTENSIONS=new Set([".html",".css",".js",".jsx",".ts",".tsx",".vue",".svelte"]),DEFAULT_SKIP_DIRS=new Set([".git","node_modules","dist","build",".next",".nuxt","coverage",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]),IMAGE_HOST_HINTS=["unsplash.com","images.unsplash.com","googleusercontent.com","lh3.googleusercontent.com"],IMAGE_EXTENSIONS=new Set([".png",".jpg",".jpeg",".gif",".webp",".svg",".avif",".bmp",".ico"]),VIDEO_EXTENSIONS=new Set([".mp4",".webm",".mov",".m4v",".avi",".mkv"]),HTTPS_FORCE_HOST_SUFFIXES=["21epub.com"],URL_PATTERN=/https?:\/\/[^\s"'`)>\]]+/giu,LOCAL_ASSET_REF_PATTERN=/["'`](\.{1,2}\/[^"'`]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))["'`]/giu,CSS_URL_PATTERN=/url\((['"]?)(\.{1,2}\/[^)'"]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\1\)/giu,IMPORT_LOCAL_ASSET_PATTERN=/^(\s*)import\s+([A-Za-z_$][\w$]*)\s+from\s+(["'])(\.{1,2}\/[^"'`\n]+?\.(?:png|jpg|jpeg|gif|webp|svg|avif|bmp|ico))\3;?(\s*)$/gmu,LOCAL_IMAGE_UPLOAD_MAX_WIDTH=2048,PREFLIGHT_LOCAL_ASSET_WARN_BYTES=5*1024*1024,CACHE_VERSION=1,REMOTE_IMAGE_CONCURRENCY=3;function logProgress(message){process.stderr.write(`[app import preprocess] ${message}
2411
2411
  `)}async function runWithConcurrency(items,concurrency,worker){let limit=Math.max(1,concurrency),results=new Array(items.length),nextIndex=0;async function consume(){for(;;){let currentIndex=nextIndex;if(nextIndex+=1,currentIndex>=items.length)return;results[currentIndex]=await worker(items[currentIndex],currentIndex)}}let runners=Array.from({length:Math.min(limit,items.length)},()=>consume());return await Promise.all(runners),results}function printAppImportPreprocessUsage(){process.stdout.write(["platform app import preprocess","","\u7528\u6CD5\uFF1A"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run] [--json]"," platform app import preprocess --dir <third-party-source-dir> --folder-id <asset-folder-id>","","\u4F5C\u7528\uFF1A"," \u626B\u63CF\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u505A\u7D20\u6750\u4E0A\u4F20\u56DE\u5199\u3001clean-source \u751F\u6210\u3001path-base \u57FA\u7840\u4FEE\u6B63\u4E0E\u9884\u5904\u7406\u62A5\u544A\u8F93\u51FA\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u7B49\u4EF7\u4E8E\u5728\u5F53\u524D\u76EE\u5F55\u6267\u884C\u9884\u5904\u7406\uFF1B\u82E5\u672A\u4F20 `--dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002"," - \u9ED8\u8BA4\u4F1A\u590D\u7528 `.design-preprocess/cache/` \u4E2D\u5DF2\u6210\u529F\u4E0A\u4F20\u7684\u7D20\u6750\u6620\u5C04\uFF1B\u82E5\u9700\u5FFD\u7565\u7F13\u5B58\u91CD\u8DD1\uFF0C\u53EF\u663E\u5F0F\u4F20 `--reset-cache`\u3002",""].join(`
2412
- `))}function parseArgs2(argv){let result={dir:"",include:new Set(DEFAULT_INCLUDE_EXTENSIONS),folderId:"",type:"auto",dryRun:!1,resume:!0,resetCache:!1,cliCmd:process.env.PLATFORM_CLI_CMD?.trim()||"platform",localReport:"",json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--resume"){result.resume=!0;continue}if(arg==="--reset-cache"){result.resetCache=!0;continue}if(arg==="--dir"){result.dir=argv[index+1]??"",index+=1;continue}if(arg==="--include"){let raw=argv[index+1]??"";index+=1,result.include=normalizeInclude(raw);continue}if(arg==="--folder-id"){result.folderId=argv[index+1]??"",index+=1;continue}if(arg==="--type"){result.type=argv[index+1]??result.type,index+=1;continue}if(arg==="--cli-cmd"){result.cliCmd=argv[index+1]??result.cliCmd,index+=1;continue}if(arg==="--local-report"){result.localReport=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function normalizeInclude(raw){let values=raw.split(",").map(item=>item.trim().toLowerCase()).filter(Boolean).map(item=>item.startsWith(".")?item:`.${item}`);return values.length>0?new Set(values):new Set(DEFAULT_INCLUDE_EXTENSIONS)}function buildRemoteCacheKey(url){return`remote:${url}`}function buildLocalCacheKey(contentHash){return`local:${contentHash}`}function defaultAssetCache(sourceDir){return{version:CACHE_VERSION,source_dir:sourceDir,entries:{}}}function defaultLockState(){return{version:CACHE_VERSION,active_run_id:null,started_at:null,phase:null,in_progress_keys:[],last_interrupted_at:null}}function readJsonIfExists2(filePath,fallbackValue){if(!existsSync16(filePath))return fallbackValue;try{return JSON.parse(readFileSync16(filePath,"utf8"))}catch{return fallbackValue}}function loadAssetCache(cacheFile,sourceDir){let loaded=readJsonIfExists2(cacheFile,defaultAssetCache(sourceDir));return{version:CACHE_VERSION,source_dir:loaded.source_dir||sourceDir,entries:loaded.entries&&typeof loaded.entries=="object"?loaded.entries:{}}}function persistAssetCache(cacheFile,payload){ensureDir(dirname10(cacheFile)),writeJson2(cacheFile,payload)}function loadLockState(lockFile){let loaded=readJsonIfExists2(lockFile,defaultLockState());return{version:CACHE_VERSION,active_run_id:loaded.active_run_id??null,started_at:loaded.started_at??null,phase:loaded.phase??null,in_progress_keys:Array.isArray(loaded.in_progress_keys)?loaded.in_progress_keys:[],last_interrupted_at:loaded.last_interrupted_at??null}}function persistLockState(lockFile,payload){ensureDir(dirname10(lockFile)),writeJson2(lockFile,payload)}function beginLockRun(lockFile,previousLock){let interruptedItems=previousLock.active_run_id?previousLock.in_progress_keys.length:0,next={version:CACHE_VERSION,active_run_id:`preprocess-${Date.now()}`,started_at:new Date().toISOString(),phase:"scan",in_progress_keys:[],last_interrupted_at:previousLock.active_run_id?new Date().toISOString():previousLock.last_interrupted_at};return persistLockState(lockFile,next),{lock:next,interruptedItems}}function updateLockState(lockFile,currentLock,patch){let next={...currentLock,...patch};return persistLockState(lockFile,next),next}function completeLockRun(lockFile,currentLock){let next={...currentLock,active_run_id:null,phase:"completed",in_progress_keys:[]};return persistLockState(lockFile,next),next}function cacheEntryReusable(entry){return!!(entry&&typeof entry.final_url=="string"&&entry.final_url.trim()&&entry.asset_id&&entry.status!=="failed")}function updateCacheEntry(cache,cacheKey,patch){cache.entries[cacheKey]={...cache.entries[cacheKey]??{},...patch,updated_at:new Date().toISOString()}}function walkFiles(rootDir,includeExtensions){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname2(entry.name).toLowerCase();includeExtensions.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function walkAssetFiles(rootDir){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname2(entry.name).toLowerCase();IMAGE_EXTENSIONS.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function normalizeMatchedUrl(rawUrl){return rawUrl.replace(/[),.;]+$/u,"").replace(/^(&quot;?|&#34;?|&apos;?|&#39;?)+/iu,"").replace(/(&quot;?|&#34;?|&apos;?|&#39;?)+$/iu,"").replace(/&amp;/giu,"&")}function findLineNumber(text2,offset){let line=1;for(let index=0;index<offset;index+=1)text2.charCodeAt(index)===10&&(line+=1);return line}function inferExtensionFromUrl(url){try{let parsed=new URL(url);return extname2(parsed.pathname).toLowerCase()}catch{return extname2(url).toLowerCase()}}function classifyUrl(url,surroundingText){let lowerUrl=url.toLowerCase(),extension=inferExtensionFromUrl(lowerUrl),lowerContext=surroundingText.toLowerCase(),nonImageContext=lowerContext.includes("<script")||lowerContext.includes("script src")||lowerContext.includes('rel="stylesheet"')||lowerContext.includes("rel='stylesheet'")||lowerContext.includes("xmlns="),nonImageUrl=lowerUrl.includes("cdn.tailwindcss.com")||lowerUrl.includes("fonts.googleapis.com")||lowerUrl.includes("fonts.gstatic.com")||lowerUrl.includes("w3.org/2000/svg");return lowerContext.includes("poster")?"poster":VIDEO_EXTENSIONS.has(extension)?"video":nonImageContext||nonImageUrl||extension===".js"||extension===".mjs"||extension===".css"?"unknown_remote":IMAGE_EXTENSIONS.has(extension)||IMAGE_HOST_HINTS.some(item=>lowerUrl.includes(item))||lowerContext.includes("<img")||lowerContext.includes("background-image")||lowerContext.includes("url(")?"image":"unknown_remote"}function computeRewriteSupported(kind){return kind==="image"}function compactContext(value){return value.replace(/\s+/gu," ").trim().slice(0,200)}function kindPriority(kind){switch(kind){case"video":return 4;case"poster":return 3;case"image":return 2;default:return 1}}function collectRemoteCandidates(rootDir,files){let byUrl=new Map;for(let filePath of files){let raw=readFileSync16(filePath,"utf8");for(let match2 of raw.matchAll(URL_PATTERN)){let matched=match2[0],offset=match2.index??0,url=normalizeMatchedUrl(matched),line=findLineNumber(raw,offset),surroundingText=raw.slice(Math.max(0,offset-80),Math.min(raw.length,offset+url.length+80)),kind=classifyUrl(url,surroundingText),occurrence={file:relative3(rootDir,filePath),line,kind,context:compactContext(surroundingText)},existing=byUrl.get(url);if(existing){existing.occurrences.push(occurrence),kindPriority(kind)>kindPriority(existing.kind)&&(existing.kind=kind,existing.rewrite_supported=computeRewriteSupported(kind));continue}byUrl.set(url,{url,kind,rewrite_supported:computeRewriteSupported(kind),occurrences:[occurrence],notes:kind==="video"?["\u5F53\u524D\u7B2C\u4E00\u7248\u4EC5\u626B\u63CF\uFF0C\u4E0D\u81EA\u52A8\u56DE\u5199\u89C6\u9891\u3002"]:[]})}}return[...byUrl.values()].sort((left,right)=>left.url.localeCompare(right.url))}function buildReport(rootDir,files,candidates,reportDir=join12(rootDir,".third-party-design-reports")){let byKind=candidates.reduce((accumulator,item)=>(accumulator[item.kind]=(accumulator[item.kind]??0)+1,accumulator),{}),pendingManualItems=candidates.filter(item=>item.rewrite_supported!==!0);return{tool:"assetize-project-urls",version:1,mode:"scan",project_dir:rootDir,scanned_files:files.map(file=>relative3(rootDir,file)),summary:{scanned_file_count:files.length,unique_remote_candidates:candidates.length,image_count:byKind.image??0,video_count:byKind.video??0,poster_count:byKind.poster??0,unknown_remote_count:byKind.unknown_remote??0},remote_candidates:candidates,pending_videos:candidates.filter(item=>item.kind==="video"),pending_manual_items:pendingManualItems,report_dir:reportDir}}function hashFileContent(filePath){let content=readFileSync16(filePath);return createHash5("sha256").update(content).digest("hex")}function collectReferencedLocalAssetPaths(sourceFilePath,sourceText){let found=new Set;for(let match2 of sourceText.matchAll(LOCAL_ASSET_REF_PATTERN))found.add(resolve9(dirname10(sourceFilePath),match2[1]));for(let match2 of sourceText.matchAll(CSS_URL_PATTERN))found.add(resolve9(dirname10(sourceFilePath),match2[2]));return found}function collectLocalAssetCandidates(rootDir,sourceFiles,assetFiles){let assetPathSet=new Set(assetFiles.map(filePath=>resolve9(filePath))),byHash=new Map,referencedAssets=new Map;for(let sourceFilePath of sourceFiles){let raw=readFileSync16(sourceFilePath,"utf8"),refs=collectReferencedLocalAssetPaths(sourceFilePath,raw);for(let absoluteRef of refs){if(!assetPathSet.has(absoluteRef))continue;let existing=referencedAssets.get(absoluteRef);if(existing){existing.referenced_by.push(relative3(rootDir,sourceFilePath));continue}referencedAssets.set(absoluteRef,{absolute_path:absoluteRef,relative_path:relative3(rootDir,absoluteRef),referenced_by:[relative3(rootDir,sourceFilePath)]})}}for(let asset of referencedAssets.values()){let stats=statSync5(asset.absolute_path),contentHash=hashFileContent(asset.absolute_path),existing=byHash.get(contentHash);if(existing){existing.source_paths.push(asset.relative_path),existing.referenced_by.push(...asset.referenced_by);continue}byHash.set(contentHash,{hash:contentHash,path:asset.relative_path,source_paths:[asset.relative_path],file_name:basename3(asset.absolute_path),size_bytes:stats.size,kind:"local_image",upload_supported:!0,referenced_by:[...asset.referenced_by]})}return[...byHash.values()].sort((left,right)=>left.path.localeCompare(right.path))}function detectProjectType(rootDir,requestedType="auto"){return requestedType==="static-site"||requestedType==="frontend-app"?requestedType:existsSync16(join12(rootDir,"package.json"))?"frontend-app":"static-site"}function collectPathBaseViolations(rootDir,files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let filePath of files){let relativePath=relative3(rootDir,filePath);if(!textFilePattern.test(relativePath))continue;let lines=readFileSync16(filePath,"utf8").split(/\r?\n/u);for(let index=0;index<lines.length;index+=1){let line=lines[index];for(let pattern of patterns)pattern.regex.lastIndex=0,pattern.regex.test(line)&&violations.push({file:relativePath,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function toPosixPath(value){return value.replace(/\\/gu,"/")}function ensureDotRelativePath(value){return value===""||value==="."?"./":value.startsWith("./")||value.startsWith("../")?value:`./${value}`}function resolveRootRelativePathForFile(rootDir,filePath,rootRelativePath){let normalizedTarget=rootRelativePath.replace(/^\/+/u,""),targetPath=join12(rootDir,normalizedTarget),relativePath=relative3(dirname10(filePath),targetPath);return ensureDotRelativePath(toPosixPath(relativePath))}function rewritePathBaseRefsInContent(rootDir,filePath,content){let changed=!1,rewrites=[],patterns=[{regex:/\b(src|href)\s*=\s*(["'])\/(?!\/)([^"'`]+)\2/gu,buildReplacement(attrName,quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"attribute",attr:attrName,from:`/${rawPath}`,to:nextPath}),`${attrName}=${quote}${nextPath}${quote}`}},{regex:/\bfetch\(\s*(["'])\/(?!\/)([^"'`]+)\1/gu,buildReplacement(quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"fetch",from:`/${rawPath}`,to:nextPath}),`fetch(${quote}${nextPath}${quote}`}}],next=content;return next=next.replace(patterns[0].regex,(fullMatch,attrName,quote,rawPath)=>(changed=!0,patterns[0].buildReplacement(attrName,quote,rawPath))),next=next.replace(patterns[1].regex,(fullMatch,quote,rawPath)=>(changed=!0,patterns[1].buildReplacement(quote,rawPath))),{changed,content:next,rewrites}}async function runPathBaseRewrite(args,report,files){let rewrittenFiles=[],rewriteEntries=[],warnings=[];for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),rewritten=rewritePathBaseRefsInContent(report.project_dir,absolutePath,before);rewritten.changed&&(args.dryRun||writeFileSync10(absolutePath,rewritten.content,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)),rewriteEntries.push({file:relative3(report.project_dir,absolutePath),rewrites:rewritten.rewrites}))}return rewriteEntries.length>0&&warnings.push(`\u5DF2\u4FEE\u6B63 root-relative \u9759\u6001\u8D44\u6E90\u5F15\u7528: ${rewriteEntries.length} \u4E2A\u6587\u4EF6`),{rewritten_files:rewrittenFiles,rewrite_entries:rewriteEntries,warnings}}function collectSourcePackageBytes(rootDir){let total=0;function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){visit(fullPath);continue}entry.isFile()&&(total+=statSync5(fullPath).size)}}return visit(rootDir),total}function collectPreflightWarnings(rootDir,localAssetCandidates){let warnings=[];existsSync16(join12(rootDir,"pnpm-workspace.yaml"))&&warnings.push({kind:"workspace_like",file:"pnpm-workspace.yaml",message:"\u68C0\u6D4B\u5230 pnpm-workspace.yaml\uFF1B\u540E\u7EED\u6A21\u677F\u627F\u63A5\u6216\u4E91\u7AEF\u6784\u5EFA\u524D\u901A\u5E38\u9700\u8981\u5904\u7406 workspace-like \u7ED3\u6784\u3002"});for(let asset of localAssetCandidates)asset.size_bytes>=PREFLIGHT_LOCAL_ASSET_WARN_BYTES&&warnings.push({kind:"large_local_asset",file:asset.path,size_bytes:asset.size_bytes,message:"\u68C0\u6D4B\u5230\u5927\u4F53\u79EF\u672C\u5730\u56FE\u7247\uFF1B\u5EFA\u8BAE\u5728\u9884\u5904\u7406\u9636\u6BB5\u5B8C\u6210\u4E0A\u4F20\u3001\u56DE\u5199\u4E0E\u6E05\u7406\u3002"});return warnings}function inferExtensionFromMimeType2(mimeType){switch((mimeType||"").toLowerCase()){case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"image/avif":return".avif";case"image/jpeg":case"image/jpg":return".jpg";default:return".jpg"}}function sanitizeFileStem(value){return value.toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,80)}function sanitizeFileName(value){let trimmed=value.trim(),extension=extname2(trimmed).toLowerCase(),stem=trimmed.slice(0,Math.max(0,trimmed.length-extension.length));return`${sanitizeFileStem(stem)||"remote-image"}${extension||".jpg"}`}function inferRemoteFileName(url,mimeType){let extension=inferExtensionFromUrl(url),fallbackExtension=inferExtensionFromMimeType2(mimeType);if(extension)try{let segment=new URL(url).pathname.split("/").filter(Boolean).at(-1);if(segment)return sanitizeFileName(decodeURIComponent(segment))}catch{}try{let parsed=new URL(url),rawSegment=parsed.pathname.split("/").filter(Boolean).at(-1)||parsed.hostname,sanitizedBase=sanitizeFileStem(decodeURIComponent(rawSegment).replace(/\.[a-z0-9]+$/iu,"").trim());if(sanitizedBase)return`${sanitizedBase}${fallbackExtension}`}catch{}switch((mimeType||"").toLowerCase()){case"image/png":return"remote-image.png";case"image/webp":return"remote-image.webp";case"image/gif":return"remote-image.gif";case"image/svg+xml":return"remote-image.svg";case"image/avif":return"remote-image.avif";default:return"remote-image.jpg"}}async function downloadRemoteImage(url){try{return await downloadRemoteImageViaFetch(url)}catch(error){if(!shouldRetryRemoteDownloadWithCurl(error)||!commandExists("curl"))throw error;return await downloadRemoteImageViaCurl(url)}}async function downloadRemoteImageViaFetch(url){let response=await fetch(url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let mimeType=String(response.headers.get("content-type")??"").split(";")[0].trim().toLowerCase();if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=Buffer.from(await response.arrayBuffer());if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}function shouldRetryRemoteDownloadWithCurl(error){let message=error instanceof Error?error.message:String(error);return/fetch failed|timed?out|econnreset|socket|network|tls|und_err/iu.test(message)}function extractLastContentType(headerText){let matches=[...headerText.matchAll(/^content-type:\s*([^\r\n;]+)/gimu)];return matches.length>0?String(matches[matches.length-1][1]).trim().toLowerCase():""}async function downloadRemoteImageViaCurl(url){let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-remote-")),outputPath=join12(tempRoot,"remote.bin"),headerPath=join12(tempRoot,"headers.txt");try{await new Promise((resolve17,reject)=>{let child=spawn("curl",["-L","--fail","--silent","--show-error","-D",headerPath,"-o",outputPath,url],{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"]}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolve17();return}reject(new Error(stderr.trim()||`curl \u4E0B\u8F7D\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})});let mimeType=extractLastContentType(existsSync16(headerPath)?readFileSync16(headerPath,"utf8"):"");if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=readFileSync16(outputPath);if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function uploadImageViaCli(args){let commandArgs=["asset","upload",args.filePath,"--json"];args.title&&commandArgs.push("--title",args.title),args.folderId&&commandArgs.push("--folder-id",args.folderId);let result=spawnSync(args.cliCmd,commandArgs,{cwd:args.cwd,env:process.env,encoding:"utf8"});if(result.status!==0)throw new Error(result.stderr?.trim()||result.stdout?.trim()||"\u7D20\u6750\u4E0A\u4F20\u5931\u8D25");let parsed=JSON.parse(result.stdout);if(!parsed||typeof parsed.original_url!="string"||!parsed.original_url.trim())throw new Error("\u7D20\u6750\u4E0A\u4F20\u8FD4\u56DE\u7F3A\u5C11 original_url");return parsed}function commandExists(command){return spawnSync("bash",["-lc",`command -v ${command}`],{cwd:process.cwd(),env:process.env,encoding:"utf8"}).status===0}function shouldRetryWithCompression(error){let message=error instanceof Error?error.message:String(error);return/\b413\b/u.test(message)}function buildCompressedFilePath(tempRoot,sourcePath){let safeStem=sanitizeFileStem(basename3(sourcePath,extname2(sourcePath)))||"compressed-image";return join12(tempRoot,`${safeStem}-${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}.jpg`)}function compressLocalImageWithSips(sourcePath,tempRoot){if(!commandExists("sips"))throw new Error("\u5F53\u524D\u673A\u5668\u7F3A\u5C11 sips\uFF0C\u65E0\u6CD5\u6267\u884C\u672C\u5730\u56FE\u7247\u538B\u7F29\u515C\u5E95");let outputPath=buildCompressedFilePath(tempRoot,sourcePath),result=spawnSync("sips",["-s","format","jpeg","--resampleWidth",String(LOCAL_IMAGE_UPLOAD_MAX_WIDTH),sourcePath,"--out",outputPath],{cwd:process.cwd(),env:process.env,encoding:"utf8"});if(result.status!==0)throw new Error(result.stderr?.trim()||result.stdout?.trim()||"sips \u538B\u7F29\u5931\u8D25");return outputPath}function shouldForceHttps(hostname){let lower=hostname.toLowerCase();return lower==="localhost"||lower==="127.0.0.1"||lower==="::1"?!1:HTTPS_FORCE_HOST_SUFFIXES.some(suffix=>lower===suffix||lower.endsWith(`.${suffix}`))}function normalizeUploadedAssetUrl(rawUrl){try{let parsed=new URL(rawUrl);return parsed.protocol==="http:"&&shouldForceHttps(parsed.hostname)?(parsed.protocol="https:",parsed.toString()):rawUrl}catch{return rawUrl}}function replaceUrlInContent(content,originalUrl,finalUrl){return content.split(originalUrl).join(finalUrl)}function normalizeLocalAssetReportPath(args,reportDir){return args.localReport?resolve9(args.localReport):join12(reportDir,"local-asset-report.json")}function loadLocalUploadMappings(reportPath){if(!existsSync16(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync16(reportPath,"utf8"));if(!Array.isArray(payload.uploaded_local_assets))throw new Error(`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u683C\u5F0F\u65E0\u6548\uFF0C\u7F3A\u5C11 uploaded_local_assets: ${reportPath}`);let bySourcePath=new Map;for(let item of payload.uploaded_local_assets){if(!item||typeof item.final_url!="string"||!item.final_url.trim()||item.status!=="uploaded"&&item.status!=="uploaded_after_compress"&&item.status!=="reused_from_cache")continue;let allSourcePaths=Array.isArray(item.source_paths)&&item.source_paths.length>0?item.source_paths:[item.source_path];for(let sourcePath of allSourcePaths)typeof sourcePath=="string"&&sourcePath.trim()&&bySourcePath.set(sourcePath,item.final_url)}return{reportPath,bySourcePath}}function rewriteImportedLocalAssets(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(IMPORT_LOCAL_ASSET_PATTERN,(fullMatch,leading,identifier,quote,rawRef,trailing)=>{let resolved=relative3(rootDir,resolve9(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,`${leading}const ${identifier} = ${quote}${finalUrl}${quote};${trailing}`):fullMatch});return{changed,content:next}}function rewriteLiteralLocalAssetRefs(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(LOCAL_ASSET_REF_PATTERN,(fullMatch,rawRef)=>{let resolved=relative3(rootDir,resolve9(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,fullMatch.replace(rawRef,finalUrl)):fullMatch});return{changed,content:next}}async function runRewriteLocal(args,report,files,cacheContext){let warnings=[];if(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0)return{rewritten_files:[],deleted_clean_source_assets:[],warnings};let localReportPath=normalizeLocalAssetReportPath(args,report.report_dir),loaded=loadLocalUploadMappings(localReportPath),relativePathToUrl=loaded.bySourcePath;if(relativePathToUrl.size===0){let noLocalAssetCandidates=report.local_asset_candidates.length===0,message=noLocalAssetCandidates?`\u5F53\u524D\u6E90\u7801\u5305\u672A\u68C0\u6D4B\u5230\u9700\u8981\u56DE\u5199\u7684\u672C\u5730\u7D20\u6750: ${loaded.reportPath}`:`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u91CC\u6CA1\u6709\u53EF\u56DE\u5199\u7684\u6210\u529F\u4E0A\u4F20\u8BB0\u5F55: ${loaded.reportPath}`;if(args.dryRun)return{rewritten_files:[],deleted_clean_source_assets:[],warnings:[`dry-run \u6A21\u5F0F\u4E0B\u672A\u751F\u6210\u672C\u5730\u7D20\u6750\u56DE\u5199\u6620\u5C04: ${loaded.reportPath}`]};if(noLocalAssetCandidates)return{rewritten_files:[],deleted_clean_source_assets:[],warnings:[message]};throw new Error(message)}let rewrittenFiles=[],deletedLocalAssets=[],hashBySourcePath=new Map;for(let asset of report.local_asset_candidates)for(let sourcePath of asset.source_paths)hashBySourcePath.set(sourcePath,asset.hash);for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),after=before;after=rewriteImportedLocalAssets(report.project_dir,absolutePath,after,relativePathToUrl).content,after=rewriteLiteralLocalAssetRefs(report.project_dir,absolutePath,after,relativePathToUrl).content,after!==before&&(args.dryRun||writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_local_refs"});for(let sourcePath of[...relativePathToUrl.keys()]){let contentHash=hashBySourcePath.get(sourcePath);if(!contentHash)continue;let cacheKey=buildLocalCacheKey(contentHash),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}for(let sourcePath of[...relativePathToUrl.keys()].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,sourcePath);if(!existsSync16(absolutePath))continue;let contentHash=hashBySourcePath.get(sourcePath),cacheKey=contentHash?buildLocalCacheKey(contentHash):null;if(cacheContext?.enabled&&cacheKey){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"cleanup_local_assets",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]});let cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaning"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}args.dryRun||unlinkSync2(absolutePath),deletedLocalAssets.push(sourcePath),cacheContext?.enabled&&cacheKey&&(cacheContext.cache.entries[cacheKey]&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaned"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}return warnings.push(`\u5DF2\u57FA\u4E8E\u4E0A\u4F20\u62A5\u544A\u56DE\u5199\u672C\u5730\u56FE\u7247\u5F15\u7528: ${loaded.reportPath}`),{rewritten_files:rewrittenFiles,deleted_clean_source_assets:deletedLocalAssets,warnings}}function copyWorkspaceForPreprocess(sourceDir,cleanSourceDir){rmSync4(cleanSourceDir,{recursive:!0,force:!0}),ensureDir(cleanSourceDir);let entries=readdirSync5(sourceDir,{withFileTypes:!0});for(let entry of entries)DEFAULT_SKIP_DIRS.has(entry.name)||cpSync2(join12(sourceDir,entry.name),join12(cleanSourceDir,entry.name),{recursive:!0})}function buildPreflightPayload(report,sourceDir,cleanSourceDir,options){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,detected_type:options.detectedType,upstream_source_package_bytes:options.upstreamSourcePackageBytes,clean_source_package_bytes_before_rewrite:options.cleanSourcePackageBytesBeforeRewrite,summary:report.summary,path_base_violations_detected:options.pathBaseViolationsDetected,path_base_rewrites:options.pathBaseRewrites,path_base_violations_remaining:options.pathBaseViolationsRemaining,preflight_warnings:options.preflightWarnings,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,pending_videos:report.pending_videos,pending_manual_items:report.pending_manual_items}}function buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets}}function countAppliedRemoteUploads(rewriteResult){return rewriteResult.uploaded_assets.filter(item=>item.status==="uploaded").length}function countAppliedLocalUploads(localUploadResult){return localUploadResult.uploaded_local_assets.filter(item=>item.status==="uploaded"||item.status==="uploaded_after_compress").length}function buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult){return{remote_upload_candidates:rewriteResult.uploaded_assets.length,local_upload_candidates:localUploadResult.uploaded_local_assets.length,path_base_rewrite_candidates:pathBaseRewriteResult.rewritten_files.length,local_cleanup_candidates:localRewriteResult.deleted_clean_source_assets.length,file_rewrite_candidates:rewriteResult.rewritten_files.length+localRewriteResult.rewritten_files.length+pathBaseRewriteResult.rewritten_files.length,pending_video_candidates:report.pending_videos.length}}function buildWarningsPayload(report,importManifest,reportsDir,cacheContext){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:importManifest.source_dir,clean_source_dir:importManifest.clean_source_dir,warnings:importManifest.warnings,pending_manual_items:report.pending_manual_items,pending_videos:report.pending_videos,cache_warnings:cacheContext?.warnings??[],recovery_actions:{resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0},report_files:{preflight_report:join12(reportsDir,"preflight-report.json"),asset_inventory:join12(reportsDir,"asset-inventory.json"),import_manifest:join12(reportsDir,"import-manifest.json"),pending_videos:join12(reportsDir,"pending-videos.json")}}}function buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext){return{tool:report.tool,version:report.version,generated_at:new Date().toISOString(),mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,cache_dir:cacheContext?.cacheDir??null,cache_enabled:cacheContext?.enabled??!1,resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0,clean_source_package_bytes:collectSourcePackageBytes(cleanSourceDir),summary:report.summary,planned_actions:buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult),asset_mappings:{remote:rewriteResult.uploaded_assets,local:localUploadResult.uploaded_local_assets},rewritten_files:[...rewriteResult.rewritten_files,...localRewriteResult.rewritten_files,...pathBaseRewriteResult.rewritten_files],deleted_clean_source_assets:localRewriteResult.deleted_clean_source_assets,path_base_rewrites:pathBaseRewriteResult.rewrite_entries,pending_videos:report.pending_videos,warnings:[...rewriteResult.warnings,...localUploadResult.warnings,...localRewriteResult.warnings,...pathBaseRewriteResult.warnings]}}async function runRewrite(args,report,cacheContext){let imageCandidates=report.remote_candidates.filter(item=>item.kind==="image"&&item.rewrite_supported===!0),warnings=[],uploads=[],replacements=new Map;if(args.dryRun)return{uploaded_assets:imageCandidates.map(item=>({original_url:item.url,final_url:item.url,status:"dry-run"})),rewritten_files:[],warnings};let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-project-"));try{let total=imageCandidates.length,uploadResults=await runWithConcurrency(imageCandidates,REMOTE_IMAGE_CONCURRENCY,async(candidate,index)=>{let itemLabel=`remote image ${index+1}/${total}`,cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached))return logProgress(`${itemLabel} reused from cache: ${candidate.url}`),cacheContext.stats.remote_reused+=1,{candidate,finalUrl:cached.final_url,assetId:cached.asset_id??null,status:"reused_from_cache"};try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_remote",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploading",original_ref:candidate.url}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let downloadStart=Date.now();logProgress(`${itemLabel} downloading: ${candidate.url}`);let downloaded=await downloadRemoteImage(candidate.url),downloadMs=Date.now()-downloadStart,tempFilePath=join12(tempRoot,`${index+1}-${downloaded.fileName}`);writeFileSync10(tempFilePath,downloaded.content),logProgress(`${itemLabel} downloaded in ${downloadMs}ms, uploading asset`);let uploadStart=Date.now(),uploaded=uploadImageViaCli({cliCmd:args.cliCmd,cwd:report.project_dir,filePath:tempFilePath,title:downloaded.fileName,folderId:args.folderId||void 0}),uploadMs=Date.now()-uploadStart,finalUrl=normalizeUploadedAssetUrl(uploaded.original_url);return logProgress(`${itemLabel} uploaded in ${uploadMs}ms`),finalUrl!==uploaded.original_url&&warnings.push(`\u5DF2\u5C06\u7D20\u6750 URL \u534F\u8BAE\u89C4\u8303\u5316\u4E3A HTTPS: ${uploaded.original_url} -> ${finalUrl}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploaded",original_ref:candidate.url,final_url:finalUrl,asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,content_digest:`sha256:${createHash5("sha256").update(downloaded.content).digest("hex")}`}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)})),{candidate,finalUrl,assetId:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}}catch(error){let message=error instanceof Error?error.message:String(error);return logProgress(`${itemLabel} failed: ${message}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"failed",original_ref:candidate.url,last_error:message}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),{candidate,error:message,status:"fallback"}}});for(let result of uploadResults){if(result.error){warnings.push(`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${result.candidate.url} (${result.error})`),uploads.push({original_url:result.candidate.url,final_url:result.candidate.url,status:"fallback"});continue}replacements.set(result.candidate.url,result.finalUrl),uploads.push({original_url:result.candidate.url,final_url:result.finalUrl,asset_id:result.assetId??null,status:result.status})}let targetFiles=new Set(imageCandidates.flatMap(candidate=>candidate.occurrences.map(occurrence=>occurrence.file))),rewrittenFiles=[];for(let relativePath of[...targetFiles].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,relativePath),before=readFileSync16(absolutePath,"utf8"),after=before;for(let[originalUrl,finalUrl]of replacements)after=replaceUrlInContent(after,originalUrl,finalUrl);after!==before&&(writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relativePath))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_remote_refs"});for(let candidate of imageCandidates){let cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}return{uploaded_assets:uploads,rewritten_files:rewrittenFiles,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}async function runUploadLocal(args,report,cacheContext){let warnings=[],uploads=[],tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-local-"));try{if(args.dryRun)return{uploaded_local_assets:report.local_asset_candidates.map(item=>({source_path:item.path,title:item.file_name,status:"dry-run"})),warnings};for(let asset of report.local_asset_candidates){let absolutePath=join12(report.project_dir,asset.path),cacheKey=buildLocalCacheKey(asset.hash),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached)){uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:cached.title??asset.file_name,final_url:cached.final_url,asset_id:cached.asset_id??null,status:"reused_from_cache"}),cacheContext.stats.local_reused+=1;continue}try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_local",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploading",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let uploaded=uploadImageViaCli({cliCmd:args.cliCmd,cwd:report.project_dir,filePath:absolutePath,title:asset.file_name,folderId:args.folderId||void 0});uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}catch(error){if(shouldRetryWithCompression(error))try{let compressedPath=compressLocalImageWithSips(absolutePath,tempRoot),uploaded=uploadImageViaCli({cliCmd:args.cliCmd,cwd:report.project_dir,filePath:compressedPath,title:basename3(compressedPath),folderId:args.folderId||void 0});warnings.push(`\u672C\u5730\u56FE\u7247\u8FC7\u5927\uFF0C\u5DF2\u81EA\u52A8\u538B\u7F29\u540E\u4E0A\u4F20: ${asset.path}`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:basename3(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded_after_compress"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:basename3(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}));continue}catch(compressionError){warnings.push(`\u672C\u5730\u56FE\u7247\u538B\u7F29\u91CD\u8BD5\u5931\u8D25: ${asset.path} (${compressionError instanceof Error?compressionError.message:String(compressionError)})`)}warnings.push(`\u672C\u5730\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${asset.path} (${error instanceof Error?error.message:String(error)})`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,status:"failed"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"failed",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,last_error:error instanceof Error?error.message:String(error)}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}}return{uploaded_local_assets:uploads,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function renderMarkdown(report){let lines=[];if(lines.push("# Scan Report",""),lines.push(`- Project: \`${report.project_dir}\``),lines.push(`- Mode: \`${report.mode}\``),lines.push(`- Scanned files: ${report.summary.scanned_file_count}`),lines.push(`- Unique remote candidates: ${report.summary.unique_remote_candidates}`),lines.push(`- Images: ${report.summary.image_count}`),lines.push(`- Videos: ${report.summary.video_count}`),lines.push(`- Posters: ${report.summary.poster_count}`),lines.push(`- Unknown remote: ${report.summary.unknown_remote_count}`),lines.push(`- Local images: ${report.summary.local_asset_count??0}`,""),report.remote_candidates.length===0&&(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0))return lines.push("No candidates found.",""),lines.join(`
2412
+ `))}function parseArgs2(argv){let result={dir:"",include:new Set(DEFAULT_INCLUDE_EXTENSIONS),folderId:"",type:"auto",dryRun:!1,resume:!0,resetCache:!1,localReport:"",json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--resume"){result.resume=!0;continue}if(arg==="--reset-cache"){result.resetCache=!0;continue}if(arg==="--dir"){result.dir=argv[index+1]??"",index+=1;continue}if(arg==="--include"){let raw=argv[index+1]??"";index+=1,result.include=normalizeInclude(raw);continue}if(arg==="--folder-id"){result.folderId=argv[index+1]??"",index+=1;continue}if(arg==="--type"){result.type=argv[index+1]??result.type,index+=1;continue}if(arg==="--local-report"){result.localReport=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function normalizeInclude(raw){let values=raw.split(",").map(item=>item.trim().toLowerCase()).filter(Boolean).map(item=>item.startsWith(".")?item:`.${item}`);return values.length>0?new Set(values):new Set(DEFAULT_INCLUDE_EXTENSIONS)}function buildRemoteCacheKey(url){return`remote:${url}`}function buildLocalCacheKey(contentHash){return`local:${contentHash}`}function defaultAssetCache(sourceDir){return{version:CACHE_VERSION,source_dir:sourceDir,entries:{}}}function defaultLockState(){return{version:CACHE_VERSION,active_run_id:null,started_at:null,phase:null,in_progress_keys:[],last_interrupted_at:null}}function readJsonIfExists2(filePath,fallbackValue){if(!existsSync16(filePath))return fallbackValue;try{return JSON.parse(readFileSync16(filePath,"utf8"))}catch{return fallbackValue}}function loadAssetCache(cacheFile,sourceDir){let loaded=readJsonIfExists2(cacheFile,defaultAssetCache(sourceDir));return{version:CACHE_VERSION,source_dir:loaded.source_dir||sourceDir,entries:loaded.entries&&typeof loaded.entries=="object"?loaded.entries:{}}}function persistAssetCache(cacheFile,payload){ensureDir(dirname10(cacheFile)),writeJson2(cacheFile,payload)}function loadLockState(lockFile){let loaded=readJsonIfExists2(lockFile,defaultLockState());return{version:CACHE_VERSION,active_run_id:loaded.active_run_id??null,started_at:loaded.started_at??null,phase:loaded.phase??null,in_progress_keys:Array.isArray(loaded.in_progress_keys)?loaded.in_progress_keys:[],last_interrupted_at:loaded.last_interrupted_at??null}}function persistLockState(lockFile,payload){ensureDir(dirname10(lockFile)),writeJson2(lockFile,payload)}function beginLockRun(lockFile,previousLock){let interruptedItems=previousLock.active_run_id?previousLock.in_progress_keys.length:0,next={version:CACHE_VERSION,active_run_id:`preprocess-${Date.now()}`,started_at:new Date().toISOString(),phase:"scan",in_progress_keys:[],last_interrupted_at:previousLock.active_run_id?new Date().toISOString():previousLock.last_interrupted_at};return persistLockState(lockFile,next),{lock:next,interruptedItems}}function updateLockState(lockFile,currentLock,patch){let next={...currentLock,...patch};return persistLockState(lockFile,next),next}function completeLockRun(lockFile,currentLock){let next={...currentLock,active_run_id:null,phase:"completed",in_progress_keys:[]};return persistLockState(lockFile,next),next}function cacheEntryReusable(entry){return!!(entry&&typeof entry.final_url=="string"&&entry.final_url.trim()&&entry.asset_id&&entry.status!=="failed")}function updateCacheEntry(cache,cacheKey,patch){cache.entries[cacheKey]={...cache.entries[cacheKey]??{},...patch,updated_at:new Date().toISOString()}}function walkFiles(rootDir,includeExtensions){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname3(entry.name).toLowerCase();includeExtensions.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function walkAssetFiles(rootDir){let files=[];function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;visit(fullPath);continue}if(!entry.isFile())continue;let extension=extname3(entry.name).toLowerCase();IMAGE_EXTENSIONS.has(extension)&&files.push(fullPath)}}return visit(rootDir),files.sort((left,right)=>left.localeCompare(right))}function normalizeMatchedUrl(rawUrl){return rawUrl.replace(/[),.;]+$/u,"").replace(/^(&quot;?|&#34;?|&apos;?|&#39;?)+/iu,"").replace(/(&quot;?|&#34;?|&apos;?|&#39;?)+$/iu,"").replace(/&amp;/giu,"&")}function findLineNumber(text2,offset){let line=1;for(let index=0;index<offset;index+=1)text2.charCodeAt(index)===10&&(line+=1);return line}function inferExtensionFromUrl(url){try{let parsed=new URL(url);return extname3(parsed.pathname).toLowerCase()}catch{return extname3(url).toLowerCase()}}function classifyUrl(url,surroundingText){let lowerUrl=url.toLowerCase(),extension=inferExtensionFromUrl(lowerUrl),lowerContext=surroundingText.toLowerCase(),nonImageContext=lowerContext.includes("<script")||lowerContext.includes("script src")||lowerContext.includes('rel="stylesheet"')||lowerContext.includes("rel='stylesheet'")||lowerContext.includes("xmlns="),nonImageUrl=lowerUrl.includes("cdn.tailwindcss.com")||lowerUrl.includes("fonts.googleapis.com")||lowerUrl.includes("fonts.gstatic.com")||lowerUrl.includes("w3.org/2000/svg");return lowerContext.includes("poster")?"poster":VIDEO_EXTENSIONS.has(extension)?"video":nonImageContext||nonImageUrl||extension===".js"||extension===".mjs"||extension===".css"?"unknown_remote":IMAGE_EXTENSIONS.has(extension)||IMAGE_HOST_HINTS.some(item=>lowerUrl.includes(item))||lowerContext.includes("<img")||lowerContext.includes("background-image")||lowerContext.includes("url(")?"image":"unknown_remote"}function computeRewriteSupported(kind){return kind==="image"}function compactContext(value){return value.replace(/\s+/gu," ").trim().slice(0,200)}function kindPriority(kind){switch(kind){case"video":return 4;case"poster":return 3;case"image":return 2;default:return 1}}function collectRemoteCandidates(rootDir,files){let byUrl=new Map;for(let filePath of files){let raw=readFileSync16(filePath,"utf8");for(let match2 of raw.matchAll(URL_PATTERN)){let matched=match2[0],offset=match2.index??0,url=normalizeMatchedUrl(matched),line=findLineNumber(raw,offset),surroundingText=raw.slice(Math.max(0,offset-80),Math.min(raw.length,offset+url.length+80)),kind=classifyUrl(url,surroundingText),occurrence={file:relative3(rootDir,filePath),line,kind,context:compactContext(surroundingText)},existing=byUrl.get(url);if(existing){existing.occurrences.push(occurrence),kindPriority(kind)>kindPriority(existing.kind)&&(existing.kind=kind,existing.rewrite_supported=computeRewriteSupported(kind));continue}byUrl.set(url,{url,kind,rewrite_supported:computeRewriteSupported(kind),occurrences:[occurrence],notes:kind==="video"?["\u5F53\u524D\u7B2C\u4E00\u7248\u4EC5\u626B\u63CF\uFF0C\u4E0D\u81EA\u52A8\u56DE\u5199\u89C6\u9891\u3002"]:[]})}}return[...byUrl.values()].sort((left,right)=>left.url.localeCompare(right.url))}function buildReport(rootDir,files,candidates,reportDir=join12(rootDir,".third-party-design-reports")){let byKind=candidates.reduce((accumulator,item)=>(accumulator[item.kind]=(accumulator[item.kind]??0)+1,accumulator),{}),pendingManualItems=candidates.filter(item=>item.rewrite_supported!==!0);return{tool:"assetize-project-urls",version:1,mode:"scan",project_dir:rootDir,scanned_files:files.map(file=>relative3(rootDir,file)),summary:{scanned_file_count:files.length,unique_remote_candidates:candidates.length,image_count:byKind.image??0,video_count:byKind.video??0,poster_count:byKind.poster??0,unknown_remote_count:byKind.unknown_remote??0},remote_candidates:candidates,pending_videos:candidates.filter(item=>item.kind==="video"),pending_manual_items:pendingManualItems,report_dir:reportDir}}function hashFileContent(filePath){let content=readFileSync16(filePath);return createHash5("sha256").update(content).digest("hex")}function collectReferencedLocalAssetPaths(sourceFilePath,sourceText){let found=new Set;for(let match2 of sourceText.matchAll(LOCAL_ASSET_REF_PATTERN))found.add(resolve10(dirname10(sourceFilePath),match2[1]));for(let match2 of sourceText.matchAll(CSS_URL_PATTERN))found.add(resolve10(dirname10(sourceFilePath),match2[2]));return found}function collectLocalAssetCandidates(rootDir,sourceFiles,assetFiles){let assetPathSet=new Set(assetFiles.map(filePath=>resolve10(filePath))),byHash=new Map,referencedAssets=new Map;for(let sourceFilePath of sourceFiles){let raw=readFileSync16(sourceFilePath,"utf8"),refs=collectReferencedLocalAssetPaths(sourceFilePath,raw);for(let absoluteRef of refs){if(!assetPathSet.has(absoluteRef))continue;let existing=referencedAssets.get(absoluteRef);if(existing){existing.referenced_by.push(relative3(rootDir,sourceFilePath));continue}referencedAssets.set(absoluteRef,{absolute_path:absoluteRef,relative_path:relative3(rootDir,absoluteRef),referenced_by:[relative3(rootDir,sourceFilePath)]})}}for(let asset of referencedAssets.values()){let stats=statSync5(asset.absolute_path),contentHash=hashFileContent(asset.absolute_path),existing=byHash.get(contentHash);if(existing){existing.source_paths.push(asset.relative_path),existing.referenced_by.push(...asset.referenced_by);continue}byHash.set(contentHash,{hash:contentHash,path:asset.relative_path,source_paths:[asset.relative_path],file_name:basename4(asset.absolute_path),size_bytes:stats.size,kind:"local_image",upload_supported:!0,referenced_by:[...asset.referenced_by]})}return[...byHash.values()].sort((left,right)=>left.path.localeCompare(right.path))}function detectProjectType(rootDir,requestedType="auto"){return requestedType==="static-site"||requestedType==="frontend-app"?requestedType:existsSync16(join12(rootDir,"package.json"))?"frontend-app":"static-site"}function collectPathBaseViolations(rootDir,files){let violations=[],textFilePattern=/\.(?:[cm]?[jt]sx?|html?|css)$/i,patterns=[{kind:"root_relative_fetch",regex:/\bfetch\(\s*['"`]\/(?!\/)/g},{kind:"root_relative_href",regex:/\bhref\s*=\s*['"]\/(?!\/)/g},{kind:"root_relative_src",regex:/\bsrc\s*=\s*['"]\/(?!\/)/g}];for(let filePath of files){let relativePath=relative3(rootDir,filePath);if(!textFilePattern.test(relativePath))continue;let lines=readFileSync16(filePath,"utf8").split(/\r?\n/u);for(let index=0;index<lines.length;index+=1){let line=lines[index];for(let pattern of patterns)pattern.regex.lastIndex=0,pattern.regex.test(line)&&violations.push({file:relativePath,line:index+1,kind:pattern.kind,snippet:line.trim().slice(0,180)})}}return violations}function toPosixPath(value){return value.replace(/\\/gu,"/")}function ensureDotRelativePath(value){return value===""||value==="."?"./":value.startsWith("./")||value.startsWith("../")?value:`./${value}`}function resolveRootRelativePathForFile(rootDir,filePath,rootRelativePath){let normalizedTarget=rootRelativePath.replace(/^\/+/u,""),targetPath=join12(rootDir,normalizedTarget),relativePath=relative3(dirname10(filePath),targetPath);return ensureDotRelativePath(toPosixPath(relativePath))}function rewritePathBaseRefsInContent(rootDir,filePath,content){let changed=!1,rewrites=[],patterns=[{regex:/\b(src|href)\s*=\s*(["'])\/(?!\/)([^"'`]+)\2/gu,buildReplacement(attrName,quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"attribute",attr:attrName,from:`/${rawPath}`,to:nextPath}),`${attrName}=${quote}${nextPath}${quote}`}},{regex:/\bfetch\(\s*(["'])\/(?!\/)([^"'`]+)\1/gu,buildReplacement(quote,rawPath){let nextPath=resolveRootRelativePathForFile(rootDir,filePath,rawPath);return rewrites.push({kind:"fetch",from:`/${rawPath}`,to:nextPath}),`fetch(${quote}${nextPath}${quote}`}}],next=content;return next=next.replace(patterns[0].regex,(fullMatch,attrName,quote,rawPath)=>(changed=!0,patterns[0].buildReplacement(attrName,quote,rawPath))),next=next.replace(patterns[1].regex,(fullMatch,quote,rawPath)=>(changed=!0,patterns[1].buildReplacement(quote,rawPath))),{changed,content:next,rewrites}}async function runPathBaseRewrite(args,report,files){let rewrittenFiles=[],rewriteEntries=[],warnings=[];for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),rewritten=rewritePathBaseRefsInContent(report.project_dir,absolutePath,before);rewritten.changed&&(args.dryRun||writeFileSync10(absolutePath,rewritten.content,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)),rewriteEntries.push({file:relative3(report.project_dir,absolutePath),rewrites:rewritten.rewrites}))}return rewriteEntries.length>0&&warnings.push(`\u5DF2\u4FEE\u6B63 root-relative \u9759\u6001\u8D44\u6E90\u5F15\u7528: ${rewriteEntries.length} \u4E2A\u6587\u4EF6`),{rewritten_files:rewrittenFiles,rewrite_entries:rewriteEntries,warnings}}function collectSourcePackageBytes(rootDir){let total=0;function visit(currentDir){let entries=readdirSync5(currentDir,{withFileTypes:!0});for(let entry of entries){if(DEFAULT_SKIP_DIRS.has(entry.name))continue;let fullPath=join12(currentDir,entry.name);if(entry.isDirectory()){visit(fullPath);continue}entry.isFile()&&(total+=statSync5(fullPath).size)}}return visit(rootDir),total}function collectPreflightWarnings(rootDir,localAssetCandidates){let warnings=[];existsSync16(join12(rootDir,"pnpm-workspace.yaml"))&&warnings.push({kind:"workspace_like",file:"pnpm-workspace.yaml",message:"\u68C0\u6D4B\u5230 pnpm-workspace.yaml\uFF1B\u540E\u7EED\u6A21\u677F\u627F\u63A5\u6216\u4E91\u7AEF\u6784\u5EFA\u524D\u901A\u5E38\u9700\u8981\u5904\u7406 workspace-like \u7ED3\u6784\u3002"});for(let asset of localAssetCandidates)asset.size_bytes>=PREFLIGHT_LOCAL_ASSET_WARN_BYTES&&warnings.push({kind:"large_local_asset",file:asset.path,size_bytes:asset.size_bytes,message:"\u68C0\u6D4B\u5230\u5927\u4F53\u79EF\u672C\u5730\u56FE\u7247\uFF1B\u5EFA\u8BAE\u5728\u9884\u5904\u7406\u9636\u6BB5\u5B8C\u6210\u4E0A\u4F20\u3001\u56DE\u5199\u4E0E\u6E05\u7406\u3002"});return warnings}function inferExtensionFromMimeType2(mimeType){switch((mimeType||"").toLowerCase()){case"image/png":return".png";case"image/webp":return".webp";case"image/gif":return".gif";case"image/svg+xml":return".svg";case"image/avif":return".avif";case"image/jpeg":case"image/jpg":return".jpg";default:return".jpg"}}function sanitizeFileStem(value){return value.toLowerCase().replace(/[^a-z0-9]+/gu,"-").replace(/^-+|-+$/gu,"").slice(0,80)}function sanitizeFileName(value){let trimmed=value.trim(),extension=extname3(trimmed).toLowerCase(),stem=trimmed.slice(0,Math.max(0,trimmed.length-extension.length));return`${sanitizeFileStem(stem)||"remote-image"}${extension||".jpg"}`}function inferRemoteFileName(url,mimeType){let extension=inferExtensionFromUrl(url),fallbackExtension=inferExtensionFromMimeType2(mimeType);if(extension)try{let segment=new URL(url).pathname.split("/").filter(Boolean).at(-1);if(segment)return sanitizeFileName(decodeURIComponent(segment))}catch{}try{let parsed=new URL(url),rawSegment=parsed.pathname.split("/").filter(Boolean).at(-1)||parsed.hostname,sanitizedBase=sanitizeFileStem(decodeURIComponent(rawSegment).replace(/\.[a-z0-9]+$/iu,"").trim());if(sanitizedBase)return`${sanitizedBase}${fallbackExtension}`}catch{}switch((mimeType||"").toLowerCase()){case"image/png":return"remote-image.png";case"image/webp":return"remote-image.webp";case"image/gif":return"remote-image.gif";case"image/svg+xml":return"remote-image.svg";case"image/avif":return"remote-image.avif";default:return"remote-image.jpg"}}async function downloadRemoteImage(url,deps={}){let fetchImpl=deps.fetchImpl??fetch,runCurl=deps.runCurl??runCurlProcess;try{return await downloadRemoteImageViaFetch(url,fetchImpl)}catch(error){if(!shouldRetryRemoteDownloadWithCurl(error))throw error;try{return await downloadRemoteImageViaCurl(url,runCurl)}catch(curlError){let fetchMessage=error instanceof Error?error.message:String(error),curlMessage=curlError instanceof Error?curlError.message:String(curlError),unavailable=curlError&&typeof curlError=="object"&&curlError.code==="ENOENT";throw new Error(`${fetchMessage}
2413
+ ${unavailable?"[curl_unavailable] ":"[curl_failed] "}${curlMessage}`,{cause:error})}}}async function downloadRemoteImageViaFetch(url,fetchImpl=fetch){let response=await fetchImpl(url,{headers:{accept:"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"}});if(!response.ok)throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`);let mimeType=String(response.headers.get("content-type")??"").split(";")[0].trim().toLowerCase();if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=Buffer.from(await response.arrayBuffer());if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}function shouldRetryRemoteDownloadWithCurl(error){let message=error instanceof Error?error.message:String(error);return/fetch failed|timed?out|econnreset|socket|network|tls|und_err/iu.test(message)}function extractLastContentType(headerText){let matches=[...headerText.matchAll(/^content-type:\s*([^\r\n;]+)/gimu)];return matches.length>0?String(matches[matches.length-1][1]).trim().toLowerCase():""}async function runCurlProcess(executable,args){await new Promise((resolvePromise,reject)=>{let child=spawn(executable,args,{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`curl \u4E0B\u8F7D\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})})}async function downloadRemoteImageViaCurl(url,runCurl=runCurlProcess){let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-remote-")),outputPath=join12(tempRoot,"remote.bin"),headerPath=join12(tempRoot,"headers.txt");try{let injectedResult=await runCurl("curl",["-L","--fail","--silent","--show-error","-D",headerPath,"-o",outputPath,url]),headerText=typeof injectedResult?.headers=="string"?injectedResult.headers:existsSync16(headerPath)?readFileSync16(headerPath,"utf8"):"",mimeType=extractLastContentType(headerText);if(mimeType&&!mimeType.startsWith("image/"))throw new Error(`\u8FDC\u7A0B\u8D44\u6E90\u4E0D\u662F\u56FE\u7247\uFF1A${mimeType}`);let content=injectedResult?.content?Buffer.from(injectedResult.content):readFileSync16(outputPath);if(content.byteLength===0)throw new Error("\u8FDC\u7A0B\u56FE\u7247\u5185\u5BB9\u4E3A\u7A7A");return{mimeType,content,fileName:inferRemoteFileName(url,mimeType)}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function shouldRetryWithCompression(error){if(error&&typeof error=="object"&&"status"in error&&Number(error.status)===413)return!0;let message=error instanceof Error?error.message:String(error);return/\b413\b/u.test(message)}function buildCompressedFilePath(tempRoot,sourcePath){let safeStem=sanitizeFileStem(basename4(sourcePath,extname3(sourcePath)))||"compressed-image";return join12(tempRoot,`${safeStem}-${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}.jpg`)}function resolveImageCompressionRetry(platform){return platform==="darwin"?{mode:"sips"}:platform==="win32"?{mode:"manual",code:"image_compression_unsupported_on_windows"}:{mode:"manual",code:"image_compression_unavailable"}}async function runSipsCompressor({sourcePath,outputPath}){return await new Promise((resolvePromise,reject)=>{let child=spawn("sips",["-s","format","jpeg","--resampleWidth",String(LOCAL_IMAGE_UPLOAD_MAX_WIDTH),sourcePath,"--out",outputPath],{cwd:process.cwd(),env:process.env,stdio:["ignore","ignore","pipe"],shell:!1}),stderr="";child.stderr.on("data",chunk=>{stderr+=String(chunk)}),child.on("error",reject),child.on("close",code2=>{if(code2===0){resolvePromise();return}reject(new Error(stderr.trim()||`sips \u538B\u7F29\u5931\u8D25\uFF08exit ${code2??"unknown"}\uFF09`))})}),outputPath}function shouldForceHttps(hostname){let lower=hostname.toLowerCase();return lower==="localhost"||lower==="127.0.0.1"||lower==="::1"?!1:HTTPS_FORCE_HOST_SUFFIXES.some(suffix=>lower===suffix||lower.endsWith(`.${suffix}`))}function normalizeUploadedAssetUrl(rawUrl){try{let parsed=new URL(rawUrl);return parsed.protocol==="http:"&&shouldForceHttps(parsed.hostname)?(parsed.protocol="https:",parsed.toString()):rawUrl}catch{return rawUrl}}function replaceUrlInContent(content,originalUrl,finalUrl){return content.split(originalUrl).join(finalUrl)}function normalizeLocalAssetReportPath(args,reportDir){return args.localReport?resolve10(args.localReport):join12(reportDir,"local-asset-report.json")}function loadLocalUploadMappings(reportPath){if(!existsSync16(reportPath))throw new Error(`\u672A\u627E\u5230\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A: ${reportPath}`);let payload=JSON.parse(readFileSync16(reportPath,"utf8"));if(!Array.isArray(payload.uploaded_local_assets))throw new Error(`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u683C\u5F0F\u65E0\u6548\uFF0C\u7F3A\u5C11 uploaded_local_assets: ${reportPath}`);let bySourcePath=new Map;for(let item of payload.uploaded_local_assets){if(!item||typeof item.final_url!="string"||!item.final_url.trim()||item.status!=="uploaded"&&item.status!=="uploaded_after_compress"&&item.status!=="reused_from_cache")continue;let allSourcePaths=Array.isArray(item.source_paths)&&item.source_paths.length>0?item.source_paths:[item.source_path];for(let sourcePath of allSourcePaths)typeof sourcePath=="string"&&sourcePath.trim()&&bySourcePath.set(sourcePath,item.final_url)}return{reportPath,bySourcePath}}function rewriteImportedLocalAssets(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(IMPORT_LOCAL_ASSET_PATTERN,(fullMatch,leading,identifier,quote,rawRef,trailing)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,`${leading}const ${identifier} = ${quote}${finalUrl}${quote};${trailing}`):fullMatch});return{changed,content:next}}function rewriteLiteralLocalAssetRefs(rootDir,filePath,content,relativePathToUrl){let changed=!1,next=content.replace(LOCAL_ASSET_REF_PATTERN,(fullMatch,rawRef)=>{let resolved=relative3(rootDir,resolve10(dirname10(filePath),rawRef)),finalUrl=relativePathToUrl.get(resolved);return finalUrl?(changed=!0,fullMatch.replace(rawRef,finalUrl)):fullMatch});return{changed,content:next}}async function runRewriteLocal(args,report,files,cacheContext){let warnings=[];if(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0)return{rewritten_files:[],deleted_clean_source_assets:[],warnings};let localReportPath=normalizeLocalAssetReportPath(args,report.report_dir),loaded=loadLocalUploadMappings(localReportPath),relativePathToUrl=loaded.bySourcePath;if(relativePathToUrl.size===0){let message=report.local_asset_candidates.length===0?`\u5F53\u524D\u6E90\u7801\u5305\u672A\u68C0\u6D4B\u5230\u9700\u8981\u56DE\u5199\u7684\u672C\u5730\u7D20\u6750: ${loaded.reportPath}`:`\u672C\u5730\u7D20\u6750\u4E0A\u4F20\u62A5\u544A\u91CC\u6CA1\u6709\u53EF\u56DE\u5199\u7684\u6210\u529F\u4E0A\u4F20\u8BB0\u5F55: ${loaded.reportPath}`;return args.dryRun?{rewritten_files:[],deleted_clean_source_assets:[],warnings:[`dry-run \u6A21\u5F0F\u4E0B\u672A\u751F\u6210\u672C\u5730\u7D20\u6750\u56DE\u5199\u6620\u5C04: ${loaded.reportPath}`]}:{rewritten_files:[],deleted_clean_source_assets:[],warnings:[message]}}let rewrittenFiles=[],deletedLocalAssets=[],hashBySourcePath=new Map;for(let asset of report.local_asset_candidates)for(let sourcePath of asset.source_paths)hashBySourcePath.set(sourcePath,asset.hash);for(let absolutePath of files){let before=readFileSync16(absolutePath,"utf8"),after=before;after=rewriteImportedLocalAssets(report.project_dir,absolutePath,after,relativePathToUrl).content,after=rewriteLiteralLocalAssetRefs(report.project_dir,absolutePath,after,relativePathToUrl).content,after!==before&&(args.dryRun||writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relative3(report.project_dir,absolutePath)))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_local_refs"});for(let sourcePath of[...relativePathToUrl.keys()]){let contentHash=hashBySourcePath.get(sourcePath);if(!contentHash)continue;let cacheKey=buildLocalCacheKey(contentHash),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}for(let sourcePath of[...relativePathToUrl.keys()].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,sourcePath);if(!existsSync16(absolutePath))continue;let contentHash=hashBySourcePath.get(sourcePath),cacheKey=contentHash?buildLocalCacheKey(contentHash):null;if(cacheContext?.enabled&&cacheKey){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"cleanup_local_assets",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]});let cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaning"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}args.dryRun||unlinkSync2(absolutePath),deletedLocalAssets.push(sourcePath),cacheContext?.enabled&&cacheKey&&(cacheContext.cache.entries[cacheKey]&&(updateCacheEntry(cacheContext.cache,cacheKey,{status:"cleaned"}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}return warnings.push(`\u5DF2\u57FA\u4E8E\u4E0A\u4F20\u62A5\u544A\u56DE\u5199\u672C\u5730\u56FE\u7247\u5F15\u7528: ${loaded.reportPath}`),{rewritten_files:rewrittenFiles,deleted_clean_source_assets:deletedLocalAssets,warnings}}function copyWorkspaceForPreprocess(sourceDir,cleanSourceDir){rmSync4(cleanSourceDir,{recursive:!0,force:!0}),ensureDir(cleanSourceDir);let entries=readdirSync5(sourceDir,{withFileTypes:!0});for(let entry of entries)DEFAULT_SKIP_DIRS.has(entry.name)||copyWorkspaceEntry(join12(sourceDir,entry.name),join12(cleanSourceDir,entry.name))}function copyWorkspaceEntry(sourcePath,targetPath){let sourceStats=lstatSync(sourcePath,{throwIfNoEntry:!1});if(!sourceStats)throw new Error(`\u9884\u5904\u7406\u590D\u5236\u6E90\u4E0D\u5B58\u5728: ${sourcePath}`);if(sourceStats.isSymbolicLink())throw new Error(`\u9884\u5904\u7406\u4E0D\u652F\u6301\u7B26\u53F7\u94FE\u63A5\u6216\u76EE\u5F55\u8054\u63A5\uFF0C\u8BF7\u5148\u8F6C\u6362\u4E3A\u666E\u901A\u6587\u4EF6\u6216\u76EE\u5F55: ${sourcePath}`);if(sourceStats.isDirectory()){ensureDir(targetPath);for(let entry of readdirSync5(sourcePath,{withFileTypes:!0}))copyWorkspaceEntry(join12(sourcePath,entry.name),join12(targetPath,entry.name));return}if(sourceStats.isFile()){ensureDir(dirname10(targetPath)),copyFileSync(sourcePath,targetPath);return}throw new Error(`\u9884\u5904\u7406\u4E0D\u652F\u6301\u590D\u5236\u6B64\u6587\u4EF6\u7C7B\u578B: ${sourcePath}`)}function buildPreflightPayload(report,sourceDir,cleanSourceDir,options){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,detected_type:options.detectedType,upstream_source_package_bytes:options.upstreamSourcePackageBytes,clean_source_package_bytes_before_rewrite:options.cleanSourcePackageBytesBeforeRewrite,summary:report.summary,path_base_violations_detected:options.pathBaseViolationsDetected,path_base_rewrites:options.pathBaseRewrites,path_base_violations_remaining:options.pathBaseViolationsRemaining,preflight_warnings:options.preflightWarnings,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,pending_videos:report.pending_videos,pending_manual_items:report.pending_manual_items}}function buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,remote_candidates:report.remote_candidates,local_asset_candidates:report.local_asset_candidates,uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets}}function countAppliedRemoteUploads(rewriteResult){return rewriteResult.uploaded_assets.filter(item=>item.status==="uploaded").length}function countAppliedLocalUploads(localUploadResult){return localUploadResult.uploaded_local_assets.filter(item=>item.status==="uploaded"||item.status==="uploaded_after_compress").length}function buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult){return{remote_upload_candidates:rewriteResult.uploaded_assets.length,local_upload_candidates:localUploadResult.uploaded_local_assets.length,path_base_rewrite_candidates:pathBaseRewriteResult.rewritten_files.length,local_cleanup_candidates:localRewriteResult.deleted_clean_source_assets.length,file_rewrite_candidates:rewriteResult.rewritten_files.length+localRewriteResult.rewritten_files.length+pathBaseRewriteResult.rewritten_files.length,pending_video_candidates:report.pending_videos.length}}function buildWarningsPayload(report,importManifest,reportsDir,cacheContext){return{tool:report.tool,version:report.version,mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:importManifest.source_dir,clean_source_dir:importManifest.clean_source_dir,warnings:importManifest.warnings,pending_manual_items:report.pending_manual_items,pending_videos:report.pending_videos,cache_warnings:cacheContext?.warnings??[],recovery_actions:{resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0},report_files:{preflight_report:join12(reportsDir,"preflight-report.json"),asset_inventory:join12(reportsDir,"asset-inventory.json"),import_manifest:join12(reportsDir,"import-manifest.json"),pending_videos:join12(reportsDir,"pending-videos.json")}}}function buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext){return{tool:report.tool,version:report.version,generated_at:new Date().toISOString(),mode:"preprocess",execution_mode:report.execution_mode??"apply",source_dir:sourceDir,clean_source_dir:cleanSourceDir,cache_dir:cacheContext?.cacheDir??null,cache_enabled:cacheContext?.enabled??!1,resumed_from_cache:cacheContext?.stats?.resumed_from_cache??!1,reused_uploaded_assets_count:cacheContext?.stats?.remote_reused??0,reused_uploaded_local_assets_count:cacheContext?.stats?.local_reused??0,interrupted_items_count:cacheContext?.stats?.interrupted_items_count??0,clean_source_package_bytes:collectSourcePackageBytes(cleanSourceDir),summary:report.summary,planned_actions:buildPlannedActions(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult),asset_mappings:{remote:rewriteResult.uploaded_assets,local:localUploadResult.uploaded_local_assets},rewritten_files:[...rewriteResult.rewritten_files,...localRewriteResult.rewritten_files,...pathBaseRewriteResult.rewritten_files],deleted_clean_source_assets:localRewriteResult.deleted_clean_source_assets,path_base_rewrites:pathBaseRewriteResult.rewrite_entries,pending_videos:report.pending_videos,warnings:[...rewriteResult.warnings,...localUploadResult.warnings,...localRewriteResult.warnings,...pathBaseRewriteResult.warnings]}}async function runRewrite(args,report,cacheContext,deps){let imageCandidates=report.remote_candidates.filter(item=>item.kind==="image"&&item.rewrite_supported===!0),warnings=[],uploads=[],replacements=new Map;if(args.dryRun)return{uploaded_assets:imageCandidates.map(item=>({original_url:item.url,final_url:item.url,status:"dry-run"})),rewritten_files:[],warnings};let tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-project-"));try{let total=imageCandidates.length,uploadResults=await runWithConcurrency(imageCandidates,REMOTE_IMAGE_CONCURRENCY,async(candidate,index)=>{let itemLabel=`remote image ${index+1}/${total}`,cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached))return logProgress(`${itemLabel} reused from cache: ${candidate.url}`),cacheContext.stats.remote_reused+=1,{candidate,finalUrl:cached.final_url,assetId:cached.asset_id??null,status:"reused_from_cache"};try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_remote",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploading",original_ref:candidate.url}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let downloadStart=Date.now();logProgress(`${itemLabel} downloading: ${candidate.url}`);let downloaded=await downloadRemoteImage(candidate.url,{fetchImpl:deps.fetchImpl,runCurl:deps.runCurl}),downloadMs=Date.now()-downloadStart,tempFilePath=join12(tempRoot,`${index+1}-${downloaded.fileName}`);writeFileSync10(tempFilePath,downloaded.content),logProgress(`${itemLabel} downloaded in ${downloadMs}ms, uploading asset`);let uploadStart=Date.now(),uploaded=await deps.uploadAsset({filePath:tempFilePath,title:downloaded.fileName,folderId:args.folderId||void 0}),uploadMs=Date.now()-uploadStart,finalUrl=normalizeUploadedAssetUrl(uploaded.original_url);return logProgress(`${itemLabel} uploaded in ${uploadMs}ms`),finalUrl!==uploaded.original_url&&warnings.push(`\u5DF2\u5C06\u7D20\u6750 URL \u534F\u8BAE\u89C4\u8303\u5316\u4E3A HTTPS: ${uploaded.original_url} -> ${finalUrl}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"uploaded",original_ref:candidate.url,final_url:finalUrl,asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,content_digest:`sha256:${createHash5("sha256").update(downloaded.content).digest("hex")}`}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)})),{candidate,finalUrl,assetId:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}}catch(error){let message=error instanceof Error?error.message:String(error);return logProgress(`${itemLabel} failed: ${message}`),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"remote_image",status:"failed",original_ref:candidate.url,last_error:message}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache)),{candidate,error:message,status:"fallback"}}});for(let result of uploadResults){if(result.error){warnings.push(`\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${result.candidate.url} (${result.error})`),uploads.push({original_url:result.candidate.url,final_url:result.candidate.url,status:"fallback"});continue}replacements.set(result.candidate.url,result.finalUrl),uploads.push({original_url:result.candidate.url,final_url:result.finalUrl,asset_id:result.assetId??null,status:result.status})}let targetFiles=new Set(imageCandidates.flatMap(candidate=>candidate.occurrences.map(occurrence=>occurrence.file))),rewrittenFiles=[];for(let relativePath of[...targetFiles].sort((left,right)=>left.localeCompare(right))){let absolutePath=join12(report.project_dir,relativePath),before=readFileSync16(absolutePath,"utf8"),after=before;for(let[originalUrl,finalUrl]of replacements)after=replaceUrlInContent(after,originalUrl,finalUrl);after!==before&&(writeFileSync10(absolutePath,after,"utf8"),rewrittenFiles.push(relativePath))}if(cacheContext?.enabled&&rewrittenFiles.length>0){cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"rewrite_remote_refs"});for(let candidate of imageCandidates){let cacheKey=buildRemoteCacheKey(candidate.url),cached=cacheContext.cache.entries[cacheKey];cacheEntryReusable(cached)&&updateCacheEntry(cacheContext.cache,cacheKey,{status:"rewritten"})}persistAssetCache(cacheContext.cacheFile,cacheContext.cache)}return{uploaded_assets:uploads,rewritten_files:rewrittenFiles,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}async function runUploadLocal(args,report,cacheContext,deps){let warnings=[],uploads=[],tempRoot=mkdtempSync3(join12(tmpdir2(),"platform-assetize-local-"));try{if(args.dryRun)return{uploaded_local_assets:report.local_asset_candidates.map(item=>({source_path:item.path,title:item.file_name,status:"dry-run"})),warnings};for(let asset of report.local_asset_candidates){let absolutePath=join12(report.project_dir,asset.path),cacheKey=buildLocalCacheKey(asset.hash),cached=cacheContext?.cache?.entries?.[cacheKey];if(cacheContext?.enabled&&cacheEntryReusable(cached)){uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:cached.title??asset.file_name,final_url:cached.final_url,asset_id:cached.asset_id??null,status:"reused_from_cache"}),cacheContext.stats.local_reused+=1;continue}try{cacheContext?.enabled&&(cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{phase:"upload_local",in_progress_keys:[...new Set([...cacheContext.lock.in_progress_keys,cacheKey])]}),updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploading",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache));let uploaded=await deps.uploadAsset({filePath:absolutePath,title:asset.file_name,folderId:args.folderId||void 0});uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}))}catch(error){if(shouldRetryWithCompression(error)){let hostPlatform=deps.platform??process.platform,retry=resolveImageCompressionRetry(hostPlatform);if(retry.mode==="manual")warnings.push(`[${retry.code}] \u672C\u5730\u56FE\u7247\u8D85\u8FC7\u4E0A\u4F20\u9650\u5236\uFF08HTTP 413\uFF09\uFF0C${hostPlatform==="win32"?"Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u538B\u7F29":"\u5F53\u524D\u5E73\u53F0\u65E0\u6CD5\u81EA\u52A8\u538B\u7F29"}: ${asset.path}\u3002\u8BF7\u5C06\u56FE\u7247\u5BBD\u5EA6\u538B\u7F29\u81F3\u4E0D\u8D85\u8FC7 ${LOCAL_IMAGE_UPLOAD_MAX_WIDTH}px \u5E76\u51CF\u5C0F\u6587\u4EF6\u4F53\u79EF\uFF0C\u7136\u540E\u6267\u884C\uFF1Aplatform app import preprocess --dir "${report.project_dir}" --reset-cache`);else try{let outputPath=buildCompressedFilePath(tempRoot,absolutePath),compressedPath=await(deps.runCompressor??runSipsCompressor)({sourcePath:absolutePath,outputPath}),uploaded=await deps.uploadAsset({filePath:compressedPath,title:basename4(compressedPath),folderId:args.folderId||void 0});warnings.push(`\u672C\u5730\u56FE\u7247\u8FC7\u5927\uFF0C\u5DF2\u81EA\u52A8\u538B\u7F29\u540E\u4E0A\u4F20: ${asset.path}`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null,status:"uploaded_after_compress"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"uploaded",source_paths:asset.source_paths,content_hash:asset.hash,title:basename4(compressedPath),final_url:normalizeUploadedAssetUrl(uploaded.original_url),asset_id:uploaded.asset?.asset_id??uploaded.asset?.asset?.asset_id??null}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache),cacheContext.lock=updateLockState(cacheContext.lockFile,cacheContext.lock,{in_progress_keys:cacheContext.lock.in_progress_keys.filter(item=>item!==cacheKey)}));continue}catch(compressionError){warnings.push(`\u672C\u5730\u56FE\u7247\u538B\u7F29\u91CD\u8BD5\u5931\u8D25: ${asset.path} (${compressionError instanceof Error?compressionError.message:String(compressionError)})`)}}warnings.push(`\u672C\u5730\u56FE\u7247\u4E0A\u4F20\u5931\u8D25: ${asset.path} (${error instanceof Error?error.message:String(error)})`),uploads.push({source_path:asset.path,source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,status:"failed"}),cacheContext?.enabled&&(updateCacheEntry(cacheContext.cache,cacheKey,{kind:"local_image",status:"failed",source_paths:asset.source_paths,content_hash:asset.hash,title:asset.file_name,last_error:error instanceof Error?error.message:String(error)}),persistAssetCache(cacheContext.cacheFile,cacheContext.cache))}}return{uploaded_local_assets:uploads,warnings}}finally{rmSync4(tempRoot,{recursive:!0,force:!0})}}function renderMarkdown(report){let lines=[];if(lines.push("# Scan Report",""),lines.push(`- Project: \`${report.project_dir}\``),lines.push(`- Mode: \`${report.mode}\``),lines.push(`- Scanned files: ${report.summary.scanned_file_count}`),lines.push(`- Unique remote candidates: ${report.summary.unique_remote_candidates}`),lines.push(`- Images: ${report.summary.image_count}`),lines.push(`- Videos: ${report.summary.video_count}`),lines.push(`- Posters: ${report.summary.poster_count}`),lines.push(`- Unknown remote: ${report.summary.unknown_remote_count}`),lines.push(`- Local images: ${report.summary.local_asset_count??0}`,""),report.remote_candidates.length===0&&(!Array.isArray(report.local_asset_candidates)||report.local_asset_candidates.length===0))return lines.push("No candidates found.",""),lines.join(`
2413
2414
  `);if(report.remote_candidates.length>0){lines.push("## Remote Candidates","","| Kind | Rewrite | URL | Refs |","|---|---|---|---:|");for(let item of report.remote_candidates)lines.push(`| ${item.kind} | ${item.rewrite_supported?"yes":"no"} | ${escapeMdCell(item.url)} | ${item.occurrences.length} |`);lines.push("")}if(report.pending_videos.length>0){lines.push("## Pending Videos","");for(let item of report.pending_videos)lines.push(`- ${item.url}`);lines.push("")}if(Array.isArray(report.local_asset_candidates)&&report.local_asset_candidates.length>0){lines.push("## Local Images","","| File | Dedupe Refs | Size (bytes) | Upload |","|---|---:|---:|---|");for(let item of report.local_asset_candidates)lines.push(`| ${escapeMdCell(item.path)} | ${item.source_paths.length} | ${item.size_bytes} | ${item.upload_supported?"yes":"no"} |`);lines.push("")}if(report.remote_candidates.length>0){lines.push("## Occurrences","");for(let item of report.remote_candidates){lines.push(`### ${item.url}`,"",`- kind: \`${item.kind}\``,`- rewrite_supported: \`${item.rewrite_supported}\``),Array.isArray(item.notes)&&item.notes.length>0&&lines.push(`- notes: ${item.notes.join(" / ")}`);for(let occurrence of item.occurrences)lines.push(`- ${occurrence.file}:${occurrence.line} (${occurrence.kind})`);lines.push("")}}return lines.join(`
2414
2415
  `)}function escapeMdCell(value){return value.replace(/\|/gu,"\\|")}function ensureDir(dirPath){mkdirSync9(dirPath,{recursive:!0})}function writeJson2(filePath,payload){writeFileSync10(filePath,`${JSON.stringify(payload,null,2)}
2415
- `,"utf8")}async function runPreprocess(args,sourceDir){let preprocessRoot=join12(sourceDir,".design-preprocess"),cleanSourceDir=join12(preprocessRoot,"clean-source"),reportsDir=join12(preprocessRoot,"reports"),cacheDir=join12(preprocessRoot,"cache"),cacheFile=join12(cacheDir,"assets.json"),lockFile=join12(cacheDir,"locks.json");args.resetCache&&!args.dryRun&&rmSync4(cacheDir,{recursive:!0,force:!0}),rmSync4(cleanSourceDir,{recursive:!0,force:!0}),rmSync4(reportsDir,{recursive:!0,force:!0}),ensureDir(reportsDir),ensureDir(cacheDir),copyWorkspaceForPreprocess(sourceDir,cleanSourceDir);let cache=loadAssetCache(cacheFile,sourceDir),previousLock=loadLockState(lockFile),lockRun=args.dryRun?{lock:defaultLockState(),interruptedItems:0}:beginLockRun(lockFile,previousLock),lock=lockRun.lock,cacheContext={enabled:!args.dryRun&&args.resume!==!1,cacheDir,cacheFile,cache,lockFile,lock,warnings:[],stats:{resumed_from_cache:!1,remote_reused:0,local_reused:0,interrupted_items_count:lockRun.interruptedItems}};cacheContext.stats.interrupted_items_count>0&&(cacheContext.stats.resumed_from_cache=!0,cacheContext.warnings.push(`\u68C0\u6D4B\u5230\u4E0A\u6B21\u9884\u5904\u7406\u53EF\u80FD\u4E2D\u65AD\uFF1B\u5C06\u5C1D\u8BD5\u4ECE\u672C\u5730 cache \u6062\u590D\uFF08\u4E2D\u65AD\u9879: ${cacheContext.stats.interrupted_items_count}\uFF09\u3002`));let files=walkFiles(cleanSourceDir,args.include),assetFiles=walkAssetFiles(cleanSourceDir),candidates=collectRemoteCandidates(cleanSourceDir,files),localAssetCandidates=collectLocalAssetCandidates(cleanSourceDir,files,assetFiles),report=buildReport(cleanSourceDir,files,candidates,reportsDir);report.execution_mode=args.dryRun?"dry-run":"apply",report.local_asset_candidates=localAssetCandidates,report.summary.local_asset_count=localAssetCandidates.length;let detectedType=detectProjectType(sourceDir,args.type),upstreamSourcePackageBytes=collectSourcePackageBytes(sourceDir),cleanSourcePackageBytesBeforeRewrite=collectSourcePackageBytes(cleanSourceDir),pathBaseViolationsDetected=collectPathBaseViolations(cleanSourceDir,files),preflightWarnings=collectPreflightWarnings(cleanSourceDir,localAssetCandidates);cacheContext.enabled&&(lock=updateLockState(lockFile,lock,{phase:"rewrite_path_base"}),cacheContext.lock=lock);let pathBaseRewriteResult=await runPathBaseRewrite(args,report,files),pathBaseViolationsRemaining=collectPathBaseViolations(cleanSourceDir,files);writeJson2(join12(reportsDir,"preflight-report.json"),buildPreflightPayload(report,sourceDir,cleanSourceDir,{detectedType,upstreamSourcePackageBytes,cleanSourcePackageBytesBeforeRewrite,pathBaseViolationsDetected,pathBaseRewrites:pathBaseRewriteResult.rewrite_entries,pathBaseViolationsRemaining,preflightWarnings})),writeFileSync10(join12(reportsDir,"preflight-report.md"),`${renderMarkdown(report)}
2416
- `,"utf8");let rewriteResult=await runRewrite(args,report,cacheContext),localUploadResult=await runUploadLocal(args,report,cacheContext),localUploadFullReport={...report,mode:"upload-local",uploaded_assets:[],uploaded_local_assets:localUploadResult.uploaded_local_assets,rewritten_files:[],warnings:[...localUploadResult.warnings]};writeJson2(join12(reportsDir,"local-asset-report.json"),localUploadFullReport),writeFileSync10(join12(reportsDir,"local-asset-report.md"),`${renderMarkdown(localUploadFullReport)}
2416
+ `,"utf8")}async function runPreprocess(args,sourceDir,deps){let preprocessRoot=join12(sourceDir,".design-preprocess"),cleanSourceDir=join12(preprocessRoot,"clean-source"),reportsDir=join12(preprocessRoot,"reports"),cacheDir=join12(preprocessRoot,"cache"),cacheFile=join12(cacheDir,"assets.json"),lockFile=join12(cacheDir,"locks.json");args.resetCache&&!args.dryRun&&rmSync4(cacheDir,{recursive:!0,force:!0}),rmSync4(cleanSourceDir,{recursive:!0,force:!0}),rmSync4(reportsDir,{recursive:!0,force:!0}),ensureDir(reportsDir),ensureDir(cacheDir),copyWorkspaceForPreprocess(sourceDir,cleanSourceDir);let cache=loadAssetCache(cacheFile,sourceDir),previousLock=loadLockState(lockFile),lockRun=args.dryRun?{lock:defaultLockState(),interruptedItems:0}:beginLockRun(lockFile,previousLock),lock=lockRun.lock,cacheContext={enabled:!args.dryRun&&args.resume!==!1,cacheDir,cacheFile,cache,lockFile,lock,warnings:[],stats:{resumed_from_cache:!1,remote_reused:0,local_reused:0,interrupted_items_count:lockRun.interruptedItems}};cacheContext.stats.interrupted_items_count>0&&(cacheContext.stats.resumed_from_cache=!0,cacheContext.warnings.push(`\u68C0\u6D4B\u5230\u4E0A\u6B21\u9884\u5904\u7406\u53EF\u80FD\u4E2D\u65AD\uFF1B\u5C06\u5C1D\u8BD5\u4ECE\u672C\u5730 cache \u6062\u590D\uFF08\u4E2D\u65AD\u9879: ${cacheContext.stats.interrupted_items_count}\uFF09\u3002`));let files=walkFiles(cleanSourceDir,args.include),assetFiles=walkAssetFiles(cleanSourceDir),candidates=collectRemoteCandidates(cleanSourceDir,files),localAssetCandidates=collectLocalAssetCandidates(cleanSourceDir,files,assetFiles),report=buildReport(cleanSourceDir,files,candidates,reportsDir);report.execution_mode=args.dryRun?"dry-run":"apply",report.local_asset_candidates=localAssetCandidates,report.summary.local_asset_count=localAssetCandidates.length;let detectedType=detectProjectType(sourceDir,args.type),upstreamSourcePackageBytes=collectSourcePackageBytes(sourceDir),cleanSourcePackageBytesBeforeRewrite=collectSourcePackageBytes(cleanSourceDir),pathBaseViolationsDetected=collectPathBaseViolations(cleanSourceDir,files),preflightWarnings=collectPreflightWarnings(cleanSourceDir,localAssetCandidates);cacheContext.enabled&&(lock=updateLockState(lockFile,lock,{phase:"rewrite_path_base"}),cacheContext.lock=lock);let pathBaseRewriteResult=await runPathBaseRewrite(args,report,files),pathBaseViolationsRemaining=collectPathBaseViolations(cleanSourceDir,files);writeJson2(join12(reportsDir,"preflight-report.json"),buildPreflightPayload(report,sourceDir,cleanSourceDir,{detectedType,upstreamSourcePackageBytes,cleanSourcePackageBytesBeforeRewrite,pathBaseViolationsDetected,pathBaseRewrites:pathBaseRewriteResult.rewrite_entries,pathBaseViolationsRemaining,preflightWarnings})),writeFileSync10(join12(reportsDir,"preflight-report.md"),`${renderMarkdown(report)}
2417
+ `,"utf8");let rewriteResult=await runRewrite(args,report,cacheContext,deps),localUploadResult=await runUploadLocal(args,report,cacheContext,deps),localUploadFullReport={...report,mode:"upload-local",uploaded_assets:[],uploaded_local_assets:localUploadResult.uploaded_local_assets,rewritten_files:[],warnings:[...localUploadResult.warnings]};writeJson2(join12(reportsDir,"local-asset-report.json"),localUploadFullReport),writeFileSync10(join12(reportsDir,"local-asset-report.md"),`${renderMarkdown(localUploadFullReport)}
2417
2418
  `,"utf8");let localRewriteResult=await runRewriteLocal({...args,localReport:join12(reportsDir,"local-asset-report.json")},report,files,cacheContext);(cacheContext.stats.remote_reused>0||cacheContext.stats.local_reused>0)&&(cacheContext.stats.resumed_from_cache=!0);let assetInventory=buildAssetInventoryPayload(report,rewriteResult,localUploadResult,sourceDir,cleanSourceDir),importManifestWithCache=buildImportManifest(report,rewriteResult,localUploadResult,localRewriteResult,pathBaseRewriteResult,sourceDir,cleanSourceDir,cacheContext),warningsPayload=buildWarningsPayload(report,importManifestWithCache,reportsDir,cacheContext);return writeJson2(join12(reportsDir,"asset-inventory.json"),assetInventory),writeJson2(join12(reportsDir,"import-manifest.json"),importManifestWithCache),writeJson2(join12(reportsDir,"warnings.json"),warningsPayload),writeJson2(join12(reportsDir,"pending-videos.json"),{pending_videos:report.pending_videos}),writeFileSync10(join12(reportsDir,"import-manifest.md"),`${renderMarkdown({...report,mode:"preprocess",uploaded_assets:rewriteResult.uploaded_assets,uploaded_local_assets:localUploadResult.uploaded_local_assets,rewritten_files:importManifestWithCache.rewritten_files,deleted_clean_source_assets:importManifestWithCache.deleted_clean_source_assets,warnings:importManifestWithCache.warnings})}
2418
- `,"utf8"),cacheContext.enabled&&(cacheContext.lock=completeLockRun(lockFile,cacheContext.lock)),{preprocess_root:preprocessRoot,clean_source_dir:cleanSourceDir,reports_dir:reportsDir,cache_dir:cacheDir,report,pathBaseRewriteResult,rewriteResult,localUploadResult,localRewriteResult,importManifest:importManifestWithCache,cacheContext}}async function runAppImportPreprocessCli(argv){let args=parseArgs2(argv);if(args.help){printAppImportPreprocessUsage();return}let rootDir=resolve9(args.dir||process.env.PLATFORM_INVOCATION_CWD||process.env.INIT_CWD||process.cwd()),stats=statSync5(rootDir,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${rootDir}`);let result=await runPreprocess(args,rootDir),warnings=result.importManifest.warnings,output={tool:"assetize-project-urls",version:1,mode:"preprocess",execution_mode:args.dryRun?"dry-run":"apply",source_dir:rootDir,clean_source_dir:result.clean_source_dir,reports_dir:result.reports_dir,cache_dir:result.cache_dir,summary:result.report.summary,planned_actions:result.importManifest.planned_actions,path_base_rewritten_files:result.pathBaseRewriteResult.rewritten_files.length,uploaded_assets:countAppliedRemoteUploads(result.rewriteResult),uploaded_local_assets:countAppliedLocalUploads(result.localUploadResult),resumed_from_cache:result.importManifest.resumed_from_cache,reused_uploaded_assets:result.importManifest.reused_uploaded_assets_count,reused_uploaded_local_assets:result.importManifest.reused_uploaded_local_assets_count,interrupted_items_count:result.importManifest.interrupted_items_count,rewritten_files:args.dryRun?0:result.importManifest.rewritten_files.length,deleted_clean_source_assets:args.dryRun?0:result.importManifest.deleted_clean_source_assets.length,warnings,report_files:{preflight_report:join12(result.reports_dir,"preflight-report.json"),asset_inventory:join12(result.reports_dir,"asset-inventory.json"),import_manifest:join12(result.reports_dir,"import-manifest.json"),warnings:join12(result.reports_dir,"warnings.json"),pending_videos:join12(result.reports_dir,"pending-videos.json")}};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2419
+ `,"utf8"),cacheContext.enabled&&(cacheContext.lock=completeLockRun(lockFile,cacheContext.lock)),{preprocess_root:preprocessRoot,clean_source_dir:cleanSourceDir,reports_dir:reportsDir,cache_dir:cacheDir,report,pathBaseRewriteResult,rewriteResult,localUploadResult,localRewriteResult,importManifest:importManifestWithCache,cacheContext}}async function runAppImportPreprocess(argv,deps={}){let args=parseArgs2(argv);if(args.help)throw new Error("\u5E2E\u52A9\u8BF7\u6C42\u5E94\u7531 runAppImportPreprocessCli \u5904\u7406\u3002");let rootDir=resolve10(args.dir||process.env.PLATFORM_INVOCATION_CWD||process.env.INIT_CWD||process.cwd()),stats=statSync5(rootDir,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${rootDir}`);let uploadAsset=deps.uploadAsset??(async()=>{throw new Error("app import preprocess \u7F3A\u5C11\u8FDB\u7A0B\u5185\u7D20\u6750\u4E0A\u4F20\u4F9D\u8D56\u3002")}),result=await runPreprocess(args,rootDir,{...deps,uploadAsset,platform:deps.platform??process.platform}),warnings=result.importManifest.warnings;return{tool:"assetize-project-urls",version:1,mode:"preprocess",execution_mode:args.dryRun?"dry-run":"apply",source_dir:rootDir,clean_source_dir:result.clean_source_dir,reports_dir:result.reports_dir,cache_dir:result.cache_dir,summary:result.report.summary,planned_actions:result.importManifest.planned_actions,path_base_rewritten_files:result.pathBaseRewriteResult.rewritten_files.length,uploaded_assets:countAppliedRemoteUploads(result.rewriteResult),uploaded_local_assets:countAppliedLocalUploads(result.localUploadResult),resumed_from_cache:result.importManifest.resumed_from_cache,reused_uploaded_assets:result.importManifest.reused_uploaded_assets_count,reused_uploaded_local_assets:result.importManifest.reused_uploaded_local_assets_count,interrupted_items_count:result.importManifest.interrupted_items_count,rewritten_files:args.dryRun?0:result.importManifest.rewritten_files.length,deleted_clean_source_assets:args.dryRun?0:result.importManifest.deleted_clean_source_assets.length,warnings,report_files:{preflight_report:join12(result.reports_dir,"preflight-report.json"),asset_inventory:join12(result.reports_dir,"asset-inventory.json"),import_manifest:join12(result.reports_dir,"import-manifest.json"),warnings:join12(result.reports_dir,"warnings.json"),pending_videos:join12(result.reports_dir,"pending-videos.json")}}}async function runAppImportPreprocessCli(argv,deps={}){let args=parseArgs2(argv);if(args.help){printAppImportPreprocessUsage();return}let output=await runAppImportPreprocess(argv,deps);if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2419
2420
  `);return}process.stdout.write(["third-party design preprocess completed",`mode: ${output.mode}`,`execution_mode: ${output.execution_mode}`,`source_dir: ${output.source_dir}`,`clean_source_dir: ${output.clean_source_dir}`,`cache_dir: ${output.cache_dir}`,`scanned_files: ${output.summary.scanned_file_count}`,`unique_remote_candidates: ${output.summary.unique_remote_candidates}`,`local_images: ${output.summary.local_asset_count}`,`planned_remote_upload_candidates: ${output.planned_actions.remote_upload_candidates}`,`planned_local_upload_candidates: ${output.planned_actions.local_upload_candidates}`,`planned_file_rewrite_candidates: ${output.planned_actions.file_rewrite_candidates}`,`planned_local_cleanup_candidates: ${output.planned_actions.local_cleanup_candidates}`,`path_base_rewritten_files: ${output.path_base_rewritten_files}`,`uploaded_assets: ${output.uploaded_assets}`,`uploaded_local_assets: ${output.uploaded_local_assets}`,`resumed_from_cache: ${output.resumed_from_cache}`,`reused_uploaded_assets: ${output.reused_uploaded_assets}`,`reused_uploaded_local_assets: ${output.reused_uploaded_local_assets}`,`interrupted_items_count: ${output.interrupted_items_count}`,`rewritten_files: ${output.rewritten_files}`,`deleted_clean_source_assets: ${output.deleted_clean_source_assets}`,`warnings: ${output.warnings.length}`,`preflight_report: ${output.report_files.preflight_report}`,`import_manifest: ${output.report_files.import_manifest}`].join(`
2420
2421
  `)+`
2421
- `)}import{cpSync as cpSync3,existsSync as existsSync17,mkdirSync as mkdirSync10,readFileSync as readFileSync17,readdirSync as readdirSync6,rmSync as rmSync5,statSync as statSync6,writeFileSync as writeFileSync11}from"node:fs";import{basename as basename4,dirname as dirname11,join as join13,resolve as resolve10}from"node:path";var WORKSPACE_REQUIRED_FILES=["app.yaml","package.json"],REPORT_FILE_NAMES=["import-manifest.json","preflight-report.json","asset-inventory.json","warnings.json","pending-videos.json"],TOP_LEVEL_IMPORT_CANDIDATES=["src","public","_videos","guidelines","index.html","README.md","ATTRIBUTIONS.md"],SKIP_DIRS=new Set([".git","node_modules","dist","build",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]);function printAppImportStageUsage(){process.stdout.write(["platform app import stage","","\u7528\u6CD5\uFF1A"," platform app import stage [--workspace-dir <template-workspace-dir>] --preprocess <source-dir|.design-preprocess|reports|import-manifest.json> [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06\u9884\u5904\u7406\u4EA7\u7269\u4EE5\u975E\u7834\u574F\u65B9\u5F0F stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A `.design-import/`\uFF0C\u4E0D\u76F4\u63A5\u8986\u76D6\u6A21\u677F\u5165\u53E3\u4E0E\u8FD0\u884C\u5951\u7EA6\u6587\u4EF6\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",""].join(`
2422
+ `)}import{cpSync as cpSync2,existsSync as existsSync17,mkdirSync as mkdirSync10,readFileSync as readFileSync17,readdirSync as readdirSync6,rmSync as rmSync5,statSync as statSync6,writeFileSync as writeFileSync11}from"node:fs";import{basename as basename5,dirname as dirname11,join as join13,resolve as resolve11}from"node:path";var WORKSPACE_REQUIRED_FILES=["app.yaml","package.json"],REPORT_FILE_NAMES=["import-manifest.json","preflight-report.json","asset-inventory.json","warnings.json","pending-videos.json"],TOP_LEVEL_IMPORT_CANDIDATES=["src","public","_videos","guidelines","index.html","README.md","ATTRIBUTIONS.md"],SKIP_DIRS=new Set([".git","node_modules","dist","build",".platform",".sandbox",".design-preprocess",".third-party-design-reports"]);function printAppImportStageUsage(){process.stdout.write(["platform app import stage","","\u7528\u6CD5\uFF1A"," platform app import stage [--workspace-dir <template-workspace-dir>] --preprocess <source-dir|.design-preprocess|reports|import-manifest.json> [--dry-run] [--json]","","\u4F5C\u7528\uFF1A"," \u5C06\u9884\u5904\u7406\u4EA7\u7269\u4EE5\u975E\u7834\u574F\u65B9\u5F0F stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A `.design-import/`\uFF0C\u4E0D\u76F4\u63A5\u8986\u76D6\u6A21\u677F\u5165\u53E3\u4E0E\u8FD0\u884C\u5951\u7EA6\u6587\u4EF6\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",""].join(`
2422
2423
  `))}function parseArgs3(argv){let result={workspaceDir:"",preprocess:"",dryRun:!1,json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--dry-run"){result.dryRun=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}if(arg==="--preprocess"){result.preprocess=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function ensureDir2(dirPath){mkdirSync10(dirPath,{recursive:!0})}function writeJson3(filePath,payload){writeFileSync11(filePath,`${JSON.stringify(payload,null,2)}
2423
- `,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync17(filePath,"utf8"))}function assertDirectory2(pathValue,label){let stats=statSync6(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function resolveManifestPath(inputPath){let absolute=resolve10(inputPath),stats=statSync6(absolute,{throwIfNoEntry:!1});if(!stats)throw new Error(`\u672A\u627E\u5230\u9884\u5904\u7406\u8F93\u5165: ${absolute}`);if(stats.isFile()){if(basename4(absolute)!=="import-manifest.json")throw new Error(`\u9884\u5904\u7406\u8F93\u5165\u6587\u4EF6\u5FC5\u987B\u662F import-manifest.json: ${absolute}`);return absolute}let candidates=[join13(absolute,"reports","import-manifest.json"),join13(absolute,"import-manifest.json"),join13(absolute,".design-preprocess","reports","import-manifest.json")];for(let candidate of candidates)if(existsSync17(candidate))return candidate;throw new Error(`\u65E0\u6CD5\u4ECE\u9884\u5904\u7406\u8F93\u5165\u89E3\u6790 import-manifest.json: ${absolute}`)}function validateWorkspace2(workspaceDir){assertDirectory2(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=WORKSPACE_REQUIRED_FILES.filter(file=>!existsSync17(join13(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function topLevelEntries(rootDir){return readdirSync6(rootDir,{withFileTypes:!0}).filter(entry=>!SKIP_DIRS.has(entry.name)).map(entry=>({name:entry.name,kind:entry.isDirectory()?"dir":entry.isFile()?"file":"other"})).sort((left,right)=>left.name.localeCompare(right.name))}function collectImportCandidates(cleanSourceDir,layout,sourceDetectedType){return topLevelEntries(cleanSourceDir).filter(entry=>TOP_LEVEL_IMPORT_CANDIDATES.includes(entry.name)).map(entry=>({path:entry.name,kind:entry.kind,suggested_target:entry.name==="src"?sourceDetectedType==="frontend-app"?`workspace/${layout.imported_upstream_root}/ (\u6309 pages/components/styles/lib/imports \u53D7\u63A7\u5E76\u5165)`:`workspace/.design-import/upstream-clean-source/${entry.name}`:entry.name==="_videos"?"workspace/public/imported-upstream/_videos/ \u6216\u6A21\u677F\u9759\u6001\u8D44\u6E90\u76EE\u5F55":entry.name==="public"?"workspace/public/imported-upstream/ (\u9700\u4EBA\u5DE5\u5BA1\u67E5\u51B2\u7A81)":`workspace/.design-import/upstream-clean-source/${entry.name}`}))}function collectPreservedWorkspaceFiles(workspaceDir,layout){return layout.preserved_workspace_files.filter(file=>existsSync17(join13(workspaceDir,file)))}function buildImportSummary(args,payload){let sourcePreprocessExecutionMode=payload.importManifest.execution_mode??"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1Bstaged clean source \u4ECD\u53EF\u80FD\u5305\u542B\u672A\u771F\u5B9E\u56DE\u5199\u6216\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"import-clean-source",version:1,mode:"import-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,preprocess_manifest:payload.manifestPath,source_dir:payload.importManifest.source_dir,clean_source_dir:payload.importManifest.clean_source_dir,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,imported_upstream_root:payload.layout.imported_upstream_root,staged_clean_source_dir:payload.stagedCleanSourceDir,staged_reports_dir:payload.stagedReportsDir,source_detected_type:payload.preflightReport.detected_type??"unknown",clean_source_package_bytes:payload.importManifest.clean_source_package_bytes??null,upstream_source_package_bytes:payload.preflightReport.upstream_source_package_bytes??null,import_candidates:collectImportCandidates(payload.importManifest.clean_source_dir,payload.layout,payload.preflightReport.detected_type??"unknown"),preserved_workspace_files:collectPreservedWorkspaceFiles(payload.workspaceDir,payload.layout),pending_videos_count:Array.isArray(payload.importManifest.pending_videos)?payload.importManifest.pending_videos.length:0,pending_manual_items_count:Array.isArray(payload.warningsReport.pending_manual_items)?payload.warningsReport.pending_manual_items.length:0,warnings,next_steps:["\u5148\u5728 .design-import/upstream-clean-source \u4E2D\u5BA1\u67E5\u4E0A\u6E38 clean source",`\u518D\u6309 import_candidates \u9009\u62E9\u6027\u5408\u5E76\u5230\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 ${payload.layout.frontend_root}/public \u7B49\u76EE\u5F55`,"\u4FDD\u7559\u6A21\u677F\u4E3B\u5BFC\u6587\u4EF6\uFF08app.yaml / package.json / vite.config.ts / \u8FD0\u884C\u5165\u53E3 / platform \u5C42\uFF09\u4E0D\u88AB\u8986\u76D6","\u5B8C\u6210\u9875\u9762\u5408\u5E76\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}function stageReports(sourceReportsDir,stagedReportsDir,dryRun){let copied=[];for(let fileName of REPORT_FILE_NAMES){let sourcePath=join13(sourceReportsDir,fileName);existsSync17(sourcePath)&&(copied.push(fileName),dryRun||cpSync3(sourcePath,join13(stagedReportsDir,fileName)))}return copied}async function runAppImportStageCli(argv){let args=parseArgs3(argv);if(args.help){printAppImportStageUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");if(!args.preprocess)throw new Error("\u7F3A\u5C11 `--preprocess <source-dir|.design-preprocess|reports|import-manifest.json>`\u3002");let workspaceDir=resolve10(args.workspaceDir);validateWorkspace2(workspaceDir);let manifestPath=resolveManifestPath(args.preprocess),reportsDir=resolve10(dirname11(manifestPath)),importManifest=readJson2(manifestPath),preflightReport=readJson2(join13(reportsDir,"preflight-report.json")),warningsReport=readJson2(join13(reportsDir,"warnings.json")),cleanSourceDir=resolve10(importManifest.clean_source_dir);assertDirectory2(cleanSourceDir,"clean-source");let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join13(workspaceDir,".design-import"),stagedCleanSourceDir=join13(designImportRoot,"upstream-clean-source"),stagedReportsDir=join13(designImportRoot,"reports");args.dryRun||(rmSync5(designImportRoot,{recursive:!0,force:!0}),ensureDir2(stagedReportsDir),cpSync3(cleanSourceDir,stagedCleanSourceDir,{recursive:!0}));let copiedReports=stageReports(reportsDir,stagedReportsDir,args.dryRun),summary=buildImportSummary(args,{workspaceDir,manifestPath,importManifest,preflightReport,warningsReport,layout,stagedCleanSourceDir,stagedReportsDir});args.dryRun||writeJson3(join13(designImportRoot,"import-summary.json"),summary);let output={...summary,copied_report_files:copiedReports};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2424
+ `,"utf8")}function readJson2(filePath){return JSON.parse(readFileSync17(filePath,"utf8"))}function assertDirectory2(pathValue,label){let stats=statSync6(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function resolveManifestPath(inputPath){let absolute=resolve11(inputPath),stats=statSync6(absolute,{throwIfNoEntry:!1});if(!stats)throw new Error(`\u672A\u627E\u5230\u9884\u5904\u7406\u8F93\u5165: ${absolute}`);if(stats.isFile()){if(basename5(absolute)!=="import-manifest.json")throw new Error(`\u9884\u5904\u7406\u8F93\u5165\u6587\u4EF6\u5FC5\u987B\u662F import-manifest.json: ${absolute}`);return absolute}let candidates=[join13(absolute,"reports","import-manifest.json"),join13(absolute,"import-manifest.json"),join13(absolute,".design-preprocess","reports","import-manifest.json")];for(let candidate of candidates)if(existsSync17(candidate))return candidate;throw new Error(`\u65E0\u6CD5\u4ECE\u9884\u5904\u7406\u8F93\u5165\u89E3\u6790 import-manifest.json: ${absolute}`)}function validateWorkspace2(workspaceDir){assertDirectory2(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=WORKSPACE_REQUIRED_FILES.filter(file=>!existsSync17(join13(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function topLevelEntries(rootDir){return readdirSync6(rootDir,{withFileTypes:!0}).filter(entry=>!SKIP_DIRS.has(entry.name)).map(entry=>({name:entry.name,kind:entry.isDirectory()?"dir":entry.isFile()?"file":"other"})).sort((left,right)=>left.name.localeCompare(right.name))}function collectImportCandidates(cleanSourceDir,layout,sourceDetectedType){return topLevelEntries(cleanSourceDir).filter(entry=>TOP_LEVEL_IMPORT_CANDIDATES.includes(entry.name)).map(entry=>({path:entry.name,kind:entry.kind,suggested_target:entry.name==="src"?sourceDetectedType==="frontend-app"?`workspace/${layout.imported_upstream_root}/ (\u6309 pages/components/styles/lib/imports \u53D7\u63A7\u5E76\u5165)`:`workspace/.design-import/upstream-clean-source/${entry.name}`:entry.name==="_videos"?"workspace/public/imported-upstream/_videos/ \u6216\u6A21\u677F\u9759\u6001\u8D44\u6E90\u76EE\u5F55":entry.name==="public"?"workspace/public/imported-upstream/ (\u9700\u4EBA\u5DE5\u5BA1\u67E5\u51B2\u7A81)":`workspace/.design-import/upstream-clean-source/${entry.name}`}))}function collectPreservedWorkspaceFiles(workspaceDir,layout){return layout.preserved_workspace_files.filter(file=>existsSync17(join13(workspaceDir,file)))}function buildImportSummary(args,payload){let sourcePreprocessExecutionMode=payload.importManifest.execution_mode??"unknown",warnings=[];return sourcePreprocessExecutionMode==="dry-run"&&warnings.push("\u5F53\u524D\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1Bstaged clean source \u4ECD\u53EF\u80FD\u5305\u542B\u672A\u771F\u5B9E\u56DE\u5199\u6216\u672A\u6E05\u7406\u7684\u672C\u5730\u7D20\u6750\u3002"),{tool:"import-clean-source",version:1,mode:"import-stage",execution_mode:args.dryRun?"dry-run":"apply",workspace_dir:payload.workspaceDir,preprocess_manifest:payload.manifestPath,source_dir:payload.importManifest.source_dir,clean_source_dir:payload.importManifest.clean_source_dir,source_preprocess_execution_mode:sourcePreprocessExecutionMode,target_template_key:payload.layout.template_key,frontend_root:payload.layout.frontend_root,imported_upstream_root:payload.layout.imported_upstream_root,staged_clean_source_dir:payload.stagedCleanSourceDir,staged_reports_dir:payload.stagedReportsDir,source_detected_type:payload.preflightReport.detected_type??"unknown",clean_source_package_bytes:payload.importManifest.clean_source_package_bytes??null,upstream_source_package_bytes:payload.preflightReport.upstream_source_package_bytes??null,import_candidates:collectImportCandidates(payload.importManifest.clean_source_dir,payload.layout,payload.preflightReport.detected_type??"unknown"),preserved_workspace_files:collectPreservedWorkspaceFiles(payload.workspaceDir,payload.layout),pending_videos_count:Array.isArray(payload.importManifest.pending_videos)?payload.importManifest.pending_videos.length:0,pending_manual_items_count:Array.isArray(payload.warningsReport.pending_manual_items)?payload.warningsReport.pending_manual_items.length:0,warnings,next_steps:["\u5148\u5728 .design-import/upstream-clean-source \u4E2D\u5BA1\u67E5\u4E0A\u6E38 clean source",`\u518D\u6309 import_candidates \u9009\u62E9\u6027\u5408\u5E76\u5230\u6A21\u677F\u5DE5\u4F5C\u533A\u7684 ${payload.layout.frontend_root}/public \u7B49\u76EE\u5F55`,"\u4FDD\u7559\u6A21\u677F\u4E3B\u5BFC\u6587\u4EF6\uFF08app.yaml / package.json / vite.config.ts / \u8FD0\u884C\u5165\u53E3 / platform \u5C42\uFF09\u4E0D\u88AB\u8986\u76D6","\u5B8C\u6210\u9875\u9762\u5408\u5E76\u540E\uFF0C\u518D\u6267\u884C platform dev / verify / preview"]}}function stageReports(sourceReportsDir,stagedReportsDir,dryRun){let copied=[];for(let fileName of REPORT_FILE_NAMES){let sourcePath=join13(sourceReportsDir,fileName);existsSync17(sourcePath)&&(copied.push(fileName),dryRun||cpSync2(sourcePath,join13(stagedReportsDir,fileName)))}return copied}async function runAppImportStageCli(argv){let args=parseArgs3(argv);if(args.help){printAppImportStageUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");if(!args.preprocess)throw new Error("\u7F3A\u5C11 `--preprocess <source-dir|.design-preprocess|reports|import-manifest.json>`\u3002");let workspaceDir=resolve11(args.workspaceDir);validateWorkspace2(workspaceDir);let manifestPath=resolveManifestPath(args.preprocess),reportsDir=resolve11(dirname11(manifestPath)),importManifest=readJson2(manifestPath),preflightReport=readJson2(join13(reportsDir,"preflight-report.json")),warningsReport=readJson2(join13(reportsDir,"warnings.json")),cleanSourceDir=resolve11(importManifest.clean_source_dir);assertDirectory2(cleanSourceDir,"clean-source");let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join13(workspaceDir,".design-import"),stagedCleanSourceDir=join13(designImportRoot,"upstream-clean-source"),stagedReportsDir=join13(designImportRoot,"reports");args.dryRun||(rmSync5(designImportRoot,{recursive:!0,force:!0}),ensureDir2(stagedReportsDir),cpSync2(cleanSourceDir,stagedCleanSourceDir,{recursive:!0}));let copiedReports=stageReports(reportsDir,stagedReportsDir,args.dryRun),summary=buildImportSummary(args,{workspaceDir,manifestPath,importManifest,preflightReport,warningsReport,layout,stagedCleanSourceDir,stagedReportsDir});args.dryRun||writeJson3(join13(designImportRoot,"import-summary.json"),summary);let output={...summary,copied_report_files:copiedReports};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2424
2425
  `);return}process.stdout.write(["third-party design import stage completed",`execution_mode: ${output.execution_mode}`,`workspace_dir: ${output.workspace_dir}`,`source_detected_type: ${output.source_detected_type}`,`staged_clean_source_dir: ${output.staged_clean_source_dir}`,`staged_reports_dir: ${output.staged_reports_dir}`,`import_candidates: ${output.import_candidates.length}`,`preserved_workspace_files: ${output.preserved_workspace_files.length}`,`pending_videos_count: ${output.pending_videos_count}`,`pending_manual_items_count: ${output.pending_manual_items_count}`].join(`
2425
2426
  `)+`
2426
- `)}import{existsSync as existsSync18,readFileSync as readFileSync18,statSync as statSync7}from"node:fs";import{join as join14,resolve as resolve11}from"node:path";var REQUIRED_WORKSPACE_FILES2=["app.yaml","package.json"];function printAppImportVerifyUsage(){process.stdout.write(["platform app import verify","","\u7528\u6CD5\uFF1A"," platform app import verify [--workspace-dir <template-workspace-dir>] [--json]","","\u4F5C\u7528\uFF1A"," \u6821\u9A8C\u6A21\u677F\u5DE5\u4F5C\u533A\u662F\u5426\u5DF2\u5177\u5907 preprocess / stage / merge \u7684\u57FA\u7840\u4EA7\u7269\uFF0C\u5E76\u8F93\u51FA\u4E0B\u4E00\u6B65\u5EFA\u8BAE\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002"," - verify \u53EA\u505A\u72B6\u6001\u6821\u9A8C\uFF0C\u4E0D\u4F1A\u6267\u884C\u7D20\u6750\u4E0A\u4F20\u3001\u6587\u4EF6\u642C\u8FD0\u6216\u6A21\u677F\u63A5\u7EBF\u3002",""].join(`
2427
- `))}function parseArgs4(argv){let result={workspaceDir:"",json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJsonIfExists3(filePath,fallbackValue=null){return existsSync18(filePath)?JSON.parse(readFileSync18(filePath,"utf8")):fallbackValue}function assertDirectory3(pathValue,label){let stats=statSync7(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace3(workspaceDir){assertDirectory3(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES2.filter(file=>!existsSync18(join14(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function listMissingItems(state){let missing=[];return state.hasPreprocessManifest||missing.push(".design-import/reports/import-manifest.json"),state.hasPreflightReport||missing.push(".design-import/reports/preflight-report.json"),state.hasWarningsReport||missing.push(".design-import/reports/warnings.json"),state.hasImportSummary||missing.push(".design-import/import-summary.json"),state.mergeRequired&&(state.hasMergeSummary||missing.push(".design-import/merge-summary.json"),state.hasImportedUpstreamDir||missing.push(`${state.importedUpstreamRoot}/`)),missing}function deriveStatus(state){return state.hasImportSummary?state.mergeRequired&&(!state.hasMergeSummary||!state.hasImportedUpstreamDir)?"needs_merge":state.sourcePreprocessExecutionMode==="dry-run"?"needs_apply_preprocess":"ready_for_manual_wiring":"needs_stage"}function buildNextSteps(status,state){switch(status){case"needs_stage":return["\u5148\u6267\u884C platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>","\u786E\u8BA4 .design-import/upstream-clean-source/ \u4E0E .design-import/reports/ \u5DF2\u751F\u6210"];case"needs_merge":return["\u6267\u884C platform app import merge",`\u786E\u8BA4 ${state.importedUpstreamRoot}/ \u5DF2\u751F\u6210\uFF0C\u518D\u5F00\u59CB\u4EBA\u5DE5\u63A5\u7EBF`];case"needs_apply_preprocess":return["\u5F53\u524D\u4E0A\u6E38\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1B\u8BF7\u91CD\u65B0\u6267\u884C platform app import preprocess\uFF08\u975E --dry-run\uFF09","\u91CD\u65B0 stage / merge \u540E\u518D\u7EE7\u7EED\u6A21\u677F\u63A5\u7EBF"];default:return state.templateKey==="backend-app-node"?["\u5728 src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]:["\u5728 src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A\u54CD\u5E94\u5F0F\u4FEE\u6B63\u4E0E CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]}}async function runAppImportVerifyCli(argv){let args=parseArgs4(argv);if(args.help){printAppImportVerifyUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve11(args.workspaceDir);validateWorkspace3(workspaceDir);let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join14(workspaceDir,".design-import"),reportsDir=join14(designImportRoot,"reports"),importManifestPath=join14(reportsDir,"import-manifest.json"),preflightReportPath=join14(reportsDir,"preflight-report.json"),warningsReportPath=join14(reportsDir,"warnings.json"),importSummaryPath=join14(designImportRoot,"import-summary.json"),mergeSummaryPath=join14(designImportRoot,"merge-summary.json"),importedUpstreamDir=join14(workspaceDir,...layout.imported_upstream_root.split("/")),sourceContextPath=join14(workspaceDir,".platform","source-context.json"),importManifest=readJsonIfExists3(importManifestPath,{}),preflightReport=readJsonIfExists3(preflightReportPath,{}),warningsReport=readJsonIfExists3(warningsReportPath,{}),importSummary=readJsonIfExists3(importSummaryPath,{}),mergeSummary=readJsonIfExists3(mergeSummaryPath,{}),state={hasPreprocessManifest:existsSync18(importManifestPath),hasPreflightReport:existsSync18(preflightReportPath),hasWarningsReport:existsSync18(warningsReportPath),hasImportSummary:existsSync18(importSummaryPath),hasMergeSummary:existsSync18(mergeSummaryPath),hasImportedUpstreamDir:existsSync18(importedUpstreamDir),mergeRequired:!0,templateKey:layout.template_key,frontendRoot:layout.frontend_root,importedUpstreamRoot:layout.imported_upstream_root,hasSourceContext:existsSync18(sourceContextPath),sourcePreprocessExecutionMode:importSummary.source_preprocess_execution_mode||importManifest.execution_mode||"unknown",pendingVideosCount:Array.isArray(importManifest.pending_videos)?importManifest.pending_videos.length:Array.isArray(warningsReport.pending_videos)?warningsReport.pending_videos.length:0,pendingManualItemsCount:Array.isArray(warningsReport.pending_manual_items)?warningsReport.pending_manual_items.length:0,pathBaseViolationsRemaining:Array.isArray(preflightReport.path_base_violations_remaining)?preflightReport.path_base_violations_remaining.length:0,cleanSourcePackageBytes:importManifest.clean_source_package_bytes??null,upstreamSourcePackageBytes:preflightReport.upstream_source_package_bytes??null,mergedPathsCount:Array.isArray(mergeSummary.merged_paths)?mergeSummary.merged_paths.length:0},status=deriveStatus(state),output={tool:"app-import-verify",version:1,mode:"verify",workspace_dir:workspaceDir,design_import_dir:designImportRoot,target_template_key:layout.template_key,frontend_root:layout.frontend_root,imported_upstream_dir:layout.imported_upstream_root,status,state,missing_items:listMissingItems(state),next_steps:buildNextSteps(status,state)};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2427
+ `)}import{existsSync as existsSync18,readFileSync as readFileSync18,statSync as statSync7}from"node:fs";import{join as join14,resolve as resolve12}from"node:path";var REQUIRED_WORKSPACE_FILES2=["app.yaml","package.json"];function printAppImportVerifyUsage(){process.stdout.write(["platform app import verify","","\u7528\u6CD5\uFF1A"," platform app import verify [--workspace-dir <template-workspace-dir>] [--json]","","\u4F5C\u7528\uFF1A"," \u6821\u9A8C\u6A21\u677F\u5DE5\u4F5C\u533A\u662F\u5426\u5DF2\u5177\u5907 preprocess / stage / merge \u7684\u57FA\u7840\u4EA7\u7269\uFF0C\u5E76\u8F93\u51FA\u4E0B\u4E00\u6B65\u5EFA\u8BAE\u3002","","\u8BF4\u660E\uFF1A"," - \u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F5C\u4E3A\u6A21\u677F\u5DE5\u4F5C\u533A\uFF1B\u82E5\u672A\u4F20 `--workspace-dir`\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002"," - verify \u53EA\u505A\u72B6\u6001\u6821\u9A8C\uFF0C\u4E0D\u4F1A\u6267\u884C\u7D20\u6750\u4E0A\u4F20\u3001\u6587\u4EF6\u642C\u8FD0\u6216\u6A21\u677F\u63A5\u7EBF\u3002",""].join(`
2428
+ `))}function parseArgs4(argv){let result={workspaceDir:"",json:!1,help:!1};for(let index=0;index<argv.length;index+=1){let arg=argv[index];if(arg==="--help"||arg==="-h"){result.help=!0;continue}if(arg==="--json"){result.json=!0;continue}if(arg==="--workspace-dir"){result.workspaceDir=argv[index+1]??"",index+=1;continue}throw new Error(`\u672A\u77E5\u53C2\u6570: ${arg}`)}return result}function readJsonIfExists3(filePath,fallbackValue=null){return existsSync18(filePath)?JSON.parse(readFileSync18(filePath,"utf8")):fallbackValue}function assertDirectory3(pathValue,label){let stats=statSync7(pathValue,{throwIfNoEntry:!1});if(!stats||!stats.isDirectory())throw new Error(`${label} \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BBF\u95EE: ${pathValue}`)}function validateWorkspace3(workspaceDir){assertDirectory3(workspaceDir,"\u6A21\u677F\u5DE5\u4F5C\u533A");let missing=REQUIRED_WORKSPACE_FILES2.filter(file=>!existsSync18(join14(workspaceDir,file)));if(missing.length>0)throw new Error(`\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u6709\u6548\u6A21\u677F\u5DE5\u4F5C\u533A\uFF0C\u7F3A\u5C11: ${missing.join(", ")}`)}function listMissingItems(state){let missing=[];return state.hasPreprocessManifest||missing.push(".design-import/reports/import-manifest.json"),state.hasPreflightReport||missing.push(".design-import/reports/preflight-report.json"),state.hasWarningsReport||missing.push(".design-import/reports/warnings.json"),state.hasImportSummary||missing.push(".design-import/import-summary.json"),state.mergeRequired&&(state.hasMergeSummary||missing.push(".design-import/merge-summary.json"),state.hasImportedUpstreamDir||missing.push(`${state.importedUpstreamRoot}/`)),missing}function deriveStatus(state){return state.hasImportSummary?state.mergeRequired&&(!state.hasMergeSummary||!state.hasImportedUpstreamDir)?"needs_merge":state.sourcePreprocessExecutionMode==="dry-run"?"needs_apply_preprocess":"ready_for_manual_wiring":"needs_stage"}function buildNextSteps(status,state){switch(status){case"needs_stage":return["\u5148\u6267\u884C platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>","\u786E\u8BA4 .design-import/upstream-clean-source/ \u4E0E .design-import/reports/ \u5DF2\u751F\u6210"];case"needs_merge":return["\u6267\u884C platform app import merge",`\u786E\u8BA4 ${state.importedUpstreamRoot}/ \u5DF2\u751F\u6210\uFF0C\u518D\u5F00\u59CB\u4EBA\u5DE5\u63A5\u7EBF`];case"needs_apply_preprocess":return["\u5F53\u524D\u4E0A\u6E38\u9884\u5904\u7406\u4EA7\u7269\u6765\u81EA dry-run\uFF1B\u8BF7\u91CD\u65B0\u6267\u884C platform app import preprocess\uFF08\u975E --dry-run\uFF09","\u91CD\u65B0 stage / merge \u540E\u518D\u7EE7\u7EED\u6A21\u677F\u63A5\u7EBF"];default:return state.templateKey==="backend-app-node"?["\u5728 src/web/app.tsx \u6216 src/web/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/server/* \u4E0E src/web/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]:["\u5728 src/app.tsx \u6216 src/pages/* \u4E2D\u9009\u62E9\u6027\u5F15\u7528 imported-upstream \u5185\u5BB9","\u4FDD\u6301 src/platform/* \u7531\u6A21\u677F\u4E3B\u5BFC\uFF0C\u518D\u7EE7\u7EED\u505A\u54CD\u5E94\u5F0F\u4FEE\u6B63\u4E0E CMS / DB / Auth \u63A5\u5165","\u63A5\u7EBF\u5B8C\u6210\u540E\u518D\u6267\u884C platform dev / preview"]}}async function runAppImportVerifyCli(argv){let args=parseArgs4(argv);if(args.help){printAppImportVerifyUsage();return}if(!args.workspaceDir)throw new Error("\u7F3A\u5C11 `--workspace-dir <template-workspace-dir>`\u3002");let workspaceDir=resolve12(args.workspaceDir);validateWorkspace3(workspaceDir);let layout=resolveAppImportLayout(workspaceDir),designImportRoot=join14(workspaceDir,".design-import"),reportsDir=join14(designImportRoot,"reports"),importManifestPath=join14(reportsDir,"import-manifest.json"),preflightReportPath=join14(reportsDir,"preflight-report.json"),warningsReportPath=join14(reportsDir,"warnings.json"),importSummaryPath=join14(designImportRoot,"import-summary.json"),mergeSummaryPath=join14(designImportRoot,"merge-summary.json"),importedUpstreamDir=join14(workspaceDir,...layout.imported_upstream_root.split("/")),sourceContextPath=join14(workspaceDir,".platform","source-context.json"),importManifest=readJsonIfExists3(importManifestPath,{}),preflightReport=readJsonIfExists3(preflightReportPath,{}),warningsReport=readJsonIfExists3(warningsReportPath,{}),importSummary=readJsonIfExists3(importSummaryPath,{}),mergeSummary=readJsonIfExists3(mergeSummaryPath,{}),state={hasPreprocessManifest:existsSync18(importManifestPath),hasPreflightReport:existsSync18(preflightReportPath),hasWarningsReport:existsSync18(warningsReportPath),hasImportSummary:existsSync18(importSummaryPath),hasMergeSummary:existsSync18(mergeSummaryPath),hasImportedUpstreamDir:existsSync18(importedUpstreamDir),mergeRequired:!0,templateKey:layout.template_key,frontendRoot:layout.frontend_root,importedUpstreamRoot:layout.imported_upstream_root,hasSourceContext:existsSync18(sourceContextPath),sourcePreprocessExecutionMode:importSummary.source_preprocess_execution_mode||importManifest.execution_mode||"unknown",pendingVideosCount:Array.isArray(importManifest.pending_videos)?importManifest.pending_videos.length:Array.isArray(warningsReport.pending_videos)?warningsReport.pending_videos.length:0,pendingManualItemsCount:Array.isArray(warningsReport.pending_manual_items)?warningsReport.pending_manual_items.length:0,pathBaseViolationsRemaining:Array.isArray(preflightReport.path_base_violations_remaining)?preflightReport.path_base_violations_remaining.length:0,cleanSourcePackageBytes:importManifest.clean_source_package_bytes??null,upstreamSourcePackageBytes:preflightReport.upstream_source_package_bytes??null,mergedPathsCount:Array.isArray(mergeSummary.merged_paths)?mergeSummary.merged_paths.length:0},status=deriveStatus(state),output={tool:"app-import-verify",version:1,mode:"verify",workspace_dir:workspaceDir,design_import_dir:designImportRoot,target_template_key:layout.template_key,frontend_root:layout.frontend_root,imported_upstream_dir:layout.imported_upstream_root,status,state,missing_items:listMissingItems(state),next_steps:buildNextSteps(status,state)};if(args.json){process.stdout.write(`${JSON.stringify(output,null,2)}
2428
2429
  `);return}process.stdout.write(["third-party design verify completed",`workspace_dir: ${output.workspace_dir}`,`status: ${output.status}`,`source_preprocess_execution_mode: ${output.state.sourcePreprocessExecutionMode}`,`has_import_summary: ${output.state.hasImportSummary}`,`has_merge_summary: ${output.state.hasMergeSummary}`,`has_imported_upstream_dir: ${output.state.hasImportedUpstreamDir}`,`pending_videos: ${output.state.pendingVideosCount}`,`pending_manual_items: ${output.state.pendingManualItemsCount}`,`path_base_violations_remaining: ${output.state.pathBaseViolationsRemaining}`,`missing_items: ${output.missing_items.length}`].join(`
2429
2430
  `)+`
2430
2431
  `)}function hasFlag(args,key){return args.options[key]===!0}function readOption(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function currentWorkspaceDir(){return process.env.PLATFORM_INVOCATION_CWD||process.env.INIT_CWD||process.cwd()}function printAppImportHelp(subcommand){switch(subcommand){case"preprocess":printAppImportPreprocessUsage();return;case"stage":printAppImportStageUsage();return;case"merge":printAppImportMergeUsage();return;case"verify":printAppImportVerifyUsage();return;default:process.stdout.write(["platform app import","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app import preprocess \u751F\u6210 clean-source \u4E0E\u9884\u5904\u7406\u62A5\u544A"," platform app import stage \u628A clean-source \u4E0E reports stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," platform app import merge \u6309\u6A21\u677F\u524D\u7AEF\u6839\u76EE\u5F55\u628A\u4E0A\u6E38\u5185\u5BB9\u5B89\u5168\u5E76\u5165 imported-upstream \u843D\u70B9"," platform app import verify \u6821\u9A8C preprocess / stage / merge \u4EA7\u7269\u72B6\u6001","","\u8BF4\u660E\uFF1A"," \u5F53\u524D P0 \u81EA\u52A8\u5316\u53EA\u8986\u76D6\u6700\u8017\u65F6\u3001\u6700\u673A\u68B0\u7684\u4E09\u6BB5\uFF1Apreprocess / stage / merge\u3002"," create / wiring / CMS-DB-Auth \u63A5\u7EBF\u4ECD\u7531\u6A21\u677F\u5DE5\u4F5C\u533A\u4E0E\u4EBA\u5DE5\u5DE5\u7A0B\u5316\u627F\u63A5\u3002",""].join(`
2431
- `))}}async function runAppImportCommand(args){let subcommand=args.rest[1]??"help";if(hasFlag(args,"help")||hasFlag(args,"h")){printAppImportHelp(subcommand==="help"?void 0:subcommand);return}if(subcommand==="help"){printAppImportHelp();return}if(subcommand!=="preprocess"&&subcommand!=="stage"&&subcommand!=="merge"&&subcommand!=="verify")throw new Error("`platform app import` \u76EE\u524D\u652F\u6301 `preprocess`\u3001`stage`\u3001`merge` \u6216 `verify`\u3002");if(subcommand==="preprocess"){let cliArgs2=["--dir",readOption(args,"dir")??currentWorkspaceDir()],include=readOption(args,"include"),folderId=readOption(args,"folder-id"),type=readOption(args,"type"),cliCmd=readOption(args,"cli-cmd"),localReport=readOption(args,"local-report");include&&cliArgs2.push("--include",include),folderId&&cliArgs2.push("--folder-id",folderId),type&&cliArgs2.push("--type",type),cliCmd&&cliArgs2.push("--cli-cmd",cliCmd),localReport&&cliArgs2.push("--local-report",localReport),hasFlag(args,"dry-run")&&cliArgs2.push("--dry-run"),hasFlag(args,"resume")&&cliArgs2.push("--resume"),hasFlag(args,"reset-cache")&&cliArgs2.push("--reset-cache"),hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportPreprocessCli(cliArgs2);return}if(subcommand==="stage"){let preprocess=readOption(args,"preprocess");if(!preprocess)throw new Error("`platform app import stage` \u9700\u8981 `--preprocess <source-dir|.design-preprocess|reports|import-manifest.json>`\u3002");let cliArgs2=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir(),"--preprocess",preprocess];hasFlag(args,"dry-run")&&cliArgs2.push("--dry-run"),hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportStageCli(cliArgs2);return}if(subcommand==="verify"){let cliArgs2=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir()];hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportVerifyCli(cliArgs2);return}let cliArgs=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir()];hasFlag(args,"dry-run")&&cliArgs.push("--dry-run"),hasFlag(args,"json")&&cliArgs.push("--json"),await runAppImportMergeCli(cliArgs)}var AUTH_CONFIGURE_TEMPLATE_VALUES=["email_magic_link_only","admin_password_only","email_magic_link_and_admin_password","phone_sms_otp_only","email_magic_link_and_phone_sms_otp"],AUTH_CONFIGURE_TEMPLATE_VALUES_TEXT=AUTH_CONFIGURE_TEMPLATE_VALUES.map(item=>`\`${item}\``).join("\u3001");function formatAuthorizationCodeLoginPrompt(input){return input.opened?`\u5DF2\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B8C\u6210\u6388\u6743\u7801\u767B\u5F55\u3002
2432
+ `))}}async function runAppImportCommand(args,deps={}){let subcommand=args.rest[1]??"help";if(hasFlag(args,"help")||hasFlag(args,"h")){printAppImportHelp(subcommand==="help"?void 0:subcommand);return}if(subcommand==="help"){printAppImportHelp();return}if(subcommand!=="preprocess"&&subcommand!=="stage"&&subcommand!=="merge"&&subcommand!=="verify")throw new Error("`platform app import` \u76EE\u524D\u652F\u6301 `preprocess`\u3001`stage`\u3001`merge` \u6216 `verify`\u3002");if(subcommand==="preprocess"){let cliArgs2=["--dir",readOption(args,"dir")??currentWorkspaceDir()],include=readOption(args,"include"),folderId=readOption(args,"folder-id"),type=readOption(args,"type"),localReport=readOption(args,"local-report");include&&cliArgs2.push("--include",include),folderId&&cliArgs2.push("--folder-id",folderId),type&&cliArgs2.push("--type",type),localReport&&cliArgs2.push("--local-report",localReport),hasFlag(args,"dry-run")&&cliArgs2.push("--dry-run"),hasFlag(args,"resume")&&cliArgs2.push("--resume"),hasFlag(args,"reset-cache")&&cliArgs2.push("--reset-cache"),hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportPreprocessCli(cliArgs2,deps);return}if(subcommand==="stage"){let preprocess=readOption(args,"preprocess");if(!preprocess)throw new Error("`platform app import stage` \u9700\u8981 `--preprocess <source-dir|.design-preprocess|reports|import-manifest.json>`\u3002");let cliArgs2=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir(),"--preprocess",preprocess];hasFlag(args,"dry-run")&&cliArgs2.push("--dry-run"),hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportStageCli(cliArgs2);return}if(subcommand==="verify"){let cliArgs2=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir()];hasFlag(args,"json")&&cliArgs2.push("--json"),await runAppImportVerifyCli(cliArgs2);return}let cliArgs=["--workspace-dir",readOption(args,"workspace-dir")??currentWorkspaceDir()];hasFlag(args,"dry-run")&&cliArgs.push("--dry-run"),hasFlag(args,"json")&&cliArgs.push("--json"),await runAppImportMergeCli(cliArgs)}var AUTH_CONFIGURE_TEMPLATE_VALUES=["email_magic_link_only","admin_password_only","email_magic_link_and_admin_password","phone_sms_otp_only","email_magic_link_and_phone_sms_otp"],AUTH_CONFIGURE_TEMPLATE_VALUES_TEXT=AUTH_CONFIGURE_TEMPLATE_VALUES.map(item=>`\`${item}\``).join("\u3001");function formatAuthorizationCodeLoginPrompt(input){return input.opened?`\u5DF2\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B8C\u6210\u6388\u6743\u7801\u767B\u5F55\u3002
2432
2433
  `:[input.source==="cli-app"?"\u4F7F\u7528\u4E13\u7528 CLI App \u6267\u884C\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\uFF0C\u5E76\u81EA\u52A8\u9644\u5E26 consent \u4EE5\u6362\u53D6 refresh token\u3002":"\u4F7F\u7528 workbench \u914D\u7F6E\u56DE\u9000\u6267\u884C\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\uFF0C\u5E76\u5F3A\u5236 prompt=login consent \u4EE5\u907F\u514D\u590D\u7528\u9519\u8BEF SSO \u4F1A\u8BDD\u5E76\u6362\u53D6 refresh token\u3002","\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u6388\u6743\u7801\u767B\u5F55\u3002",`\u6388\u6743\u5730\u5740: ${input.authorizationUrl}`,`\u56DE\u8C03\u5730\u5740: ${input.redirectUri}`,input.source==="workbench-fallback"?"\u82E5\u56DE\u8C03\u7AEF\u53E3\u88AB\u672C\u5730 workbench \u5360\u7528\uFF0C\u8BF7\u5148\u6682\u65F6\u505C\u6B62\u5BF9\u5E94\u670D\u52A1\u540E\u91CD\u8BD5\u3002":"\u8BF7\u786E\u8BA4\u8BE5\u56DE\u8C03\u5730\u5740\u5DF2\u5728\u4E13\u7528 CLI App \u4E2D\u6CE8\u518C\u3002",""].join(`
2433
2434
  `)}function normalizeAuthTemplate(value){if(value!==void 0){if(AUTH_CONFIGURE_TEMPLATE_VALUES.includes(value))return value;throw new Error(`\u65E0\u6548\u7684 \`--template\`\uFF0C\u4EC5\u652F\u6301 ${AUTH_CONFIGURE_TEMPLATE_VALUES_TEXT}\u3002`)}}function buildAuthConfigurePayload(options){let templatePayload=buildTemplatePayload(options.template);if(options.enablePhoneSmsOtp===!1&&templatePayload.enable_phone_sms_otp===!0)throw new Error("\u5F53\u524D `--template` \u4F9D\u8D56 `phone_sms_otp`\uFF0C\u4E0D\u80FD\u540C\u65F6\u4F20 `--disable-phone-sms-otp`\u3002");return{auth_enabled:options.enable?!0:void 0,user_store_id:options.userStoreId,auth_template:templatePayload.auth_template,enable_admin_provisioned_password:options.enableAdminProvisionedPassword,enable_phone_sms_otp:typeof options.enablePhoneSmsOtp=="boolean"?options.enablePhoneSmsOtp:templatePayload.enable_phone_sms_otp,enabled_sign_in_methods:templatePayload.enabled_sign_in_methods,default_sign_in_method:templatePayload.default_sign_in_method,registration_mode:templatePayload.registration_mode}}function hasAuthConfigureChanges(payload){return payload.auth_enabled!==void 0||payload.user_store_id!==void 0||payload.auth_template!==void 0||payload.enable_admin_provisioned_password!==void 0||payload.enable_phone_sms_otp!==void 0||payload.enabled_sign_in_methods!==void 0||payload.default_sign_in_method!==void 0||payload.registration_mode!==void 0}function buildTemplatePayload(template){switch(template){case"phone_sms_otp_only":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["phone_sms_otp"],default_sign_in_method:"phone_sms_otp",registration_mode:"open"};case"email_magic_link_and_phone_sms_otp":return{enable_phone_sms_otp:!0,enabled_sign_in_methods:["email_magic_link","phone_sms_otp"],default_sign_in_method:"email_magic_link",registration_mode:"open"};case"email_magic_link_only":case"admin_password_only":case"email_magic_link_and_admin_password":return{auth_template:template};default:return{}}}var BUILD_POLL_INTERVAL_MS=1500,BUILD_POLL_TIMEOUT_MS=18e4;async function runBuildCommand(args){if(hasHelpFlag3(args)){printBuildHelp(args.rest[0]);return}let subcommand=args.rest[0];if(subcommand!=="get"&&subcommand!=="events"&&subcommand!=="validate"&&subcommand!=="run")throw new Error("`platform build` \u4EC5\u652F\u6301 `run`\u3001`get <build-id>`\u3001`events <build-id>` \u6216 `validate --source-version <srcver>`\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let binding;try{binding=readBinding(process.cwd())?.binding}catch{binding=null}let tenantId=readStringOption3(args,"tenant")??binding?.tenant_id,buildId=args.rest[1]??readStringOption3(args,"build");if((subcommand==="get"||subcommand==="events")&&!buildId)throw new Error(`\`platform build ${subcommand}\` \u9700\u8981 <build-id>\uFF0C\u6216\u4F20\u5165 \`--build <build-id>\`\u3002`);let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"});if(subcommand==="run"){let appId=readStringOption3(args,"app")??binding?.app_id,sourceVersionId=readStringOption3(args,"source-version")??readStringOption3(args,"source_version");if(!tenantId||!appId||!sourceVersionId)throw new Error("`platform build run` \u9700\u8981 `--source-version <srcver>`\uFF0C\u4EE5\u53CA\u5DF2\u7ED1\u5B9A\u76EE\u5F55\u6216 `--tenant` / `--app`\u3002");let requestedBy=await resolveRequestedBy(sdk),buildConfig=await resolveBuildRunConfig(sdk,appId,sourceVersionId,readBuildConfig(args.options)),created=await sdk.createBuild({tenant_id:tenantId,app_id:appId,source_version_id:sourceVersionId,requested_by:requestedBy,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}}).catch(error=>{throw formatBuildRunError(error,appId,sourceVersionId)}),wait=args.options.wait===!0;if(args.options.json===!0&&!wait){process.stdout.write(`${JSON.stringify(created,null,2)}
2434
2435
  `);return}if(!wait){printBuildStarted(created);return}let completed=await waitForBuild(sdk,created.id);if(args.options.json===!0){process.stdout.write(`${JSON.stringify(completed,null,2)}
@@ -2448,14 +2449,14 @@ ${routeMarker}`)}return next}function buildAuthDebugPageSource(){return["export
2448
2449
  `)}
2449
2450
  `)}async function loadBuildCliMetadata(sdk,appId,sourceVersionId){let[sourceVersions,publishSettings]=await Promise.all([sdk.listTenantAppSourceVersions(appId).catch(()=>({items:[]})),sdk.getTenantAppPublishSettings(appId).catch(()=>null)]);return{sourceVersion:sourceVersions.items.find(item=>item.source_version_id===sourceVersionId)??null,publishSettings}}function readStringOption3(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasHelpFlag3(args){return args.options.help===!0||args.options.h===!0}function printBuildHelp(subcommand){if(subcommand==="run"){process.stdout.write(["platform build run","","\u8BF4\u660E\uFF1A\u8FD9\u662F\u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\u3002\u5E38\u89C4\u7248\u672C\u9884\u89C8\u4F18\u5148\u4F7F\u7528 `platform preview generate`\u3002","","\u7528\u6CD5\uFF1A"," platform build run --source-version <srcver> [--wait] [--tenant <tenant-id>] [--app <app-id>]","","\u53EF\u9009\u6784\u5EFA\u914D\u7F6E\uFF1A"," --dockerfile <path>"," --context-subdir <dir>"," --target <stage>","","\u8BF4\u660E\uFF1A"," \u53D1\u8D77\u771F\u5B9E\u4E91\u7AEF\u6784\u5EFA\uFF1B\u9ED8\u8BA4\u7ACB\u5373\u8FD4\u56DE build id\uFF0C\u52A0 `--wait` \u5219\u7B49\u5F85\u6784\u5EFA\u7ED3\u675F\u3002",""].join(`
2450
2451
  `));return}process.stdout.write(["platform build","","\u8BF4\u660E\uFF1A\u8FD9\u662F\u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\u3002\u666E\u901A\u5F00\u53D1\u4E0E\u9A8C\u8BC1\u4E3B\u8DEF\u5F84\u4F18\u5148\u4F7F\u7528 `platform preview` / `platform publish`\u3002","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform build validate --app <app-id> --source-version <srcver> --target static","","\u8BF4\u660E\uFF1A"," - `run` \u53D1\u8D77\u771F\u5B9E\u4E91\u7AEF\u6784\u5EFA"," - `get/events` \u67E5\u8BE2\u6784\u5EFA\u72B6\u6001\u4E0E\u4E8B\u4EF6"," - `validate` \u53EA\u505A\u6784\u5EFA\u524D\u9884\u68C0\u67E5",""].join(`
2451
- `))}function readBuildConfig(options){let dockerfilePath=typeof options.dockerfile=="string"?options.dockerfile:void 0,contextSubdir=typeof options["context-subdir"]=="string"?options["context-subdir"]:void 0,target=typeof options.target=="string"?options.target:void 0;return{...dockerfilePath?{dockerfile_path:dockerfilePath}:{},...contextSubdir?{context_subdir:contextSubdir}:{},...target?{target}:{}}}async function resolveBuildRunConfig(sdk,appId,sourceVersionId,buildConfig){if(buildConfig.target)return buildConfig;try{return(await sdk.getBuildPrecheck(appId,{source_version_id:sourceVersionId,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}})).normalized_build_config??buildConfig}catch(error){if(!isBuildPrecheckFallbackAllowed(error))throw error;return buildConfig}}function isBuildPrecheckFallbackAllowed(error){return!(error instanceof PlatformApiError)||error.code==="capability_unavailable"?!0:error.status>=500}async function resolveRequestedBy(sdk){return(await sdk.getWhoAmI()).subject_id}async function waitForBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus(build.status)||Date.now()-startedAt>=timeoutMs)return build;await sleep2(intervalMs)}}function isTerminalBuildStatus(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function sleep2(ms){return new Promise(resolve17=>{setTimeout(resolve17,ms)})}function formatBuildCommandError(error,subcommand,buildId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2452
+ `))}function readBuildConfig(options){let dockerfilePath=typeof options.dockerfile=="string"?options.dockerfile:void 0,contextSubdir=typeof options["context-subdir"]=="string"?options["context-subdir"]:void 0,target=typeof options.target=="string"?options.target:void 0;return{...dockerfilePath?{dockerfile_path:dockerfilePath}:{},...contextSubdir?{context_subdir:contextSubdir}:{},...target?{target}:{}}}async function resolveBuildRunConfig(sdk,appId,sourceVersionId,buildConfig){if(buildConfig.target)return buildConfig;try{return(await sdk.getBuildPrecheck(appId,{source_version_id:sourceVersionId,...Object.keys(buildConfig).length>0?{build_config:buildConfig}:{}})).normalized_build_config??buildConfig}catch(error){if(!isBuildPrecheckFallbackAllowed(error))throw error;return buildConfig}}function isBuildPrecheckFallbackAllowed(error){return!(error instanceof PlatformApiError)||error.code==="capability_unavailable"?!0:error.status>=500}async function resolveRequestedBy(sdk){return(await sdk.getWhoAmI()).subject_id}async function waitForBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus(build.status)||Date.now()-startedAt>=timeoutMs)return build;await sleep2(intervalMs)}}function isTerminalBuildStatus(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function sleep2(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}function formatBuildCommandError(error,subcommand,buildId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2452
2453
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ${subcommand} \u5931\u8D25: ${buildId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
2453
2454
  `))}return error instanceof Error?error:new Error(`platform build ${subcommand} \u5931\u8D25: ${buildId}`)}function formatBuildValidateError(error,appId,sourceVersionId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2454
2455
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build validate \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
2455
2456
  `))}return error instanceof Error?error:new Error(`platform build validate \u5931\u8D25: ${appId}/${sourceVersionId}`)}function formatBuildRunError(error,appId,sourceVersionId){if(error instanceof PlatformApiError){let suffix=error.detail?`
2456
2457
  detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`,`code: ${error.code}`,`message: ${error.message}${suffix}`].join(`
2457
- `))}return error instanceof Error?error:new Error(`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`)}import{readFileSync as readFileSync19}from"node:fs";import{basename as basename5,extname as extname3,resolve as resolve12}from"node:path";async function runBlobCommand(args,deps){if(hasHelpFlag4(args)||args.rest.length===0){printBlobHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runBlobUpload(args,deps);return}if(subcommand==="list"){await runBlobList(args,deps);return}if(subcommand==="get"){await runBlobGet(args,deps);return}if(subcommand==="url"){await runBlobUrl(args,deps);return}throw new Error("`platform blob` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`url`\u3002")}function isBlobHelpRequest(args){return hasHelpFlag4(args)||args.rest.length===0}function printBlobHelp(){process.stdout.write(["platform blob <command>","","Commands:"," platform blob upload <file-path> [--app <app-id>] [--content-type <mime>] [--client-request-id <id>] [--json]"," platform blob list [--app <app-id>] [--q <keyword>] [--cursor <cursor>] [--limit <n>] [--json]"," platform blob get <blob-id> [--json]"," platform blob url <blob-id> [--ttl-seconds <n>] [--json]","","Notes:"," - Object Storage \u5F53\u524D\u8D70 tenant \u63A7\u5236\u9762\uFF0C\u4E0D\u8D70 public/runtime SDK"," - `upload` \u590D\u7528\u4E09\u6B65\u5F0F\u4E0A\u4F20\uFF1Acreate session -> upload binary -> complete"," - `url` \u9ED8\u8BA4\u7B7E\u53D1 1 \u5C0F\u65F6\u4E0B\u8F7D\u94FE\u63A5",""].join(`
2458
- `))}async function runBlobUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform blob upload` \u9700\u8981 <file-path>\u3002");let filePath=resolve12(filePathArg),fileName=basename5(filePath),content=new Uint8Array(readFileSync19(filePath)),contentType=readStringOption4(args,"content-type")?.trim()||inferMimeType2(fileName),appId=readStringOption4(args,"app")?.trim(),clientRequestId=readStringOption4(args,"client-request-id")?.trim(),session=await deps.sdk.createTenantBlobUploadSession({original_filename:fileName,content_type:contentType,size_bytes:content.byteLength,...appId?{app_id:appId}:{},...clientRequestId?{client_request_id:clientRequestId}:{}}).catch(error=>{throw formatBlobError(error,"upload(create session)")});await deps.sdk.uploadTenantBlobBinary(session.upload_session_id,{content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}).catch(error=>{throw formatBlobError(error,"upload(content)")});let response=await deps.sdk.completeTenantBlobUpload(session.upload_session_id,{size_bytes:content.byteLength}).catch(error=>{throw formatBlobError(error,"upload(complete)")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify({upload_session:session,result:response},null,2)}
2458
+ `))}return error instanceof Error?error:new Error(`platform build run \u5931\u8D25: ${appId}/${sourceVersionId}`)}import{readFileSync as readFileSync19}from"node:fs";import{basename as basename6,extname as extname4,resolve as resolve13}from"node:path";async function runBlobCommand(args,deps){if(hasHelpFlag4(args)||args.rest.length===0){printBlobHelp();return}let subcommand=args.rest[0];if(subcommand==="upload"){await runBlobUpload(args,deps);return}if(subcommand==="list"){await runBlobList(args,deps);return}if(subcommand==="get"){await runBlobGet(args,deps);return}if(subcommand==="url"){await runBlobUrl(args,deps);return}throw new Error("`platform blob` \u4EC5\u652F\u6301 `upload`\u3001`list`\u3001`get`\u3001`url`\u3002")}function isBlobHelpRequest(args){return hasHelpFlag4(args)||args.rest.length===0}function printBlobHelp(){process.stdout.write(["platform blob <command>","","Commands:"," platform blob upload <file-path> [--app <app-id>] [--content-type <mime>] [--client-request-id <id>] [--json]"," platform blob list [--app <app-id>] [--q <keyword>] [--cursor <cursor>] [--limit <n>] [--json]"," platform blob get <blob-id> [--json]"," platform blob url <blob-id> [--ttl-seconds <n>] [--json]","","Notes:"," - Object Storage \u5F53\u524D\u8D70 tenant \u63A7\u5236\u9762\uFF0C\u4E0D\u8D70 public/runtime SDK"," - `upload` \u590D\u7528\u4E09\u6B65\u5F0F\u4E0A\u4F20\uFF1Acreate session -> upload binary -> complete"," - `url` \u9ED8\u8BA4\u7B7E\u53D1 1 \u5C0F\u65F6\u4E0B\u8F7D\u94FE\u63A5",""].join(`
2459
+ `))}async function runBlobUpload(args,deps){let filePathArg=args.rest[1];if(!filePathArg)throw new Error("`platform blob upload` \u9700\u8981 <file-path>\u3002");let filePath=resolve13(filePathArg),fileName=basename6(filePath),content=new Uint8Array(readFileSync19(filePath)),contentType=readStringOption4(args,"content-type")?.trim()||inferMimeType(fileName),appId=readStringOption4(args,"app")?.trim(),clientRequestId=readStringOption4(args,"client-request-id")?.trim(),session=await deps.sdk.createTenantBlobUploadSession({original_filename:fileName,content_type:contentType,size_bytes:content.byteLength,...appId?{app_id:appId}:{},...clientRequestId?{client_request_id:clientRequestId}:{}}).catch(error=>{throw formatBlobError(error,"upload(create session)")});await deps.sdk.uploadTenantBlobBinary(session.upload_session_id,{content,content_type:contentType,upload_url:session.upload_url,headers:session.headers}).catch(error=>{throw formatBlobError(error,"upload(content)")});let response=await deps.sdk.completeTenantBlobUpload(session.upload_session_id,{size_bytes:content.byteLength}).catch(error=>{throw formatBlobError(error,"upload(complete)")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify({upload_session:session,result:response},null,2)}
2459
2460
  `);return}process.stdout.write(["Blob \u5DF2\u4E0A\u4F20\u3002",`tenant: ${deps.tenantId}`,`blob: ${response.blob_id}`,`upload_session: ${response.upload_session_id}`,`file: ${fileName}`,`content_type: ${contentType}`,`size: ${content.byteLength} bytes`,`source: ${appId?`app:${appId}`:"tenant_workbench"}`,""].join(`
2460
2461
  `))}async function runBlobList(args,deps){let response=await deps.sdk.listTenantBlobs({...readStringOption4(args,"app")?{app_id:readStringOption4(args,"app")}:{},...readStringOption4(args,"q")?{q:readStringOption4(args,"q")}:{},...readStringOption4(args,"cursor")?{cursor:readStringOption4(args,"cursor")}:{},...readNumberOption2(args,"limit")!==void 0?{limit:readNumberOption2(args,"limit")}:{}}).catch(error=>{throw formatBlobError(error,"list")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2461
2462
  `);return}process.stdout.write([`tenant: ${deps.tenantId}`,`items: ${response.items.length}`,`next_cursor: ${response.next_cursor??"-"}`,...response.items.map(item=>[item.blob_id,item.original_filename,`source=${item.source_type}`,`mime=${item.content_type??"-"}`,`size=${item.size_bytes}`,`created_at=${item.created_at}`].join(" ")),""].join(`
@@ -2463,16 +2464,16 @@ detail: ${JSON.stringify(error.detail)}`:"";return new Error([`platform build ru
2463
2464
  `);return}process.stdout.write([`tenant: ${deps.tenantId}`,`blob: ${response.blob_id}`,`source_type: ${response.source_type}`,`app_id: ${response.app_id??"-"}`,`file: ${response.original_filename}`,`content_type: ${response.content_type??"-"}`,`size: ${response.size_bytes} bytes`,`sha256: ${response.sha256??"-"}`,`bucket: ${response.bucket}`,`object_key: ${response.object_key}`,`created_by: ${response.created_by}`,`created_at: ${response.created_at}`,""].join(`
2464
2465
  `))}async function runBlobUrl(args,deps){let blobId=args.rest[1];if(!blobId)throw new Error("`platform blob url` \u9700\u8981 <blob-id>\u3002");let ttlSeconds=readNumberOption2(args,"ttl-seconds")??3600,response=await deps.sdk.issueTenantBlobDownloadUrl(blobId,{ttl_seconds:ttlSeconds}).catch(error=>{throw formatBlobError(error,"url")});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(response,null,2)}
2465
2466
  `);return}process.stdout.write([response.url,`expires_at: ${response.expires_at}`,`ttl_seconds: ${ttlSeconds}`,`tenant: ${deps.tenantId}`,""].join(`
2466
- `))}function readStringOption4(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption2(args,key){let value=readStringOption4(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed)||parsed<=0)throw new Error(`\`--${key}\` \u9700\u8981\u6B63\u6574\u6570\u3002`);return Math.trunc(parsed)}function hasHelpFlag4(args){return args.options.help===!0||args.options.h===!0}function inferMimeType2(fileName){switch(extname3(fileName).toLowerCase()){case".json":return"application/json";case".pdf":return"application/pdf";case".txt":return"text/plain";case".csv":return"text/csv";case".html":return"text/html";case".md":return"text/markdown";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".gif":return"image/gif";case".webp":return"image/webp";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";case".zip":return"application/zip";default:return"application/octet-stream"}}function formatBlobError(error,action){return error instanceof PlatformApiError?new Error([`Blob ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
2467
- `)):error instanceof Error?error:new Error(`Blob ${action} \u5931\u8D25\u3002`)}function buildTenantAssetReference2(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function resolveCmsAttachAssetField(fields,fieldName){let field=fields.find(entry=>entry.name===fieldName);if(!field)throw new Error(`Collection does not contain field \`${fieldName}\`.`);if(field.type!=="image"&&field.type!=="images")throw new Error(`\u5B57\u6BB5 \`${fieldName}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return field}function isAssetReferenceRecord(value){return typeof value=="object"&&value!==null&&typeof value.asset_id=="string"}function dedupeAssetReferences(values){let seen=new Set,deduped=[];for(let value of values)seen.has(value.asset_id)||(seen.add(value.asset_id),deduped.push(value));return deduped}function buildCmsAttachAssetPayload(args){let assetReferences=args.assets.map(buildTenantAssetReference2),nextContent=normalizeCmsContentForWrite2(args.item.content,args.fields);if(args.field.type==="image"){if(assetReferences.length!==1)throw new Error("\u5355\u56FE\u5B57\u6BB5\u4E00\u6B21\u53EA\u80FD\u6302\u8F7D\u4E00\u4E2A\u7D20\u6750\u3002");nextContent[args.field.name]=assetReferences[0]}else if(args.field.type==="images"){let currentValues=Array.isArray(args.item.content[args.field.name])?args.item.content[args.field.name].filter(isAssetReferenceRecord):[];nextContent[args.field.name]=dedupeAssetReferences(args.replace?assetReferences:[...currentValues,...assetReferences])}else throw new Error(`\u5B57\u6BB5 \`${args.field.name}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return{collection:args.item.collection,system:{...args.item.system.publish_status?{publish_status:args.item.system.publish_status}:{},...args.item.system.slug?{slug:args.item.system.slug}:{},...args.item.system.tags?{tags:[...args.item.system.tags]}:{},...Object.prototype.hasOwnProperty.call(args.item.system,"category_id")?{category_id:args.item.system.category_id??null}:{},...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:nextContent}}function normalizeCmsContentForWrite2(content,fields){let normalized={...content};for(let field of fields){let currentValue=normalized[field.name];if(field.type==="relation"){typeof currentValue=="object"&&currentValue!==null&&typeof currentValue.id=="string"&&(normalized[field.name]=currentValue.id);continue}field.type==="relations"&&Array.isArray(currentValue)&&(normalized[field.name]=currentValue.map(item=>typeof item=="string"?item:typeof item=="object"&&item!==null&&typeof item.id=="string"?item.id:null).filter(item=>typeof item=="string"))}return normalized}import{existsSync as existsSync19,readFileSync as readFileSync20}from"node:fs";import{createConnection}from"node:net";import{dirname as dirname12,resolve as resolve13}from"node:path";import process2 from"node:process";function isLikelyControlApiConnectionError(error){if(!(error instanceof Error))return!1;let message=error.message.toLowerCase();if(message.includes("fetch failed")||message.includes("econnrefused")||message.includes("failed to fetch"))return!0;let cause=error.cause;if(cause&&typeof cause=="object"&&"code"in cause){let code2=String(cause.code).toLowerCase();return code2==="econnrefused"||code2==="enotfound"||code2==="econnreset"}return!1}function isControlApiDiagnosticError(error){return error instanceof PlatformApiError&&(error.category==="capability_health"||error.category==="runtime_binding"||error.code==="capability_unavailable"||error.code==="runtime_binding_missing")}function formatControlApiDiagnosticErrorText(error){let lines=["control-api diagnostic error:",`- code: ${error.code??"unknown"}`,`- category: ${error.category??"unknown"}`,`- capability: ${error.capability??"unknown"}`,`- message: ${error.message}`];return error.requestId&&lines.push(`- request_id: ${error.requestId}`),error.remediation&&lines.push(`- action: ${error.remediation}`),`${lines.join(`
2467
+ `))}function readStringOption4(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption2(args,key){let value=readStringOption4(args,key);if(value===void 0)return;let parsed=Number(value);if(!Number.isFinite(parsed)||parsed<=0)throw new Error(`\`--${key}\` \u9700\u8981\u6B63\u6574\u6570\u3002`);return Math.trunc(parsed)}function hasHelpFlag4(args){return args.options.help===!0||args.options.h===!0}function inferMimeType(fileName){switch(extname4(fileName).toLowerCase()){case".json":return"application/json";case".pdf":return"application/pdf";case".txt":return"text/plain";case".csv":return"text/csv";case".html":return"text/html";case".md":return"text/markdown";case".png":return"image/png";case".jpg":case".jpeg":return"image/jpeg";case".gif":return"image/gif";case".webp":return"image/webp";case".svg":return"image/svg+xml";case".mp4":return"video/mp4";case".mov":return"video/quicktime";case".webm":return"video/webm";case".zip":return"application/zip";default:return"application/octet-stream"}}function formatBlobError(error,action){return error instanceof PlatformApiError?new Error([`Blob ${action} \u5931\u8D25\u3002`,`\u72B6\u6001\u7801: ${error.status}`,`\u9519\u8BEF\u7801: ${error.code??"-"}`,error.message].join(`
2468
+ `)):error instanceof Error?error:new Error(`Blob ${action} \u5931\u8D25\u3002`)}function buildTenantAssetReference2(asset){return{asset_id:asset.asset.asset_id,title:asset.asset.title,media_type:asset.asset.media_type,mime_type:asset.asset.mime_type,size_bytes:asset.original_file.size_bytes,folder_id:asset.asset.folder_id,original_url:asset.original_url,variant_urls:asset.variant_urls}}function resolveCmsAttachAssetField(fields,fieldName){let field=fields.find(entry=>entry.name===fieldName);if(!field)throw new Error(`Collection does not contain field \`${fieldName}\`.`);if(field.type!=="image"&&field.type!=="images")throw new Error(`\u5B57\u6BB5 \`${fieldName}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return field}function isAssetReferenceRecord(value){return typeof value=="object"&&value!==null&&typeof value.asset_id=="string"}function dedupeAssetReferences(values){let seen=new Set,deduped=[];for(let value of values)seen.has(value.asset_id)||(seen.add(value.asset_id),deduped.push(value));return deduped}function buildCmsAttachAssetPayload(args){let assetReferences=args.assets.map(buildTenantAssetReference2),nextContent=normalizeCmsContentForWrite2(args.item.content,args.fields);if(args.field.type==="image"){if(assetReferences.length!==1)throw new Error("\u5355\u56FE\u5B57\u6BB5\u4E00\u6B21\u53EA\u80FD\u6302\u8F7D\u4E00\u4E2A\u7D20\u6750\u3002");nextContent[args.field.name]=assetReferences[0]}else if(args.field.type==="images"){let currentValues=Array.isArray(args.item.content[args.field.name])?args.item.content[args.field.name].filter(isAssetReferenceRecord):[];nextContent[args.field.name]=dedupeAssetReferences(args.replace?assetReferences:[...currentValues,...assetReferences])}else throw new Error(`\u5B57\u6BB5 \`${args.field.name}\` \u4E0D\u662F\u53EF\u6302\u8F7D\u7D20\u6750\u7684\u56FE\u7247\u5B57\u6BB5\u3002`);return{collection:args.item.collection,system:{...args.item.system.publish_status?{publish_status:args.item.system.publish_status}:{},...args.item.system.slug?{slug:args.item.system.slug}:{},...args.item.system.tags?{tags:[...args.item.system.tags]}:{},...Object.prototype.hasOwnProperty.call(args.item.system,"category_id")?{category_id:args.item.system.category_id??null}:{},...args.item.system.content_format?{content_format:args.item.system.content_format}:{},...args.item.system.source?{source:{...args.item.system.source}}:{}},content:nextContent}}function normalizeCmsContentForWrite2(content,fields){let normalized={...content};for(let field of fields){let currentValue=normalized[field.name];if(field.type==="relation"){typeof currentValue=="object"&&currentValue!==null&&typeof currentValue.id=="string"&&(normalized[field.name]=currentValue.id);continue}field.type==="relations"&&Array.isArray(currentValue)&&(normalized[field.name]=currentValue.map(item=>typeof item=="string"?item:typeof item=="object"&&item!==null&&typeof item.id=="string"?item.id:null).filter(item=>typeof item=="string"))}return normalized}import{existsSync as existsSync19,readFileSync as readFileSync20}from"node:fs";import{createConnection}from"node:net";import{dirname as dirname12,resolve as resolve14}from"node:path";import process2 from"node:process";function isLikelyControlApiConnectionError(error){if(!(error instanceof Error))return!1;let message=error.message.toLowerCase();if(message.includes("fetch failed")||message.includes("econnrefused")||message.includes("failed to fetch"))return!0;let cause=error.cause;if(cause&&typeof cause=="object"&&"code"in cause){let code2=String(cause.code).toLowerCase();return code2==="econnrefused"||code2==="enotfound"||code2==="econnreset"}return!1}function isControlApiDiagnosticError(error){return error instanceof PlatformApiError&&(error.category==="capability_health"||error.category==="runtime_binding"||error.code==="capability_unavailable"||error.code==="runtime_binding_missing")}function formatControlApiDiagnosticErrorText(error){let lines=["control-api diagnostic error:",`- code: ${error.code??"unknown"}`,`- category: ${error.category??"unknown"}`,`- capability: ${error.capability??"unknown"}`,`- message: ${error.message}`];return error.requestId&&lines.push(`- request_id: ${error.requestId}`),error.remediation&&lines.push(`- action: ${error.remediation}`),`${lines.join(`
2468
2469
  `)}
2469
2470
  `}async function collectControlApiFailureDiagnostics(baseUrl=getControlApiBaseUrl(),startDir=process2.cwd()){let parsedBaseUrl=new URL(baseUrl),isLocal=isLocalControlApiUrl(parsedBaseUrl),healthz=await probeEndpoint(new URL("/healthz",parsedBaseUrl)),readyz=healthz.status==="ok"||healthz.status==="failed"?await probeEndpoint(new URL("/readyz",parsedBaseUrl)):{status:"skipped",httpStatus:null},port=Number.parseInt(parsedBaseUrl.port||(parsedBaseUrl.protocol==="https:"?"443":"80"),10),host=normalizeProbeHost(parsedBaseUrl.hostname),lock=isLocal?readControlApiDevLock(startDir,port):emptyLock(),listening=isLocal?await isPortListening(host,port):null,diagnosis=buildDiagnosis({healthz,readyz,isLocal,lockExists:lock.exists,pidAlive:lock.pid_alive,portListening:listening}),endpoints=await collectEndpointDiagnostics(baseUrl,healthz),capabilityHealth=extractCapabilityHealthDiagnostics(healthz.body);return{control_api:{base_url:baseUrl,reachable:healthz.status==="ok"||healthz.status==="failed",healthz:{status:healthz.status==="not_ready"?"failed":healthz.status,http_status:healthz.httpStatus},readyz:{status:readyz.status,http_status:readyz.httpStatus}},capability_health:capabilityHealth,endpoints,local_dev:{is_local_base_url:isLocal,lock,port:{host,port,listening}},diagnosis,recommendations:buildRecommendations(diagnosis.code,isLocal)}}function formatControlApiFailureDiagnosticsText(diagnostics){return formatControlApiDiagnosticsText(diagnostics,"control-api unreachable:")}function formatControlApiDiagnosticsText(diagnostics,title="control-api diagnostics:"){let lines=[title,`- base_url: ${diagnostics.control_api.base_url}`,`- healthz: ${diagnostics.control_api.healthz.status}${diagnostics.control_api.healthz.http_status==null?"":` (${diagnostics.control_api.healthz.http_status})`}`,`- readyz: ${diagnostics.control_api.readyz.status}${diagnostics.control_api.readyz.http_status==null?"":` (${diagnostics.control_api.readyz.http_status})`}`];return lines.push(`- endpoint control: ${diagnostics.endpoints.control.healthz.status}`,`- endpoint runtime: ${formatEndpointState(diagnostics.endpoints.runtime)}`,`- endpoint public: ${formatEndpointState(diagnostics.endpoints.public)}`),diagnostics.capability_health.degraded.length>0&&lines.push(`- degraded capabilities: ${formatHealthItems(diagnostics.capability_health.degraded)}`),diagnostics.capability_health.workers.length>0&&lines.push(`- degraded workers: ${formatHealthItems(diagnostics.capability_health.workers)}`),diagnostics.local_dev.is_local_base_url&&lines.push(`- lock: ${diagnostics.local_dev.lock.exists?`exists pid=${diagnostics.local_dev.lock.pid??"-"} alive=${diagnostics.local_dev.lock.pid_alive??"-"}`:"missing"}`,`- port: ${diagnostics.local_dev.port.listening?"listening":"not listening"}`),lines.push(`- likely_cause: ${diagnostics.diagnosis.code}`,...diagnostics.recommendations.map(item=>`- action: ${item}`)),`${lines.join(`
2470
2471
  `)}
2471
- `}async function collectEndpointDiagnostics(controlBaseUrl,controlHealthz){let endpoints=listResolvedControlApiEndpoints({...process2.env,CONTROL_API_BASE_URL:controlBaseUrl}),results=await Promise.all(endpoints.map(async endpoint=>{if(endpoint.role==="control")return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:controlHealthz.status,http_status:controlHealthz.httpStatus}};if(!endpoint.enabled||endpoint.baseUrl==null)return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!1,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,reason:endpoint.reason,healthz:{status:"skipped",http_status:null}};let healthz=await probeEndpoint(new URL("/healthz",endpoint.baseUrl));return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:healthz.status,http_status:healthz.httpStatus}}}));return{control:results.find(endpoint=>endpoint.role==="control"),runtime:results.find(endpoint=>endpoint.role==="runtime"),public:results.find(endpoint=>endpoint.role==="public")}}function formatEndpointState(endpoint){return endpoint.enabled?`${endpoint.healthz.status}${endpoint.healthz.http_status==null?"":` (${endpoint.healthz.http_status})`}`:`${endpoint.reason??"disabled"}${endpoint.base_url?` (${endpoint.base_url})`:""}`}async function probeEndpoint(url){try{let response=await fetch(url,{signal:AbortSignal.timeout(1200)}),body=await readJsonBody(response);return response.ok?{status:"ok",httpStatus:response.status,body}:{status:response.status===503?"not_ready":"failed",httpStatus:response.status,body}}catch{return{status:"unreachable",httpStatus:null}}}async function readJsonBody(response){let text2=await response.text().catch(()=>"");if(text2)try{return JSON.parse(text2)}catch{return}}function extractCapabilityHealthDiagnostics(body){if(!body||typeof body!="object")return{status:null,degraded:[],workers:[]};let record=body;return{status:typeof record.status=="string"?record.status:null,degraded:extractDegradedHealthItems(record.capabilities),workers:extractDegradedHealthItems(record.workers)}}function extractDegradedHealthItems(input){return!input||typeof input!="object"?[]:Object.entries(input).map(([key,value])=>toHealthDiagnostic(key,value)).filter(item=>!!item)}function toHealthDiagnostic(key,value){if(!value||typeof value!="object")return null;let record=value,status=typeof record.status=="string"?record.status:"unknown";return status!=="degraded"&&status!=="unavailable"?null:{key,status,summary:typeof record.summary=="string"?record.summary:"",issues:Array.isArray(record.issues)?record.issues.filter(item=>typeof item=="string"):[],...typeof record.check_level=="string"?{check_level:record.check_level}:{}}}function formatHealthItems(items){return items.map(item=>{let issueText=item.issues.length>0?` issues=${item.issues.join(",")}`:"",levelText=item.check_level?` level=${item.check_level}`:"";return`${item.key}:${item.status}${levelText}${issueText}`}).join("; ")}function isLocalControlApiUrl(url){return url.hostname==="localhost"||url.hostname==="127.0.0.1"||url.hostname==="0.0.0.0"}function normalizeProbeHost(host){return host==="0.0.0.0"?"127.0.0.1":host}function readControlApiDevLock(startDir,port){let path2=findControlApiLockPath(startDir,port);if(!path2||!existsSync19(path2))return{path:path2,exists:!1,pid:null,pid_alive:null};let raw=readFileSync20(path2,"utf8").trim(),pid=parseLockPid(raw);return{path:path2,exists:!0,pid,pid_alive:pid==null?null:isPidRunning(pid)}}function emptyLock(){return{path:null,exists:!1,pid:null,pid_alive:null}}function findControlApiLockPath(startDir,port){let current=resolve13(startDir);for(;;){let candidate=resolve13(current,"services","control-api",`.dev-server.${port}.lock`);if(existsSync19(resolve13(current,"services","control-api")))return candidate;let parent=dirname12(current);if(parent===current)return null;current=parent}}function parseLockPid(raw){if(!raw)return null;try{let parsed=JSON.parse(raw),pid=Number.parseInt(String(parsed.pid??""),10);return Number.isFinite(pid)&&pid>0?pid:null}catch{let pid=Number.parseInt(raw,10);return Number.isFinite(pid)&&pid>0?pid:null}}function isPidRunning(pid){try{return process2.kill(pid,0),!0}catch{return!1}}function isPortListening(host,port){return new Promise(resolvePromise=>{let socket=createConnection({host,port});socket.setTimeout(800),socket.once("connect",()=>{socket.destroy(),resolvePromise(!0)}),socket.once("timeout",()=>{socket.destroy(),resolvePromise(!1)}),socket.once("error",()=>{socket.destroy(),resolvePromise(!1)})})}function buildDiagnosis(args){return args.healthz.status==="ok"&&args.readyz.status==="ok"?{category:"control_api_infrastructure",code:"control_api_ok",message:"control-api is reachable and ready"}:args.readyz.status==="not_ready"?{category:"control_api_infrastructure",code:"readyz_not_ready",message:"control-api is reachable but not ready"}:args.isLocal&&args.lockExists&&args.pidAlive===!0&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_manager_alive_but_http_not_ready",message:"control-api dev manager is alive but HTTP server is not listening"}:args.isLocal&&args.lockExists&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_lock_exists_port_not_listening",message:"control-api dev lock exists but HTTP port is not listening"}:{category:"control_api_infrastructure",code:args.healthz.status==="unreachable"?"healthz_unreachable":"control_api_unreachable",message:"control-api is unreachable"}}function buildRecommendations(code2,isLocal){return code2==="control_api_ok"?[]:isLocal?code2==="dev_manager_alive_but_http_not_ready"||code2==="dev_lock_exists_port_not_listening"?["restart `pnpm --filter @platform/control-api dev`"]:["start `pnpm --filter @platform/control-api dev`"]:["check CONTROL_API_BASE_URL, network connectivity, and environment configuration"]}function normalizeCategorySlug(value){return value.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"category"}function parseCmsCategoryPath(path2){let segments=path2.split("/").map(segment=>segment.trim()).filter(Boolean);if(segments.length===0)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\u3002");return segments.map(name=>({name,slug:normalizeCategorySlug(name)}))}function findCmsCategoryPathMatch(categories,parentId,segment){return categories.find(node=>(node.parent_id??null)===parentId&&node.slug===segment.slug)??categories.find(node=>(node.parent_id??null)===parentId&&node.name===segment.name)??null}async function ensureCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,ensuredNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,ensuredNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}let created=await args.createCategory(segment,parentId);categories.push(created),finalNode=created,parentId=created.id,ensuredNodes.push({id:created.id,name:created.name,slug:created.slug,parent_id:created.parent_id??null,action:"created"})}if(!finalNode)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u89E3\u6790\u5931\u8D25\uFF0C\u672A\u751F\u6210\u76EE\u6807\u5206\u7C7B\u3002");return{categories,finalNode,ensuredNodes}}function planCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,plannedNodeCounter=0,plannedNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,plannedNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}plannedNodes.push({id:null,name:segment.name,slug:segment.slug,parent_id:parentId,action:"created"}),finalNode=null,plannedNodeCounter+=1,parentId=`__planned_category_${plannedNodeCounter}`}return{finalNode,plannedNodes}}import{createHash as createHash6}from"node:crypto";import{readdirSync as readdirSync7,statSync as statSync8}from"node:fs";import{basename as basename6,extname as extname4,join as join15,relative as relative4,resolve as resolve14}from"node:path";import YAML3 from"yaml";function normalizeLineEndings(input){return input.replace(/\r\n/g,`
2472
- `)}function computeChecksum2(input){return`sha256:${createHash6("sha256").update(input).digest("hex")}`}function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toStringArray(value){if(Array.isArray(value))return value.filter(item=>typeof item=="string").map(item=>item.trim()).filter(Boolean);if(typeof value=="string")return value.split(",").map(item=>item.trim()).filter(Boolean)}function toOptionalString(value){return typeof value=="string"&&value.trim().length>0?value.trim():void 0}function isMarkdownFilePath(filePath){let extension=extname4(filePath).toLowerCase();return extension===".md"||extension===".markdown"}function normalizeSourcePath(filePath){let normalized=relative4(process.cwd(),filePath).replace(/\\/g,"/");return normalized.length>0&&!normalized.startsWith("..")?normalized:filePath.replace(/\\/g,"/")}function inferDefaultTitleFromPath(filePath){let title=basename6(filePath,extname4(filePath)).trim();return title.length>0?title:void 0}function inferDefaultSlugFromPath(filePath){let slug=basename6(filePath,extname4(filePath)).trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);return slug.length>0?slug:void 0}function normalizeItemIdSegment(value){return value.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function inferItemIdFromPrefix(prefix,filePath){let normalizedPrefix=normalizeItemIdSegment(prefix)||"cms-item",normalizedSource=filePath.replace(/\.[^.]+$/,""),pathSegment=normalizeItemIdSegment(normalizedSource),hash=createHash6("sha256").update(filePath).digest("hex").slice(0,8),readableSegment=pathSegment.length>0?pathSegment.slice(0,64):"item";return`${normalizedPrefix}-${readableSegment}-${hash}`}function collectMarkdownImportSources(targetPath,recursive){let absoluteTargetPath=resolve14(targetPath),stats=statSync8(absoluteTargetPath);if(stats.isFile()){if(!isMarkdownFilePath(absoluteTargetPath))throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\uFF1A${targetPath}`);return[{absolutePath:absoluteTargetPath,sourcePath:normalizeSourcePath(absoluteTargetPath)}]}if(!stats.isDirectory())throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\u6216\u76EE\u5F55\uFF1A${targetPath}`);let collected=[],visitDirectory=directoryPath=>{let entries=readdirSync7(directoryPath,{withFileTypes:!0}).sort((left,right)=>left.name.localeCompare(right.name));for(let entry of entries){let entryPath=join15(directoryPath,entry.name);if(entry.isDirectory()){recursive&&visitDirectory(entryPath);continue}!entry.isFile()||!isMarkdownFilePath(entryPath)||collected.push({absolutePath:entryPath,sourcePath:normalizeSourcePath(entryPath)})}};return visitDirectory(absoluteTargetPath),collected}function parseMarkdownWithFrontmatter(input){let raw=normalizeLineEndings(input),checksum3=computeChecksum2(raw);if(!raw.startsWith(`---
2472
+ `}async function collectEndpointDiagnostics(controlBaseUrl,controlHealthz){let endpoints=listResolvedControlApiEndpoints({...process2.env,CONTROL_API_BASE_URL:controlBaseUrl}),results=await Promise.all(endpoints.map(async endpoint=>{if(endpoint.role==="control")return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:controlHealthz.status,http_status:controlHealthz.httpStatus}};if(!endpoint.enabled||endpoint.baseUrl==null)return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!1,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,reason:endpoint.reason,healthz:{status:"skipped",http_status:null}};let healthz=await probeEndpoint(new URL("/healthz",endpoint.baseUrl));return{role:endpoint.role,base_url:endpoint.baseUrl,enabled:!0,capabilities:endpoint.capabilities,request_class:endpoint.requestClass,healthz:{status:healthz.status,http_status:healthz.httpStatus}}}));return{control:results.find(endpoint=>endpoint.role==="control"),runtime:results.find(endpoint=>endpoint.role==="runtime"),public:results.find(endpoint=>endpoint.role==="public")}}function formatEndpointState(endpoint){return endpoint.enabled?`${endpoint.healthz.status}${endpoint.healthz.http_status==null?"":` (${endpoint.healthz.http_status})`}`:`${endpoint.reason??"disabled"}${endpoint.base_url?` (${endpoint.base_url})`:""}`}async function probeEndpoint(url){try{let response=await fetch(url,{signal:AbortSignal.timeout(1200)}),body=await readJsonBody(response);return response.ok?{status:"ok",httpStatus:response.status,body}:{status:response.status===503?"not_ready":"failed",httpStatus:response.status,body}}catch{return{status:"unreachable",httpStatus:null}}}async function readJsonBody(response){let text2=await response.text().catch(()=>"");if(text2)try{return JSON.parse(text2)}catch{return}}function extractCapabilityHealthDiagnostics(body){if(!body||typeof body!="object")return{status:null,degraded:[],workers:[]};let record=body;return{status:typeof record.status=="string"?record.status:null,degraded:extractDegradedHealthItems(record.capabilities),workers:extractDegradedHealthItems(record.workers)}}function extractDegradedHealthItems(input){return!input||typeof input!="object"?[]:Object.entries(input).map(([key,value])=>toHealthDiagnostic(key,value)).filter(item=>!!item)}function toHealthDiagnostic(key,value){if(!value||typeof value!="object")return null;let record=value,status=typeof record.status=="string"?record.status:"unknown";return status!=="degraded"&&status!=="unavailable"?null:{key,status,summary:typeof record.summary=="string"?record.summary:"",issues:Array.isArray(record.issues)?record.issues.filter(item=>typeof item=="string"):[],...typeof record.check_level=="string"?{check_level:record.check_level}:{}}}function formatHealthItems(items){return items.map(item=>{let issueText=item.issues.length>0?` issues=${item.issues.join(",")}`:"",levelText=item.check_level?` level=${item.check_level}`:"";return`${item.key}:${item.status}${levelText}${issueText}`}).join("; ")}function isLocalControlApiUrl(url){return url.hostname==="localhost"||url.hostname==="127.0.0.1"||url.hostname==="0.0.0.0"}function normalizeProbeHost(host){return host==="0.0.0.0"?"127.0.0.1":host}function readControlApiDevLock(startDir,port){let path2=findControlApiLockPath(startDir,port);if(!path2||!existsSync19(path2))return{path:path2,exists:!1,pid:null,pid_alive:null};let raw=readFileSync20(path2,"utf8").trim(),pid=parseLockPid(raw);return{path:path2,exists:!0,pid,pid_alive:pid==null?null:isPidRunning(pid)}}function emptyLock(){return{path:null,exists:!1,pid:null,pid_alive:null}}function findControlApiLockPath(startDir,port){let current=resolve14(startDir);for(;;){let candidate=resolve14(current,"services","control-api",`.dev-server.${port}.lock`);if(existsSync19(resolve14(current,"services","control-api")))return candidate;let parent=dirname12(current);if(parent===current)return null;current=parent}}function parseLockPid(raw){if(!raw)return null;try{let parsed=JSON.parse(raw),pid=Number.parseInt(String(parsed.pid??""),10);return Number.isFinite(pid)&&pid>0?pid:null}catch{let pid=Number.parseInt(raw,10);return Number.isFinite(pid)&&pid>0?pid:null}}function isPidRunning(pid){try{return process2.kill(pid,0),!0}catch{return!1}}function isPortListening(host,port){return new Promise(resolvePromise=>{let socket=createConnection({host,port});socket.setTimeout(800),socket.once("connect",()=>{socket.destroy(),resolvePromise(!0)}),socket.once("timeout",()=>{socket.destroy(),resolvePromise(!1)}),socket.once("error",()=>{socket.destroy(),resolvePromise(!1)})})}function buildDiagnosis(args){return args.healthz.status==="ok"&&args.readyz.status==="ok"?{category:"control_api_infrastructure",code:"control_api_ok",message:"control-api is reachable and ready"}:args.readyz.status==="not_ready"?{category:"control_api_infrastructure",code:"readyz_not_ready",message:"control-api is reachable but not ready"}:args.isLocal&&args.lockExists&&args.pidAlive===!0&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_manager_alive_but_http_not_ready",message:"control-api dev manager is alive but HTTP server is not listening"}:args.isLocal&&args.lockExists&&args.portListening===!1?{category:"control_api_infrastructure",code:"dev_lock_exists_port_not_listening",message:"control-api dev lock exists but HTTP port is not listening"}:{category:"control_api_infrastructure",code:args.healthz.status==="unreachable"?"healthz_unreachable":"control_api_unreachable",message:"control-api is unreachable"}}function buildRecommendations(code2,isLocal){return code2==="control_api_ok"?[]:isLocal?code2==="dev_manager_alive_but_http_not_ready"||code2==="dev_lock_exists_port_not_listening"?["restart `pnpm --filter @platform/control-api dev`"]:["start `pnpm --filter @platform/control-api dev`"]:["check CONTROL_API_BASE_URL, network connectivity, and environment configuration"]}function normalizeCategorySlug(value){return value.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"category"}function parseCmsCategoryPath(path2){let segments=path2.split("/").map(segment=>segment.trim()).filter(Boolean);if(segments.length===0)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\u3002");return segments.map(name=>({name,slug:normalizeCategorySlug(name)}))}function findCmsCategoryPathMatch(categories,parentId,segment){return categories.find(node=>(node.parent_id??null)===parentId&&node.slug===segment.slug)??categories.find(node=>(node.parent_id??null)===parentId&&node.name===segment.name)??null}async function ensureCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,ensuredNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,ensuredNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}let created=await args.createCategory(segment,parentId);categories.push(created),finalNode=created,parentId=created.id,ensuredNodes.push({id:created.id,name:created.name,slug:created.slug,parent_id:created.parent_id??null,action:"created"})}if(!finalNode)throw new Error("\u5206\u7C7B\u8DEF\u5F84\u89E3\u6790\u5931\u8D25\uFF0C\u672A\u751F\u6210\u76EE\u6807\u5206\u7C7B\u3002");return{categories,finalNode,ensuredNodes}}function planCmsCategoryPath(args){let categories=[...args.categories],parentId=null,finalNode=null,plannedNodeCounter=0,plannedNodes=[];for(let segment of args.segments){let existing=findCmsCategoryPathMatch(categories,parentId,segment);if(existing){finalNode=existing,parentId=existing.id,plannedNodes.push({id:existing.id,name:existing.name,slug:existing.slug,parent_id:existing.parent_id??null,action:"reused"});continue}plannedNodes.push({id:null,name:segment.name,slug:segment.slug,parent_id:parentId,action:"created"}),finalNode=null,plannedNodeCounter+=1,parentId=`__planned_category_${plannedNodeCounter}`}return{finalNode,plannedNodes}}import{createHash as createHash6}from"node:crypto";import{readdirSync as readdirSync7,statSync as statSync8}from"node:fs";import{basename as basename7,extname as extname5,join as join15,relative as relative4,resolve as resolve15}from"node:path";import YAML3 from"yaml";function normalizeLineEndings(input){return input.replace(/\r\n/g,`
2473
+ `)}function computeChecksum2(input){return`sha256:${createHash6("sha256").update(input).digest("hex")}`}function isPlainObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toStringArray(value){if(Array.isArray(value))return value.filter(item=>typeof item=="string").map(item=>item.trim()).filter(Boolean);if(typeof value=="string")return value.split(",").map(item=>item.trim()).filter(Boolean)}function toOptionalString(value){return typeof value=="string"&&value.trim().length>0?value.trim():void 0}function isMarkdownFilePath(filePath){let extension=extname5(filePath).toLowerCase();return extension===".md"||extension===".markdown"}function normalizeSourcePath(filePath){let normalized=relative4(process.cwd(),filePath).replace(/\\/g,"/");return normalized.length>0&&!normalized.startsWith("..")?normalized:filePath.replace(/\\/g,"/")}function inferDefaultTitleFromPath(filePath){let title=basename7(filePath,extname5(filePath)).trim();return title.length>0?title:void 0}function inferDefaultSlugFromPath(filePath){let slug=basename7(filePath,extname5(filePath)).trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);return slug.length>0?slug:void 0}function normalizeItemIdSegment(value){return value.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function inferItemIdFromPrefix(prefix,filePath){let normalizedPrefix=normalizeItemIdSegment(prefix)||"cms-item",normalizedSource=filePath.replace(/\.[^.]+$/,""),pathSegment=normalizeItemIdSegment(normalizedSource),hash=createHash6("sha256").update(filePath).digest("hex").slice(0,8),readableSegment=pathSegment.length>0?pathSegment.slice(0,64):"item";return`${normalizedPrefix}-${readableSegment}-${hash}`}function collectMarkdownImportSources(targetPath,recursive){let absoluteTargetPath=resolve15(targetPath),stats=statSync8(absoluteTargetPath);if(stats.isFile()){if(!isMarkdownFilePath(absoluteTargetPath))throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\uFF1A${targetPath}`);return[{absolutePath:absoluteTargetPath,sourcePath:normalizeSourcePath(absoluteTargetPath)}]}if(!stats.isDirectory())throw new Error(`\u4EC5\u652F\u6301\u5BFC\u5165 Markdown \u6587\u4EF6\u6216\u76EE\u5F55\uFF1A${targetPath}`);let collected=[],visitDirectory=directoryPath=>{let entries=readdirSync7(directoryPath,{withFileTypes:!0}).sort((left,right)=>left.name.localeCompare(right.name));for(let entry of entries){let entryPath=join15(directoryPath,entry.name);if(entry.isDirectory()){recursive&&visitDirectory(entryPath);continue}!entry.isFile()||!isMarkdownFilePath(entryPath)||collected.push({absolutePath:entryPath,sourcePath:normalizeSourcePath(entryPath)})}};return visitDirectory(absoluteTargetPath),collected}function parseMarkdownWithFrontmatter(input){let raw=normalizeLineEndings(input),checksum3=computeChecksum2(raw);if(!raw.startsWith(`---
2473
2474
  `))return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let closingIndex=raw.indexOf(`
2474
2475
  ---
2475
- `,4);if(closingIndex===-1)return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let frontmatterSource=raw.slice(4,closingIndex),body=raw.slice(closingIndex+5).trim(),parsed=YAML3.parse(frontmatterSource);return{frontmatter:isPlainObject(parsed)?parsed:{},body,raw,checksum:checksum3}}function buildMarkdownItemPayload(args){let parsed=parseMarkdownWithFrontmatter(args.markdownContent),frontmatter={...parsed.frontmatter},title=args.title??toOptionalString(frontmatter.title)??inferDefaultTitleFromPath(args.markdownPath),slug=args.slug??toOptionalString(frontmatter.slug)??inferDefaultSlugFromPath(args.markdownPath),summary=args.summary??toOptionalString(frontmatter.summary),tags=args.tags??toStringArray(frontmatter.tags),categoryId=args.categoryId??toOptionalString(frontmatter.category_id)??null,publishStatus=args.publishStatus??toOptionalString(frontmatter.publish_status)??"draft";delete frontmatter.title,delete frontmatter.slug,delete frontmatter.summary,delete frontmatter.tags,delete frontmatter.category_id,delete frontmatter.publish_status;let content={...frontmatter,body:parsed.body};return title&&(content.title=title),summary&&(content.summary=summary),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:publishStatus,...slug?{slug}:{},...tags!==void 0?{tags}:{},...categoryId?{category_id:categoryId}:{},content_format:"markdown",source:{source_type:"markdown",source_url:null,source_path:args.markdownPath,source_raw:parsed.raw,checksum:parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"markdown-importer.v1"}},content}}function resolveMarkdownImportLookupKey(payload){return typeof payload.item_id=="string"&&payload.item_id.trim().length>0?{kind:"item_id",value:payload.item_id}:typeof payload.system.slug=="string"&&payload.system.slug.trim().length>0?{kind:"slug",value:payload.system.slug}:null}function summarizeMarkdownImportResults(items){let importedOrPlanned=0,skipped=0,draft=0,published=0,archived=0;for(let item of items){if(item.state==="skipped"?skipped+=1:importedOrPlanned+=1,item.publish_status==="draft"){draft+=1;continue}if(item.publish_status==="published"){published+=1;continue}item.publish_status==="archived"&&(archived+=1)}return{total:items.length,imported_or_planned:importedOrPlanned,skipped,draft,published,archived}}function normalizeSlugCandidate(value){return value.trim().slice(0,120)}function applySlugSuffix(baseSlug,suffix){let suffixText=`-${suffix}`;return`${baseSlug.slice(0,Math.max(1,120-suffixText.length))}${suffixText}`}async function findTenantCmsItemByExactSlug(args){let normalizedSlug=normalizeSlugCandidate(args.slug);if(!normalizedSlug)return null;let page=1,pageSize=100;for(;;){let response=await args.sdk.listTenantCmsItems({collection:args.collection,page,pageSize,query:normalizedSlug}),matched=response.items.find(item=>item.system.slug===normalizedSlug);if(matched)return matched;if(page*pageSize>=response.total||response.items.length===0)return null;page+=1}}async function resolveUniqueTenantCmsSlug(args){let normalizedSlug=args.slug?normalizeSlugCandidate(args.slug):void 0;if(!normalizedSlug)return{slug:void 0,adjusted:!1};let candidate=normalizedSlug,suffix=2;for(;;){let conflictsInBatch=args.reservedSlugs?.has(candidate)??!1,existing=conflictsInBatch?null:await findTenantCmsItemByExactSlug({sdk:args.sdk,collection:args.collection,slug:candidate});if(!conflictsInBatch&&(!existing||existing.system.id===args.itemId))return{slug:candidate,adjusted:candidate!==normalizedSlug,originalSlug:candidate!==normalizedSlug?normalizedSlug:void 0};candidate=applySlugSuffix(normalizedSlug,suffix),suffix+=1}}import{createHash as createHash7}from"node:crypto";import{URL as URL3}from"node:url";import{Readability}from"@mozilla/readability";import{JSDOM}from"jsdom";import sanitizeHtml from"sanitize-html";function computeChecksum3(input){return`sha256:${createHash7("sha256").update(input).digest("hex")}`}function stripUnsupportedJsonChars(value){return value.replace(/\u0000/g,"")}function trimToUndefined2(value){let normalized=value?.trim();return normalized||void 0}function getMetaContent(document,key){let selectors=[`meta[property="${key}"]`,`meta[name="${key}"]`,`meta[itemprop="${key}"]`];for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.getAttribute("content"));if(value)return value}}function getFirstText(document,selectors){for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.textContent);if(value)return value}}function normalizeUrl2(value,baseUrl){if(!value)return;let trimmed=value.trim();if(trimmed)try{return new URL3(trimmed,baseUrl).toString()}catch{return}}function escapeHtmlAttribute(value){return value.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function inferMimeTypeFromUrl2(value){if(!value)return;let pathname=(()=>{try{return new URL3(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg"}function extractArticleImageCandidates(document,baseUrl){let selectors=[".news-detail .image.parbase img",".news-detail .news-img img",".news-detail .richtext img","article img","main img"],results=[],seen=new Set;for(let selector of selectors)for(let image2 of document.querySelectorAll(selector)){let className=image2.getAttribute("class")?.toLowerCase()??"",parentClassName=image2.parentElement?.getAttribute("class")?.toLowerCase()??"";if(className.includes("qrcode")||className.includes("qr-code")||parentClassName.includes("qrcode")||parentClassName.includes("qr-code"))continue;let rawSrc=image2.getAttribute("src")??image2.getAttribute("data-src")??image2.getAttribute("data-original")??image2.getAttribute("data-original-src")??image2.getAttribute("data-lazy-src")??void 0,absoluteUrl=normalizeUrl2(rawSrc??void 0,baseUrl);!absoluteUrl||seen.has(absoluteUrl)||absoluteUrl.startsWith("data:")||(seen.add(absoluteUrl),results.push({url:absoluteUrl,alt:trimToUndefined2(image2.getAttribute("alt")??image2.getAttribute("title")??void 0)}))}return results}function normalizePublishedAt(value){if(!value)return;let timestamp=Date.parse(value);if(!Number.isNaN(timestamp))return new Date(timestamp).toISOString()}function inferDefaultTitleFromUrl(value){try{let parsed=new URL3(value),segment=parsed.pathname.replace(/\/+$/,"").split("/").filter(Boolean).at(-1)?.trim();return segment&&segment.length>0?decodeURIComponent(segment):parsed.hostname}catch{return}}function stripPageExtension(value){if(value)return value.replace(/\.(html?|xhtml|shtml)$/i,"")}function inferDefaultSlug(args){let candidates=[stripPageExtension(inferDefaultTitleFromUrl(args.resolvedUrl)),stripPageExtension(inferDefaultTitleFromUrl(args.requestedUrl)),args.title];for(let candidate of candidates){let normalized=candidate?.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);if(normalized)return normalized}}function absolutizeRichTextHtml(html,baseUrl){let body=new JSDOM(`<body>${html}</body>`,{url:baseUrl}).window.document.body;for(let anchor of body.querySelectorAll("a[href]")){let href=anchor.getAttribute("href"),absoluteHref=normalizeUrl2(href??void 0,baseUrl);absoluteHref&&anchor.setAttribute("href",absoluteHref)}let firstImageUrl;for(let image2 of body.querySelectorAll("img[src]")){let src=image2.getAttribute("src"),absoluteSrc=normalizeUrl2(src??void 0,baseUrl);absoluteSrc&&(image2.setAttribute("src",absoluteSrc),firstImageUrl??=absoluteSrc)}return{html:body.innerHTML,firstImageUrl}}function sanitizeArticleHtml(html){return sanitizeHtml(html,{allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","blockquote","pre","code","ul","ol","li","strong","em","b","i","del","a","img","table","thead","tbody","tr","th","td"],allowedAttributes:{a:["href","title"],img:["src","alt","title"],code:["class"],pre:["class"]},allowedSchemes:["http","https","mailto"],disallowedTagsMode:"discard"})}async function fetchUrlImportSource(url,fetchImpl=fetch){let response=await fetchImpl(url,{redirect:"follow",headers:{"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","cache-control":"no-cache",pragma:"no-cache"}});if(!response.ok)throw new Error(`URL \u6293\u53D6\u5931\u8D25\uFF1AHTTP ${response.status}`);let raw=stripUnsupportedJsonChars(await response.text());if(!trimToUndefined2(raw))throw new Error("URL \u9875\u9762\u5185\u5BB9\u4E3A\u7A7A\u3002");return{requestedUrl:url,resolvedUrl:response.url||url,raw,checksum:computeChecksum3(raw)}}function parseUrlImportHtml(args){let metadataDocument=new JSDOM(args.raw,{url:args.resolvedUrl}).window.document,articleImageCandidates=extractArticleImageCandidates(metadataDocument,args.resolvedUrl),readabilityDom=new JSDOM(args.raw,{url:args.resolvedUrl}),article=new Readability(readabilityDom.window.document).parse();if(!article?.content||!trimToUndefined2(article.textContent))throw new Error("\u672A\u80FD\u4ECE\u9875\u9762\u4E2D\u63D0\u53D6\u6B63\u6587\u3002");let{html:articleHtml,firstImageUrl}=absolutizeRichTextHtml(article.content,args.resolvedUrl),cleanedHtml=sanitizeArticleHtml(articleHtml).trim();if(!cleanedHtml)throw new Error("\u9875\u9762\u6B63\u6587\u5728\u6E05\u6D17\u540E\u4E3A\u7A7A\u3002");let leadImage=articleImageCandidates[0];if(!firstImageUrl&&leadImage){let altText=leadImage.alt?` alt="${escapeHtmlAttribute(leadImage.alt)}"`:' alt=""';cleanedHtml=`<p><img src="${escapeHtmlAttribute(leadImage.url)}"${altText} /></p>${cleanedHtml}`}let title=getMetaContent(metadataDocument,"og:title")??getMetaContent(metadataDocument,"twitter:title")??trimToUndefined2(metadataDocument.title)??trimToUndefined2(article.title)??getFirstText(metadataDocument,["h1"]),summary=getMetaContent(metadataDocument,"og:description")??getMetaContent(metadataDocument,"description")??trimToUndefined2(article.excerpt),metaCoverUrl=normalizeUrl2(getMetaContent(metadataDocument,"og:image"),args.resolvedUrl)??normalizeUrl2(getMetaContent(metadataDocument,"twitter:image"),args.resolvedUrl),bodyCoverUrl=firstImageUrl,coverUrl=leadImage?.url??bodyCoverUrl??metaCoverUrl,coverMimeType=coverUrl===metaCoverUrl?getMetaContent(metadataDocument,"og:image:type")??inferMimeTypeFromUrl2(coverUrl):inferMimeTypeFromUrl2(coverUrl)??getMetaContent(metadataDocument,"og:image:type"),sourceAuthor=getMetaContent(metadataDocument,"article:author")??getMetaContent(metadataDocument,"author")??getMetaContent(metadataDocument,"parsely-author")??getFirstText(metadataDocument,['[rel="author"]','[itemprop="author"]',".author",".ArticleAuthor-name"]),sourceSite=getMetaContent(metadataDocument,"og:site_name")??(()=>{try{return new URL3(args.resolvedUrl).hostname.replace(/^www\./,"")}catch{return}})(),sourcePublishedAt=normalizePublishedAt(getMetaContent(metadataDocument,"article:published_time")??getMetaContent(metadataDocument,"publishdate")??trimToUndefined2(metadataDocument.querySelector("time[datetime]")?.getAttribute("datetime")));return{requestedUrl:args.requestedUrl,resolvedUrl:args.resolvedUrl,title,summary,coverUrl,coverMimeType,sourceAuthor,sourceSite,sourcePublishedAt,body:cleanedHtml,contentFormat:"html",raw:args.raw,checksum:args.checksum??computeChecksum3(args.raw),warnings:[]}}function buildUrlItemPayload(args){let title=args.title??args.parsed.title??inferDefaultTitleFromUrl(args.parsed.resolvedUrl),slug=args.slug??inferDefaultSlug(args.parsed),summary=args.summary??args.parsed.summary,content={body:args.parsed.body,source_url:args.parsed.resolvedUrl};title&&(content.title=title),summary&&(content.summary=summary),args.parsed.sourceAuthor&&(content.source_author=args.parsed.sourceAuthor),args.parsed.sourceSite&&(content.source_site=args.parsed.sourceSite),args.parsed.sourcePublishedAt&&(content.source_published_at=args.parsed.sourcePublishedAt);let cover=resolveImportedUrlCover({parsed:args.parsed,cover:args.cover,title});return cover&&(content.cover=cover),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:args.publishStatus??"draft",...slug?{slug}:{},...args.tags&&args.tags.length>0?{tags:args.tags}:{},...args.categoryId!==void 0?{category_id:args.categoryId}:{},content_format:args.parsed.contentFormat,source:{source_type:"url",source_url:args.parsed.resolvedUrl,source_path:null,source_raw:args.parsed.raw,checksum:args.parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"url-importer.v1"}},content}}function resolveImportedUrlCover(args){if(args.cover?.mode==="asset"||args.cover?.mode==="remote")return args.cover.value;if(args.cover?.mode!=="none"&&args.parsed.coverUrl)return{title:args.title??"Remote cover",...args.parsed.coverMimeType?{mime_type:args.parsed.coverMimeType}:{},original_url:args.parsed.coverUrl}}async function assetizeParsedUrlImages(args){if(!args.includeBody&&!args.includeCover)return{parsed:args.parsed,cover:{mode:"none"},warnings:[]};let assetization=await assetizeExternalImagesInHtml({sdk:args.sdk,html:args.includeBody?args.parsed.body:"",baseUrl:args.parsed.resolvedUrl,coverUrl:args.includeCover?args.parsed.coverUrl:void 0,coverTitle:args.parsed.title,coverMimeType:args.parsed.coverMimeType,bodyTitle:args.parsed.title});return{parsed:{...args.parsed,body:args.includeBody?assetization.html:args.parsed.body},cover:assetization.cover,warnings:assetization.warnings}}function restrictItemPayloadToSchemaFields(payload,fields){let allowedFieldNames=new Set(fields.map(field=>field.name)),nextContent=Object.fromEntries(Object.entries(payload.content).filter(([key])=>allowedFieldNames.has(key))),droppedFields=Object.keys(payload.content).filter(key=>!allowedFieldNames.has(key));return{payload:{...payload,content:nextContent},droppedFields}}import process3 from"node:process";import{existsSync as existsSync21,readFileSync as readFileSync22}from"node:fs";import{join as join17}from"node:path";import{createHash as createHash9}from"node:crypto";import{existsSync as existsSync20,readdirSync as readdirSync8,readFileSync as readFileSync21}from"node:fs";import{basename as basename7,join as join16,relative as relative5}from"node:path";function assertNonEmptyString(value,field){if(typeof value!="string"||value.trim().length===0)throw new Error(`Auth policy field \`${field}\` must be a non-empty string.`);return value.trim()}function normalizePermissions(value){if(!Array.isArray(value))throw new Error("Auth policy field `permissions` must be an array.");let permissions=value.map((item,index)=>assertNonEmptyString(item,`permissions[${index}]`));return[...new Set(permissions)]}function normalizeAuthPolicy(input){if(typeof input!="object"||input===null)throw new Error("Auth policy must be an object.");let record=input;return{version:assertNonEmptyString(record.version,"version"),role:assertNonEmptyString(record.role,"role"),permissions:normalizePermissions(record.permissions)}}function deriveAuthResourceKey(policy,fallbackName){if(typeof policy=="object"&&policy!==null){let record=policy;if(typeof record.role=="string"&&record.role.trim().length>0)return`auth/${record.role.trim()}`;if(typeof record.policy=="string"&&record.policy.trim().length>0)return`auth/${record.policy.trim()}`}return`auth/${fallbackName}`}var DATA_FORM_ACCESS_SCOPES=["public","own","admin"];var DATA_FORM_GENERATED_SOURCE_TAG="data_form_generated";function buildSourceTagComment(source){return`-- source: ${source}`}function renderColumn(column){let parts=[`${column.column_name} ${column.data_type}`];return parts.push(column.nullable?"NULL":"NOT NULL"),column.default_sql!==void 0&&parts.push(`DEFAULT ${column.default_sql}`),parts.join(" ")}function renderCreateTable(tableName,columns){return[`CREATE TABLE IF NOT EXISTS ${tableName} (`,columns.map(column=>` ${renderColumn(column)}`).join(`,
2476
+ `,4);if(closingIndex===-1)return{frontmatter:{},body:raw.trim(),raw,checksum:checksum3};let frontmatterSource=raw.slice(4,closingIndex),body=raw.slice(closingIndex+5).trim(),parsed=YAML3.parse(frontmatterSource);return{frontmatter:isPlainObject(parsed)?parsed:{},body,raw,checksum:checksum3}}function buildMarkdownItemPayload(args){let parsed=parseMarkdownWithFrontmatter(args.markdownContent),frontmatter={...parsed.frontmatter},title=args.title??toOptionalString(frontmatter.title)??inferDefaultTitleFromPath(args.markdownPath),slug=args.slug??toOptionalString(frontmatter.slug)??inferDefaultSlugFromPath(args.markdownPath),summary=args.summary??toOptionalString(frontmatter.summary),tags=args.tags??toStringArray(frontmatter.tags),categoryId=args.categoryId??toOptionalString(frontmatter.category_id)??null,publishStatus=args.publishStatus??toOptionalString(frontmatter.publish_status)??"draft";delete frontmatter.title,delete frontmatter.slug,delete frontmatter.summary,delete frontmatter.tags,delete frontmatter.category_id,delete frontmatter.publish_status;let content={...frontmatter,body:parsed.body};return title&&(content.title=title),summary&&(content.summary=summary),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:publishStatus,...slug?{slug}:{},...tags!==void 0?{tags}:{},...categoryId?{category_id:categoryId}:{},content_format:"markdown",source:{source_type:"markdown",source_url:null,source_path:args.markdownPath,source_raw:parsed.raw,checksum:parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"markdown-importer.v1"}},content}}function resolveMarkdownImportLookupKey(payload){return typeof payload.item_id=="string"&&payload.item_id.trim().length>0?{kind:"item_id",value:payload.item_id}:typeof payload.system.slug=="string"&&payload.system.slug.trim().length>0?{kind:"slug",value:payload.system.slug}:null}function summarizeMarkdownImportResults(items){let importedOrPlanned=0,skipped=0,draft=0,published=0,archived=0;for(let item of items){if(item.state==="skipped"?skipped+=1:importedOrPlanned+=1,item.publish_status==="draft"){draft+=1;continue}if(item.publish_status==="published"){published+=1;continue}item.publish_status==="archived"&&(archived+=1)}return{total:items.length,imported_or_planned:importedOrPlanned,skipped,draft,published,archived}}function normalizeSlugCandidate(value){return value.trim().slice(0,120)}function applySlugSuffix(baseSlug,suffix){let suffixText=`-${suffix}`;return`${baseSlug.slice(0,Math.max(1,120-suffixText.length))}${suffixText}`}async function findTenantCmsItemByExactSlug(args){let normalizedSlug=normalizeSlugCandidate(args.slug);if(!normalizedSlug)return null;let page=1,pageSize=100;for(;;){let response=await args.sdk.listTenantCmsItems({collection:args.collection,page,pageSize,query:normalizedSlug}),matched=response.items.find(item=>item.system.slug===normalizedSlug);if(matched)return matched;if(page*pageSize>=response.total||response.items.length===0)return null;page+=1}}async function resolveUniqueTenantCmsSlug(args){let normalizedSlug=args.slug?normalizeSlugCandidate(args.slug):void 0;if(!normalizedSlug)return{slug:void 0,adjusted:!1};let candidate=normalizedSlug,suffix=2;for(;;){let conflictsInBatch=args.reservedSlugs?.has(candidate)??!1,existing=conflictsInBatch?null:await findTenantCmsItemByExactSlug({sdk:args.sdk,collection:args.collection,slug:candidate});if(!conflictsInBatch&&(!existing||existing.system.id===args.itemId))return{slug:candidate,adjusted:candidate!==normalizedSlug,originalSlug:candidate!==normalizedSlug?normalizedSlug:void 0};candidate=applySlugSuffix(normalizedSlug,suffix),suffix+=1}}import{createHash as createHash7}from"node:crypto";import{URL as URL3}from"node:url";import{Readability}from"@mozilla/readability";import{JSDOM}from"jsdom";import sanitizeHtml from"sanitize-html";function computeChecksum3(input){return`sha256:${createHash7("sha256").update(input).digest("hex")}`}function stripUnsupportedJsonChars(value){return value.replace(/\u0000/g,"")}function trimToUndefined2(value){let normalized=value?.trim();return normalized||void 0}function getMetaContent(document,key){let selectors=[`meta[property="${key}"]`,`meta[name="${key}"]`,`meta[itemprop="${key}"]`];for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.getAttribute("content"));if(value)return value}}function getFirstText(document,selectors){for(let selector of selectors){let value=trimToUndefined2(document.querySelector(selector)?.textContent);if(value)return value}}function normalizeUrl2(value,baseUrl){if(!value)return;let trimmed=value.trim();if(trimmed)try{return new URL3(trimmed,baseUrl).toString()}catch{return}}function escapeHtmlAttribute(value){return value.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function inferMimeTypeFromUrl2(value){if(!value)return;let pathname=(()=>{try{return new URL3(value).pathname.toLowerCase()}catch{return value.toLowerCase()}})();if(pathname.endsWith(".png"))return"image/png";if(pathname.endsWith(".webp"))return"image/webp";if(pathname.endsWith(".gif"))return"image/gif";if(pathname.endsWith(".svg"))return"image/svg+xml";if(pathname.endsWith(".jpg")||pathname.endsWith(".jpeg"))return"image/jpeg"}function extractArticleImageCandidates(document,baseUrl){let selectors=[".news-detail .image.parbase img",".news-detail .news-img img",".news-detail .richtext img","article img","main img"],results=[],seen=new Set;for(let selector of selectors)for(let image2 of document.querySelectorAll(selector)){let className=image2.getAttribute("class")?.toLowerCase()??"",parentClassName=image2.parentElement?.getAttribute("class")?.toLowerCase()??"";if(className.includes("qrcode")||className.includes("qr-code")||parentClassName.includes("qrcode")||parentClassName.includes("qr-code"))continue;let rawSrc=image2.getAttribute("src")??image2.getAttribute("data-src")??image2.getAttribute("data-original")??image2.getAttribute("data-original-src")??image2.getAttribute("data-lazy-src")??void 0,absoluteUrl=normalizeUrl2(rawSrc??void 0,baseUrl);!absoluteUrl||seen.has(absoluteUrl)||absoluteUrl.startsWith("data:")||(seen.add(absoluteUrl),results.push({url:absoluteUrl,alt:trimToUndefined2(image2.getAttribute("alt")??image2.getAttribute("title")??void 0)}))}return results}function normalizePublishedAt(value){if(!value)return;let timestamp=Date.parse(value);if(!Number.isNaN(timestamp))return new Date(timestamp).toISOString()}function inferDefaultTitleFromUrl(value){try{let parsed=new URL3(value),segment=parsed.pathname.replace(/\/+$/,"").split("/").filter(Boolean).at(-1)?.trim();return segment&&segment.length>0?decodeURIComponent(segment):parsed.hostname}catch{return}}function stripPageExtension(value){if(value)return value.replace(/\.(html?|xhtml|shtml)$/i,"")}function inferDefaultSlug(args){let candidates=[stripPageExtension(inferDefaultTitleFromUrl(args.resolvedUrl)),stripPageExtension(inferDefaultTitleFromUrl(args.requestedUrl)),args.title];for(let candidate of candidates){let normalized=candidate?.trim().toLowerCase().replace(/[\/\\]+/g,"-").replace(/\s+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,120);if(normalized)return normalized}}function absolutizeRichTextHtml(html,baseUrl){let body=new JSDOM(`<body>${html}</body>`,{url:baseUrl}).window.document.body;for(let anchor of body.querySelectorAll("a[href]")){let href=anchor.getAttribute("href"),absoluteHref=normalizeUrl2(href??void 0,baseUrl);absoluteHref&&anchor.setAttribute("href",absoluteHref)}let firstImageUrl;for(let image2 of body.querySelectorAll("img[src]")){let src=image2.getAttribute("src"),absoluteSrc=normalizeUrl2(src??void 0,baseUrl);absoluteSrc&&(image2.setAttribute("src",absoluteSrc),firstImageUrl??=absoluteSrc)}return{html:body.innerHTML,firstImageUrl}}function sanitizeArticleHtml(html){return sanitizeHtml(html,{allowedTags:["h1","h2","h3","h4","h5","h6","p","br","hr","blockquote","pre","code","ul","ol","li","strong","em","b","i","del","a","img","table","thead","tbody","tr","th","td"],allowedAttributes:{a:["href","title"],img:["src","alt","title"],code:["class"],pre:["class"]},allowedSchemes:["http","https","mailto"],disallowedTagsMode:"discard"})}async function fetchUrlImportSource(url,fetchImpl=fetch){let response=await fetchImpl(url,{redirect:"follow",headers:{"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","cache-control":"no-cache",pragma:"no-cache"}});if(!response.ok)throw new Error(`URL \u6293\u53D6\u5931\u8D25\uFF1AHTTP ${response.status}`);let raw=stripUnsupportedJsonChars(await response.text());if(!trimToUndefined2(raw))throw new Error("URL \u9875\u9762\u5185\u5BB9\u4E3A\u7A7A\u3002");return{requestedUrl:url,resolvedUrl:response.url||url,raw,checksum:computeChecksum3(raw)}}function parseUrlImportHtml(args){let metadataDocument=new JSDOM(args.raw,{url:args.resolvedUrl}).window.document,articleImageCandidates=extractArticleImageCandidates(metadataDocument,args.resolvedUrl),readabilityDom=new JSDOM(args.raw,{url:args.resolvedUrl}),article=new Readability(readabilityDom.window.document).parse();if(!article?.content||!trimToUndefined2(article.textContent))throw new Error("\u672A\u80FD\u4ECE\u9875\u9762\u4E2D\u63D0\u53D6\u6B63\u6587\u3002");let{html:articleHtml,firstImageUrl}=absolutizeRichTextHtml(article.content,args.resolvedUrl),cleanedHtml=sanitizeArticleHtml(articleHtml).trim();if(!cleanedHtml)throw new Error("\u9875\u9762\u6B63\u6587\u5728\u6E05\u6D17\u540E\u4E3A\u7A7A\u3002");let leadImage=articleImageCandidates[0];if(!firstImageUrl&&leadImage){let altText=leadImage.alt?` alt="${escapeHtmlAttribute(leadImage.alt)}"`:' alt=""';cleanedHtml=`<p><img src="${escapeHtmlAttribute(leadImage.url)}"${altText} /></p>${cleanedHtml}`}let title=getMetaContent(metadataDocument,"og:title")??getMetaContent(metadataDocument,"twitter:title")??trimToUndefined2(metadataDocument.title)??trimToUndefined2(article.title)??getFirstText(metadataDocument,["h1"]),summary=getMetaContent(metadataDocument,"og:description")??getMetaContent(metadataDocument,"description")??trimToUndefined2(article.excerpt),metaCoverUrl=normalizeUrl2(getMetaContent(metadataDocument,"og:image"),args.resolvedUrl)??normalizeUrl2(getMetaContent(metadataDocument,"twitter:image"),args.resolvedUrl),bodyCoverUrl=firstImageUrl,coverUrl=leadImage?.url??bodyCoverUrl??metaCoverUrl,coverMimeType=coverUrl===metaCoverUrl?getMetaContent(metadataDocument,"og:image:type")??inferMimeTypeFromUrl2(coverUrl):inferMimeTypeFromUrl2(coverUrl)??getMetaContent(metadataDocument,"og:image:type"),sourceAuthor=getMetaContent(metadataDocument,"article:author")??getMetaContent(metadataDocument,"author")??getMetaContent(metadataDocument,"parsely-author")??getFirstText(metadataDocument,['[rel="author"]','[itemprop="author"]',".author",".ArticleAuthor-name"]),sourceSite=getMetaContent(metadataDocument,"og:site_name")??(()=>{try{return new URL3(args.resolvedUrl).hostname.replace(/^www\./,"")}catch{return}})(),sourcePublishedAt=normalizePublishedAt(getMetaContent(metadataDocument,"article:published_time")??getMetaContent(metadataDocument,"publishdate")??trimToUndefined2(metadataDocument.querySelector("time[datetime]")?.getAttribute("datetime")));return{requestedUrl:args.requestedUrl,resolvedUrl:args.resolvedUrl,title,summary,coverUrl,coverMimeType,sourceAuthor,sourceSite,sourcePublishedAt,body:cleanedHtml,contentFormat:"html",raw:args.raw,checksum:args.checksum??computeChecksum3(args.raw),warnings:[]}}function buildUrlItemPayload(args){let title=args.title??args.parsed.title??inferDefaultTitleFromUrl(args.parsed.resolvedUrl),slug=args.slug??inferDefaultSlug(args.parsed),summary=args.summary??args.parsed.summary,content={body:args.parsed.body,source_url:args.parsed.resolvedUrl};title&&(content.title=title),summary&&(content.summary=summary),args.parsed.sourceAuthor&&(content.source_author=args.parsed.sourceAuthor),args.parsed.sourceSite&&(content.source_site=args.parsed.sourceSite),args.parsed.sourcePublishedAt&&(content.source_published_at=args.parsed.sourcePublishedAt);let cover=resolveImportedUrlCover({parsed:args.parsed,cover:args.cover,title});return cover&&(content.cover=cover),{...args.itemId?{item_id:args.itemId}:{},collection:args.collection,system:{publish_status:args.publishStatus??"draft",...slug?{slug}:{},...args.tags&&args.tags.length>0?{tags:args.tags}:{},...args.categoryId!==void 0?{category_id:args.categoryId}:{},content_format:args.parsed.contentFormat,source:{source_type:"url",source_url:args.parsed.resolvedUrl,source_path:null,source_raw:args.parsed.raw,checksum:args.parsed.checksum,imported_by:args.importedBy??"ide-agent",parser_version:"url-importer.v1"}},content}}function resolveImportedUrlCover(args){if(args.cover?.mode==="asset"||args.cover?.mode==="remote")return args.cover.value;if(args.cover?.mode!=="none"&&args.parsed.coverUrl)return{title:args.title??"Remote cover",...args.parsed.coverMimeType?{mime_type:args.parsed.coverMimeType}:{},original_url:args.parsed.coverUrl}}async function assetizeParsedUrlImages(args){if(!args.includeBody&&!args.includeCover)return{parsed:args.parsed,cover:{mode:"none"},warnings:[]};let assetization=await assetizeExternalImagesInHtml({sdk:args.sdk,html:args.includeBody?args.parsed.body:"",baseUrl:args.parsed.resolvedUrl,coverUrl:args.includeCover?args.parsed.coverUrl:void 0,coverTitle:args.parsed.title,coverMimeType:args.parsed.coverMimeType,bodyTitle:args.parsed.title});return{parsed:{...args.parsed,body:args.includeBody?assetization.html:args.parsed.body},cover:assetization.cover,warnings:assetization.warnings}}function restrictItemPayloadToSchemaFields(payload,fields){let allowedFieldNames=new Set(fields.map(field=>field.name)),nextContent=Object.fromEntries(Object.entries(payload.content).filter(([key])=>allowedFieldNames.has(key))),droppedFields=Object.keys(payload.content).filter(key=>!allowedFieldNames.has(key));return{payload:{...payload,content:nextContent},droppedFields}}import process3 from"node:process";import{existsSync as existsSync21,readFileSync as readFileSync22}from"node:fs";import{join as join17}from"node:path";import{createHash as createHash9}from"node:crypto";import{existsSync as existsSync20,readdirSync as readdirSync8,readFileSync as readFileSync21}from"node:fs";import{basename as basename8,join as join16,relative as relative5}from"node:path";function assertNonEmptyString(value,field){if(typeof value!="string"||value.trim().length===0)throw new Error(`Auth policy field \`${field}\` must be a non-empty string.`);return value.trim()}function normalizePermissions(value){if(!Array.isArray(value))throw new Error("Auth policy field `permissions` must be an array.");let permissions=value.map((item,index)=>assertNonEmptyString(item,`permissions[${index}]`));return[...new Set(permissions)]}function normalizeAuthPolicy(input){if(typeof input!="object"||input===null)throw new Error("Auth policy must be an object.");let record=input;return{version:assertNonEmptyString(record.version,"version"),role:assertNonEmptyString(record.role,"role"),permissions:normalizePermissions(record.permissions)}}function deriveAuthResourceKey(policy,fallbackName){if(typeof policy=="object"&&policy!==null){let record=policy;if(typeof record.role=="string"&&record.role.trim().length>0)return`auth/${record.role.trim()}`;if(typeof record.policy=="string"&&record.policy.trim().length>0)return`auth/${record.policy.trim()}`}return`auth/${fallbackName}`}var DATA_FORM_ACCESS_SCOPES=["public","own","admin"];var DATA_FORM_GENERATED_SOURCE_TAG="data_form_generated";function buildSourceTagComment(source){return`-- source: ${source}`}function renderColumn(column){let parts=[`${column.column_name} ${column.data_type}`];return parts.push(column.nullable?"NULL":"NOT NULL"),column.default_sql!==void 0&&parts.push(`DEFAULT ${column.default_sql}`),parts.join(" ")}function renderCreateTable(tableName,columns){return[`CREATE TABLE IF NOT EXISTS ${tableName} (`,columns.map(column=>` ${renderColumn(column)}`).join(`,
2476
2477
  `),");"].join(`
2477
2478
  `)}function renderAlterColumn(tableName,columnName,nullable,defaultSql){let statements=[];return nullable!==void 0&&statements.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${nullable?"DROP NOT NULL":"SET NOT NULL"};`),defaultSql!==void 0&&statements.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} SET DEFAULT ${defaultSql};`),statements}function renderDataFormDiffSql(diff){let statements=[buildSourceTagComment(diff.source),`-- resource_key: ${diff.resource_key}`,`-- table_name: ${diff.table_name}`,""];for(let operation of diff.operations)switch(operation.kind){case"create_table":statements.push(renderCreateTable(operation.table_name,operation.columns));break;case"add_column":statements.push(`ALTER TABLE ${operation.table_name} ADD COLUMN ${renderColumn(operation.column)};`);break;case"alter_column":statements.push(...renderAlterColumn(operation.table_name,operation.column_name,operation.nullable,operation.default_sql));break}return`${statements.filter(item=>item.length>0).join(`
2478
2479
  `)}
@@ -2499,7 +2500,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2499
2500
  `)}var DATA_FORM_RUNTIME_ROUTE_PREFIX="/api/public/apps";function buildDataFormRuntimeBasePath(appId){return`${DATA_FORM_RUNTIME_ROUTE_PREFIX}/${encodeURIComponent(appId)}/data-form`}function buildDataFormRuntimeResourcesPath(appId){return`${buildDataFormRuntimeBasePath(appId)}/resources`}function buildDataFormRuntimeRecordsPath(appId,resourceKey){return`${buildDataFormRuntimeResourcesPath(appId)}/${encodeURIComponent(resourceKey)}/records`}function buildDataFormRuntimeRecordPath(appId,resourceKey,recordId){return`${buildDataFormRuntimeRecordsPath(appId,resourceKey)}/${encodeURIComponent(recordId)}`}function normalizeDataFormRuntimeListQuery(query){return{page:normalizePositiveInteger(query.page,1),page_size:normalizePositiveInteger(query.page_size,20),owner_scope:query.owner_scope==="all"?"all":"me",q:typeof query.q=="string"?query.q.trim():""}}function normalizePositiveInteger(value,fallback){if(!Number.isFinite(value)||value===void 0)return fallback;let normalized=Math.floor(value);return normalized>0?normalized:fallback}function buildWorkflowObjectModelSummary(args){let objectTypes=new Set;for(let definition of args.definitions)definition.object_type&&objectTypes.add(definition.object_type);for(let binding of args.bindings)binding.object_type&&objectTypes.add(binding.object_type);return Array.from(objectTypes).sort((left,right)=>left.localeCompare(right)).map(objectType=>{let definitions=args.definitions.filter(item=>item.object_type===objectType),bindings=args.bindings.filter(item=>item.object_type===objectType),bindingDefinitionKeys=Array.from(new Set(bindings.map(item=>item.definition_key))).sort((left,right)=>left.localeCompare(right)),definitionKeys=Array.from(new Set([...definitions.map(item=>item.definition_key),...bindingDefinitionKeys])).sort((left,right)=>left.localeCompare(right)),relatedRoleBindings=args.roleBindings.filter(item=>bindingDefinitionKeys.includes(item.definition_key));return{object_type:objectType,default_definition_key:bindingDefinitionKeys.length===1?bindingDefinitionKeys[0]:definitions.length===1?definitions[0]?.definition_key:void 0,definition_keys:definitionKeys,binding_definition_keys:bindingDefinitionKeys,role_keys:Array.from(new Set(relatedRoleBindings.map(item=>item.role_key))).sort((left,right)=>left.localeCompare(right)),principal_role_keys:Array.from(new Set(relatedRoleBindings.map(item=>item.principal_role_key))).sort((left,right)=>left.localeCompare(right)),target_scopes:Array.from(new Set(bindings.map(item=>item.target_scope))).sort((left,right)=>left.localeCompare(right))}})}async function syncLocalControlPlaneSummary(args){try{let summary=await collectControlPlaneSummary(args);updateSourceContext(args.startDir??process.cwd(),{tenant_id:args.tenantId,app_id:args.appId,control_plane:summary})}catch{}}async function collectControlPlaneSummary(args){let[authInspect,dbPreview,dbProd,workflowDefinitions,workflowBindings,deploymentTimeline,cmsCollections]=await Promise.all([args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.getTenantAppDbInstance(args.appId,"preview").catch(()=>null),args.sdk.getTenantAppDbInstance(args.appId,"prod").catch(()=>null),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[]),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listTenantCmsCollections().catch(()=>({items:[]}))]),previewDeployment=deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),previewAuth=authInspect?.environments.find(item=>item.env==="preview"),prodAuth=authInspect?.environments.find(item=>item.env==="prod"),workflowRoleBindings=(await Promise.all(workflowBindings.map(binding=>args.sdk.listWorkflowRoleBindings({target_scope:binding.target_scope,target_id:binding.target_id,definition_key:binding.definition_key}).catch(()=>[])))).flat(),cmsCollectionDetails=await Promise.all(cmsCollections.items.map(async item=>{let discovered=await args.sdk.discoverTenantCmsCollection(item.collection).catch(()=>null);return{...item,has_active_schema:!!discovered?.active_schema,has_draft_schema:!!discovered?.draft_schema,categories_count:discovered?.categories.length??0}}));return{synced_at:new Date().toISOString(),auth:{inspect_status:authInspect?.inspect_status??null,issues:authInspect?.issues??[],environments:{preview:previewAuth?{status:previewAuth.status,missing_binding_keys:previewAuth.missing_binding_keys,issues:previewAuth.issues}:void 0,prod:prodAuth?{status:prodAuth.status,missing_binding_keys:prodAuth.missing_binding_keys,issues:prodAuth.issues}:void 0}},db:{preview:dbPreview?{bound:dbPreview.bound,status:dbPreview.status,schema_name:dbPreview.schema_name??null,database_name:dbPreview.database_name??null,tables_count:typeof dbPreview.tables_count=="number"?dbPreview.tables_count:null,latest_migration:dbPreview.latest_migration?.migration_path??null}:void 0,prod:dbProd?{bound:dbProd.bound,status:dbProd.status,schema_name:dbProd.schema_name??null,database_name:dbProd.database_name??null,tables_count:typeof dbProd.tables_count=="number"?dbProd.tables_count:null,latest_migration:dbProd.latest_migration?.migration_path??null}:void 0},workflow:{active_definition_count:workflowDefinitions.length,binding_count:workflowBindings.length,definition_keys:workflowDefinitions.map(item=>item.definition_key),definitions:workflowDefinitions.map(item=>({definition_key:item.definition_key,object_type:item.object_type,status:item.status})),bindings:workflowBindings.map(item=>({definition_key:item.definition_key,target_scope:item.target_scope,target_id:item.target_id,object_type:item.object_type,status:item.status,role_binding_count:workflowRoleBindings.filter(binding=>binding.definition_key===item.definition_key&&binding.target_id===item.target_id).length})),role_bindings:workflowRoleBindings.map(item=>({definition_key:item.definition_key,role_key:item.role_key,actor_scope:item.actor_scope,principal_role_key:item.principal_role_key})),object_models:buildWorkflowObjectModelSummary({definitions:workflowDefinitions,bindings:workflowBindings,roleBindings:workflowRoleBindings})},cms:{collection_count:cmsCollectionDetails.length,collections:cmsCollectionDetails.map(item=>({collection:item.collection,label:item.label,template:item.template,collection_status:item.collection_status,item_count:item.item_count,has_draft:item.has_draft,schema_status:item.schema_status,schema_version:item.schema_version,has_active_schema:item.has_active_schema,has_draft_schema:item.has_draft_schema,categories_count:item.categories_count}))},runtime:{preview:previewDeployment?{health:previewDeployment.health??null,source_version_id:previewDeployment.source_version_id??null,preview_url:previewDeployment.preview_url??null}:void 0,prod:prodDeployment?{health:prodDeployment.health??null,source_version_id:prodDeployment.source_version_id??null}:void 0}}}import YAML4 from"yaml";var GENERATED_AUTH_MANIFEST_PATH=".platform/generated/auth/end-user-auth.json",GENERATED_AUTH_POLICY={version:"0.1.0",role:"end-user-auth",permissions:["auth:enabled"]};async function runResourcesCommand(args){let subcommand=args.rest[0];if(subcommand!=="diff"&&subcommand!=="apply"&&subcommand!=="rollback")throw new Error("`platform resources` \u4EC5\u652F\u6301 `diff`\u3001`apply` \u6216 `rollback` \u5B50\u547D\u4EE4\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption5(args,"tenant")??binding?.tenant_id,appId=readStringOption5(args,"app")??binding?.app_id,env=readStringOption5(args,"env")??binding?.env??"preview",baseSnapshotId=readStringOption5(args,"base-snapshot"),targetSnapshotId=args.rest[1]??readStringOption5(args,"target-snapshot");if(!tenantId||!appId)throw new Error("`platform resources` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(subcommand==="rollback"&&!targetSnapshotId)throw new Error("`platform resources rollback` \u9700\u8981 `<snapshot-id>` \u6216 `--target-snapshot <snapshot-id>`\u3002");let requestedBy=await resolveRequestedBy2({accessToken:selectApiToken(credentials),tenantId});subcommand!=="rollback"&&readAppManifest(appRoot);let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"}),localResources=await collectEffectiveResources(appRoot,{sdk,appId});if(subcommand==="rollback"){let approveId=readStringOption5(args,"approve-id"),rollbackPayload={operation:"rollback",tenant_id:tenantId,app_id:appId,env,target_snapshot_id:targetSnapshotId,requested_by:requestedBy,reason:readStringOption5(args,"reason")??"manual_resource_rollback",...approveId?{approve_id:approveId}:{}},result2=await withPendingFeedback(args.options.json===!0,`\u6B63\u5728\u6267\u884C\u8D44\u6E90\u56DE\u9000: ${appId}/${env} -> ${targetSnapshotId}`,"\u8D44\u6E90\u56DE\u9000\u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u5BA1\u6279\u6821\u9A8C\u3001\u5FEB\u7167\u88C5\u8F7D\u4E0E\u8D44\u6E90\u5E94\u7528...",()=>sdk.rollbackResources(rollbackPayload)).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,targetSnapshotId,approveId})});if(args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
2500
2501
  `);return}printRollback(result2,appRoot,env);return}let payload={operation:subcommand==="apply"?"apply":"diff",tenant_id:tenantId,app_id:appId,env,requested_by:requestedBy,...subcommand==="apply"&&args.options["dry-run"]===!0?{dry_run:!0}:{},...baseSnapshotId?{base_snapshot_id:baseSnapshotId}:{},local_resources:localResources};if(subcommand==="diff"){let result2=await sdk.diffResources(payload).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,baseSnapshotId})});if(await syncLocalControlPlaneSummary({sdk,startDir:appRoot,tenantId,appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(result2,null,2)}
2501
2502
  `);return}printDiff(result2,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"});return}let result=await withPendingFeedback(args.options.json===!0,`\u6B63\u5728\u6267\u884C\u8D44\u6E90\u53D8\u66F4: ${appId}/${env}${baseSnapshotId?`\uFF0C\u57FA\u7EBF ${baseSnapshotId}`:"\uFF0C\u57FA\u7EBF\u5C06\u81EA\u52A8\u89E3\u6790"}`,"\u8D44\u6E90 Apply \u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u57FA\u7EBF\u89E3\u6790\u3001diff\u3001\u9501\u6821\u9A8C\u4E0E\u8D44\u6E90\u7F16\u6392...",()=>sdk.applyResources(payload)).catch(error=>{throw formatResourceCommandError({error,appId,env,subcommand,baseSnapshotId})});if(await syncLocalControlPlaneSummary({sdk,startDir:appRoot,tenantId,appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(result,null,2)}
2502
- `);return}printApply(result,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"})}async function resolveRequestedBy2(args){return(await createControlApiSdk({accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()).subject_id}function readStringOption5(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}async function collectEffectiveResources(appRoot,options){let dbResources=collectDbResources(appRoot),authResources=collectAuthResources(appRoot);if(authResources.length>0||!options?.sdk||!options.appId)return[...dbResources,...authResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path));let bridgedAuthResources=await collectBridgedAuthResources(options.sdk,options.appId);return[...dbResources,...authResources,...bridgedAuthResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectDbResources(appRoot){let directory=join16(appRoot,"resources","db","migrations"),sqlResources=existsSync20(directory)?readdirSync8(directory).filter(entry=>entry.endsWith(".sql")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),sql=readFileSync21(filePath,"utf8"),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"db",resource_key:`db/${basename7(entry,".sql")}`,manifest_path:manifestPath,checksum:checksum2(sql),spec:{kind:"migration",sql,statements_count:sql.split(";").map(part=>part.trim()).filter(Boolean).length}}}):[],dataFormDirectory=join16(appRoot,"resources","data-forms"),dataFormResources=existsSync20(dataFormDirectory)?readdirSync8(dataFormDirectory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(dataFormDirectory,entry),raw=YAML4.parse(readFileSync21(filePath,"utf8")),schema=normalizeDataFormResourceSchema(raw),manifestPath=toWorkspaceRelative(appRoot,filePath),artifact=buildDataFormMigrationArtifact({schema,sourceManifestPath:manifestPath});return{resource_type:"db",resource_key:artifact.resource_key,manifest_path:manifestPath,checksum:artifact.checksum,spec:{kind:"migration",sql:artifact.sql,statements_count:artifact.statements_count,source:artifact.source,table_name:artifact.table_name,source_manifest_path:artifact.source_manifest_path,source_of_truth:"data_form_schema",data_form_resource:schema}}}):[];return[...sqlResources,...dataFormResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectAuthResources(appRoot){let directory=join16(appRoot,"resources","auth","policies");return existsSync20(directory)?readdirSync8(directory).filter(entry=>entry.endsWith(".json")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),raw=readFileSync21(filePath,"utf8"),policy=normalizeAuthPolicy(JSON.parse(raw)),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,basename7(entry,".json")),manifest_path:manifestPath,checksum:checksum2(raw),spec:{kind:"policy",policy}}}):[]}async function collectBridgedAuthResources(sdk,appId){if((await sdk.getTenantAppEndUserAuthConfig(appId)).auth_enabled!==!0)return[];let policy=normalizeAuthPolicy(GENERATED_AUTH_POLICY),raw=JSON.stringify(policy,null,2);return[{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,"end-user-auth"),manifest_path:GENERATED_AUTH_MANIFEST_PATH,checksum:checksum2(raw),spec:{kind:"policy",policy}}]}function toWorkspaceRelative(appRoot,filePath){return relative5(appRoot,filePath).split("\\").join("/")}function checksum2(value){return createHash9("sha256").update(value).digest("hex")}function printDiff(result,appRoot,options){let lines=[`\u8D44\u6E90 Diff \u5DF2\u5B8C\u6210\uFF0C\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`\u672C\u5730\u8D44\u6E90: ${result.resources.local_count}\uFF0C\u8FDC\u7AEF\u8D44\u6E90: ${result.resources.remote_count}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`];if(result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative5(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`+(change.previous_checksum?` (${change.previous_checksum} -> ${change.checksum??"deleted"})`:""))}process.stdout.write(`${lines.join(`
2503
+ `);return}printApply(result,appRoot,{baseSnapshotSource:baseSnapshotId?"explicit":"auto"})}async function resolveRequestedBy2(args){return(await createControlApiSdk({accessToken:args.accessToken,tenantId:args.tenantId,capability:"auth",requestClass:"control"}).getWhoAmI()).subject_id}function readStringOption5(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}async function collectEffectiveResources(appRoot,options){let dbResources=collectDbResources(appRoot),authResources=collectAuthResources(appRoot);if(authResources.length>0||!options?.sdk||!options.appId)return[...dbResources,...authResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path));let bridgedAuthResources=await collectBridgedAuthResources(options.sdk,options.appId);return[...dbResources,...authResources,...bridgedAuthResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectDbResources(appRoot){let directory=join16(appRoot,"resources","db","migrations"),sqlResources=existsSync20(directory)?readdirSync8(directory).filter(entry=>entry.endsWith(".sql")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),sql=readFileSync21(filePath,"utf8"),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"db",resource_key:`db/${basename8(entry,".sql")}`,manifest_path:manifestPath,checksum:checksum2(sql),spec:{kind:"migration",sql,statements_count:sql.split(";").map(part=>part.trim()).filter(Boolean).length}}}):[],dataFormDirectory=join16(appRoot,"resources","data-forms"),dataFormResources=existsSync20(dataFormDirectory)?readdirSync8(dataFormDirectory).filter(entry=>entry.endsWith(".yaml")||entry.endsWith(".yml")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(dataFormDirectory,entry),raw=YAML4.parse(readFileSync21(filePath,"utf8")),schema=normalizeDataFormResourceSchema(raw),manifestPath=toWorkspaceRelative(appRoot,filePath),artifact=buildDataFormMigrationArtifact({schema,sourceManifestPath:manifestPath});return{resource_type:"db",resource_key:artifact.resource_key,manifest_path:manifestPath,checksum:artifact.checksum,spec:{kind:"migration",sql:artifact.sql,statements_count:artifact.statements_count,source:artifact.source,table_name:artifact.table_name,source_manifest_path:artifact.source_manifest_path,source_of_truth:"data_form_schema",data_form_resource:schema}}}):[];return[...sqlResources,...dataFormResources].sort((left,right)=>left.manifest_path.localeCompare(right.manifest_path))}function collectAuthResources(appRoot){let directory=join16(appRoot,"resources","auth","policies");return existsSync20(directory)?readdirSync8(directory).filter(entry=>entry.endsWith(".json")).sort((left,right)=>left.localeCompare(right)).map(entry=>{let filePath=join16(directory,entry),raw=readFileSync21(filePath,"utf8"),policy=normalizeAuthPolicy(JSON.parse(raw)),manifestPath=toWorkspaceRelative(appRoot,filePath);return{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,basename8(entry,".json")),manifest_path:manifestPath,checksum:checksum2(raw),spec:{kind:"policy",policy}}}):[]}async function collectBridgedAuthResources(sdk,appId){if((await sdk.getTenantAppEndUserAuthConfig(appId)).auth_enabled!==!0)return[];let policy=normalizeAuthPolicy(GENERATED_AUTH_POLICY),raw=JSON.stringify(policy,null,2);return[{resource_type:"auth",resource_key:deriveAuthResourceKey(policy,"end-user-auth"),manifest_path:GENERATED_AUTH_MANIFEST_PATH,checksum:checksum2(raw),spec:{kind:"policy",policy}}]}function toWorkspaceRelative(appRoot,filePath){return relative5(appRoot,filePath).split("\\").join("/")}function checksum2(value){return createHash9("sha256").update(value).digest("hex")}function printDiff(result,appRoot,options){let lines=[`\u8D44\u6E90 Diff \u5DF2\u5B8C\u6210\uFF0C\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`\u672C\u5730\u8D44\u6E90: ${result.resources.local_count}\uFF0C\u8FDC\u7AEF\u8D44\u6E90: ${result.resources.remote_count}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`];if(result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative5(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`+(change.previous_checksum?` (${change.previous_checksum} -> ${change.checksum??"deleted"})`:""))}process.stdout.write(`${lines.join(`
2503
2504
  `)}
2504
2505
  `)}function printApply(result,appRoot,options){let lines=[`\u8D44\u6E90 Apply ${result.status==="failed"?"\u5931\u8D25":"\u5B8C\u6210"}${result.dry_run?"\uFF08dry-run\uFF09":""}`,`\u57FA\u7EBF\u5FEB\u7167: ${result.base_snapshot_id}`,`\u57FA\u7EBF\u6765\u6E90: ${options.baseSnapshotSource==="auto"?"\u81EA\u52A8\u89E3\u6790":"\u624B\u52A8\u6307\u5B9A"}`,`status: ${result.status}`,`\u65B0\u589E ${result.summary.added}\uFF0C\u4FEE\u6539 ${result.summary.modified}\uFF0C\u5220\u9664 ${result.summary.deleted}`,`\u6267\u884C\u8D44\u6E90: ${result.summary.applied}\uFF0CDB ${result.summary.db_resources}\uFF0CAuth ${result.summary.auth_resources}`];if(result.result_snapshot_id&&lines.push(`\u7ED3\u679C\u5FEB\u7167: ${result.result_snapshot_id}`),result.db_skill&&lines.push(`DB Skill: ${result.db_skill.binding_key} -> ${result.db_skill.tenant_database_id} (schema=${result.db_skill.schema_name})`),result.auth_skill&&lines.push(`Auth Skill: ${result.auth_skill.binding_key} -> ${result.auth_skill.skill_instance_id}`),result.errors&&result.errors.length>0&&lines.push(`errors: ${result.errors.join(" | ")}`),result.status==="succeeded"&&result.result_snapshot_id&&lines.push(`\u4E0B\u4E00\u6B21 diff/apply \u53EF\u76F4\u63A5\u4F7F\u7528: --base-snapshot ${result.result_snapshot_id}`),result.status==="dry_run"&&lines.push("\u4E0B\u4E00\u6B65: \u786E\u8BA4\u7ED3\u679C\u65E0\u8BEF\u540E\uFF0C\u53BB\u6389 `--dry-run` \u518D\u6267\u884C\u4E00\u6B21 apply\u3002"),result.changes.length>0){lines.push("");for(let change of result.changes)lines.push(`- ${formatChangePrefix(change.change_type)} ${relative5(appRoot,join16(appRoot,change.manifest_path)).split("\\").join("/")}`)}process.stdout.write(`${lines.join(`
2505
2506
  `)}
@@ -2552,13 +2553,13 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2552
2553
  `)+`
2553
2554
  `);return}process.stdout.write(["platform data-form",""," platform data-form validate [--resource <resource-key>] [--json]"," platform data-form compile [--resource <resource-key>] [--json]"," platform data-form inspect [--resource <resource-key>] [--json]"," platform data-form apply [--env preview|prod] [--dry-run] [--json]"," platform data-form records --resource <resource-key> [--record <record-id>] [--env preview|prod] [--page <n>] [--page-size <n>] [--owner-scope me|all] [--q <keyword>] [--json]",""," \u672C\u5730\u6821\u9A8C\u3001\u67E5\u770B\u751F\u6210 migration\u3001\u901A\u8FC7\u73B0\u6709\u8D44\u6E90\u4E3B\u94FE\u5E94\u7528 `resources/data-forms/*.yaml`\uFF0C\u5E76\u901A\u8FC7 runtime API \u67E5\u8BE2\u8BB0\u5F55\u3002"].join(`
2554
2555
  `)+`
2555
- `)}import{spawn as spawn2}from"node:child_process";import net from"node:net";import WebSocket from"ws";async function prepareLocalDevDatabaseBindings(runtimeBindings,options={}){let databaseUrl=runtimeBindings.DATABASE_URL?.trim();if(!databaseUrl)return{bindings:runtimeBindings,warnings:[],cleanup:null};let proxyTransport=runtimeBindings.DATABASE_PROXY_TRANSPORT?.trim(),proxyWsUrl=runtimeBindings.DATABASE_PROXY_WS_URL?.trim();if(proxyTransport==="ws_tunnel"&&proxyWsUrl)return await prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,proxyWsUrl);if(!shouldTunnelDatabaseUrl(databaseUrl))return{bindings:runtimeBindings,warnings:[],cleanup:null};if(!((process.env.PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL||"").trim()==="1"))throw new Error(["dev_runtime_binding_not_available","\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\uFF0C`platform dev --remote-bindings` \u5DF2\u62D2\u7EDD\u4F7F\u7528\u79C1\u7F51\u6570\u636E\u5E93\u5730\u5740\u3002","\u8BF7\u5148\u6539\u7528 `platform preview` \u9A8C\u8BC1\u771F\u5B9E\u5199\u5E93\u94FE\u8DEF\uFF1B\u5982\u4E3A\u5E73\u53F0\u7BA1\u7406\u5458\u5185\u90E8\u6392\u969C\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL=1` \u540E\u91CD\u8BD5\u3002"].join(" "));let sshHost=(options.sshHost||process.env.TEST_ENV_SSH_HOST||"").trim();if(!sshHost)throw new Error("\u5F53\u524D\u5DF2\u663E\u5F0F\u542F\u7528\u5185\u90E8 SSH \u515C\u5E95\uFF0C\u4F46\u672A\u914D\u7F6E TEST_ENV_SSH_HOST\uFF0C\u65E0\u6CD5\u5EFA\u7ACB\u672C\u5730 SSH \u96A7\u9053\u3002");let parsed=new URL(databaseUrl),remoteHost=parsed.hostname,remotePort=Number(parsed.port||"5432"),localPort=await allocateLocalPort(),child=spawn2("ssh",["-o","ExitOnForwardFailure=yes","-o","BatchMode=yes","-o","ConnectTimeout=8","-N","-L",`127.0.0.1:${localPort}:${remoteHost}:${remotePort}`,sshHost],{stdio:"ignore"});try{await waitForTunnelReady(localPort,child)}catch(error){throw child.kill("SIGTERM"),await waitForChildExit(child),error}let localUrl=rewriteDatabaseUrlForLocalPort(databaseUrl,localPort);return{bindings:{...runtimeBindings,DATABASE_URL:localUrl},warnings:[`\u68C0\u6D4B\u5230\u79C1\u7F51 DB host\uFF08${remoteHost}:${remotePort}\uFF09\uFF0C\u5DF2\u901A\u8FC7 SSH \u96A7\u9053\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{child.kill("SIGTERM"),await waitForChildExit(child)}}}async function prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,wsUrl){let localPort=await allocateLocalPort(),sockets=new Set,bridges=new Set,server=net.createServer(clientSocket=>{clientSocket.setNoDelay(!0),sockets.add(clientSocket);let bridge=new WebSocket(wsUrl);bridges.add(bridge);let closeBoth=()=>{sockets.delete(clientSocket),bridges.delete(bridge),clientSocket.destroyed||clientSocket.destroy(),(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close()};bridge.on("open",()=>{clientSocket.on("data",chunk=>{bridge.readyState===WebSocket.OPEN&&bridge.send(chunk)}),clientSocket.resume()}),bridge.on("message",payload=>{clientSocket.write(Buffer.isBuffer(payload)?payload:Buffer.from(payload))}),bridge.on("close",closeBoth),bridge.on("error",closeBoth),clientSocket.on("close",closeBoth),clientSocket.on("error",closeBoth),clientSocket.pause()});return await listenLocalServer(server,localPort),{bindings:{...runtimeBindings,DATABASE_URL:rewriteDatabaseUrlForLocalPort(databaseUrl,localPort)},warnings:[`\u68C0\u6D4B\u5230\u6B63\u5F0F dev proxy WebSocket \u6570\u636E\u9762\uFF0C\u5DF2\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{for(let socket of sockets)socket.destroyed||socket.destroy();for(let bridge of bridges)(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close();await closeServer(server)}}}function shouldTunnelDatabaseUrl(databaseUrl){try{let url=new URL(databaseUrl);return shouldTunnelHostname(url.hostname)}catch{return!1}}function rewriteDatabaseUrlForLocalPort(databaseUrl,localPort){let url=new URL(databaseUrl);return url.hostname="127.0.0.1",url.port=String(localPort),url.toString()}function shouldTunnelHostname(hostname){let value=hostname.trim().toLowerCase();return!value||["localhost","127.0.0.1"].includes(value)?!1:!!(["host.docker.internal","host.containers.internal"].includes(value)||isPrivateIpv4(value))}function isPrivateIpv4(hostname){let parts=hostname.split(".");if(parts.length!==4||parts.some(part=>!/^\d+$/.test(part)))return!1;let[a,b]=parts.map(part=>Number(part));return a===10||a===192&&b===168||a===172&&b>=16&&b<=31}async function allocateLocalPort(){return await new Promise((resolve17,reject)=>{let server=net.createServer();server.once("error",reject),server.listen(0,"127.0.0.1",()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u5206\u914D\u672C\u5730\u7AEF\u53E3\u3002")));return}let port=address.port;server.close(error=>{if(error){reject(error);return}resolve17(port)})})})}async function listenLocalServer(server,port){await new Promise((resolve17,reject)=>{server.once("error",reject),server.listen(port,"127.0.0.1",()=>{server.off("error",reject),resolve17()})})}async function closeServer(server){await new Promise(resolve17=>{server.close(()=>resolve17())})}async function waitForTunnelReady(localPort,child){let startedAt=Date.now();for(;Date.now()-startedAt<1e4;){if(child.exitCode!==null)throw new Error(`SSH \u96A7\u9053\u8FDB\u7A0B\u63D0\u524D\u9000\u51FA\uFF08code=${child.exitCode}\uFF09\u3002`);if(await canConnect("127.0.0.1",localPort))return;await sleep3(200)}throw new Error(`SSH \u96A7\u9053\u672A\u5728\u9884\u671F\u65F6\u95F4\u5185\u5C31\u7EEA\uFF1A127.0.0.1:${localPort}`)}async function canConnect(host,port){return await new Promise(resolve17=>{let socket=net.createConnection({host,port}),done=value=>{socket.removeAllListeners(),socket.destroyed||socket.destroy(),resolve17(value)};socket.once("connect",()=>done(!0)),socket.once("error",()=>done(!1)),socket.setTimeout(500,()=>done(!1))})}async function waitForChildExit(child){await new Promise(resolve17=>{if(child.exitCode!==null){resolve17();return}child.once("exit",()=>resolve17()),setTimeout(()=>resolve17(),1e3)})}function sleep3(ms){return new Promise(resolve17=>{setTimeout(resolve17,ms)})}import{spawn as spawn3}from"node:child_process";import{watch}from"node:fs";import process4 from"node:process";var IGNORED_PATH_SEGMENTS=new Set(["node_modules",".git",".platform","dist",".next"]),RESTART_DEBOUNCE_MS=250;async function runDevSupervisor(options){let platform=options.platform??process4.platform,spawnImpl=options.spawnImpl??spawn3,terminateProcessTreeImpl=options.terminateProcessTreeImpl??terminateProcessTree,signalSource=options.signalSource??process4,restartDebounceMs=options.restartDebounceMs??RESTART_DEBOUNCE_MS,expectedStops=new WeakSet,state={child:null,watcher:null,restartTimer:null,stopping:!1,restarting:!1,restartPending:!1,cleanupPromise:null},runPromise=new Promise((resolve17,reject)=>{state.resolveRun=resolve17,state.rejectRun=reject}),stopChild=async()=>{let child=state.child;if(!child)return;expectedStops.add(child);let exitPromise=waitForChildExit2(child);if(typeof child.pid=="number"){try{await terminateProcessTreeImpl(child.pid,{platform})}catch(error){if(child.exitCode===null&&child.signalCode===null)throw error}await exitPromise}else child.kill("SIGTERM");state.child===child&&(state.child=null)},cleanup=()=>(state.cleanupPromise||(state.stopping=!0,state.restartTimer&&(clearTimeout(state.restartTimer),state.restartTimer=null),state.watcher?.close(),state.watcher=null,state.cleanupPromise=stopChild()),state.cleanupPromise),handleSignal=signal=>{cleanup().then(()=>{let exitCode=signal==="SIGINT"?130:143;(options.setExitCode??(code2=>{process4.exitCode=code2}))(exitCode),state.resolveRun?.()}).catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},handleSigint=()=>handleSignal("SIGINT"),handleSigterm=()=>handleSignal("SIGTERM");signalSource.once("SIGINT",handleSigint),signalSource.once("SIGTERM",handleSigterm);let startChild=()=>{let child=spawnImpl(options.command,{cwd:options.cwd,env:options.env,stdio:"inherit",shell:!0,detached:platform!=="win32"});state.child=child,child.on("exit",(code2,signal)=>{if(state.child===child&&(state.child=null),!(expectedStops.has(child)||state.stopping||state.restarting)){if(signal){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u9000\u51FA\uFF0C\u72B6\u6001\u7801 ${code2}`));return}state.resolveRun?.()}}),child.on("error",error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},performPendingRestarts=async()=>{if(!(state.restarting||state.stopping)){state.restarting=!0;try{for(;state.restartPending&&!state.stopping;)state.restartPending=!1,await stopChild(),state.stopping||startChild()}finally{state.restarting=!1}}},scheduleRestart=changedPath=>{let normalized=typeof changedPath=="string"?changedPath:changedPath?.toString("utf8");normalized&&normalized.split(/[\\/]+/u).filter(Boolean).some(segment=>IGNORED_PATH_SEGMENTS.has(segment))||(state.restartTimer&&clearTimeout(state.restartTimer),state.restartTimer=setTimeout(()=>{state.restartTimer=null,state.restartPending=!0,options.onWatching?.(`\u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4${normalized?`\uFF1A${normalized}`:""}\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B...`),performPendingRestarts().catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},restartDebounceMs))};if(options.watchRoot)try{state.watcher=watch(options.watchRoot,{recursive:!0},(_eventType,filename)=>{scheduleRestart(filename)}),options.onWatching?.("\u5DF2\u542F\u7528\u6587\u4EF6\u76D1\u542C\uFF1B\u6E90\u7801\u53D8\u66F4\u540E\u5C06\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002")}catch{options.onWatching?.("\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u9012\u5F52\u6587\u4EF6\u76D1\u542C\uFF1Bdev \u5B50\u8FDB\u7A0B\u5C06\u4FDD\u6301\u5355\u6B21\u542F\u52A8\u3002")}startChild();try{await runPromise}finally{try{await cleanup()}finally{signalSource.removeListener("SIGINT",handleSigint),signalSource.removeListener("SIGTERM",handleSigterm)}}}function waitForChildExit2(child){return child.exitCode!==null||child.signalCode!==null?Promise.resolve():new Promise(resolve17=>{child.once("exit",()=>resolve17())})}import{chmodSync as chmodSync2,existsSync as existsSync23,mkdirSync as mkdirSync11,readFileSync as readFileSync24,rmSync as rmSync6,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname13,resolve as resolve15}from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import YAML6 from"yaml";var MANAGED_ENV_KEYS=["CONTROL_API_BASE_URL","PUBLIC_API_BASE_URL","RUNTIME_API_BASE_URL","OIDC_ISSUER","OIDC_AUDIENCE","LOGTO_CLI_APP_ID","LOGTO_CLI_REDIRECT_URI","LOGTO_TENANT_APP_ID","LOGTO_TENANT_REDIRECT_URI","TEST_ENV_PROFILE"];function getEnvironmentProfilePath(){return resolveCliStateFilePath("environment.json")}function loadStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();return existsSync23(envProfilePath)?JSON.parse(readFileSync24(envProfilePath,"utf8")):null}function persistStoredEnvironmentProfile(input){withCliStateFileWriteFallback({fileName:"environment.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync11(stateDir,{recursive:!0}),writeFileSync12(filePath,`${JSON.stringify({active_profile:input.active_profile,values:normalizeProfileValues(input.values),updated_at:new Date().toISOString()},null,2)}
2556
- `,"utf8"),chmodSync2(filePath,384)}})}function clearStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();existsSync23(envProfilePath)&&rmSync6(envProfilePath)}function applyStoredEnvironmentProfile(env=process.env){let stored=loadStoredEnvironmentProfile();if(!stored)return null;for(let key of MANAGED_ENV_KEYS){let current=env[key];if(typeof current=="string"&&current.trim().length>0)continue;let nextValue=stored.values[key];typeof nextValue=="string"&&nextValue.trim().length>0&&(env[key]=nextValue)}return stored}function listKnownEnvironmentProfiles(startDir=getInvocationCwd()){return loadEnvironmentProfileRegistry(startDir).map(profile=>({name:profile.name,values:resolveProfileValues(profile)}))}function resolveKnownEnvironmentProfile(profileName,startDir=getInvocationCwd()){let matched=loadEnvironmentProfileRegistry(startDir).find(profile=>profile.name===profileName);return matched?{name:matched.name,values:resolveProfileValues(matched)}:null}function normalizeProfileValues(values){let normalized={};for(let key of MANAGED_ENV_KEYS){let value=values[key];if(typeof value!="string")continue;let trimmed=value.trim();trimmed.length>0&&(normalized[key]=trimmed)}return normalized}function resolveProfileValues(profile){let values={},scheme=profile.topology?.scheme?.trim(),controlHost=profile.hosts?.control?.trim(),publicHost=profile.hosts?.public?.trim(),runtimeHost=profile.hosts?.runtime?.trim(),authHost=profile.hosts?.auth?.trim(),tenantHost=profile.hosts?.tenant?.trim(),issuer=profile.auth?.issuer?.trim(),audience=profile.auth?.audience?.trim();return scheme&&controlHost&&(values.CONTROL_API_BASE_URL=`${scheme}://${controlHost}`),scheme&&publicHost&&(values.PUBLIC_API_BASE_URL=`${scheme}://${publicHost}`),scheme&&runtimeHost&&(values.RUNTIME_API_BASE_URL=`${scheme}://${runtimeHost}`),issuer&&(values.OIDC_ISSUER=issuer),audience&&(values.OIDC_AUDIENCE=audience),tenantHost&&scheme&&(values.LOGTO_TENANT_REDIRECT_URI=`${scheme}://${tenantHost}/callback`),authHost&&profile.name==="local"?values.LOGTO_CLI_REDIRECT_URI="http://localhost:7300/callback":authHost&&(values.LOGTO_CLI_REDIRECT_URI="http://127.0.0.1:7300/callback"),values.TEST_ENV_PROFILE=profile.name,values}function loadEnvironmentProfileRegistry(startDir){let registryPath=resolveEnvironmentRegistryPath(startDir);if(!existsSync23(registryPath))return[];let parsed=YAML6.parse(readFileSync24(registryPath,"utf8"));return Array.isArray(parsed?.profiles)?parsed.profiles:[]}function resolveEnvironmentRegistryPath(startDir){let invocationWorkspaceRoot=findWorkspaceRoot(startDir),invocationCandidate=resolve15(invocationWorkspaceRoot,"deploy","registry","environment-profiles.yaml");if(existsSync23(invocationCandidate))return invocationCandidate;let cliModuleRoot=resolve15(dirname13(fileURLToPath5(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve15(cliWorkspaceRoot,"deploy","registry","environment-profiles.yaml")}async function runLogsCommand(args){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption8(args,"tenant")??binding?.tenant_id,appId=readStringOption8(args,"app")??binding?.app_id,env=readStringOption8(args,"env")??binding?.env??"preview",releaseId=readStringOption8(args,"release"),limit=readNumberOption3(args,"limit")??100,follow=args.options.follow===!0,from=readStringOption8(args,"from")??new Date(Date.now()-900*1e3).toISOString(),to=readStringOption8(args,"to")??new Date().toISOString();if(!tenantId||!appId)throw new Error("`platform logs` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"}),payload={tenant_id:tenantId,app_id:appId,env,...releaseId?{release_id:releaseId}:{},from,to,limit,follow};if(!follow){let result=await sdk.queryLogs(payload);printLogs(result,args.options.json===!0);return}let seen=new Set,currentFrom=from;for(;;){let result=await sdk.queryLogs({...payload,from:currentFrom,to:new Date().toISOString(),follow:!0});if(args.options.json===!0)process.stdout.write(`${JSON.stringify(result,null,2)}
2556
+ `)}import{spawn as spawn2}from"node:child_process";import net from"node:net";import WebSocket from"ws";async function prepareLocalDevDatabaseBindings(runtimeBindings,options={}){let databaseUrl=runtimeBindings.DATABASE_URL?.trim();if(!databaseUrl)return{bindings:runtimeBindings,warnings:[],cleanup:null};let proxyTransport=runtimeBindings.DATABASE_PROXY_TRANSPORT?.trim(),proxyWsUrl=runtimeBindings.DATABASE_PROXY_WS_URL?.trim();if(proxyTransport==="ws_tunnel"&&proxyWsUrl)return await prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,proxyWsUrl);if(!shouldTunnelDatabaseUrl(databaseUrl))return{bindings:runtimeBindings,warnings:[],cleanup:null};if(!((process.env.PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL||"").trim()==="1"))throw new Error(["dev_runtime_binding_not_available","\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\uFF0C`platform dev --remote-bindings` \u5DF2\u62D2\u7EDD\u4F7F\u7528\u79C1\u7F51\u6570\u636E\u5E93\u5730\u5740\u3002","\u8BF7\u5148\u6539\u7528 `platform preview` \u9A8C\u8BC1\u771F\u5B9E\u5199\u5E93\u94FE\u8DEF\uFF1B\u5982\u4E3A\u5E73\u53F0\u7BA1\u7406\u5458\u5185\u90E8\u6392\u969C\uFF0C\u53EF\u663E\u5F0F\u8BBE\u7F6E `PLATFORM_INTERNAL_ENABLE_DB_SSH_TUNNEL=1` \u540E\u91CD\u8BD5\u3002"].join(" "));let sshHost=(options.sshHost||process.env.TEST_ENV_SSH_HOST||"").trim();if(!sshHost)throw new Error("\u5F53\u524D\u5DF2\u663E\u5F0F\u542F\u7528\u5185\u90E8 SSH \u515C\u5E95\uFF0C\u4F46\u672A\u914D\u7F6E TEST_ENV_SSH_HOST\uFF0C\u65E0\u6CD5\u5EFA\u7ACB\u672C\u5730 SSH \u96A7\u9053\u3002");let parsed=new URL(databaseUrl),remoteHost=parsed.hostname,remotePort=Number(parsed.port||"5432"),localPort=await allocateLocalPort(),child=spawn2("ssh",["-o","ExitOnForwardFailure=yes","-o","BatchMode=yes","-o","ConnectTimeout=8","-N","-L",`127.0.0.1:${localPort}:${remoteHost}:${remotePort}`,sshHost],{stdio:"ignore"});try{await waitForTunnelReady(localPort,child)}catch(error){throw child.kill("SIGTERM"),await waitForChildExit(child),error}let localUrl=rewriteDatabaseUrlForLocalPort(databaseUrl,localPort);return{bindings:{...runtimeBindings,DATABASE_URL:localUrl},warnings:[`\u68C0\u6D4B\u5230\u79C1\u7F51 DB host\uFF08${remoteHost}:${remotePort}\uFF09\uFF0C\u5DF2\u901A\u8FC7 SSH \u96A7\u9053\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{child.kill("SIGTERM"),await waitForChildExit(child)}}}async function prepareWebSocketDatabaseTunnel(runtimeBindings,databaseUrl,wsUrl){let localPort=await allocateLocalPort(),sockets=new Set,bridges=new Set,server=net.createServer(clientSocket=>{clientSocket.setNoDelay(!0),sockets.add(clientSocket);let bridge=new WebSocket(wsUrl);bridges.add(bridge);let closeBoth=()=>{sockets.delete(clientSocket),bridges.delete(bridge),clientSocket.destroyed||clientSocket.destroy(),(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close()};bridge.on("open",()=>{clientSocket.on("data",chunk=>{bridge.readyState===WebSocket.OPEN&&bridge.send(chunk)}),clientSocket.resume()}),bridge.on("message",payload=>{clientSocket.write(Buffer.isBuffer(payload)?payload:Buffer.from(payload))}),bridge.on("close",closeBoth),bridge.on("error",closeBoth),clientSocket.on("close",closeBoth),clientSocket.on("error",closeBoth),clientSocket.pause()});return await listenLocalServer(server,localPort),{bindings:{...runtimeBindings,DATABASE_URL:rewriteDatabaseUrlForLocalPort(databaseUrl,localPort)},warnings:[`\u68C0\u6D4B\u5230\u6B63\u5F0F dev proxy WebSocket \u6570\u636E\u9762\uFF0C\u5DF2\u6620\u5C04\u5230\u672C\u5730 127.0.0.1:${localPort}\u3002`],cleanup:async()=>{for(let socket of sockets)socket.destroyed||socket.destroy();for(let bridge of bridges)(bridge.readyState===WebSocket.OPEN||bridge.readyState===WebSocket.CONNECTING)&&bridge.close();await closeServer(server)}}}function shouldTunnelDatabaseUrl(databaseUrl){try{let url=new URL(databaseUrl);return shouldTunnelHostname(url.hostname)}catch{return!1}}function rewriteDatabaseUrlForLocalPort(databaseUrl,localPort){let url=new URL(databaseUrl);return url.hostname="127.0.0.1",url.port=String(localPort),url.toString()}function shouldTunnelHostname(hostname){let value=hostname.trim().toLowerCase();return!value||["localhost","127.0.0.1"].includes(value)?!1:!!(["host.docker.internal","host.containers.internal"].includes(value)||isPrivateIpv4(value))}function isPrivateIpv4(hostname){let parts=hostname.split(".");if(parts.length!==4||parts.some(part=>!/^\d+$/.test(part)))return!1;let[a,b]=parts.map(part=>Number(part));return a===10||a===192&&b===168||a===172&&b>=16&&b<=31}async function allocateLocalPort(){return await new Promise((resolve19,reject)=>{let server=net.createServer();server.once("error",reject),server.listen(0,"127.0.0.1",()=>{let address=server.address();if(!address||typeof address=="string"){server.close(()=>reject(new Error("\u65E0\u6CD5\u5206\u914D\u672C\u5730\u7AEF\u53E3\u3002")));return}let port=address.port;server.close(error=>{if(error){reject(error);return}resolve19(port)})})})}async function listenLocalServer(server,port){await new Promise((resolve19,reject)=>{server.once("error",reject),server.listen(port,"127.0.0.1",()=>{server.off("error",reject),resolve19()})})}async function closeServer(server){await new Promise(resolve19=>{server.close(()=>resolve19())})}async function waitForTunnelReady(localPort,child){let startedAt=Date.now();for(;Date.now()-startedAt<1e4;){if(child.exitCode!==null)throw new Error(`SSH \u96A7\u9053\u8FDB\u7A0B\u63D0\u524D\u9000\u51FA\uFF08code=${child.exitCode}\uFF09\u3002`);if(await canConnect("127.0.0.1",localPort))return;await sleep3(200)}throw new Error(`SSH \u96A7\u9053\u672A\u5728\u9884\u671F\u65F6\u95F4\u5185\u5C31\u7EEA\uFF1A127.0.0.1:${localPort}`)}async function canConnect(host,port){return await new Promise(resolve19=>{let socket=net.createConnection({host,port}),done=value=>{socket.removeAllListeners(),socket.destroyed||socket.destroy(),resolve19(value)};socket.once("connect",()=>done(!0)),socket.once("error",()=>done(!1)),socket.setTimeout(500,()=>done(!1))})}async function waitForChildExit(child){await new Promise(resolve19=>{if(child.exitCode!==null){resolve19();return}child.once("exit",()=>resolve19()),setTimeout(()=>resolve19(),1e3)})}function sleep3(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}import{spawn as spawn3}from"node:child_process";import{watch}from"node:fs";import process4 from"node:process";var IGNORED_PATH_SEGMENTS=new Set(["node_modules",".git",".platform","dist",".next"]),RESTART_DEBOUNCE_MS=250;async function runDevSupervisor(options){let platform=options.platform??process4.platform,spawnImpl=options.spawnImpl??spawn3,terminateProcessTreeImpl=options.terminateProcessTreeImpl??terminateProcessTree,signalSource=options.signalSource??process4,restartDebounceMs=options.restartDebounceMs??RESTART_DEBOUNCE_MS,expectedStops=new WeakSet,state={child:null,watcher:null,restartTimer:null,stopping:!1,restarting:!1,restartPending:!1,cleanupPromise:null},runPromise=new Promise((resolve19,reject)=>{state.resolveRun=resolve19,state.rejectRun=reject}),stopChild=async()=>{let child=state.child;if(!child)return;expectedStops.add(child);let exitPromise=waitForChildExit2(child);if(typeof child.pid=="number"){try{await terminateProcessTreeImpl(child.pid,{platform})}catch(error){if(child.exitCode===null&&child.signalCode===null)throw error}await exitPromise}else child.kill("SIGTERM");state.child===child&&(state.child=null)},cleanup=()=>(state.cleanupPromise||(state.stopping=!0,state.restartTimer&&(clearTimeout(state.restartTimer),state.restartTimer=null),state.watcher?.close(),state.watcher=null,state.cleanupPromise=stopChild()),state.cleanupPromise),handleSignal=signal=>{cleanup().then(()=>{let exitCode=signal==="SIGINT"?130:143;(options.setExitCode??(code2=>{process4.exitCode=code2}))(exitCode),state.resolveRun?.()}).catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},handleSigint=()=>handleSignal("SIGINT"),handleSigterm=()=>handleSignal("SIGTERM");signalSource.once("SIGINT",handleSigint),signalSource.once("SIGTERM",handleSigterm);let startChild=()=>{let child=spawnImpl(options.command,{cwd:options.cwd,env:options.env,stdio:"inherit",shell:!0,detached:platform!=="win32"});state.child=child,child.on("exit",(code2,signal)=>{if(state.child===child&&(state.child=null),!(expectedStops.has(child)||state.stopping||state.restarting)){if(signal){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){state.rejectRun?.(new Error(`dev \u547D\u4EE4\u9000\u51FA\uFF0C\u72B6\u6001\u7801 ${code2}`));return}state.resolveRun?.()}}),child.on("error",error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},performPendingRestarts=async()=>{if(!(state.restarting||state.stopping)){state.restarting=!0;try{for(;state.restartPending&&!state.stopping;)state.restartPending=!1,await stopChild(),state.stopping||startChild()}finally{state.restarting=!1}}},scheduleRestart=changedPath=>{let normalized=typeof changedPath=="string"?changedPath:changedPath?.toString("utf8");normalized&&normalized.split(/[\\/]+/u).filter(Boolean).some(segment=>IGNORED_PATH_SEGMENTS.has(segment))||(state.restartTimer&&clearTimeout(state.restartTimer),state.restartTimer=setTimeout(()=>{state.restartTimer=null,state.restartPending=!0,options.onWatching?.(`\u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4${normalized?`\uFF1A${normalized}`:""}\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B...`),performPendingRestarts().catch(error=>{state.rejectRun?.(error instanceof Error?error:new Error(String(error)))})},restartDebounceMs))};if(options.watchRoot)try{state.watcher=watch(options.watchRoot,{recursive:!0},(_eventType,filename)=>{scheduleRestart(filename)}),options.onWatching?.("\u5DF2\u542F\u7528\u6587\u4EF6\u76D1\u542C\uFF1B\u6E90\u7801\u53D8\u66F4\u540E\u5C06\u81EA\u52A8\u91CD\u542F dev \u5B50\u8FDB\u7A0B\u3002")}catch{options.onWatching?.("\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u9012\u5F52\u6587\u4EF6\u76D1\u542C\uFF1Bdev \u5B50\u8FDB\u7A0B\u5C06\u4FDD\u6301\u5355\u6B21\u542F\u52A8\u3002")}startChild();try{await runPromise}finally{try{await cleanup()}finally{signalSource.removeListener("SIGINT",handleSigint),signalSource.removeListener("SIGTERM",handleSigterm)}}}function waitForChildExit2(child){return child.exitCode!==null||child.signalCode!==null?Promise.resolve():new Promise(resolve19=>{child.once("exit",()=>resolve19())})}import{chmodSync as chmodSync2,existsSync as existsSync23,mkdirSync as mkdirSync11,readFileSync as readFileSync24,rmSync as rmSync6,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname13,resolve as resolve16}from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import YAML6 from"yaml";var MANAGED_ENV_KEYS=["CONTROL_API_BASE_URL","PUBLIC_API_BASE_URL","RUNTIME_API_BASE_URL","OIDC_ISSUER","OIDC_AUDIENCE","LOGTO_CLI_APP_ID","LOGTO_CLI_REDIRECT_URI","LOGTO_TENANT_APP_ID","LOGTO_TENANT_REDIRECT_URI","TEST_ENV_PROFILE"];function getEnvironmentProfilePath(){return resolveCliStateFilePath("environment.json")}function loadStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();return existsSync23(envProfilePath)?JSON.parse(readFileSync24(envProfilePath,"utf8")):null}function persistStoredEnvironmentProfile(input){withCliStateFileWriteFallback({fileName:"environment.json",operation:"\u5199\u5165",write:({filePath,stateDir})=>{mkdirSync11(stateDir,{recursive:!0}),writeFileSync12(filePath,`${JSON.stringify({active_profile:input.active_profile,values:normalizeProfileValues(input.values),updated_at:new Date().toISOString()},null,2)}
2557
+ `,"utf8"),chmodSync2(filePath,384)}})}function clearStoredEnvironmentProfile(){let envProfilePath=getEnvironmentProfilePath();existsSync23(envProfilePath)&&rmSync6(envProfilePath)}function applyStoredEnvironmentProfile(env=process.env){let stored=loadStoredEnvironmentProfile();if(!stored)return null;for(let key of MANAGED_ENV_KEYS){let current=env[key];if(typeof current=="string"&&current.trim().length>0)continue;let nextValue=stored.values[key];typeof nextValue=="string"&&nextValue.trim().length>0&&(env[key]=nextValue)}return stored}function listKnownEnvironmentProfiles(startDir=getInvocationCwd()){return loadEnvironmentProfileRegistry(startDir).map(profile=>({name:profile.name,values:resolveProfileValues(profile)}))}function resolveKnownEnvironmentProfile(profileName,startDir=getInvocationCwd()){let matched=loadEnvironmentProfileRegistry(startDir).find(profile=>profile.name===profileName);return matched?{name:matched.name,values:resolveProfileValues(matched)}:null}function normalizeProfileValues(values){let normalized={};for(let key of MANAGED_ENV_KEYS){let value=values[key];if(typeof value!="string")continue;let trimmed=value.trim();trimmed.length>0&&(normalized[key]=trimmed)}return normalized}function resolveProfileValues(profile){let values={},scheme=profile.topology?.scheme?.trim(),controlHost=profile.hosts?.control?.trim(),publicHost=profile.hosts?.public?.trim(),runtimeHost=profile.hosts?.runtime?.trim(),authHost=profile.hosts?.auth?.trim(),tenantHost=profile.hosts?.tenant?.trim(),issuer=profile.auth?.issuer?.trim(),audience=profile.auth?.audience?.trim();return scheme&&controlHost&&(values.CONTROL_API_BASE_URL=`${scheme}://${controlHost}`),scheme&&publicHost&&(values.PUBLIC_API_BASE_URL=`${scheme}://${publicHost}`),scheme&&runtimeHost&&(values.RUNTIME_API_BASE_URL=`${scheme}://${runtimeHost}`),issuer&&(values.OIDC_ISSUER=issuer),audience&&(values.OIDC_AUDIENCE=audience),tenantHost&&scheme&&(values.LOGTO_TENANT_REDIRECT_URI=`${scheme}://${tenantHost}/callback`),authHost&&profile.name==="local"?values.LOGTO_CLI_REDIRECT_URI="http://localhost:7300/callback":authHost&&(values.LOGTO_CLI_REDIRECT_URI="http://127.0.0.1:7300/callback"),values.TEST_ENV_PROFILE=profile.name,values}function loadEnvironmentProfileRegistry(startDir){let registryPath=resolveEnvironmentRegistryPath(startDir);if(!existsSync23(registryPath))return[];let parsed=YAML6.parse(readFileSync24(registryPath,"utf8"));return Array.isArray(parsed?.profiles)?parsed.profiles:[]}function resolveEnvironmentRegistryPath(startDir){let invocationWorkspaceRoot=findWorkspaceRoot(startDir),invocationCandidate=resolve16(invocationWorkspaceRoot,"deploy","registry","environment-profiles.yaml");if(existsSync23(invocationCandidate))return invocationCandidate;let cliModuleRoot=resolve16(dirname13(fileURLToPath5(import.meta.url)),".."),cliWorkspaceRoot=findWorkspaceRoot(cliModuleRoot);return resolve16(cliWorkspaceRoot,"deploy","registry","environment-profiles.yaml")}async function runLogsCommand(args){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let appRoot=findAppRoot(process.cwd()),binding=readBinding(appRoot)?.binding,tenantId=readStringOption8(args,"tenant")??binding?.tenant_id,appId=readStringOption8(args,"app")??binding?.app_id,env=readStringOption8(args,"env")??binding?.env??"preview",releaseId=readStringOption8(args,"release"),limit=readNumberOption3(args,"limit")??100,follow=args.options.follow===!0,from=readStringOption8(args,"from")??new Date(Date.now()-900*1e3).toISOString(),to=readStringOption8(args,"to")??new Date().toISOString();if(!tenantId||!appId)throw new Error("`platform logs` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:"m1",requestClass:"control"}),payload={tenant_id:tenantId,app_id:appId,env,...releaseId?{release_id:releaseId}:{},from,to,limit,follow};if(!follow){let result=await sdk.queryLogs(payload);printLogs(result,args.options.json===!0);return}let seen=new Set,currentFrom=from;for(;;){let result=await sdk.queryLogs({...payload,from:currentFrom,to:new Date().toISOString(),follow:!0});if(args.options.json===!0)process.stdout.write(`${JSON.stringify(result,null,2)}
2557
2558
  `);else for(let entry of result.entries)seen.has(entry.id)||(seen.add(entry.id),process.stdout.write(`${formatEntry(entry)}
2558
2559
  `));result.entries.length>0&&(currentFrom=result.entries[result.entries.length-1]?.timestamp??currentFrom),await sleep4(2e3)}}function printLogs(result,asJson){if(asJson){process.stdout.write(`${JSON.stringify(result,null,2)}
2559
2560
  `);return}if(result.entries.length===0){process.stdout.write(`\u672A\u67E5\u8BE2\u5230\u65E5\u5FD7\u3002
2560
2561
  `);return}for(let entry of result.entries)process.stdout.write(`${formatEntry(entry)}
2561
- `)}function formatEntry(entry){return`[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.source}/${entry.stream}: ${entry.message}`}function readStringOption8(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption3(args,key){let value=readStringOption8(args,key);if(!value)return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function sleep4(ms){return new Promise(resolve17=>{setTimeout(resolve17,ms)})}import process5 from"node:process";async function runNotificationCommand(args){let subcommand=args.rest[0];if(!subcommand||!["inbox","announce","delivery","end-user"].includes(subcommand))throw new Error("`platform notification` \u4EC5\u652F\u6301 `inbox`\u3001`announce`\u3001`delivery` \u6216 `end-user` \u5B50\u547D\u4EE4\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let context=resolveNotificationContext(args),sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:context.tenantId,capability:"notification",requestClass:"control"});if(subcommand==="inbox"){await runInboxSubcommand(sdk,context,args);return}if(subcommand==="delivery"){if(!context.tenantId)throw new Error("`platform notification delivery` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let items=await sdk.listNotificationDeliveries({app_id:readStringOption9(args,"app")??context.appId,status:readStringOption9(args,"status")});process5.stdout.write(`${JSON.stringify(items,null,2)}
2562
+ `)}function formatEntry(entry){return`[${entry.timestamp}] ${entry.level.toUpperCase()} ${entry.source}/${entry.stream}: ${entry.message}`}function readStringOption8(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readNumberOption3(args,key){let value=readStringOption8(args,key);if(!value)return;let parsed=Number(value);return Number.isFinite(parsed)?parsed:void 0}function sleep4(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}import process5 from"node:process";async function runNotificationCommand(args){let subcommand=args.rest[0];if(!subcommand||!["inbox","announce","delivery","end-user"].includes(subcommand))throw new Error("`platform notification` \u4EC5\u652F\u6301 `inbox`\u3001`announce`\u3001`delivery` \u6216 `end-user` \u5B50\u547D\u4EE4\u3002");let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let context=resolveNotificationContext(args),sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:context.tenantId,capability:"notification",requestClass:"control"});if(subcommand==="inbox"){await runInboxSubcommand(sdk,context,args);return}if(subcommand==="delivery"){if(!context.tenantId)throw new Error("`platform notification delivery` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let items=await sdk.listNotificationDeliveries({app_id:readStringOption9(args,"app")??context.appId,status:readStringOption9(args,"status")});process5.stdout.write(`${JSON.stringify(items,null,2)}
2562
2563
  `);return}if(subcommand==="end-user"){await runEndUserSubcommand(sdk,context,args);return}await runAnnounceSubcommand(sdk,context,args)}async function runInboxSubcommand(sdk,context,args){let action=args.rest[1]??"list";if(action==="list"){if(!context.tenantId)throw new Error("`platform notification inbox list` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let response=await sdk.listNotificationInbox({app_id:readStringOption9(args,"app")??context.appId,inbox_type:readStringOption9(args,"type"),status:readStringOption9(args,"status"),limit:readNumberOption4(args,"limit")});process5.stdout.write(`${JSON.stringify(response,null,2)}
2563
2564
  `);return}if(action==="update"){if(!context.tenantId)throw new Error("`platform notification inbox update` \u9700\u8981\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u9009\u62E9\u79DF\u6237\u6216\u5E94\u7528\u3002");let itemId=readStringOption9(args,"item")??args.rest[2],status=readStringOption9(args,"status");if(!itemId||!status||!isWritableInboxStatus(status))throw new Error("`platform notification inbox update` \u9700\u8981 `<item-id>` \u6216 `--item <id>`\uFF0C\u4EE5\u53CA `--status unread|read|dismissed|archived`\u3002");let item=await sdk.updateNotificationInboxItemStatus(itemId,{status});process5.stdout.write(`${JSON.stringify(item,null,2)}
2564
2565
  `);return}throw new Error("`platform notification inbox` \u76EE\u524D\u4EC5\u652F\u6301 `list` \u6216 `update`\u3002")}async function runAnnounceSubcommand(sdk,context,args){let scope=args.rest[1];if(scope==="platform"){let tenantId=readStringOption9(args,"tenant")??context.tenantId,title=readStringOption9(args,"title");if(!tenantId||!title)throw new Error("`platform notification announce platform` \u9700\u8981 `--tenant <tenant-id>` \u548C `--title <text>`\u3002");let item=await sdk.announcePlatformNotification({tenant_id:tenantId,title,body:readStringOption9(args,"body")??null,level:readStringOption9(args,"level")});process5.stdout.write(`${JSON.stringify(item,null,2)}
@@ -2575,15 +2576,15 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2575
2576
  `));let settings=await context.sdk.updateTenantAppPublishSettings(context.appId,{source_version_id:targetSourceVersionId});if(await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:process.cwd(),tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){process.stdout.write(`${JSON.stringify(settings,null,2)}
2576
2577
  `);return}printPublishSettings(settings,{title:`\u5E94\u7528\u6B63\u5F0F\u7248\u672C\u5DF2\u5207\u56DE: ${context.appId}`})}async function loadPublishContext(args){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let binding=tryReadCurrentBinding()?.binding,tenantId=readStringOption10(args,"tenant")??binding?.tenant_id,appId=readStringOption10(args,"app")??binding?.app_id;if(!tenantId||!appId)throw new Error("`platform publish` \u9700\u8981\u5DF2\u7ED1\u5B9A\u9879\u76EE\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");let apiToken=selectApiToken(credentials);return{tenantId,appId,sdk:createControlApiSdk({accessToken:apiToken,tenantId,capability:"dashboard",requestClass:"control"})}}function tryReadCurrentBinding(){try{return readBinding(findAppRoot(process.cwd()))}catch{return null}}function resolvePublishSubcommand(args){let subcommand=args.rest[0];return subcommand?subcommand==="status"||subcommand==="set"||subcommand==="rollback"?subcommand:null:"status"}function hasHelpFlag5(args){return args.options.help===!0||args.options.h===!0}function readStringOption10(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function readPublishStatusOption(args){let value=readStringOption10(args,"status");return value==="published"||value==="unpublished"?value:void 0}function printPublishHelp(){process.stdout.write(["platform publish","","\u7528\u6CD5\uFF1A"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","\u8BF4\u660E\uFF1A"," - `platform publish` \u9ED8\u8BA4\u7B49\u4EF7\u4E8E `platform publish status`"," - `publish status` \u67E5\u770B\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," - `publish set` \u4FEE\u6539\u53D1\u5E03\u72B6\u6001\uFF0C\u6216\u5207\u6362\u5F53\u524D\u90E8\u7F72\u7248\u672C"," - `publish rollback` \u5C06\u5F53\u524D\u6B63\u5F0F\u7248\u672C\u5207\u56DE\u6307\u5B9A\u6E90\u7801\u7248\u672C",""].join(`
2577
2578
  `))}function printPublishSettings(settings,context){let candidateLines=settings.candidates.length>0?settings.candidates.map((candidate,index)=>{let label=candidate.message?.trim()||candidate.source_version_id;return`${index+1}. ${label} ${candidate.source_version_id}`}):["- \u65E0\u53EF\u9009\u7248\u672C"];process.stdout.write([context.title,`\u53D1\u5E03\u72B6\u6001: ${settings.publish_status==="published"?"\u5DF2\u53D1\u5E03":"\u672A\u53D1\u5E03"}`,`\u786E\u8BA4\u90E8\u7F72\u5F62\u6001: ${settings.deployment_class_confirmed??"-"}`,`\u5F53\u524D\u90E8\u7F72\u7248\u672C: ${settings.current_source_version_id??"-"}`,`\u5F53\u524D release: ${settings.current_release_id??"-"}`,`\u5F53\u524D deployment: ${settings.current_deployment_id??"-"}`,`\u5F53\u524D\u90E8\u7F72\u5F62\u6001: ${settings.current_deployment_class_used??"-"}`,`\u5F53\u524D\u4EA7\u7269\u7C7B\u578B: ${settings.current_artifact_kind??"-"}`,`\u5F53\u524D\u6267\u884C\u6A21\u5F0F: ${settings.current_execution_mode??"-"}`,`\u8FD0\u884C\u9A71\u52A8: ${settings.current_runtime_driver??"-"}`,`\u8FD0\u884C\u5B9E\u4F8B: ${settings.current_runtime_instance_id??"-"}`,`\u5F53\u524D\u5BF9\u8C61\u524D\u7F00: ${settings.current_object_prefix??"-"}`,`\u516C\u5F00\u6B63\u5F0F\u5165\u53E3: ${settings.public_prod_url??"-"}`,`\u8FD0\u884C\u5065\u5EB7\u68C0\u67E5: ${settings.current_runtime_health_check_url??"-"}`,"\u53EF\u9009\u6B63\u5F0F\u7248\u672C:",...candidateLines,""].join(`
2578
- `))}import{createHash as createHash10}from"node:crypto";import{readFile as readFile2,stat}from"node:fs/promises";import{join as join19,resolve as resolve16}from"node:path";function resolvePreviewProjectContext(appRoot,args){let sourceContext=readSourceContext(appRoot)?.sourceContext,binding=readBinding(appRoot)?.binding;return{tenantId:readStringOption11(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id,appId:readStringOption11(args,"app")??sourceContext?.app_id??binding?.app_id}}var SOURCE_VERSION_REUSE_SCAN_LIMIT=5,BUILD_REUSE_SCAN_LIMIT=20,PREVIEW_BUILD_POLL_TIMEOUT_MS=180*1e3,PREVIEW_BUILD_POLL_INTERVAL_MS=1500;async function runPreviewCommand(args){if(hasHelpFlag6(args)){printPreviewHelp(resolveExplicitPreviewMode(args));return}if(resolvePreviewMode(args)==="open"){await runPreviewOpenCommand(args);return}await runPreviewGenerateCommand(args)}async function runPreviewGenerateCommand(args){let context=await loadPreviewContext(args),requestedBy=await resolveRequestedBy3(context.sdk),fromBuildId=readStringOption11(args,"from-build"),explicitSourceVersionId=readStringOption11(args,"source-version"),noWait=args.options["no-wait"]===!0,forceBuild=args.options["force-build"]===!0,localBuild=args.options["local-build"]===!0||readStringOption11(args,"build-mode")==="local";if(args.options["wait-build-only"]===!0)throw new Error("`platform preview generate --wait-build-only` \u5DF2\u79FB\u9664\uFF1B\u8BF7\u6539\u7528 `platform build run --source-version <srcver> --wait`\u3002");let autoResources=await maybeAutoApplyPreviewResources({args,context,requestedBy,sourceVersionId:explicitSourceVersionId,fromBuildId});if(fromBuildId){let preview=await context.sdk.createTenantAppPreview(context.appId,{build_id:fromBuildId}).catch(async error=>{throw await formatPreviewCommandError(context.sdk,error,{appId:context.appId,buildId:fromBuildId,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for explicit build: ${fromBuildId}`);if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:fromBuildId,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);process.stdout.write(`${JSON.stringify({auto_resources:autoResources,preview,post_check:postCheck3},null,2)}
2579
+ `))}import{createHash as createHash10}from"node:crypto";import{readFile as readFile2,stat}from"node:fs/promises";import{join as join19,resolve as resolve17}from"node:path";function resolvePreviewProjectContext(appRoot,args){let sourceContext=readSourceContext(appRoot)?.sourceContext,binding=readBinding(appRoot)?.binding;return{tenantId:readStringOption11(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id,appId:readStringOption11(args,"app")??sourceContext?.app_id??binding?.app_id}}var SOURCE_VERSION_REUSE_SCAN_LIMIT=5,BUILD_REUSE_SCAN_LIMIT=20,PREVIEW_BUILD_POLL_TIMEOUT_MS=180*1e3,PREVIEW_BUILD_POLL_INTERVAL_MS=1500;async function runPreviewCommand(args){if(hasHelpFlag6(args)){printPreviewHelp(resolveExplicitPreviewMode(args));return}if(resolvePreviewMode(args)==="open"){await runPreviewOpenCommand(args);return}await runPreviewGenerateCommand(args)}async function runPreviewGenerateCommand(args){let context=await loadPreviewContext(args),requestedBy=await resolveRequestedBy3(context.sdk),fromBuildId=readStringOption11(args,"from-build"),explicitSourceVersionId=readStringOption11(args,"source-version"),noWait=args.options["no-wait"]===!0,forceBuild=args.options["force-build"]===!0,localBuild=args.options["local-build"]===!0||readStringOption11(args,"build-mode")==="local";if(args.options["wait-build-only"]===!0)throw new Error("`platform preview generate --wait-build-only` \u5DF2\u79FB\u9664\uFF1B\u8BF7\u6539\u7528 `platform build run --source-version <srcver> --wait`\u3002");let autoResources=await maybeAutoApplyPreviewResources({args,context,requestedBy,sourceVersionId:explicitSourceVersionId,fromBuildId});if(fromBuildId){let preview=await context.sdk.createTenantAppPreview(context.appId,{build_id:fromBuildId}).catch(async error=>{throw await formatPreviewCommandError(context.sdk,error,{appId:context.appId,buildId:fromBuildId,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for explicit build: ${fromBuildId}`);if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:fromBuildId,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);process.stdout.write(`${JSON.stringify({auto_resources:autoResources,preview,post_check:postCheck3},null,2)}
2579
2580
  `);return}let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,preview);printPreviewDeployResult(preview,{buildId:fromBuildId,fromBuildId,postCheck:postCheck2});return}let buildConfig=readBuildConfig2(args.options),sourceVersionId=explicitSourceVersionId,createdSourceVersionId,reusedSourceVersionId,localWorkspaceFiles=[];if((!sourceVersionId||localBuild)&&(assertSourceWorkspaceCloudUploadPolicy(context.appRoot,localBuild?"--local-build":"platform preview generate"),localWorkspaceFiles=collectSourceWorkspaceFiles(context.appRoot).files),!sourceVersionId){let sourceVersionResolution=await resolvePreviewSourceVersion({sdk:context.sdk,appId:context.appId,appRoot:context.appRoot,localFiles:localWorkspaceFiles,message:readStringOption11(args,"message")??"preview from local workspace"});sourceVersionId=sourceVersionResolution.sourceVersionId,createdSourceVersionId=sourceVersionResolution.createdSourceVersionId,reusedSourceVersionId=sourceVersionResolution.reusedSourceVersionId}if(localBuild){await runLocalBuildPreviewFlow({args,context,requestedBy,sourceVersionId,localWorkspace:localWorkspaceFiles,autoResources,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,buildConfig});return}let previewOutcome=await requestPreviewFromSourceVersion({sdk:context.sdk,appId:context.appId,appRoot:context.appRoot,sourceVersionId,buildConfig,forceBuild});if(previewOutcome.kind==="build_started"){if(!noWait){let continued=await continuePreviewAfterBuild({sdk:context.sdk,appId:context.appId,build:previewOutcome.build});if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:continued.preview.source_version_id,last_preview_build_id:continued.build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck3=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,continued.preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",auto_resources:autoResources,build:continued.build,preview:continued.preview,post_check:postCheck3,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2580
2581
  `);return}let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,continued.preview);printPreviewDeployResult(continued.preview,{buildId:continued.build.id,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,postCheck:postCheck2});return}if(args.options.json===!0){process.stdout.write(`${JSON.stringify({stage:"build_started",auto_resources:autoResources,build:previewOutcome.build,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2581
2582
  `);return}printPreviewBuildStarted(previewOutcome.build,{createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId});return}if(updateSourceContext(context.appRoot,{tenant_id:context.tenantId,app_id:context.appId,env:"preview",last_preview_source_version_id:previewOutcome.build.source_version_id,last_preview_build_id:previewOutcome.build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:context.sdk,startDir:context.appRoot,tenantId:context.tenantId,appId:context.appId}),args.options.json===!0){let postCheck2=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,previewOutcome.preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",auto_resources:autoResources,build:previewOutcome.build,preview:previewOutcome.preview,post_check:postCheck2,...reusedSourceVersionId?{reused_source_version_id:reusedSourceVersionId}:{},...createdSourceVersionId?{created_source_version_id:createdSourceVersionId}:{}},null,2)}
2582
2583
  `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(context.sdk,context.appId,previewOutcome.preview);printPreviewDeployResult(previewOutcome.preview,{buildId:previewOutcome.build.id,createdSourceVersionId,reusedSourceVersionId,requestedSourceVersionId:explicitSourceVersionId,postCheck})}async function resolvePreviewSourceVersion(args){let matchedSourceVersionId=await findMatchingLocalSourceVersion(args);if(matchedSourceVersionId)return{sourceVersionId:matchedSourceVersionId,reusedSourceVersionId:matchedSourceVersionId};let submitted=await args.sdk.createTenantAppSourceVersion(args.appId,{files:args.localFiles,message:args.message}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,stage:"submit"})});return updateSourceContext(args.appRoot,{tenant_id:submitted.tenant_id,app_id:submitted.app_id,env:"preview",template_key:submitted.template_key,last_submitted_source_version_id:submitted.source_version_id,last_submitted_at:submitted.created_at}),{sourceVersionId:submitted.source_version_id,createdSourceVersionId:submitted.source_version_id}}async function findMatchingLocalSourceVersion(args){let sourceContext=readSourceContext(args.appRoot)?.sourceContext,candidateIds=collectReusableSourceVersionCandidates(sourceContext);for(let sourceVersionId of candidateIds)if(await sourceVersionMatchesLocalWorkspace(args.sdk,args.appId,sourceVersionId,args.localFiles))return sourceVersionId;let listedVersions=await args.sdk.listTenantAppSourceVersions(args.appId).then(response=>response.items.slice(0,SOURCE_VERSION_REUSE_SCAN_LIMIT).map(item=>item.source_version_id)).catch(()=>[]);for(let sourceVersionId of listedVersions)if(!candidateIds.includes(sourceVersionId)&&await sourceVersionMatchesLocalWorkspace(args.sdk,args.appId,sourceVersionId,args.localFiles))return sourceVersionId;return null}async function sourceVersionMatchesLocalWorkspace(sdk,appId,sourceVersionId,localFiles){let workspace=await sdk.getTenantAppSourceWorkspace(appId,{sourceVersionId}).catch(()=>null);return workspace?.source_version_id?sourceWorkspaceFilesEqual(localFiles,workspace.files):!1}async function findReusableSuccessfulBuild(args){let lastPreviewBuildId=readSourceContext(args.appRoot)?.sourceContext?.last_preview_build_id;if(lastPreviewBuildId){let lastPreviewBuild=await args.sdk.getBuild(lastPreviewBuildId).catch(()=>null);if(isReusableSuccessfulBuild(lastPreviewBuild,args.sourceVersionId,args.buildConfig))return lastPreviewBuild}return(await args.sdk.listBuilds(args.appId,{limit:BUILD_REUSE_SCAN_LIMIT}).then(response=>response.items).catch(()=>[])).find(build=>isReusableSuccessfulBuild(build,args.sourceVersionId,args.buildConfig))??null}async function runLocalBuildPreviewFlow(args){assertLocalBuildArgsAllowed(args.args,args.buildConfig),await assertExplicitSourceVersionMatchesWorkspace(args);let localPrecheck=await runLocalBuildSourcePrecheck(args.context.appRoot);if((readAppManifest(args.context.appRoot).manifest.template_key?.trim()||readSourceContext(args.context.appRoot)?.sourceContext.template_key?.trim())!=="frontend-app-vite")throw new Error("`platform preview generate --local-build` \u9996\u7248\u4EC5\u652F\u6301 `frontend-app-vite`\u3002");let buildPrecheck=await args.context.sdk.getBuildPrecheck(args.context.appId,{source_version_id:args.sourceVersionId,build_config:{target:"static"}});if(buildPrecheck.result==="unsupported")throw new Error(["\u5F53\u524D\u6E90\u7801\u7248\u672C\u672A\u901A\u8FC7\u5E73\u53F0\u9759\u6001\u6784\u5EFA\u9884\u68C0\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002",...buildPrecheck.issues.map(issue=>`${issue.severity}: ${issue.code} ${issue.message}`)].join(`
2583
2584
  `));let session=await args.context.sdk.createLocalBuildSession({tenant_id:args.context.tenantId,app_id:args.context.appId,source_version_id:args.sourceVersionId,requested_by:args.requestedBy,build_config:{target:"static"}}),archive=await buildLocalStaticBundleArchive(args.context.appRoot);await args.context.sdk.uploadTenantBlobBinary(session.upload.upload_session_id,{content:archive.content,content_type:"application/zip",upload_url:session.upload.upload_url,headers:session.upload.headers});let build=await args.context.sdk.completeLocalBuildSession(session.build.id,{upload_session_id:session.upload.upload_session_id,sha256:archive.sha256Hex,size_bytes:archive.content.byteLength}).catch(async error=>{throw await formatPreviewCommandError(args.context.sdk,error,{appId:args.context.appId,buildId:session.build.id,stage:"build"})}),preview=await args.context.sdk.createTenantAppPreview(args.context.appId,{build_id:build.id}).catch(async error=>{throw await formatPreviewCommandError(args.context.sdk,error,{appId:args.context.appId,buildId:build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed local build: ${build.id}`);if(updateSourceContext(args.context.appRoot,{tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",last_preview_source_version_id:preview.source_version_id,last_preview_build_id:build.id,last_preview_generated_at:new Date().toISOString()}),await syncLocalControlPlaneSummary({sdk:args.context.sdk,startDir:args.context.appRoot,tenantId:args.context.tenantId,appId:args.context.appId}),args.args.options.json===!0){let postCheck2=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);process.stdout.write(`${JSON.stringify({stage:"preview_completed",mode:"local_build",auto_resources:args.autoResources,local_precheck:localPrecheck,build,preview,post_check:postCheck2,...args.reusedSourceVersionId?{reused_source_version_id:args.reusedSourceVersionId}:{},...args.createdSourceVersionId?{created_source_version_id:args.createdSourceVersionId}:{}},null,2)}
2584
- `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);printPreviewDeployResult(preview,{buildId:build.id,createdSourceVersionId:args.createdSourceVersionId,reusedSourceVersionId:args.reusedSourceVersionId,requestedSourceVersionId:args.requestedSourceVersionId,postCheck})}function assertLocalBuildArgsAllowed(args,buildConfig){if(readStringOption11(args,"from-build"))throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--from-build`\u3002");if(args.options["force-build"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--force-build`\uFF1B\u672C\u5730\u6A21\u5F0F\u9ED8\u8BA4\u6BCF\u6B21\u90FD\u91CD\u65B0\u6784\u5EFA\u3002");if(args.options["no-wait"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--no-wait`\u3002");if(buildConfig.dockerfile_path||buildConfig.context_subdir)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--dockerfile` \u6216 `--context-subdir`\u3002");if(buildConfig.target&&buildConfig.target!=="static")throw new Error("`platform preview generate --local-build` \u4EC5\u652F\u6301\u9759\u6001\u76EE\u6807\u3002")}async function assertExplicitSourceVersionMatchesWorkspace(args){if(!args.requestedSourceVersionId)return;let workspace=await args.context.sdk.getTenantAppSourceWorkspace(args.context.appId,{sourceVersionId:args.sourceVersionId});if(!sourceWorkspaceFilesEqual(args.localWorkspace,workspace.files))throw new Error("\u663E\u5F0F `--source-version` \u4E0E\u5F53\u524D\u672C\u5730\u5DE5\u4F5C\u533A\u4E0D\u4E00\u81F4\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002")}async function runLocalBuildSourcePrecheck(appRoot){let stats=assertSourceWorkspaceCloudUploadPolicy(appRoot,"--local-build");return{source_bytes:stats.sourceBytes,asset_hits:stats.assetHits}}async function buildLocalStaticBundleArchive(appRoot){await runLocalBuildCommand(appRoot);let outputDir=resolve16(appRoot,"dist");if(!await pathExists(join19(outputDir,"index.html")))throw new Error("\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/index.html`\uFF0C\u4E0D\u80FD\u6267\u884C\u4E0A\u4F20\u3002");await validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir);let zipped=await createZipArchiveBuffer(outputDir),sha256Hex=createHash10("sha256").update(zipped).digest("hex");return{content:zipped,sha256Hex}}async function validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir){let sourceRegistryPath=join19(appRoot,"page-render","registry.json");if(!await pathExists(sourceRegistryPath))return;let distRegistryPath=join19(outputDir,"page-render","registry.json"),distAssetsManifestPath=join19(outputDir,"page-render","assets-manifest.json");if(!await pathExists(distRegistryPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/registry.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");if(!await pathExists(distAssetsManifestPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/assets-manifest.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");await parseJsonFileOrThrow(distRegistryPath,"dist/page-render/registry.json"),await parseJsonFileOrThrow(distAssetsManifestPath,"dist/page-render/assets-manifest.json")}async function runLocalBuildCommand(appRoot){let packageJson=JSON.parse(await readFile2(join19(appRoot,"package.json"),"utf8")),hasPnpmLock=await pathExists(join19(appRoot,"pnpm-lock.yaml")),hasYarnLock=await pathExists(join19(appRoot,"yarn.lock")),packageManager=typeof packageJson.packageManager=="string"?packageJson.packageManager:"",command=packageManager.startsWith("pnpm@")||hasPnpmLock?["corepack","pnpm","run","build"]:packageManager.startsWith("yarn@")||hasYarnLock?["corepack","yarn","run","build"]:["npm","run","build"];await runSubprocess(command[0],command.slice(1),appRoot)}async function runSubprocess(command,commandArgs,cwd){await new Promise((resolvePromise,rejectPromise)=>{if(command!=="corepack"&&command!=="npm"){rejectPromise(new Error(`\u4E0D\u652F\u6301\u7684\u672C\u5730\u6784\u5EFA\u547D\u4EE4: ${command}`));return}let child=spawnCrossPlatform(command,commandArgs,{cwd,stdio:"inherit",env:{...process.env,NODE_ENV:"development",NPM_CONFIG_PRODUCTION:"false",npm_config_production:"false"}});child.on("error",rejectPromise),child.on("exit",code2=>{if(code2===0){resolvePromise();return}rejectPromise(new Error(`\u672C\u5730\u6784\u5EFA\u5931\u8D25: ${command} ${commandArgs.join(" ")} (exit ${code2??"unknown"})`))})})}async function createZipArchiveBuffer(targetDir){return createZipBuffer(targetDir)}async function pathExists(targetPath){try{return await stat(targetPath),!0}catch{return!1}}async function parseJsonFileOrThrow(filePath,label){let raw=await readFile2(filePath,"utf8");try{return JSON.parse(raw)}catch(error){throw new Error(`${label} \u4E0D\u662F\u5408\u6CD5 JSON: ${error instanceof Error?error.message:String(error)}`)}}async function requestPreviewFromSourceVersion(args){try{let preview=await args.sdk.createTenantAppPreview(args.appId,{source_version_id:args.sourceVersionId,...Object.keys(args.buildConfig).length>0?{build_config:args.buildConfig}:{},...args.forceBuild?{force_rebuild:!0}:{}});return isPreviewBuildPendingResponse(preview)?{kind:"build_started",build:await args.sdk.getBuild(preview.build_id).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:preview.build_id,stage:"build"})})}:{kind:"preview_completed",build:preview.build_id?await args.sdk.getBuild(preview.build_id):await loadPreviewBuildBySourceVersion(args),preview}}catch(error){throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,sourceVersionId:args.sourceVersionId,stage:"preview"})}}async function continuePreviewAfterBuild(args){let completedBuild=await waitForPreviewBuild(args.sdk,args.build.id);if(completedBuild.status==="cancelled"){let reusedBuildId=extractReusedBuildId2(completedBuild);if(reusedBuildId){let reusedBuild=await args.sdk.getBuild(reusedBuildId).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:reusedBuildId,stage:"build"})});return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:reusedBuild})}}return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:completedBuild})}async function createPreviewFromBuild(args){if(args.build.status!=="succeeded")throw formatPreviewBuildNotReadyError(args.build);let preview=await args.sdk.createTenantAppPreview(args.appId,{build_id:args.build.id}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,buildId:args.build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed build: ${args.build.id}`);return{build:args.build,preview}}async function waitForPreviewBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??PREVIEW_BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??PREVIEW_BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus2(build.status))return build;if(Date.now()-startedAt>=timeoutMs)throw formatPreviewBuildTimeoutError(build,timeoutMs);await sleep5(intervalMs)}}function isTerminalBuildStatus2(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId2(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function formatPreviewBuildNotReadyError(build){let lines=["Preview \u672A\u7EE7\u7EED\u53D1\u5E03\uFF0C\u56E0\u4E3A build \u672A\u6210\u529F\u5B8C\u6210\u3002",`build: ${build.id}`,`status: ${build.status}`,...build.error_code?[`error_code: ${build.error_code}`]:[],...build.error_message?[`error_message: ${build.error_message}`]:[],...build.log_ref?[`log_ref: ${build.log_ref}`]:[],`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u6216 \`platform build events ${build.id}\` \u7EE7\u7EED\u6392\u67E5\u3002`];return new Error(lines.join(`
2585
+ `);return}let postCheck=await buildPreviewSuccessPostCheckPayload(args.context.sdk,args.context.appId,preview);printPreviewDeployResult(preview,{buildId:build.id,createdSourceVersionId:args.createdSourceVersionId,reusedSourceVersionId:args.reusedSourceVersionId,requestedSourceVersionId:args.requestedSourceVersionId,postCheck})}function assertLocalBuildArgsAllowed(args,buildConfig){if(readStringOption11(args,"from-build"))throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--from-build`\u3002");if(args.options["force-build"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--force-build`\uFF1B\u672C\u5730\u6A21\u5F0F\u9ED8\u8BA4\u6BCF\u6B21\u90FD\u91CD\u65B0\u6784\u5EFA\u3002");if(args.options["no-wait"]===!0)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--no-wait`\u3002");if(buildConfig.dockerfile_path||buildConfig.context_subdir)throw new Error("`platform preview generate --local-build` \u4E0D\u652F\u6301 `--dockerfile` \u6216 `--context-subdir`\u3002");if(buildConfig.target&&buildConfig.target!=="static")throw new Error("`platform preview generate --local-build` \u4EC5\u652F\u6301\u9759\u6001\u76EE\u6807\u3002")}async function assertExplicitSourceVersionMatchesWorkspace(args){if(!args.requestedSourceVersionId)return;let workspace=await args.context.sdk.getTenantAppSourceWorkspace(args.context.appId,{sourceVersionId:args.sourceVersionId});if(!sourceWorkspaceFilesEqual(args.localWorkspace,workspace.files))throw new Error("\u663E\u5F0F `--source-version` \u4E0E\u5F53\u524D\u672C\u5730\u5DE5\u4F5C\u533A\u4E0D\u4E00\u81F4\uFF0C\u4E0D\u80FD\u6267\u884C `--local-build`\u3002")}async function runLocalBuildSourcePrecheck(appRoot){let stats=assertSourceWorkspaceCloudUploadPolicy(appRoot,"--local-build");return{source_bytes:stats.sourceBytes,asset_hits:stats.assetHits}}async function buildLocalStaticBundleArchive(appRoot){await runLocalBuildCommand(appRoot);let outputDir=resolve17(appRoot,"dist");if(!await pathExists(join19(outputDir,"index.html")))throw new Error("\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/index.html`\uFF0C\u4E0D\u80FD\u6267\u884C\u4E0A\u4F20\u3002");await validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir);let zipped=await createZipArchiveBuffer(outputDir),sha256Hex=createHash10("sha256").update(zipped).digest("hex");return{content:zipped,sha256Hex}}async function validateOptionalLocalBuiltPageRenderBundle(appRoot,outputDir){let sourceRegistryPath=join19(appRoot,"page-render","registry.json");if(!await pathExists(sourceRegistryPath))return;let distRegistryPath=join19(outputDir,"page-render","registry.json"),distAssetsManifestPath=join19(outputDir,"page-render","assets-manifest.json");if(!await pathExists(distRegistryPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/registry.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");if(!await pathExists(distAssetsManifestPath))throw new Error("\u68C0\u6D4B\u5230 `page-render/registry.json`\uFF0C\u4F46\u672C\u5730\u6784\u5EFA\u4EA7\u7269\u7F3A\u5C11 `dist/page-render/assets-manifest.json`\u3002\u8BF7\u786E\u8BA4 build \u540E\u5904\u7406\u811A\u672C\u5DF2\u6267\u884C\u3002");await parseJsonFileOrThrow(distRegistryPath,"dist/page-render/registry.json"),await parseJsonFileOrThrow(distAssetsManifestPath,"dist/page-render/assets-manifest.json")}async function runLocalBuildCommand(appRoot){let packageJson=JSON.parse(await readFile2(join19(appRoot,"package.json"),"utf8")),hasPnpmLock=await pathExists(join19(appRoot,"pnpm-lock.yaml")),hasYarnLock=await pathExists(join19(appRoot,"yarn.lock")),packageManager=typeof packageJson.packageManager=="string"?packageJson.packageManager:"",command=packageManager.startsWith("pnpm@")||hasPnpmLock?["corepack","pnpm","run","build"]:packageManager.startsWith("yarn@")||hasYarnLock?["corepack","yarn","run","build"]:["npm","run","build"];await runSubprocess(command[0],command.slice(1),appRoot)}async function runSubprocess(command,commandArgs,cwd){await new Promise((resolvePromise,rejectPromise)=>{if(command!=="corepack"&&command!=="npm"){rejectPromise(new Error(`\u4E0D\u652F\u6301\u7684\u672C\u5730\u6784\u5EFA\u547D\u4EE4: ${command}`));return}let child=spawnCrossPlatform(command,commandArgs,{cwd,stdio:"inherit",env:{...process.env,NODE_ENV:"development",NPM_CONFIG_PRODUCTION:"false",npm_config_production:"false"}});child.on("error",rejectPromise),child.on("exit",code2=>{if(code2===0){resolvePromise();return}rejectPromise(new Error(`\u672C\u5730\u6784\u5EFA\u5931\u8D25: ${command} ${commandArgs.join(" ")} (exit ${code2??"unknown"})`))})})}async function createZipArchiveBuffer(targetDir){return createZipBuffer(targetDir)}async function pathExists(targetPath){try{return await stat(targetPath),!0}catch{return!1}}async function parseJsonFileOrThrow(filePath,label){let raw=await readFile2(filePath,"utf8");try{return JSON.parse(raw)}catch(error){throw new Error(`${label} \u4E0D\u662F\u5408\u6CD5 JSON: ${error instanceof Error?error.message:String(error)}`)}}async function requestPreviewFromSourceVersion(args){try{let preview=await args.sdk.createTenantAppPreview(args.appId,{source_version_id:args.sourceVersionId,...Object.keys(args.buildConfig).length>0?{build_config:args.buildConfig}:{},...args.forceBuild?{force_rebuild:!0}:{}});return isPreviewBuildPendingResponse(preview)?{kind:"build_started",build:await args.sdk.getBuild(preview.build_id).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:preview.build_id,stage:"build"})})}:{kind:"preview_completed",build:preview.build_id?await args.sdk.getBuild(preview.build_id):await loadPreviewBuildBySourceVersion(args),preview}}catch(error){throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,sourceVersionId:args.sourceVersionId,stage:"preview"})}}async function continuePreviewAfterBuild(args){let completedBuild=await waitForPreviewBuild(args.sdk,args.build.id);if(completedBuild.status==="cancelled"){let reusedBuildId=extractReusedBuildId2(completedBuild);if(reusedBuildId){let reusedBuild=await args.sdk.getBuild(reusedBuildId).catch(async buildError=>{throw await formatPreviewCommandError(args.sdk,buildError,{appId:args.appId,buildId:reusedBuildId,stage:"build"})});return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:reusedBuild})}}return createPreviewFromBuild({sdk:args.sdk,appId:args.appId,build:completedBuild})}async function createPreviewFromBuild(args){if(args.build.status!=="succeeded")throw formatPreviewBuildNotReadyError(args.build);let preview=await args.sdk.createTenantAppPreview(args.appId,{build_id:args.build.id}).catch(async error=>{throw await formatPreviewCommandError(args.sdk,error,{appId:args.appId,buildId:args.build.id,stage:"preview"})});if(isPreviewBuildPendingResponse(preview))throw new Error(`preview unexpectedly returned build pending for completed build: ${args.build.id}`);return{build:args.build,preview}}async function waitForPreviewBuild(sdk,buildId,options){let timeoutMs=options?.timeoutMs??PREVIEW_BUILD_POLL_TIMEOUT_MS,intervalMs=options?.intervalMs??PREVIEW_BUILD_POLL_INTERVAL_MS,startedAt=Date.now();for(;;){let build=await sdk.getBuild(buildId);if(isTerminalBuildStatus2(build.status))return build;if(Date.now()-startedAt>=timeoutMs)throw formatPreviewBuildTimeoutError(build,timeoutMs);await sleep5(intervalMs)}}function isTerminalBuildStatus2(status){return status==="succeeded"||status==="failed"||status==="cancelled"}function extractReusedBuildId2(result){return result.error_code!=="build_reused_existing_success"||!result.error_message?null:result.error_message.match(/reused successful build\s+([a-zA-Z0-9-]+)/)?.[1]??null}function formatPreviewBuildNotReadyError(build){let lines=["Preview \u672A\u7EE7\u7EED\u53D1\u5E03\uFF0C\u56E0\u4E3A build \u672A\u6210\u529F\u5B8C\u6210\u3002",`build: ${build.id}`,`status: ${build.status}`,...build.error_code?[`error_code: ${build.error_code}`]:[],...build.error_message?[`error_message: ${build.error_message}`]:[],...build.log_ref?[`log_ref: ${build.log_ref}`]:[],`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u6216 \`platform build events ${build.id}\` \u7EE7\u7EED\u6392\u67E5\u3002`];return new Error(lines.join(`
2585
2586
  `))}function formatPreviewBuildTimeoutError(build,timeoutMs){return new Error(["Preview \u7B49\u5F85 build \u8D85\u65F6\uFF0C\u5C1A\u672A\u81EA\u52A8\u7EE7\u7EED\u53D1\u5E03\u3002",`build: ${build.id}`,`status: ${build.status}`,`timeout_ms: ${timeoutMs}`,`\u4E0B\u4E00\u6B65: \u6267\u884C \`platform build get ${build.id}\` \u89C2\u5BDF\u72B6\u6001\uFF1B\u5982\u5DF2\u6210\u529F\uFF0C\u53EF\u6267\u884C \`platform preview generate --from-build ${build.id}\`\u3002`].join(`
2586
- `))}function sleep5(ms){return new Promise(resolve17=>{setTimeout(resolve17,ms)})}async function loadPreviewBuildBySourceVersion(args){let build=await findReusableSuccessfulBuild({sdk:args.sdk,appId:args.appId,appRoot:args.appRoot,sourceVersionId:args.sourceVersionId,buildConfig:args.buildConfig});if(!build)throw new Error(`preview \u5DF2\u521B\u5EFA\uFF0C\u4F46\u672A\u80FD\u5B9A\u4F4D\u5BF9\u5E94 build: ${args.appId}/${args.sourceVersionId}`);return build}function collectReusableSourceVersionCandidates(sourceContext){return Array.from(new Set([sourceContext?.last_preview_source_version_id,sourceContext?.last_submitted_source_version_id,sourceContext?.base_source_version_id].filter(value=>typeof value=="string"&&value.length>0)))}function sourceWorkspaceFilesEqual(localFiles,remoteFiles){if(localFiles.length!==remoteFiles.length)return!1;for(let index=0;index<localFiles.length;index+=1){let local=localFiles[index],remote=remoteFiles[index];if(!remote||local.path!==remote.path||local.content!==remote.content)return!1}return!0}function isReusableSuccessfulBuild(build,sourceVersionId,buildConfig){return!build||build.status!=="succeeded"||build.lifecycle_status&&build.lifecycle_status!=="active"||build.source_version_id!==sourceVersionId?!1:buildConfigEqual(build.build_config,buildConfig)}function buildConfigEqual(left,right){return normalizeBuildConfig(left).key===normalizeBuildConfig(right).key}function normalizeBuildConfig(buildConfig){let normalized={...buildConfig?.dockerfile_path?{dockerfile_path:buildConfig.dockerfile_path}:{},...buildConfig?.context_subdir?{context_subdir:buildConfig.context_subdir}:{},...buildConfig?.target?{target:buildConfig.target}:{}};return{...normalized,key:JSON.stringify(normalized)}}async function maybeAutoApplyPreviewResources(args){let skipReason=resolvePreviewAutoResourcesSkipReason(args.args.options);if(skipReason)return{status:"skipped",reason:skipReason};let localResources=await collectEffectiveResources(args.context.appRoot,{sdk:args.context.sdk,appId:args.context.appId});if(localResources.length===0)return{status:"skipped",reason:"no_local_resources"};let payload={operation:"diff",tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",requested_by:args.requestedBy,local_resources:localResources},diff=await args.context.sdk.diffResources(payload).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"diff"})});if(diff.summary.added===0&&diff.summary.modified===0&&diff.summary.deleted===0)return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u662F\u6700\u65B0\uFF0C\u8DF3\u8FC7\u81EA\u52A8 apply\u3002\u57FA\u7EBF\u5FEB\u7167: ${diff.base_snapshot_id}
2587
+ `))}function sleep5(ms){return new Promise(resolve19=>{setTimeout(resolve19,ms)})}async function loadPreviewBuildBySourceVersion(args){let build=await findReusableSuccessfulBuild({sdk:args.sdk,appId:args.appId,appRoot:args.appRoot,sourceVersionId:args.sourceVersionId,buildConfig:args.buildConfig});if(!build)throw new Error(`preview \u5DF2\u521B\u5EFA\uFF0C\u4F46\u672A\u80FD\u5B9A\u4F4D\u5BF9\u5E94 build: ${args.appId}/${args.sourceVersionId}`);return build}function collectReusableSourceVersionCandidates(sourceContext){return Array.from(new Set([sourceContext?.last_preview_source_version_id,sourceContext?.last_submitted_source_version_id,sourceContext?.base_source_version_id].filter(value=>typeof value=="string"&&value.length>0)))}function sourceWorkspaceFilesEqual(localFiles,remoteFiles){if(localFiles.length!==remoteFiles.length)return!1;for(let index=0;index<localFiles.length;index+=1){let local=localFiles[index],remote=remoteFiles[index];if(!remote||local.path!==remote.path||local.content!==remote.content)return!1}return!0}function isReusableSuccessfulBuild(build,sourceVersionId,buildConfig){return!build||build.status!=="succeeded"||build.lifecycle_status&&build.lifecycle_status!=="active"||build.source_version_id!==sourceVersionId?!1:buildConfigEqual(build.build_config,buildConfig)}function buildConfigEqual(left,right){return normalizeBuildConfig(left).key===normalizeBuildConfig(right).key}function normalizeBuildConfig(buildConfig){let normalized={...buildConfig?.dockerfile_path?{dockerfile_path:buildConfig.dockerfile_path}:{},...buildConfig?.context_subdir?{context_subdir:buildConfig.context_subdir}:{},...buildConfig?.target?{target:buildConfig.target}:{}};return{...normalized,key:JSON.stringify(normalized)}}async function maybeAutoApplyPreviewResources(args){let skipReason=resolvePreviewAutoResourcesSkipReason(args.args.options);if(skipReason)return{status:"skipped",reason:skipReason};let localResources=await collectEffectiveResources(args.context.appRoot,{sdk:args.context.sdk,appId:args.context.appId});if(localResources.length===0)return{status:"skipped",reason:"no_local_resources"};let payload={operation:"diff",tenant_id:args.context.tenantId,app_id:args.context.appId,env:"preview",requested_by:args.requestedBy,local_resources:localResources},diff=await args.context.sdk.diffResources(payload).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"diff"})});if(diff.summary.added===0&&diff.summary.modified===0&&diff.summary.deleted===0)return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u662F\u6700\u65B0\uFF0C\u8DF3\u8FC7\u81EA\u52A8 apply\u3002\u57FA\u7EBF\u5FEB\u7167: ${diff.base_snapshot_id}
2587
2588
  `),{status:"no_changes",base_snapshot_id:diff.base_snapshot_id,summary:diff.summary};let applyPayload={...payload,operation:"apply"},applyResult=await withPendingFeedback2(args.args.options.json===!0,`\u68C0\u6D4B\u5230 preview \u5B58\u5728\u672A\u5E94\u7528\u8D44\u6E90\u53D8\u66F4\uFF0C\u5DF2\u81EA\u52A8\u6267\u884C resources apply: ${args.context.appId}/preview`,"preview \u8D44\u6E90 apply \u4ECD\u5728\u8FDB\u884C\uFF0C\u8BF7\u7EE7\u7EED\u7B49\u5F85\u63A7\u5236\u9762\u5B8C\u6210\u57FA\u7EBF\u89E3\u6790\u3001diff \u4E0E\u8D44\u6E90\u7F16\u6392...",()=>args.context.sdk.applyResources(applyPayload)).catch(async error=>{throw await formatPreviewAutoResourcesError(args.context.sdk,error,{appId:args.context.appId,env:"preview",stage:"apply",baseSnapshotId:diff.base_snapshot_id})});if(applyResult.status!=="succeeded")throw new Error([`preview \u8D44\u6E90\u81EA\u52A8 apply \u672A\u6210\u529F: ${args.context.appId}/preview`,`status: ${applyResult.status}`,`base_snapshot: ${applyResult.base_snapshot_id}`,...applyResult.result_snapshot_id?[`result_snapshot: ${applyResult.result_snapshot_id}`]:[],...applyResult.errors&&applyResult.errors.length>0?[`errors: ${applyResult.errors.join(" | ")}`]:[]].join(`
2588
2589
  `));return args.args.options.json!==!0&&process.stderr.write(`preview \u8D44\u6E90\u5DF2\u81EA\u52A8\u8865\u9F50\uFF1A\u65B0\u589E ${applyResult.summary.added}\uFF0C\u4FEE\u6539 ${applyResult.summary.modified}\uFF0C\u5220\u9664 ${applyResult.summary.deleted}
2589
2590
  `),{status:"applied",base_snapshot_id:applyResult.base_snapshot_id,result_snapshot_id:applyResult.result_snapshot_id,summary:applyResult.summary}}function resolvePreviewAutoResourcesSkipReason(options){return options["no-apply-resources"]===!0?"disabled":null}async function runPreviewOpenCommand(args){let context=await loadPreviewContext(args),sourceVersionId=readStringOption11(args,"source-version"),timeline=await context.sdk.listTenantAppDeploymentTimeline(context.appId,{limit:50}),previewItem=findOpenablePreviewDeployment(timeline.items,sourceVersionId);if(!previewItem?.preview_url)throw sourceVersionId?new Error([`\u672A\u627E\u5230\u53EF\u6253\u5F00\u7684 Preview: ${sourceVersionId}`,"\u8BF4\u660E\uFF1A\u8BE5\u7248\u672C\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684 Preview \u5730\u5740\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A\u5148\u6267\u884C `platform preview generate --source-version <srcver>`\u3002"].join(`
@@ -2639,11 +2640,11 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2639
2640
  `):process.stderr.write(`worker \u672A\u5B9E\u73B0: ${worker}
2640
2641
  \u5F53\u524D\u5DF2\u5B9E\u73B0: ${[...implementedWorkers].join(", ")}
2641
2642
  `),process.exitCode=1;return}await spawnControlApiWorker([worker,...serializeOptions(args.options)])}function printWorkerHelp(){process.stdout.write(["platform worker","","\u7528\u6CD5\uFF1A"," platform worker preview-retention [--once] [--dry-run] [--tenant <tenant-id>] [--app <app-id>] [--ttl-hours <n>] [--limit <n>] [--json]","","\u8BF4\u660E\uFF1A"," worker \u547D\u4EE4\u662F\u672C\u5730\u5F00\u53D1/\u8FD0\u7EF4\u5165\u53E3\uFF0C\u4F1A\u8F6C\u4EA4\u7ED9 @platform/control-api \u7684 worker \u5B9E\u73B0\u3002"," preview-retention \u9ED8\u8BA4\u4EE5\u524D\u53F0\u5E38\u9A7B worker \u8FD0\u884C\uFF1B\u52A0 --once \u65F6\u53EA\u6267\u884C\u4E00\u6B21\u3002",""].join(`
2642
- `))}function serializeOptions(options){let result=[];for(let[key,value]of Object.entries(options))key==="help"||key==="h"||(result.push(`--${key}`),typeof value=="string"&&result.push(value));return result}async function spawnControlApiWorker(args){await new Promise((resolve17,reject)=>{let child=spawn4("corepack",["pnpm","--silent","--filter","@platform/control-api","worker",...args],{stdio:"inherit"});child.on("error",reject),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`control-api worker exited by signal ${signal}`));return}code2&&code2!==0&&(process.exitCode=code2),resolve17()})})}applyStoredEnvironmentProfile();applyDistributionProfileDefaults();loadDotenvFiles();var distributionProfile=getDistributionProfile(),cliPackageVersion=getCliPackageVersion();function persistActiveTenantSelection(tenant){let currentContext=loadStoredCliContext();persistCliContext({active_tenant_id:tenant.tenant_id,active_tenant_name:tenant.name,selected_app_tenant_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_tenant_id,selected_app_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_id,selected_app_env:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_env,selected_app_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_name,selected_app_display_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_display_name})}function currentInvocationDir(){return getInvocationCwd()}function parseArgs5(argv){let[command="help",...rest]=argv,options={},positionals=[];for(let index=0;index<rest.length;index+=1){let current=rest[index];if(current==="--help"){options.help=!0;continue}if(current==="-h"){options.h=!0;continue}if(!current.startsWith("--")){positionals.push(current);continue}let[key,inlineValue]=current.slice(2).split("=",2);if(inlineValue!==void 0){options[key]=inlineValue;continue}let next=rest[index+1];if(next&&!next.startsWith("--")){options[key]=next,index+=1;continue}options[key]=!0}return{command,rest:positionals,options}}function printHelp(){let envCommandLines=distributionProfile.name!=="developer"?[]:[" env use <profile> \u5207\u6362 CLI \u73AF\u5883 profile\uFF08\u5982 local / test\uFF09"," env current \u67E5\u770B\u5F53\u524D CLI \u73AF\u5883 profile"," env list \u67E5\u770B\u53EF\u7528 CLI \u73AF\u5883 profile"];process7.stdout.write(["platform <command>","","Commands:"," login \u5168\u5C40\u767B\u5F55\u5E76\u4FDD\u5B58\u51ED\u636E"," version \u8F93\u51FA\u5F53\u524D CLI \u7248\u672C\u53F7"," app create \u5728\u4E91\u7AEF\u521B\u5EFA\u5E94\u7528\uFF0C\u5E76 checkout \u5230\u672C\u5730\u65B0\u76EE\u5F55"," app checkout \u4ECE\u4E91\u7AEF checkout \u5E94\u7528\u6E90\u7801\u526F\u672C\u5230\u672C\u5730\u65B0\u76EE\u5F55"," app submit \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u63D0\u4EA4\u4E3A\u65B0\u7684\u4E91\u7AEF\u6E90\u7801\u7248\u672C"," app version create \u5728\u5F53\u524D app \u4E0B\u57FA\u4E8E\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C\u9AA8\u67B6"," app version list \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app versions \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app status \u67E5\u770B\u5E94\u7528\u63A7\u5236\u9762\u603B\u89C8\uFF08\u542B Auth / DB / \u7248\u672C\u6982\u51B5\uFF09"," app diagnose \u67E5\u770B\u5E94\u7528\u662F\u5426\u5DF2 ready for runtime validation"," app preflight \u4E00\u6B21\u6027\u6267\u884C whoami / app current / app diagnose \u98CE\u683C\u68C0\u67E5"," app sync-platform-blocks \u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\uFF08dry-run / adopt / apply / rollback --last\uFF09"," app import preprocess \u9884\u5904\u7406\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u751F\u6210 clean-source \u4E0E\u62A5\u544A"," app import stage \u628A clean-source \u4E0E\u62A5\u544A stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," app import merge \u628A\u4E0A\u6E38 src \u5B89\u5168\u5E76\u5165 src/imported-upstream/"," app scaffold \u6309\u9700\u6CE8\u5165\u672C\u5730 debug scaffold\uFF08auth/workflow/cms/db\uFF09"," app-library \u7BA1\u7406\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93 example-app \u6761\u76EE"," app use \u517C\u5BB9\u8DEF\u5F84\uFF1A\u4E3A init/link/dev \u9009\u62E9\u76EE\u6807\u5E94\u7528"," app current \u67E5\u770B\u5F53\u524D\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587"," tenant use <id> \u8BBE\u7F6E\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587"," tenant current \u67E5\u770B\u5F53\u524D\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587",...envCommandLines," whoami \u8C03\u7528 Control API \u8F93\u51FA\u5F53\u524D\u4E3B\u4F53"," preview \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u53EF\u7528 Preview\uFF1B\u751F\u6210\u8BF7\u7528 `platform preview generate`"," init [name] \u751F\u6210\u9879\u76EE\u9AA8\u67B6\uFF0C\u5E76\u81EA\u52A8\u5199\u5165\u5DF2\u9009\u5E94\u7528\u7ED1\u5B9A"," link \u7ED1\u5B9A tenant/app/env \u5230\u5F53\u524D\u5E94\u7528\u76EE\u5F55"," dev \u9ED8\u8BA4\u8F7B\u91CF\u5F00\u53D1\u5165\u53E3\uFF1A\u6CE8\u5165\u7ED1\u5B9A\u540E\u542F\u52A8\u672C\u5730\u5F00\u53D1\u6001"," dev push \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u8986\u76D6\u63A8\u9001\u5230\u4E91\u7AEF Dev Workspace"," dev preview generate \u57FA\u4E8E\u4E91\u7AEF Dev Workspace \u751F\u6210\u5DE5\u4F5C\u533A Preview"," auth \u7BA1\u7406 Auth \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / bind / inspect\uFF09"," cms \u7BA1\u7406 CMS \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / apply / inspect\uFF09"," asset \u7BA1\u7406\u79DF\u6237\u5171\u4EAB\u7D20\u6750\uFF08upload / list / folder / get / update / analyze / move / open / tag\uFF09"," blob \u7BA1\u7406 Object Storage Blob\uFF08upload / list / get / url\uFF09"," db \u67E5\u770B DB \u72B6\u6001\u3001\u8868\u7ED3\u6784\u4E0E\u53EA\u8BFB\u67E5\u8BE2"," data-form \u6821\u9A8C/\u7F16\u8BD1/apply/query Data Form schema \u4E0E\u8BB0\u5F55"," workflow \u7BA1\u7406 Workflow \u57FA\u5EA7\u80FD\u529B\uFF08template / definition / binding / runtime\uFF09"," notification \u7BA1\u7406 Notification \u57FA\u5EA7\u80FD\u529B\uFF08inbox / announce / delivery\uFF09"," publish \u7BA1\u7406\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," resources \u6267\u884C\u8D44\u6E90 diff/apply/rollback"," logs \u67E5\u8BE2\u8FD0\u884C\u65F6\u65E5\u5FD7\uFF0C\u652F\u6301 --follow"," diagnostics \u5E73\u53F0\u672C\u5730\u8BCA\u65AD\uFF08control-api endpoint / readiness\uFF09"," worker \u542F\u52A8\u5E73\u53F0\u540E\u53F0 worker\uFF08preview-retention\uFF09","","Advanced commands:"," build \u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\uFF1A\u53D1\u8D77\u548C\u67E5\u8BE2 build"," deploy \u8FC7\u6E21\u5165\u53E3\uFF1A\u9AD8\u7EA7\u53D1\u5E03\uFF08artifact / promote\uFF09"," rollback \u8FC7\u6E21\u5165\u53E3\uFF1A\u56DE\u6EDA\u5230\u76EE\u6807 release \u6216\u7248\u672C","","App commands:"," platform app create --tenant <tenant-id> --name <display-name> --dir <project-name> [--template frontend-app-vite|backend-app-node]"," platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," platform app checkout --tenant <tenant-id> --app <app-id> --source-version <srcver>",' platform app submit --message "local iteration"',' platform app version create --message "switch template" --template backend-app-node'," platform app versions --tenant <tenant-id> --app <app-id>"," platform app status [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app sync-platform-blocks [--dry-run|--adopt|--apply|--rollback --last]"," platform app diagnose [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run]"," platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>"," platform app import merge [--workspace-dir <template-workspace-dir>]"," platform app scaffold <auth-debug|workflow-debug|cms-debug|db-debug>"," platform app-library list"," platform app-library config init"," platform app-library inspect entry-demo"," platform app-library checkout entry-demo --dir ./example-app-demo",' platform app-library create --name "Data Form Verify" --summary "\u672C\u5730\u9A8C\u8BC1\u540E\u7684\u793A\u4F8B\u5E94\u7528"'," platform app-library submit entry-demo"," platform app use --tenant <tenant-id> --app <app-id> --env preview"," platform app current","","DB commands:"," platform db status"," platform db history --limit 10"," platform db migrate [--dry-run]"," platform db tables",' platform db query --sql "SELECT ... LIMIT 5"'," platform db open","","Auth commands:"," platform auth discover [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth configure [--tenant <tenant-id>] [--app <app-id>] --enable [--template <template>] [--user-store-id <id>] [--enable-admin-password|--disable-admin-password] [--enable-phone-sms-otp|--disable-phone-sms-otp] [--json]"," platform auth bind [--tenant <tenant-id>] [--app <app-id>] [--action bind|rebind|disable] [--user-store-id <id>] [--json]"," platform auth inspect [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role list [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role create [--tenant <tenant-id>] [--app <app-id>] --key <role-key> --name <display-name> [--description <text>] [--status active|disabled] [--json]"," platform auth role inspect [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--json]"," platform auth role update [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--name <display-name>] [--description <text> | --clear-description] [--status active|disabled] [--json]"," platform auth user-role list [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> [--json]"," platform auth user-role assign [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role replace [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role remove [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --role <role-key> [--json]","","CMS commands:"," platform cms discover [--collection <name>] [--json]"," platform cms configure collection --file <spec.json> [--json]"," platform cms configure item --file <item.json> [--item-id <item-id>] [--json]"," platform cms configure category --collection <name> --name <name> --slug <slug> [--parent-id <id>] [--order <n>] [--json]"," platform cms import markdown <file> [--collection <name>] [--item-id <item-id> | --item-id-prefix <prefix>] [--tags <label,label>] [--category-path <segment/segment>] [--cover-asset-id <asset-id>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--dry-run] [--json]"," platform cms import url <url> [--collection <name>] [--item-id <item-id>] [--tags <label,label>] [--category-path <segment/segment>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--no-assetize-images] [--dry-run] [--json]"," platform cms attach asset --collection <name> --item-id <id> --field <field-name> --asset-id <id[,id]> [--replace] [--json]"," platform cms ensure category --collection <name> --path <segment/segment> [--json]"," platform cms list items --collection <name> [--page <n>] [--page-size <n>] [--status draft|published|archived] [--category-id <id>] [--q <keyword>] [--json]"," platform cms batch update --collection <name> --item-id <id[,id]> [--category-id <id> | --clear-category] [--add-tags <label,label>] [--status draft|published|archived] [--json]"," platform cms apply schema --collection <name> --version <n> [--json]"," platform cms apply publish --collection <name> --item-id <id> --status draft|published|archived [--json]"," platform cms inspect schema --collection <name> [--json]"," platform cms inspect item --collection <name> --id <id> [--json]"," platform cms inspect delivery list --collection <name> [--page <n>] [--page-size <n>] [--tag <tag>] [--category-id <id>] [--json]"," platform cms inspect delivery get --collection <name> (--slug <slug> | --id <id>) [--json]"," platform cms inspect delivery categories --collection <name> [--json]","","Asset commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>]"," platform asset list [--q <keyword>] [--media-type image|video] [--folder-id <folder-id>] [--page <n>] [--limit <n>]"," platform asset folder list"," platform asset folder create <name> [--parent-folder-id <folder-id>]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id> | --root]"," platform asset get <asset-id>"," platform asset move <asset-id> [--folder-id <folder-id> | --root]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--tags <label,label>]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>]"," platform asset tag add <asset-id> <label>"," platform asset tag remove <asset-id> <label>","","Preview commands:"," platform preview"," platform preview open [--source-version <srcver>]"," platform preview generate [--source-version <srcver>]"," platform preview generate --from-build <build-id>","","Publish commands:"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","Workflow commands:"," platform workflow template list"," platform workflow template inspect --template <key>"," platform workflow definition list [--status draft|active|inactive]"," platform workflow definition inspect --definition <key>"," platform workflow definition create --definition <key> --app <app-id> [--template <template-key> | --object-type <type> --schema <json>]"," platform workflow binding list [--app <app-id>] [--definition <key>]"," platform workflow binding inspect --definition <key> [--target-id <id>]"," platform workflow binding update --definition <key> [--target-id <id>] --file <override.json>"," platform workflow role bind --definition <key> --app <app-id> --file <bindings.json> # \u4F4E\u5C42\u9AD8\u7EA7\u5165\u53E3"," platform workflow diagnose [--app <app-id>]"," platform workflow start --definition <key> --object-type <type> --object-id <id>"," platform workflow action --instance <instance-id> --action <action-key>"," platform workflow tasks [--status pending]"," platform workflow instance <instance-id>","","Notification commands:"," platform notification inbox list [--app <app-id>] [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification inbox update <item-id> --status unread|read|dismissed|archived"," platform notification announce platform --tenant <tenant-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification announce app --tenant <tenant-id> --app <app-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification delivery [--app <app-id>] [--status pending|running|succeeded|failed|dead]"," platform notification end-user users --app <app-id>"," platform notification end-user inbox --app <app-id> --end-user <app-user-id> [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification end-user unread --app <app-id> --end-user <app-user-id>"," platform notification end-user publish --app <app-id> --end-user <app-user-id> --title <text> [--body <text>] [--kind notification|alert|announcement]"," platform notification end-user announcement --app <app-id> --end-user <app-user-id> --title <text> --body <text>"," platform notification end-user reminder --app <app-id> --end-user <app-user-id> --title <text> --remind-at <ISO datetime> [--body <text>]","","Advanced release commands:"," platform deploy [--source-version <srcver>] [--prod]"," platform rollback <release-id|version>","","Advanced build commands:"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform logs --follow"," platform diagnostics control-api [--json]"," platform worker preview-retention [--once] [--dry-run] [--json]","","Resource commands:"," platform resources diff --base-snapshot <rsnap-id>"," platform resources apply --base-snapshot <rsnap-id>"," platform resources rollback <rsnap-id> --approve-id <approve-id>","","Examples:"," platform login"," platform login --pat <personal-access-token>"," platform env use local"," platform env use test"," platform env current",' platform app create --tenant t-default --name "\u6D3B\u52A8\u9080\u8BF7\u51FD" --dir invite-frontend',' platform app create --tenant t-default --name "\u62A5\u540D\u52A9\u624B" --dir signup-runtime --template backend-app-node',' platform app create --tenant t-default --name "\u8425\u9500\u9875" --dir landing-page --template frontend-app-vite',' platform app create --tenant t-default --name "\u4E1A\u52A1\u540E\u53F0" --dir ops-console --template backend-app-node'," platform app checkout --tenant t-default --app app-demo --dir app-demo"," platform app checkout --tenant t-default --app app-demo --source-version srcver-123",' platform app submit --message "local iteration"'," platform dev push"," platform dev preview generate"," platform dev preview open",' platform asset upload ./logo.png --title "\u54C1\u724C Logo"'," platform asset folder create \u54C1\u724C\u7D20\u6750"," platform asset folder rename asset-folder-123 --name \u54C1\u724C\u89C6\u89C9 --root"," platform asset folder list"," platform asset list --q logo --tag-ids tag-1,tag-2 --page 2"," platform asset get asset-123"," platform asset move asset-123 --folder-id asset-folder-123",' platform asset update asset-123 --title "\u9996\u9875 Hero \u56FE" --scene outdoor --tags hero,homepage'," platform asset analyze asset-123"," platform asset open asset-123"," platform asset download asset-123 --variant md"," platform asset tag list --asset asset-123"," platform asset tag add asset-123 logo"," platform asset tag remove asset-123 logo"," platform app versions --tenant t-default --app app-demo"," platform whoami --tenant t-default"," platform build get build-123"," platform build events build-123"," platform build run --source-version srcver-123"," platform build validate --app app-demo --source-version srcver-123"," platform preview"," platform preview open --source-version srcver-123"," platform preview generate"," platform preview generate --source-version srcver-123"," platform publish"," platform publish status"," platform publish set --status unpublished"," platform publish set --source-version srcver-123 --status published"," platform publish rollback srcver-122"," cd signup-lite && platform dev"," cd signup-lite && platform dev push"," cd signup-lite && platform dev preview generate"," cd signup-lite && platform dev preview open"," platform deploy --source-version srcver-123"," platform deploy --prod"," platform rollback v0.2.0","","Other examples:"," platform app current"," platform tenant use t-default"," platform tenant current"," platform db status"," platform db history --limit 10"," platform db tables",' platform db query --sql "SELECT * FROM example_items LIMIT 5"'," platform auth discover --app app-demo"," platform auth configure --app app-demo --enable --template email_magic_link_only"," platform auth configure --app app-demo --enable --template phone_sms_otp_only"," platform auth configure --app app-demo --enable --template email_magic_link_and_phone_sms_otp"," platform auth configure --app app-demo --enable --enable-phone-sms-otp"," platform auth bind --app app-checkin --action bind --user-store-id us_xxx"," platform auth inspect --app app-demo --json"," platform cms discover"," platform cms discover --collection article"," platform cms configure collection --file ./cms/article.collection.json"," platform cms configure item --file ./cms/article.item.json"," platform cms import markdown ./docs/post.md --collection article --tags cms,agent --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --cover-asset-id asset-123 --publish"," platform cms import url https://zhuanlan.zhihu.com/p/488185988 --collection article --tags cms,url --dry-run"," platform cms import url https://example.com/post --collection article --no-assetize-images"," platform cms import markdown ./docs/articles --collection article --recursive --item-id-prefix article-doc --skip-existing"," platform cms import markdown ./docs/post.md --collection article --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --dry-run --json"," platform cms import markdown ./docs/post.md --collection article --skip-existing --publish"," platform cms attach asset --collection article --item-id cms-item-123 --field cover --asset-id asset-123"," platform cms ensure category --collection article --path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03"," platform cms list items --collection article --status draft"," platform cms batch update --collection article --item-id item-a,item-b --category-id cms-category-123 --add-tags cms,cli --status published"," platform cms apply schema --collection article --version 1"," platform cms inspect schema --collection article --json"," platform cms inspect item --collection article --id cms-item-123"," platform cms inspect delivery list --collection article --tag cms"," platform cms inspect delivery get --collection article --slug introducing-cms-base"," platform resources diff --base-snapshot rsnap-123"," platform resources apply --base-snapshot rsnap-123"," platform resources rollback rsnap-122 --approve-id approve-123"," platform logs --follow","","Compatible path examples:"," platform app use --tenant t-default --app app-demo --env preview"," platform init demo-app"," platform link --tenant t-default --app app-demo --env preview"," platform dev --target tenant-workbench"," platform dev --remote-bindings"," platform dev --remote-bindings=db",""].join(`
2643
+ `))}function serializeOptions(options){let result=[];for(let[key,value]of Object.entries(options))key==="help"||key==="h"||(result.push(`--${key}`),typeof value=="string"&&result.push(value));return result}async function spawnControlApiWorker(args){await new Promise((resolve19,reject)=>{let child=spawn4("corepack",["pnpm","--silent","--filter","@platform/control-api","worker",...args],{stdio:"inherit"});child.on("error",reject),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`control-api worker exited by signal ${signal}`));return}code2&&code2!==0&&(process.exitCode=code2),resolve19()})})}applyStoredEnvironmentProfile();applyDistributionProfileDefaults();loadDotenvFiles();var distributionProfile=getDistributionProfile(),cliPackageVersion=getCliPackageVersion();function persistActiveTenantSelection(tenant){let currentContext=loadStoredCliContext();persistCliContext({active_tenant_id:tenant.tenant_id,active_tenant_name:tenant.name,selected_app_tenant_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_tenant_id,selected_app_id:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_id,selected_app_env:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_env,selected_app_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_name,selected_app_display_name:contextBelongsToDifferentTenant(currentContext,tenant.tenant_id)?void 0:currentContext?.selected_app_display_name})}function currentInvocationDir(){return getInvocationCwd()}function parseArgs5(argv){let[command="help",...rest]=argv,options={},positionals=[];for(let index=0;index<rest.length;index+=1){let current=rest[index];if(current==="--help"){options.help=!0;continue}if(current==="-h"){options.h=!0;continue}if(!current.startsWith("--")){positionals.push(current);continue}let[key,inlineValue]=current.slice(2).split("=",2);if(inlineValue!==void 0){options[key]=inlineValue;continue}let next=rest[index+1];if(next&&!next.startsWith("--")){options[key]=next,index+=1;continue}options[key]=!0}return{command,rest:positionals,options}}function printHelp(){let envCommandLines=distributionProfile.name!=="developer"?[]:[" env use <profile> \u5207\u6362 CLI \u73AF\u5883 profile\uFF08\u5982 local / test\uFF09"," env current \u67E5\u770B\u5F53\u524D CLI \u73AF\u5883 profile"," env list \u67E5\u770B\u53EF\u7528 CLI \u73AF\u5883 profile"];process7.stdout.write(["platform <command>","","Commands:"," login \u5168\u5C40\u767B\u5F55\u5E76\u4FDD\u5B58\u51ED\u636E"," version \u8F93\u51FA\u5F53\u524D CLI \u7248\u672C\u53F7"," app create \u5728\u4E91\u7AEF\u521B\u5EFA\u5E94\u7528\uFF0C\u5E76 checkout \u5230\u672C\u5730\u65B0\u76EE\u5F55"," app checkout \u4ECE\u4E91\u7AEF checkout \u5E94\u7528\u6E90\u7801\u526F\u672C\u5230\u672C\u5730\u65B0\u76EE\u5F55"," app submit \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u63D0\u4EA4\u4E3A\u65B0\u7684\u4E91\u7AEF\u6E90\u7801\u7248\u672C"," app version create \u5728\u5F53\u524D app \u4E0B\u57FA\u4E8E\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C\u9AA8\u67B6"," app version list \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app versions \u67E5\u770B\u5E94\u7528\u7684\u6E90\u7801\u7248\u672C\u5217\u8868"," app status \u67E5\u770B\u5E94\u7528\u63A7\u5236\u9762\u603B\u89C8\uFF08\u542B Auth / DB / \u7248\u672C\u6982\u51B5\uFF09"," app diagnose \u67E5\u770B\u5E94\u7528\u662F\u5426\u5DF2 ready for runtime validation"," app preflight \u4E00\u6B21\u6027\u6267\u884C whoami / app current / app diagnose \u98CE\u683C\u68C0\u67E5"," app sync-platform-blocks \u540C\u6B65\u53CC\u6A21\u677F\u5E73\u53F0\u7EF4\u62A4\u533A\uFF08dry-run / adopt / apply / rollback --last\uFF09"," app import preprocess \u9884\u5904\u7406\u7B2C\u4E09\u65B9\u8BBE\u8BA1\u6E90\u7801\u5305\uFF0C\u751F\u6210 clean-source \u4E0E\u62A5\u544A"," app import stage \u628A clean-source \u4E0E\u62A5\u544A stage \u5230\u6A21\u677F\u5DE5\u4F5C\u533A"," app import merge \u628A\u4E0A\u6E38 src \u5B89\u5168\u5E76\u5165 src/imported-upstream/"," app scaffold \u6309\u9700\u6CE8\u5165\u672C\u5730 debug scaffold\uFF08auth/workflow/cms/db\uFF09"," app-library \u7BA1\u7406\u8F7B\u5E94\u7528\u8D44\u6E90\u5E93 example-app \u6761\u76EE"," app use \u517C\u5BB9\u8DEF\u5F84\uFF1A\u4E3A init/link/dev \u9009\u62E9\u76EE\u6807\u5E94\u7528"," app current \u67E5\u770B\u5F53\u524D\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587"," tenant use <id> \u8BBE\u7F6E\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587"," tenant current \u67E5\u770B\u5F53\u524D\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587",...envCommandLines," whoami \u8C03\u7528 Control API \u8F93\u51FA\u5F53\u524D\u4E3B\u4F53"," preview \u9ED8\u8BA4\u6253\u5F00\u5F53\u524D\u53EF\u7528 Preview\uFF1B\u751F\u6210\u8BF7\u7528 `platform preview generate`"," init [name] \u751F\u6210\u9879\u76EE\u9AA8\u67B6\uFF0C\u5E76\u81EA\u52A8\u5199\u5165\u5DF2\u9009\u5E94\u7528\u7ED1\u5B9A"," link \u7ED1\u5B9A tenant/app/env \u5230\u5F53\u524D\u5E94\u7528\u76EE\u5F55"," dev \u9ED8\u8BA4\u8F7B\u91CF\u5F00\u53D1\u5165\u53E3\uFF1A\u6CE8\u5165\u7ED1\u5B9A\u540E\u542F\u52A8\u672C\u5730\u5F00\u53D1\u6001"," dev push \u5C06\u5F53\u524D\u672C\u5730\u6E90\u7801\u8986\u76D6\u63A8\u9001\u5230\u4E91\u7AEF Dev Workspace"," dev preview generate \u57FA\u4E8E\u4E91\u7AEF Dev Workspace \u751F\u6210\u5DE5\u4F5C\u533A Preview"," auth \u7BA1\u7406 Auth \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / bind / inspect\uFF09"," cms \u7BA1\u7406 CMS \u57FA\u5EA7\u80FD\u529B\uFF08discover / configure / apply / inspect\uFF09"," asset \u7BA1\u7406\u79DF\u6237\u5171\u4EAB\u7D20\u6750\uFF08upload / list / folder / get / update / analyze / move / open / tag\uFF09"," blob \u7BA1\u7406 Object Storage Blob\uFF08upload / list / get / url\uFF09"," db \u67E5\u770B DB \u72B6\u6001\u3001\u8868\u7ED3\u6784\u4E0E\u53EA\u8BFB\u67E5\u8BE2"," data-form \u6821\u9A8C/\u7F16\u8BD1/apply/query Data Form schema \u4E0E\u8BB0\u5F55"," workflow \u7BA1\u7406 Workflow \u57FA\u5EA7\u80FD\u529B\uFF08template / definition / binding / runtime\uFF09"," notification \u7BA1\u7406 Notification \u57FA\u5EA7\u80FD\u529B\uFF08inbox / announce / delivery\uFF09"," publish \u7BA1\u7406\u5E94\u7528\u6B63\u5F0F\u53D1\u5E03\u72B6\u6001\u4E0E\u5F53\u524D\u90E8\u7F72\u7248\u672C"," resources \u6267\u884C\u8D44\u6E90 diff/apply/rollback"," logs \u67E5\u8BE2\u8FD0\u884C\u65F6\u65E5\u5FD7\uFF0C\u652F\u6301 --follow"," diagnostics \u5E73\u53F0\u672C\u5730\u8BCA\u65AD\uFF08control-api endpoint / readiness\uFF09"," worker \u542F\u52A8\u5E73\u53F0\u540E\u53F0 worker\uFF08preview-retention\uFF09","","Advanced commands:"," build \u9AD8\u7EA7\u8BCA\u65AD\u5165\u53E3\uFF1A\u53D1\u8D77\u548C\u67E5\u8BE2 build"," deploy \u8FC7\u6E21\u5165\u53E3\uFF1A\u9AD8\u7EA7\u53D1\u5E03\uFF08artifact / promote\uFF09"," rollback \u8FC7\u6E21\u5165\u53E3\uFF1A\u56DE\u6EDA\u5230\u76EE\u6807 release \u6216\u7248\u672C","","App commands:"," platform app create --tenant <tenant-id> --name <display-name> --dir <project-name> [--template frontend-app-vite|backend-app-node]"," platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>"," platform app checkout --tenant <tenant-id> --app <app-id> --source-version <srcver>",' platform app submit --message "local iteration"',' platform app version create --message "switch template" --template backend-app-node'," platform app versions --tenant <tenant-id> --app <app-id>"," platform app status [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app sync-platform-blocks [--dry-run|--adopt|--apply|--rollback --last]"," platform app diagnose [--tenant <tenant-id>] [--app <app-id>] [--env preview|prod]"," platform app import preprocess [--dir <third-party-source-dir>] [--dry-run]"," platform app import stage --preprocess <source-dir|.design-preprocess|reports|import-manifest.json>"," platform app import merge [--workspace-dir <template-workspace-dir>]"," platform app scaffold <auth-debug|workflow-debug|cms-debug|db-debug>"," platform app-library list"," platform app-library config init"," platform app-library inspect entry-demo"," platform app-library checkout entry-demo --dir ./example-app-demo",' platform app-library create --name "Data Form Verify" --summary "\u672C\u5730\u9A8C\u8BC1\u540E\u7684\u793A\u4F8B\u5E94\u7528"'," platform app-library submit entry-demo"," platform app use --tenant <tenant-id> --app <app-id> --env preview"," platform app current","","DB commands:"," platform db status"," platform db history --limit 10"," platform db migrate [--dry-run]"," platform db tables",' platform db query --sql "SELECT ... LIMIT 5"'," platform db open","","Auth commands:"," platform auth discover [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth configure [--tenant <tenant-id>] [--app <app-id>] --enable [--template <template>] [--user-store-id <id>] [--enable-admin-password|--disable-admin-password] [--enable-phone-sms-otp|--disable-phone-sms-otp] [--json]"," platform auth bind [--tenant <tenant-id>] [--app <app-id>] [--action bind|rebind|disable] [--user-store-id <id>] [--json]"," platform auth inspect [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role list [--tenant <tenant-id>] [--app <app-id>] [--json]"," platform auth role create [--tenant <tenant-id>] [--app <app-id>] --key <role-key> --name <display-name> [--description <text>] [--status active|disabled] [--json]"," platform auth role inspect [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--json]"," platform auth role update [--tenant <tenant-id>] [--app <app-id>] --role <role-key> [--name <display-name>] [--description <text> | --clear-description] [--status active|disabled] [--json]"," platform auth user-role list [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> [--json]"," platform auth user-role assign [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role replace [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --roles role-a,role-b [--json]"," platform auth user-role remove [--tenant <tenant-id>] [--app <app-id>] --user <app-user-id> --role <role-key> [--json]","","CMS commands:"," platform cms discover [--collection <name>] [--json]"," platform cms configure collection --file <spec.json> [--json]"," platform cms configure item --file <item.json> [--item-id <item-id>] [--json]"," platform cms configure category --collection <name> --name <name> --slug <slug> [--parent-id <id>] [--order <n>] [--json]"," platform cms import markdown <file> [--collection <name>] [--item-id <item-id> | --item-id-prefix <prefix>] [--tags <label,label>] [--category-path <segment/segment>] [--cover-asset-id <asset-id>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--dry-run] [--json]"," platform cms import url <url> [--collection <name>] [--item-id <item-id>] [--tags <label,label>] [--category-path <segment/segment>] [--publish | --publish-status draft|published|archived] [--skip-existing] [--no-assetize-images] [--dry-run] [--json]"," platform cms attach asset --collection <name> --item-id <id> --field <field-name> --asset-id <id[,id]> [--replace] [--json]"," platform cms ensure category --collection <name> --path <segment/segment> [--json]"," platform cms list items --collection <name> [--page <n>] [--page-size <n>] [--status draft|published|archived] [--category-id <id>] [--q <keyword>] [--json]"," platform cms batch update --collection <name> --item-id <id[,id]> [--category-id <id> | --clear-category] [--add-tags <label,label>] [--status draft|published|archived] [--json]"," platform cms apply schema --collection <name> --version <n> [--json]"," platform cms apply publish --collection <name> --item-id <id> --status draft|published|archived [--json]"," platform cms inspect schema --collection <name> [--json]"," platform cms inspect item --collection <name> --id <id> [--json]"," platform cms inspect delivery list --collection <name> [--page <n>] [--page-size <n>] [--tag <tag>] [--category-id <id>] [--json]"," platform cms inspect delivery get --collection <name> (--slug <slug> | --id <id>) [--json]"," platform cms inspect delivery categories --collection <name> [--json]","","Asset commands:"," platform asset upload <file-path> [--title <title>] [--folder-id <folder-id>]"," platform asset list [--q <keyword>] [--media-type image|video] [--folder-id <folder-id>] [--page <n>] [--limit <n>]"," platform asset folder list"," platform asset folder create <name> [--parent-folder-id <folder-id>]"," platform asset folder rename <folder-id> --name <name> [--parent-folder-id <folder-id> | --root]"," platform asset get <asset-id>"," platform asset move <asset-id> [--folder-id <folder-id> | --root]"," platform asset update <asset-id> [--title <title>] [--folder-id <folder-id> | --root] [--tags <label,label>]"," platform asset analyze <asset-id> [--json]"," platform asset open <asset-id> [--output <path>]"," platform asset download <asset-id> --variant thumbnail|sm|md|lg|cover [--output <path>]"," platform asset tag list [--asset <asset-id>]"," platform asset tag add <asset-id> <label>"," platform asset tag remove <asset-id> <label>","","Preview commands:"," platform preview"," platform preview open [--source-version <srcver>]"," platform preview generate [--source-version <srcver>]"," platform preview generate --from-build <build-id>","","Publish commands:"," platform publish"," platform publish status"," platform publish set [--source-version <srcver>] [--status published|unpublished]"," platform publish rollback <srcver>","","Workflow commands:"," platform workflow template list"," platform workflow template inspect --template <key>"," platform workflow definition list [--status draft|active|inactive]"," platform workflow definition inspect --definition <key>"," platform workflow definition create --definition <key> --app <app-id> [--template <template-key> | --object-type <type> --schema <json>]"," platform workflow binding list [--app <app-id>] [--definition <key>]"," platform workflow binding inspect --definition <key> [--target-id <id>]"," platform workflow binding update --definition <key> [--target-id <id>] --file <override.json>"," platform workflow role bind --definition <key> --app <app-id> --file <bindings.json> # \u4F4E\u5C42\u9AD8\u7EA7\u5165\u53E3"," platform workflow diagnose [--app <app-id>]"," platform workflow start --definition <key> --object-type <type> --object-id <id>"," platform workflow action --instance <instance-id> --action <action-key>"," platform workflow tasks [--status pending]"," platform workflow instance <instance-id>","","Notification commands:"," platform notification inbox list [--app <app-id>] [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification inbox update <item-id> --status unread|read|dismissed|archived"," platform notification announce platform --tenant <tenant-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification announce app --tenant <tenant-id> --app <app-id> --title <text> [--body <text>] [--level info|success|warning|error]"," platform notification delivery [--app <app-id>] [--status pending|running|succeeded|failed|dead]"," platform notification end-user users --app <app-id>"," platform notification end-user inbox --app <app-id> --end-user <app-user-id> [--type task_projection|announcement|notification|alert] [--status unread|read|dismissed|archived] [--limit <n>]"," platform notification end-user unread --app <app-id> --end-user <app-user-id>"," platform notification end-user publish --app <app-id> --end-user <app-user-id> --title <text> [--body <text>] [--kind notification|alert|announcement]"," platform notification end-user announcement --app <app-id> --end-user <app-user-id> --title <text> --body <text>"," platform notification end-user reminder --app <app-id> --end-user <app-user-id> --title <text> --remind-at <ISO datetime> [--body <text>]","","Advanced release commands:"," platform deploy [--source-version <srcver>] [--prod]"," platform rollback <release-id|version>","","Advanced build commands:"," platform build run --source-version <srcver>"," platform build get <build-id>"," platform build events <build-id>"," platform build validate --app <app-id> --source-version <srcver>"," platform logs --follow"," platform diagnostics control-api [--json]"," platform worker preview-retention [--once] [--dry-run] [--json]","","Resource commands:"," platform resources diff --base-snapshot <rsnap-id>"," platform resources apply --base-snapshot <rsnap-id>"," platform resources rollback <rsnap-id> --approve-id <approve-id>","","Examples:"," platform login"," platform login --pat <personal-access-token>"," platform env use local"," platform env use test"," platform env current",' platform app create --tenant t-default --name "\u6D3B\u52A8\u9080\u8BF7\u51FD" --dir invite-frontend',' platform app create --tenant t-default --name "\u62A5\u540D\u52A9\u624B" --dir signup-runtime --template backend-app-node',' platform app create --tenant t-default --name "\u8425\u9500\u9875" --dir landing-page --template frontend-app-vite',' platform app create --tenant t-default --name "\u4E1A\u52A1\u540E\u53F0" --dir ops-console --template backend-app-node'," platform app checkout --tenant t-default --app app-demo --dir app-demo"," platform app checkout --tenant t-default --app app-demo --source-version srcver-123",' platform app submit --message "local iteration"'," platform dev push"," platform dev preview generate"," platform dev preview open",' platform asset upload ./logo.png --title "\u54C1\u724C Logo"'," platform asset folder create \u54C1\u724C\u7D20\u6750"," platform asset folder rename asset-folder-123 --name \u54C1\u724C\u89C6\u89C9 --root"," platform asset folder list"," platform asset list --q logo --tag-ids tag-1,tag-2 --page 2"," platform asset get asset-123"," platform asset move asset-123 --folder-id asset-folder-123",' platform asset update asset-123 --title "\u9996\u9875 Hero \u56FE" --scene outdoor --tags hero,homepage'," platform asset analyze asset-123"," platform asset open asset-123"," platform asset download asset-123 --variant md"," platform asset tag list --asset asset-123"," platform asset tag add asset-123 logo"," platform asset tag remove asset-123 logo"," platform app versions --tenant t-default --app app-demo"," platform whoami --tenant t-default"," platform build get build-123"," platform build events build-123"," platform build run --source-version srcver-123"," platform build validate --app app-demo --source-version srcver-123"," platform preview"," platform preview open --source-version srcver-123"," platform preview generate"," platform preview generate --source-version srcver-123"," platform publish"," platform publish status"," platform publish set --status unpublished"," platform publish set --source-version srcver-123 --status published"," platform publish rollback srcver-122"," cd signup-lite && platform dev"," cd signup-lite && platform dev push"," cd signup-lite && platform dev preview generate"," cd signup-lite && platform dev preview open"," platform deploy --source-version srcver-123"," platform deploy --prod"," platform rollback v0.2.0","","Other examples:"," platform app current"," platform tenant use t-default"," platform tenant current"," platform db status"," platform db history --limit 10"," platform db tables",' platform db query --sql "SELECT * FROM example_items LIMIT 5"'," platform auth discover --app app-demo"," platform auth configure --app app-demo --enable --template email_magic_link_only"," platform auth configure --app app-demo --enable --template phone_sms_otp_only"," platform auth configure --app app-demo --enable --template email_magic_link_and_phone_sms_otp"," platform auth configure --app app-demo --enable --enable-phone-sms-otp"," platform auth bind --app app-checkin --action bind --user-store-id us_xxx"," platform auth inspect --app app-demo --json"," platform cms discover"," platform cms discover --collection article"," platform cms configure collection --file ./cms/article.collection.json"," platform cms configure item --file ./cms/article.item.json"," platform cms import markdown ./docs/post.md --collection article --tags cms,agent --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --cover-asset-id asset-123 --publish"," platform cms import url https://zhuanlan.zhihu.com/p/488185988 --collection article --tags cms,url --dry-run"," platform cms import url https://example.com/post --collection article --no-assetize-images"," platform cms import markdown ./docs/articles --collection article --recursive --item-id-prefix article-doc --skip-existing"," platform cms import markdown ./docs/post.md --collection article --category-path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03 --dry-run --json"," platform cms import markdown ./docs/post.md --collection article --skip-existing --publish"," platform cms attach asset --collection article --item-id cms-item-123 --field cover --asset-id asset-123"," platform cms ensure category --collection article --path \u4EA7\u54C1\u66F4\u65B0/\u7248\u672C\u53D1\u5E03"," platform cms list items --collection article --status draft"," platform cms batch update --collection article --item-id item-a,item-b --category-id cms-category-123 --add-tags cms,cli --status published"," platform cms apply schema --collection article --version 1"," platform cms inspect schema --collection article --json"," platform cms inspect item --collection article --id cms-item-123"," platform cms inspect delivery list --collection article --tag cms"," platform cms inspect delivery get --collection article --slug introducing-cms-base"," platform resources diff --base-snapshot rsnap-123"," platform resources apply --base-snapshot rsnap-123"," platform resources rollback rsnap-122 --approve-id approve-123"," platform logs --follow","","Compatible path examples:"," platform app use --tenant t-default --app app-demo --env preview"," platform init demo-app"," platform link --tenant t-default --app app-demo --env preview"," platform dev --target tenant-workbench"," platform dev --remote-bindings"," platform dev --remote-bindings=db",""].join(`
2643
2644
  `))}function printVersion(){process7.stdout.write(`v${cliPackageVersion}
2644
2645
  `)}function normalizeAppTemplateOption(value){return normalizeAppTemplateKey(value)}function readRequiredEnv(key){let value=process7.env[key];if(!value||value.trim().length===0)throw new Error(`\u7F3A\u5C11\u73AF\u5883\u53D8\u91CF: ${key}`);return value.trim()}function resolveBrowserLoginConfig(){let cliClientId=readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS),cliRedirectUri=readAuthConfigValue(AUTH_CLI_REDIRECT_URI_KEYS);if(cliClientId&&cliRedirectUri)return{clientId:cliClientId,redirectUri:cliRedirectUri,source:"cli-app"};let fallbackClientId=readAuthConfigValue(AUTH_TENANT_CLIENT_ID_KEYS),fallbackRedirectUri=readAuthConfigValue(AUTH_TENANT_REDIRECT_URI_KEYS);return!fallbackClientId||!fallbackRedirectUri?null:{clientId:fallbackClientId,redirectUri:fallbackRedirectUri,source:"workbench-fallback"}}function shouldFallbackToBrowserLogin(error){if(!(error instanceof Error))return!1;let message=error.message;return message.includes("OIDC discovery \u7F3A\u5C11 Device Flow \u7AEF\u70B9")||message.includes("device_code is not allowed for this client")||message.includes("grant-type:device_code is not allowed for this client")}function readOption2(args,key){let value=args.options[key];return typeof value=="string"?value:void 0}function hasFlag2(args,key){return args.options[key]===!0}function printDiagnosticsHelp(){process7.stdout.write(["platform diagnostics","","\u7528\u6CD5\uFF1A"," platform diagnostics control-api [--json]","","\u8BF4\u660E\uFF1A"," \u8F93\u51FA control/runtime/public endpoint \u5206\u533A\u8BCA\u65AD\uFF0C\u4E0D\u6539\u53D8\u9ED8\u8BA4 URL\u3002"," runtime/public endpoint \u4EC5\u5728\u914D\u7F6E\u5B58\u5728\u4E14 capability allowlist \u547D\u4E2D\u65F6\u63A2\u6D4B\u3002","","\u73AF\u5883\u53D8\u91CF\uFF1A"," CONTROL_API_BASE_URL"," RUNTIME_API_BASE_URL"," PUBLIC_API_BASE_URL"," CONTROL_API_RUNTIME_ENDPOINT_CAPABILITIES",""].join(`
2645
2646
  `))}async function runDiagnostics(args){let subcommand=args.rest[0]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")||subcommand==="help"){printDiagnosticsHelp();return}if(subcommand!=="control-api")throw printDiagnosticsHelp(),new Error(`\u672A\u77E5 diagnostics \u5B50\u547D\u4EE4: ${subcommand}`);let diagnostics=await collectControlApiFailureDiagnostics();if(args.options.json===!0){process7.stdout.write(`${JSON.stringify(diagnostics,null,2)}
2646
- `);return}process7.stdout.write(formatControlApiDiagnosticsText(diagnostics))}function readIntegerOption(args,key){let raw=readOption2(args,key);if(raw===void 0)return;let value=Number(raw);if(!Number.isInteger(value))throw new Error(`\u65E0\u6548\u7684 \`--${key}\`\uFF0C\u5FC5\u987B\u662F\u6574\u6570\u3002`);return value}function readCsvOption3(args,key){let raw=readOption2(args,key);return raw?raw.split(",").map(item=>item.trim()).filter(Boolean):[]}function readJsonInput(args,key="file"){let filePath=readOption2(args,key);if(!filePath)throw new Error(`\u7F3A\u5C11 \`--${key} <path>\`\u3002`);let content=filePath==="-"?readFileSync26(0,"utf8"):readFileSync26(filePath,"utf8");try{return JSON.parse(content)}catch(error){throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON \u8F93\u5165: ${filePath==="-"?"stdin":filePath}\u3002${error instanceof Error?` ${error.message}`:""}`)}}async function findExistingTenantCmsItemForImport(args){let lookup=args.lookup;if(!lookup)return null;if(lookup.kind==="item_id")try{return{item:await args.sdk.getTenantCmsItem({collection:args.collection,id:lookup.value}),matchedBy:"item_id"}}catch(error){if(error instanceof PlatformApiError&&error.status===404)return null;throw error}let matched=(await args.sdk.listTenantCmsItems({collection:args.collection,page:1,pageSize:20,query:lookup.value})).items.find(item=>item.system.slug===lookup.value);return matched?{item:matched,matchedBy:"slug"}:null}function resolveTenantContext(args){let linked;try{linked=readBinding(currentInvocationDir())}catch{linked=null}let storedContext=loadStoredCliContext();return readOption2(args,"tenant")??linked?.binding.tenant_id??storedContext?.selected_app_tenant_id??storedContext?.active_tenant_id}function tryReadCurrentBinding2(){try{return readBinding(currentInvocationDir())}catch{return null}}function syncSelectedAppContextFromBinding(binding){let existing=loadStoredCliContext();persistCliContext({active_tenant_id:binding.tenant_id,active_tenant_name:existing?.active_tenant_id===binding.tenant_id?existing.active_tenant_name:void 0,selected_app_tenant_id:binding.tenant_id,selected_app_id:binding.app_id,selected_app_env:binding.env,selected_app_name:binding.app_name??binding.app_id,selected_app_display_name:binding.app_display_name})}function tryReadCurrentSourceContext(){try{return readSourceContext(currentInvocationDir())}catch{return null}}function readStoredCredentialModeSafely(){try{return loadStoredCredentials()?.credential_mode}catch{return}}function readCredentialPathSafely(){try{return getCredentialPath()}catch{return}}function formatRuntimeTargetLabel(env){return env==="preview"?"\u4E91\u7AEF Preview":"\u4E91\u7AEF Prod"}function summarizePreflightAppContext(args){let binding=tryReadCurrentBinding2()?.binding??null,sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext??null,context=loadStoredCliContext(),tenantId=readOption2(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id,appId=readOption2(args,"app")??sourceContext?.app_id??binding?.app_id??context?.selected_app_id??args.rest[1],env=readOption2(args,"env")??sourceContext?.env??binding?.env??context?.selected_app_env??"preview";return sourceContext?.tenant_id&&sourceContext.app_id&&binding?.tenant_id&&binding.app_id?{status:"ready",detail:`\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A ${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:sourceContext?.tenant_id&&sourceContext.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230 source-context\uFF1A${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:binding?`${currentInvocationDir()}/.platform/config.json`:null,sourceContextPath:sourceContextResult?.path??null}:binding?.tenant_id&&binding.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230\u76EE\u5F55\u7ED1\u5B9A\uFF1A${binding.tenant_id}/${binding.app_id}/${binding.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:context?.selected_app_tenant_id&&context.selected_app_id?{status:"warning",detail:`\u5F53\u524D\u4EC5\u547D\u4E2D\u5168\u5C40 CLI \u5E94\u7528\u4E0A\u4E0B\u6587\uFF1A${context.selected_app_tenant_id}/${context.selected_app_id}/${context.selected_app_env??env}`,tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}:{status:"blocked",detail:"\u5F53\u524D\u672A\u89E3\u6790\u51FA\u53EF\u7528\u7684 tenant/app \u4E0A\u4E0B\u6587",tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}}function mergePreflightRecommendations(items){let seen=new Set,merged=[];for(let item of items){let normalized=item.trim();!normalized||seen.has(normalized)||(seen.add(normalized),merged.push(normalized))}return merged}function summarizeCheckStatuses(checks){return checks.some(item=>item.status==="blocked")?"blocked":checks.some(item=>item.status!=="ready")?"warning":"ready"}function resolveAppIdFromContext(args,positionalIndex=1){let binding=tryReadCurrentBinding2()?.binding,context=loadStoredCliContext();return readOption2(args,"app")??binding?.app_id??context?.selected_app_id??args.rest[positionalIndex]}async function collectAppControlPlaneSnapshot(args){let[overview,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings]=await Promise.all([fetchTenantOverview({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(args.credentials),tenantId:args.tenantId}),args.sdk.listTenantAppSourceVersions(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppPublishSettings(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthDiscovery(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.listTenantAppEndUsers(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppDbInstance(args.appId,args.env).catch(()=>null),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[])]),app=overview.apps.find(item=>item.id===args.appId);if(!app)throw new Error(`\u5728\u79DF\u6237 ${args.tenantId} \u4E0B\u672A\u627E\u5230\u5E94\u7528 ${args.appId}\u3002`);return{overview,app,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings}}function buildAppStatusPayload(args){let{tenantId,appId,env,snapshot}=args,authEnabled=snapshot.authConfig?.auth_enabled===!0,appUserItems=snapshot.appUsers?.items??[],blockedCount=appUserItems.filter(item=>item.status==="blocked").length,envOverview=snapshot.overview.environments.filter(item=>item.app_id===appId),previewEnv=envOverview.find(item=>item.env==="preview"),prodEnv=envOverview.find(item=>item.env==="prod"),previewDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),latestSourceVersion=snapshot.sourceVersions.items[0]??null;return{tenant_id:tenantId,app_id:appId,env,app:{display_name:snapshot.app.name,slug:snapshot.app.slug??null,template_key:snapshot.app.template_key??null,publish_status:snapshot.publishSettings?.publish_status??snapshot.app.publish_status,source_versions_count:snapshot.sourceVersions.items.length,latest_source_version_id:latestSourceVersion?.source_version_id??null,latest_source_version_message:latestSourceVersion?.message??null,latest_deployment_class_suggested:latestSourceVersion?.deployment_class_suggested??null,latest_deployment_class_post_build:latestSourceVersion?.deployment_class_post_build??null},publish:{deployment_class_confirmed:snapshot.publishSettings?.deployment_class_confirmed??null,current_deployment_class_used:snapshot.publishSettings?.current_deployment_class_used??null,current_artifact_kind:snapshot.publishSettings?.current_artifact_kind??null,current_execution_mode:snapshot.publishSettings?.current_execution_mode??null,current_object_prefix:snapshot.publishSettings?.current_object_prefix??null,public_prod_url:snapshot.publishSettings?.public_prod_url??null},auth:{enabled:authEnabled,capability_name:snapshot.authConfig?.capability_name??"auth",capability_version:snapshot.authConfig?.capability_version??null,contract_version:snapshot.authConfig?.contract_version??null,user_store_id:snapshot.authConfig?.user_store_id??null,binding_id:snapshot.authConfig?.binding_id??null,binding_mode:snapshot.authConfig?.binding_mode??null,binding_status:snapshot.authConfig?.binding_status??null,auth_template:snapshot.authConfig?.auth_template??null,ui_driver:snapshot.authConfig?.ui_driver??null,enabled_recipes:snapshot.authConfig?.enabled_recipes??[],sign_in_methods:snapshot.authConfig?.sign_in_methods?.map(item=>item.method)??[],registration_mode:snapshot.authConfig?.registration_mode??null,auto_provision_app_user:typeof snapshot.authConfig?.auto_provision_app_user=="boolean"?snapshot.authConfig.auto_provision_app_user:null,owner_service:snapshot.authConfig?.owner_service??null,last_runtime_status:snapshot.authConfig?.last_runtime_status??null,inspect_status:snapshot.authInspect?.inspect_status??null,inspect_issues:snapshot.authInspect?.issues??[],runtime_environments:snapshot.authInspect?.environments.map(item=>({env:item.env,status:item.status,missing_binding_keys:item.missing_binding_keys,issues:item.issues,updated_at:item.updated_at??null}))??[],app_user_count:appUserItems.length,blocked_app_user_count:blockedCount},runtime:{preview:{version:previewEnv?.version??null,health:previewEnv?.health??previewDeployment?.health??null,source_version_id:previewEnv?.source_version_id??previewDeployment?.source_version_id??null,preview_url:previewDeployment?.preview_url??null},prod:{version:prodEnv?.version??null,health:prodEnv?.health??prodDeployment?.health??null,source_version_id:prodEnv?.source_version_id??prodDeployment?.source_version_id??null}},db:{bound:snapshot.dbInstance?.bound??!1,status:snapshot.dbInstance?.status??null,schema_name:snapshot.dbInstance?.schema_name??null,database_name:snapshot.dbInstance?.database_name??null,tables_count:typeof snapshot.dbInstance?.tables_count=="number"?snapshot.dbInstance.tables_count:null,latest_migration:snapshot.dbInstance?.latest_migration?.migration_path??null},workflow:{active_definition_count:snapshot.workflowDefinitions.length,binding_count:snapshot.workflowBindings.length,definitions:snapshot.workflowDefinitions.map(item=>({definition_key:item.definition_key,status:item.status,object_type:item.object_type})),bindings:snapshot.workflowBindings.map(item=>({definition_key:item.definition_key,target_id:item.target_id,target_scope:item.target_scope,status:item.status}))}}}function buildAppDiagnosePayload(args){let authEnv=args.statusPayload.auth.runtime_environments.find(item=>item.env===args.env)??null,dbTablesCount=args.statusPayload.db.tables_count,databaseStatus=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?"warning":"ready":"warning",databaseDetail=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"} (0 tables)`:`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"}`:"\u5F53\u524D\u73AF\u5883\u672A\u5B8C\u6210 DB \u7ED1\u5B9A",checks={app_context:{status:args.bindingPath?"ready":"warning",detail:args.bindingPath?`\u5DF2\u7ED1\u5B9A\u9879\u76EE\u76EE\u5F55 (${args.bindingPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/config.json`"},auth_runtime:{status:args.statusPayload.auth.enabled&&authEnv?.status==="ready"?"ready":args.statusPayload.auth.enabled?"warning":"not_configured",detail:args.statusPayload.auth.enabled?authEnv?`${args.env}=${authEnv.status}`:`\u7F3A\u5C11 ${args.env} \u8FD0\u884C\u65F6\u68C0\u67E5\u7ED3\u679C`:"\u5F53\u524D app \u672A\u542F\u7528 Auth\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u767B\u5F55\uFF0C\u53EF\u5FFD\u7565"},database:{status:databaseStatus,detail:databaseDetail},workflow:{status:args.statusPayload.workflow.active_definition_count>0&&args.statusPayload.workflow.binding_count>0?"ready":args.statusPayload.workflow.active_definition_count>0?"warning":"not_configured",detail:args.statusPayload.workflow.active_definition_count>0?`definitions=${args.statusPayload.workflow.active_definition_count}, bindings=${args.statusPayload.workflow.binding_count}`:"\u5F53\u524D app \u672A\u914D\u7F6E Workflow\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u53EF\u5FFD\u7565"},preview_runtime:{status:args.env==="preview"?args.statusPayload.runtime.preview.preview_url?"ready":"warning":args.statusPayload.runtime.prod.source_version_id?"ready":"warning",detail:args.env==="preview"?args.statusPayload.runtime.preview.preview_url??"\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u4E91\u7AEF Preview \u5730\u5740":args.statusPayload.runtime.prod.source_version_id??"\u5F53\u524D\u6CA1\u6709\u4E91\u7AEF Prod \u90E8\u7F72\u7248\u672C"},source_version:{status:args.statusPayload.app.latest_source_version_id?"ready":"warning",detail:args.statusPayload.app.latest_source_version_id??"\u5F53\u524D\u5E94\u7528\u8FD8\u6CA1\u6709\u63D0\u4EA4\u8FC7\u6E90\u7801\u7248\u672C"},source_context:{status:args.sourceContextPath?"ready":"warning",detail:args.sourceContextPath?`\u5DF2\u8BB0\u5F55\u6E90\u7801\u4E0A\u4E0B\u6587 (${args.sourceContextPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/source-context.json`"}},recommendations=[];return args.bindingPath||recommendations.push("\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>`\uFF0C\u6216\u5728\u73B0\u6709\u76EE\u5F55\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002"),args.statusPayload.app.latest_source_version_id||recommendations.push('\u6267\u884C `platform app submit --message "initial iteration"` \u751F\u6210\u9996\u4E2A\u6E90\u7801\u7248\u672C\u3002'),args.statusPayload.auth.enabled&&authEnv?.status!=="ready"&&recommendations.push(`\u6267\u884C \`platform auth inspect\` \u786E\u8BA4 ${args.env} \u73AF\u5883\u7F3A\u5931\u7684\u8FD0\u884C\u65F6\u7ED1\u5B9A\uFF0C\u518D\u6839\u636E\u7ED3\u679C\u6267\u884C \`platform resources apply --env `+args.env+"`\u3002"),args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0&&recommendations.push("\u5F53\u524D DB \u5DF2\u7ED1\u5B9A\uFF0C\u4F46 schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A `resources/db/migrations/` \u91CC\u7684\u7A7A scaffold \u6539\u6210\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate`\u3001`platform db tables`\u3002"):recommendations.push("\u5982\u679C\u5F53\u524D app \u9700\u8981 DB\uFF0C\u518D\u6267\u884C `platform resources apply --env "+args.env+"`\uFF0C\u8BA9 DB \u7ED1\u5B9A\u548C\u8FC1\u79FB\u843D\u5230\u76EE\u6807\u73AF\u5883\u3002"),args.statusPayload.workflow.active_definition_count===0?recommendations.push("\u5982\u679C\u5F53\u524D app \u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u518D\u6267\u884C `platform workflow definition create ...` \u4E0E `platform workflow binding update ...`\u3002"):args.statusPayload.workflow.binding_count===0&&recommendations.push("Workflow definition \u5DF2\u5B58\u5728\uFF0C\u4F46\u7F3A\u5C11 app \u7EA7 binding\uFF1B\u8865\u6267\u884C `platform workflow binding update ...`\u3002"),args.env==="preview"&&!args.statusPayload.runtime.preview.preview_url&&recommendations.push("\u6267\u884C `platform preview generate` \u751F\u6210\u4E91\u7AEF Preview\uFF1B\u8FD9\u4E00\u6B65\u4E0D\u540C\u4E8E\u672C\u5730 `platform dev` \u9884\u89C8\u3002"),args.env==="prod"&&!args.statusPayload.runtime.prod.source_version_id&&recommendations.push("\u4E91\u7AEF Prod \u4E0D\u4F1A\u968F\u7740 Preview \u81EA\u52A8\u66F4\u65B0\uFF1B\u5982\u9700\u4E0A\u7EBF\u6B63\u5F0F\u73AF\u5883\uFF0C\u8BF7\u6267\u884C `platform publish set --source-version <srcver> --status published`\u3002"),recommendations.length===0&&recommendations.push(args.env==="prod"?"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D prod \u5DF2\u57FA\u672C ready\uFF1B\u540E\u7EED\u82E5\u8981\u5207\u6362\u6B63\u5F0F\u7248\u672C\uFF0C\u8BF7\u7EE7\u7EED\u4F7F\u7528 `platform publish`\u3002":"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D\u5E94\u7528\u5DF2\u57FA\u672C ready\uFF1B\u4E0B\u4E00\u6B65\u53EF\u76F4\u63A5\u505A\u9875\u9762\u8054\u8C03\u6216\u8FD0\u884C\u65F6\u9A8C\u8BC1\u3002"),{tenant_id:args.tenantId,app_id:args.appId,env:args.env,checks,recommendations}}function findDevPreviewTimelineItem(items,target){return items.find(item=>item.env==="preview"&&target.deploymentId&&item.deployment_id===target.deploymentId)??items.find(item=>item.env==="preview"&&target.releaseId&&item.release_id===target.releaseId)??items.find(item=>item.env==="preview"&&item.is_current_release)??null}function formatDevPreviewLines(args){let lines=[args.title,`tenant/app: ${args.tenantId}/${args.appId}`,`source version: ${args.sourceVersionId??"-"}`,`build: ${args.buildId??"-"}`,`release: ${args.releaseId??"-"}`,`deployment: ${args.deploymentId??"-"}`];return args.previewUrl&&lines.push(`preview url: ${args.previewUrl}`),args.health&&lines.push(`health: ${args.health}`),args.healthCheckUrl&&lines.push(`health_check_url: ${args.healthCheckUrl}`),args.message&&lines.push(`message: ${args.message}`),args.failureReason&&lines.push(`failure_reason: ${args.failureReason}`),args.diagnosticUrl&&lines.push(`diagnostic_url: ${args.diagnosticUrl}`),lines}function createTenantScopedSdk(credentials,tenantId,options={}){if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");return createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:options.capability,requestClass:options.requestClass??"control"})}async function loadRemoteDbRuntimeBindings(binding,requestedBindings){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)return{values:{},cleanup:null};let env=binding.env==="prod"?"prod":"preview",sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:binding.tenant_id,capability:"db",requestClass:"control"}),result=await sdk.resolveDevRuntimeBindings({app_id:binding.app_id,env,requested_bindings:requestedBindings});if(result.mode==="unavailable")throw new Error([result.message??"\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\u3002",result.remediation,result.request_id?`request_id: ${result.request_id}`:void 0].filter(item=>!!(item&&item.trim().length>0)).join(`
2647
+ `);return}process7.stdout.write(formatControlApiDiagnosticsText(diagnostics))}function readIntegerOption(args,key){let raw=readOption2(args,key);if(raw===void 0)return;let value=Number(raw);if(!Number.isInteger(value))throw new Error(`\u65E0\u6548\u7684 \`--${key}\`\uFF0C\u5FC5\u987B\u662F\u6574\u6570\u3002`);return value}function readCsvOption3(args,key){let raw=readOption2(args,key);return raw?raw.split(",").map(item=>item.trim()).filter(Boolean):[]}function readJsonInput(args,key="file"){let filePath=readOption2(args,key);if(!filePath)throw new Error(`\u7F3A\u5C11 \`--${key} <path>\`\u3002`);let content=filePath==="-"?readFileSync26(0,"utf8"):readFileSync26(filePath,"utf8");try{return JSON.parse(content)}catch(error){throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON \u8F93\u5165: ${filePath==="-"?"stdin":filePath}\u3002${error instanceof Error?` ${error.message}`:""}`)}}async function findExistingTenantCmsItemForImport(args){let lookup=args.lookup;if(!lookup)return null;if(lookup.kind==="item_id")try{return{item:await args.sdk.getTenantCmsItem({collection:args.collection,id:lookup.value}),matchedBy:"item_id"}}catch(error){if(error instanceof PlatformApiError&&error.status===404)return null;throw error}let matched=(await args.sdk.listTenantCmsItems({collection:args.collection,page:1,pageSize:20,query:lookup.value})).items.find(item=>item.system.slug===lookup.value);return matched?{item:matched,matchedBy:"slug"}:null}function resolveTenantContext(args,startDir=currentInvocationDir()){let linked;try{linked=readBinding(startDir)}catch{linked=null}let storedContext=loadStoredCliContext();return readOption2(args,"tenant")??linked?.binding.tenant_id??storedContext?.selected_app_tenant_id??storedContext?.active_tenant_id}function tryReadCurrentBinding2(){try{return readBinding(currentInvocationDir())}catch{return null}}function syncSelectedAppContextFromBinding(binding){let existing=loadStoredCliContext();persistCliContext({active_tenant_id:binding.tenant_id,active_tenant_name:existing?.active_tenant_id===binding.tenant_id?existing.active_tenant_name:void 0,selected_app_tenant_id:binding.tenant_id,selected_app_id:binding.app_id,selected_app_env:binding.env,selected_app_name:binding.app_name??binding.app_id,selected_app_display_name:binding.app_display_name})}function tryReadCurrentSourceContext(){try{return readSourceContext(currentInvocationDir())}catch{return null}}function readStoredCredentialModeSafely(){try{return loadStoredCredentials()?.credential_mode}catch{return}}function readCredentialPathSafely(){try{return getCredentialPath()}catch{return}}function formatRuntimeTargetLabel(env){return env==="preview"?"\u4E91\u7AEF Preview":"\u4E91\u7AEF Prod"}function summarizePreflightAppContext(args){let binding=tryReadCurrentBinding2()?.binding??null,sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext??null,context=loadStoredCliContext(),tenantId=readOption2(args,"tenant")??sourceContext?.tenant_id??binding?.tenant_id??context?.selected_app_tenant_id??context?.active_tenant_id,appId=readOption2(args,"app")??sourceContext?.app_id??binding?.app_id??context?.selected_app_id??args.rest[1],env=readOption2(args,"env")??sourceContext?.env??binding?.env??context?.selected_app_env??"preview";return sourceContext?.tenant_id&&sourceContext.app_id&&binding?.tenant_id&&binding.app_id?{status:"ready",detail:`\u5F53\u524D\u76EE\u5F55\u5DF2\u7ED1\u5B9A ${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:sourceContext?.tenant_id&&sourceContext.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230 source-context\uFF1A${sourceContext.tenant_id}/${sourceContext.app_id}/${sourceContext.env??env}`,tenantId,appId,env,bindingPath:binding?`${currentInvocationDir()}/.platform/config.json`:null,sourceContextPath:sourceContextResult?.path??null}:binding?.tenant_id&&binding.app_id?{status:"warning",detail:`\u5F53\u524D\u76EE\u5F55\u4EC5\u68C0\u6D4B\u5230\u76EE\u5F55\u7ED1\u5B9A\uFF1A${binding.tenant_id}/${binding.app_id}/${binding.env??env}`,tenantId,appId,env,bindingPath:`${currentInvocationDir()}/.platform/config.json`,sourceContextPath:sourceContextResult?.path??null}:context?.selected_app_tenant_id&&context.selected_app_id?{status:"warning",detail:`\u5F53\u524D\u4EC5\u547D\u4E2D\u5168\u5C40 CLI \u5E94\u7528\u4E0A\u4E0B\u6587\uFF1A${context.selected_app_tenant_id}/${context.selected_app_id}/${context.selected_app_env??env}`,tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}:{status:"blocked",detail:"\u5F53\u524D\u672A\u89E3\u6790\u51FA\u53EF\u7528\u7684 tenant/app \u4E0A\u4E0B\u6587",tenantId,appId,env,bindingPath:null,sourceContextPath:sourceContextResult?.path??null}}function mergePreflightRecommendations(items){let seen=new Set,merged=[];for(let item of items){let normalized=item.trim();!normalized||seen.has(normalized)||(seen.add(normalized),merged.push(normalized))}return merged}function summarizeCheckStatuses(checks){return checks.some(item=>item.status==="blocked")?"blocked":checks.some(item=>item.status!=="ready")?"warning":"ready"}function resolveAppIdFromContext(args,positionalIndex=1){let binding=tryReadCurrentBinding2()?.binding,context=loadStoredCliContext();return readOption2(args,"app")??binding?.app_id??context?.selected_app_id??args.rest[positionalIndex]}async function collectAppControlPlaneSnapshot(args){let[overview,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings]=await Promise.all([fetchTenantOverview({baseUrl:getControlApiBaseUrl(),accessToken:selectApiToken(args.credentials),tenantId:args.tenantId}),args.sdk.listTenantAppSourceVersions(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppPublishSettings(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthDiscovery(args.appId).catch(()=>null),args.sdk.getTenantAppEndUserAuthInspect(args.appId).catch(()=>null),args.sdk.listTenantAppEndUsers(args.appId).catch(()=>({items:[]})),args.sdk.getTenantAppDbInstance(args.appId,args.env).catch(()=>null),args.sdk.listTenantAppDeploymentTimeline(args.appId,{limit:10}).catch(()=>({items:[]})),args.sdk.listWorkflowDefinitions({target_id:args.appId,status:"active"}).catch(()=>[]),args.sdk.listWorkflowBindings({target_id:args.appId}).catch(()=>[])]),app=overview.apps.find(item=>item.id===args.appId);if(!app)throw new Error(`\u5728\u79DF\u6237 ${args.tenantId} \u4E0B\u672A\u627E\u5230\u5E94\u7528 ${args.appId}\u3002`);return{overview,app,sourceVersions,publishSettings,authConfig,authInspect,appUsers,dbInstance,deploymentTimeline,workflowDefinitions,workflowBindings}}function buildAppStatusPayload(args){let{tenantId,appId,env,snapshot}=args,authEnabled=snapshot.authConfig?.auth_enabled===!0,appUserItems=snapshot.appUsers?.items??[],blockedCount=appUserItems.filter(item=>item.status==="blocked").length,envOverview=snapshot.overview.environments.filter(item=>item.app_id===appId),previewEnv=envOverview.find(item=>item.env==="preview"),prodEnv=envOverview.find(item=>item.env==="prod"),previewDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="preview"&&item.is_current_release),prodDeployment=snapshot.deploymentTimeline.items.find(item=>item.env==="prod"&&item.is_current_release),latestSourceVersion=snapshot.sourceVersions.items[0]??null;return{tenant_id:tenantId,app_id:appId,env,app:{display_name:snapshot.app.name,slug:snapshot.app.slug??null,template_key:snapshot.app.template_key??null,publish_status:snapshot.publishSettings?.publish_status??snapshot.app.publish_status,source_versions_count:snapshot.sourceVersions.items.length,latest_source_version_id:latestSourceVersion?.source_version_id??null,latest_source_version_message:latestSourceVersion?.message??null,latest_deployment_class_suggested:latestSourceVersion?.deployment_class_suggested??null,latest_deployment_class_post_build:latestSourceVersion?.deployment_class_post_build??null},publish:{deployment_class_confirmed:snapshot.publishSettings?.deployment_class_confirmed??null,current_deployment_class_used:snapshot.publishSettings?.current_deployment_class_used??null,current_artifact_kind:snapshot.publishSettings?.current_artifact_kind??null,current_execution_mode:snapshot.publishSettings?.current_execution_mode??null,current_object_prefix:snapshot.publishSettings?.current_object_prefix??null,public_prod_url:snapshot.publishSettings?.public_prod_url??null},auth:{enabled:authEnabled,capability_name:snapshot.authConfig?.capability_name??"auth",capability_version:snapshot.authConfig?.capability_version??null,contract_version:snapshot.authConfig?.contract_version??null,user_store_id:snapshot.authConfig?.user_store_id??null,binding_id:snapshot.authConfig?.binding_id??null,binding_mode:snapshot.authConfig?.binding_mode??null,binding_status:snapshot.authConfig?.binding_status??null,auth_template:snapshot.authConfig?.auth_template??null,ui_driver:snapshot.authConfig?.ui_driver??null,enabled_recipes:snapshot.authConfig?.enabled_recipes??[],sign_in_methods:snapshot.authConfig?.sign_in_methods?.map(item=>item.method)??[],registration_mode:snapshot.authConfig?.registration_mode??null,auto_provision_app_user:typeof snapshot.authConfig?.auto_provision_app_user=="boolean"?snapshot.authConfig.auto_provision_app_user:null,owner_service:snapshot.authConfig?.owner_service??null,last_runtime_status:snapshot.authConfig?.last_runtime_status??null,inspect_status:snapshot.authInspect?.inspect_status??null,inspect_issues:snapshot.authInspect?.issues??[],runtime_environments:snapshot.authInspect?.environments.map(item=>({env:item.env,status:item.status,missing_binding_keys:item.missing_binding_keys,issues:item.issues,updated_at:item.updated_at??null}))??[],app_user_count:appUserItems.length,blocked_app_user_count:blockedCount},runtime:{preview:{version:previewEnv?.version??null,health:previewEnv?.health??previewDeployment?.health??null,source_version_id:previewEnv?.source_version_id??previewDeployment?.source_version_id??null,preview_url:previewDeployment?.preview_url??null},prod:{version:prodEnv?.version??null,health:prodEnv?.health??prodDeployment?.health??null,source_version_id:prodEnv?.source_version_id??prodDeployment?.source_version_id??null}},db:{bound:snapshot.dbInstance?.bound??!1,status:snapshot.dbInstance?.status??null,schema_name:snapshot.dbInstance?.schema_name??null,database_name:snapshot.dbInstance?.database_name??null,tables_count:typeof snapshot.dbInstance?.tables_count=="number"?snapshot.dbInstance.tables_count:null,latest_migration:snapshot.dbInstance?.latest_migration?.migration_path??null},workflow:{active_definition_count:snapshot.workflowDefinitions.length,binding_count:snapshot.workflowBindings.length,definitions:snapshot.workflowDefinitions.map(item=>({definition_key:item.definition_key,status:item.status,object_type:item.object_type})),bindings:snapshot.workflowBindings.map(item=>({definition_key:item.definition_key,target_id:item.target_id,target_scope:item.target_scope,status:item.status}))}}}function buildAppDiagnosePayload(args){let authEnv=args.statusPayload.auth.runtime_environments.find(item=>item.env===args.env)??null,dbTablesCount=args.statusPayload.db.tables_count,databaseStatus=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?"warning":"ready":"warning",databaseDetail=args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0?`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"} (0 tables)`:`${args.statusPayload.db.database_name??"-"} / ${args.statusPayload.db.schema_name??"-"}`:"\u5F53\u524D\u73AF\u5883\u672A\u5B8C\u6210 DB \u7ED1\u5B9A",checks={app_context:{status:args.bindingPath?"ready":"warning",detail:args.bindingPath?`\u5DF2\u7ED1\u5B9A\u9879\u76EE\u76EE\u5F55 (${args.bindingPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/config.json`"},auth_runtime:{status:args.statusPayload.auth.enabled&&authEnv?.status==="ready"?"ready":args.statusPayload.auth.enabled?"warning":"not_configured",detail:args.statusPayload.auth.enabled?authEnv?`${args.env}=${authEnv.status}`:`\u7F3A\u5C11 ${args.env} \u8FD0\u884C\u65F6\u68C0\u67E5\u7ED3\u679C`:"\u5F53\u524D app \u672A\u542F\u7528 Auth\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u767B\u5F55\uFF0C\u53EF\u5FFD\u7565"},database:{status:databaseStatus,detail:databaseDetail},workflow:{status:args.statusPayload.workflow.active_definition_count>0&&args.statusPayload.workflow.binding_count>0?"ready":args.statusPayload.workflow.active_definition_count>0?"warning":"not_configured",detail:args.statusPayload.workflow.active_definition_count>0?`definitions=${args.statusPayload.workflow.active_definition_count}, bindings=${args.statusPayload.workflow.binding_count}`:"\u5F53\u524D app \u672A\u914D\u7F6E Workflow\uFF1B\u5982\u679C\u5F53\u524D\u6A21\u677F\u4E0D\u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u53EF\u5FFD\u7565"},preview_runtime:{status:args.env==="preview"?args.statusPayload.runtime.preview.preview_url?"ready":"warning":args.statusPayload.runtime.prod.source_version_id?"ready":"warning",detail:args.env==="preview"?args.statusPayload.runtime.preview.preview_url??"\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u4E91\u7AEF Preview \u5730\u5740":args.statusPayload.runtime.prod.source_version_id??"\u5F53\u524D\u6CA1\u6709\u4E91\u7AEF Prod \u90E8\u7F72\u7248\u672C"},source_version:{status:args.statusPayload.app.latest_source_version_id?"ready":"warning",detail:args.statusPayload.app.latest_source_version_id??"\u5F53\u524D\u5E94\u7528\u8FD8\u6CA1\u6709\u63D0\u4EA4\u8FC7\u6E90\u7801\u7248\u672C"},source_context:{status:args.sourceContextPath?"ready":"warning",detail:args.sourceContextPath?`\u5DF2\u8BB0\u5F55\u6E90\u7801\u4E0A\u4E0B\u6587 (${args.sourceContextPath})`:"\u5F53\u524D\u76EE\u5F55\u672A\u68C0\u6D4B\u5230 `.platform/source-context.json`"}},recommendations=[];return args.bindingPath||recommendations.push("\u5148\u6267\u884C `platform app checkout --tenant <tenant-id> --app <app-id> --dir <project-name>`\uFF0C\u6216\u5728\u73B0\u6709\u76EE\u5F55\u6267\u884C `platform link --tenant <tenant-id> --app <app-id> --env preview`\u3002"),args.statusPayload.app.latest_source_version_id||recommendations.push('\u6267\u884C `platform app submit --message "initial iteration"` \u751F\u6210\u9996\u4E2A\u6E90\u7801\u7248\u672C\u3002'),args.statusPayload.auth.enabled&&authEnv?.status!=="ready"&&recommendations.push(`\u6267\u884C \`platform auth inspect\` \u786E\u8BA4 ${args.env} \u73AF\u5883\u7F3A\u5931\u7684\u8FD0\u884C\u65F6\u7ED1\u5B9A\uFF0C\u518D\u6839\u636E\u7ED3\u679C\u6267\u884C \`platform resources apply --env `+args.env+"`\u3002"),args.statusPayload.db.bound?typeof dbTablesCount=="number"&&dbTablesCount===0&&recommendations.push("\u5F53\u524D DB \u5DF2\u7ED1\u5B9A\uFF0C\u4F46 schema \u4ECD\u4E3A 0 \u8868\u3002\u82E5\u4F60\u8BA1\u5212\u63A5\u5165\u4E1A\u52A1 DB\uFF0C\u8BF7\u5148\u628A `resources/db/migrations/` \u91CC\u7684\u7A7A scaffold \u6539\u6210\u771F\u5B9E migration\uFF0C\u518D\u6267\u884C `platform db migrate`\u3001`platform db tables`\u3002"):recommendations.push("\u5982\u679C\u5F53\u524D app \u9700\u8981 DB\uFF0C\u518D\u6267\u884C `platform resources apply --env "+args.env+"`\uFF0C\u8BA9 DB \u7ED1\u5B9A\u548C\u8FC1\u79FB\u843D\u5230\u76EE\u6807\u73AF\u5883\u3002"),args.statusPayload.workflow.active_definition_count===0?recommendations.push("\u5982\u679C\u5F53\u524D app \u4F9D\u8D56\u5BA1\u6279\u6D41\uFF0C\u518D\u6267\u884C `platform workflow definition create ...` \u4E0E `platform workflow binding update ...`\u3002"):args.statusPayload.workflow.binding_count===0&&recommendations.push("Workflow definition \u5DF2\u5B58\u5728\uFF0C\u4F46\u7F3A\u5C11 app \u7EA7 binding\uFF1B\u8865\u6267\u884C `platform workflow binding update ...`\u3002"),args.env==="preview"&&!args.statusPayload.runtime.preview.preview_url&&recommendations.push("\u6267\u884C `platform preview generate` \u751F\u6210\u4E91\u7AEF Preview\uFF1B\u8FD9\u4E00\u6B65\u4E0D\u540C\u4E8E\u672C\u5730 `platform dev` \u9884\u89C8\u3002"),args.env==="prod"&&!args.statusPayload.runtime.prod.source_version_id&&recommendations.push("\u4E91\u7AEF Prod \u4E0D\u4F1A\u968F\u7740 Preview \u81EA\u52A8\u66F4\u65B0\uFF1B\u5982\u9700\u4E0A\u7EBF\u6B63\u5F0F\u73AF\u5883\uFF0C\u8BF7\u6267\u884C `platform publish set --source-version <srcver> --status published`\u3002"),recommendations.length===0&&recommendations.push(args.env==="prod"?"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D prod \u5DF2\u57FA\u672C ready\uFF1B\u540E\u7EED\u82E5\u8981\u5207\u6362\u6B63\u5F0F\u7248\u672C\uFF0C\u8BF7\u7EE7\u7EED\u4F7F\u7528 `platform publish`\u3002":"\u63A7\u5236\u9762\u89C6\u89D2\u4E0B\u5F53\u524D\u5E94\u7528\u5DF2\u57FA\u672C ready\uFF1B\u4E0B\u4E00\u6B65\u53EF\u76F4\u63A5\u505A\u9875\u9762\u8054\u8C03\u6216\u8FD0\u884C\u65F6\u9A8C\u8BC1\u3002"),{tenant_id:args.tenantId,app_id:args.appId,env:args.env,checks,recommendations}}function findDevPreviewTimelineItem(items,target){return items.find(item=>item.env==="preview"&&target.deploymentId&&item.deployment_id===target.deploymentId)??items.find(item=>item.env==="preview"&&target.releaseId&&item.release_id===target.releaseId)??items.find(item=>item.env==="preview"&&item.is_current_release)??null}function formatDevPreviewLines(args){let lines=[args.title,`tenant/app: ${args.tenantId}/${args.appId}`,`source version: ${args.sourceVersionId??"-"}`,`build: ${args.buildId??"-"}`,`release: ${args.releaseId??"-"}`,`deployment: ${args.deploymentId??"-"}`];return args.previewUrl&&lines.push(`preview url: ${args.previewUrl}`),args.health&&lines.push(`health: ${args.health}`),args.healthCheckUrl&&lines.push(`health_check_url: ${args.healthCheckUrl}`),args.message&&lines.push(`message: ${args.message}`),args.failureReason&&lines.push(`failure_reason: ${args.failureReason}`),args.diagnosticUrl&&lines.push(`diagnostic_url: ${args.diagnosticUrl}`),lines}function createTenantScopedSdk(credentials,tenantId,options={}){if(!credentials)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");return createControlApiSdk({accessToken:selectApiToken(credentials),tenantId,capability:options.capability,requestClass:options.requestClass??"control"})}async function loadRemoteDbRuntimeBindings(binding,requestedBindings){let credentials=await loadStoredCredentialsEnsuringFresh();if(!credentials)return{values:{},cleanup:null};let env=binding.env==="prod"?"prod":"preview",sdk=createControlApiSdk({accessToken:selectApiToken(credentials),tenantId:binding.tenant_id,capability:"db",requestClass:"control"}),result=await sdk.resolveDevRuntimeBindings({app_id:binding.app_id,env,requested_bindings:requestedBindings});if(result.mode==="unavailable")throw new Error([result.message??"\u5F53\u524D\u73AF\u5883\u5C1A\u672A\u63D0\u4F9B\u5F00\u53D1\u673A\u53EF\u8FBE\u7684 DB binding\u3002",result.remediation,result.request_id?`request_id: ${result.request_id}`:void 0].filter(item=>!!(item&&item.trim().length>0)).join(`
2647
2648
  `));return{values:result.values,cleanup:result.session_id?async()=>{try{await sdk.revokeDevRuntimeBindings({app_id:binding.app_id,env,session_id:result.session_id})}catch{}}:null}}function resolveRequestedRemoteBindings(args,startDir=process7.cwd()){let explicitValue=readOption2(args,"remote-bindings")?.trim().toLowerCase();if(!explicitValue||explicitValue==="auto")return{capabilities:detectRequestedRemoteBindings(startDir),mode:"auto"};if(explicitValue==="db")return{capabilities:["db"],mode:"db"};throw new Error("`platform dev --remote-bindings` \u76EE\u524D\u4EC5\u652F\u6301 `auto` \u6216 `db`\u3002")}async function runLogin(args){let issuer=readRequiredEnv("OIDC_ISSUER"),audience=process7.env.OIDC_AUDIENCE?.trim(),scopes=(process7.env.LOGTO_CLI_SCOPES??"openid profile offline_access").split(/\s+/u).filter(Boolean),cliClientId=readAuthConfigValue(AUTH_CLI_CLIENT_ID_KEYS),browserLoginConfig=resolveBrowserLoginConfig(),pat=readOption2(args,"pat")?.trim(),credentials;if(pat){if(!cliClientId)throw new Error("`platform login --pat` \u9700\u8981\u5DF2\u914D\u7F6E `AUTH_CLI_CLIENT_ID`\uFF08\u6216\u517C\u5BB9\u65E7\u540D `LOGTO_CLI_APP_ID`\uFF09\u3002");credentials=await performPatTokenExchangeLogin({issuer,clientId:cliClientId,audience,scopes,subjectToken:pat}),persistCredentials(credentials),process7.stdout.write(["PAT \u767B\u5F55\u5DF2\u5B8C\u6210\u3002",`\u51ED\u636E\u5DF2\u5199\u5165: ${getCredentialPath()}`,"\u8BF4\u660E: \u5F53\u524D\u4E3A\u673A\u5668\u51ED\u636E\u6A21\u5F0F\uFF0CCLI \u4F1A\u5728 7 \u5929\u7A97\u53E3\u5185\u81EA\u52A8\u91CD\u65B0\u4EA4\u6362 access token\u3002","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A"," 1. platform whoami"," 2. \u5982\u9700\u957F\u671F\u4EBA\u5DE5\u5F00\u53D1\uFF0C\u4F18\u5148\u6539\u7528 `platform login` \u6D4F\u89C8\u5668\u767B\u5F55",""].join(`
2648
2649
  `));return}if(cliClientId)try{credentials=await performDeviceCodeLogin({issuer,clientId:cliClientId,audience,scopes,onPrompt:async({verificationUri,userCode,expiresIn})=>{let{opened}=await openExternal(verificationUri);process7.stdout.write((opened?["\u5DF2\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u5B8C\u6210\u767B\u5F55\u6388\u6743\u3002",""]:["\u8BF7\u5728\u6D4F\u89C8\u5668\u5B8C\u6210\u767B\u5F55\u6388\u6743\u3002",`\u9A8C\u8BC1\u5730\u5740: ${verificationUri}`,`User Code: ${userCode}`,`\u6709\u6548\u671F: ${expiresIn} \u79D2`,""]).join(`
2649
2650
  `))}})}catch(error){if(!shouldFallbackToBrowserLogin(error))throw error;if(process7.stdout.write(`\u5F53\u524D\u73AF\u5883\u4E0D\u53EF\u7528 Device Flow\uFF0C\u81EA\u52A8\u5207\u6362\u5230\u6D4F\u89C8\u5668\u6388\u6743\u7801\u767B\u5F55\u3002
@@ -2661,7 +2662,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2661
2662
  `));return}if(subcommand==="clear"){clearStoredEnvironmentProfile(),process7.stdout.write(`CLI \u73AF\u5883 profile \u5DF2\u6E05\u9664\u3002
2662
2663
  \u914D\u7F6E\u6587\u4EF6: ${getEnvironmentProfilePath()}
2663
2664
 
2664
- `);return}if(subcommand!=="use")throw new Error(`\u672A\u77E5 env \u5B50\u547D\u4EE4: ${subcommand}`);let profileName=args.rest[1]??readOption2(args,"profile");if(!profileName)throw new Error("`platform env use` \u9700\u8981\u4E00\u4E2A profile \u540D\u79F0\uFF0C\u4F8B\u5982 `platform env use test`\u3002");let resolved=resolveKnownEnvironmentProfile(profileName);if(!resolved){let available=listKnownEnvironmentProfiles().map(item=>item.name).join(", ");throw new Error(available?`\u672A\u77E5\u73AF\u5883 profile: ${profileName}\u3002\u53EF\u7528 profile: ${available}`:`\u672A\u77E5\u73AF\u5883 profile: ${profileName}`)}let values={...resolved.values,...readManagedEnvironmentOverrides(args)};persistStoredEnvironmentProfile({active_profile:resolved.name,values}),printEnvironmentProfileDetail({profileName:resolved.name,values,path:getEnvironmentProfilePath()})}async function runApp(args){let subcommand=args.rest[0]??"current";if(subcommand==="import")return runAppImportCommand(args);if(subcommand==="version"){let nestedSubcommand=args.rest[1]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(`version:${nestedSubcommand}`);return}if(nestedSubcommand==="help"){process7.stdout.write(["platform app version","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app version create \u5728\u5F53\u524D app \u4E0B\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C"," platform app version list \u67E5\u770B\u5F53\u524D app \u4E0B\u5DF2\u6709\u6E90\u7801\u7248\u672C",""].join(`
2665
+ `);return}if(subcommand!=="use")throw new Error(`\u672A\u77E5 env \u5B50\u547D\u4EE4: ${subcommand}`);let profileName=args.rest[1]??readOption2(args,"profile");if(!profileName)throw new Error("`platform env use` \u9700\u8981\u4E00\u4E2A profile \u540D\u79F0\uFF0C\u4F8B\u5982 `platform env use test`\u3002");let resolved=resolveKnownEnvironmentProfile(profileName);if(!resolved){let available=listKnownEnvironmentProfiles().map(item=>item.name).join(", ");throw new Error(available?`\u672A\u77E5\u73AF\u5883 profile: ${profileName}\u3002\u53EF\u7528 profile: ${available}`:`\u672A\u77E5\u73AF\u5883 profile: ${profileName}`)}let values={...resolved.values,...readManagedEnvironmentOverrides(args)};persistStoredEnvironmentProfile({active_profile:resolved.name,values}),printEnvironmentProfileDetail({profileName:resolved.name,values,path:getEnvironmentProfilePath()})}async function runApp(args){let subcommand=args.rest[0]??"current";if(subcommand==="import"){let importAssetSdk=null,importSourceDir=resolve18(readOption2(args,"dir")??process7.env.PLATFORM_INVOCATION_CWD??process7.env.INIT_CWD??process7.cwd());return runAppImportCommand(args,{uploadAsset:async input=>{if(!importAssetSdk){let credentials2=await loadStoredCredentialsEnsuringFresh(),tenantId2=resolveTenantContext(args,importSourceDir);if(!tenantId2)throw new Error("\u672A\u89E3\u6790\u51FA\u7D20\u6750\u4E0A\u4F20\u6240\u9700\u7684 tenant \u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5148\u6267\u884C `platform tenant use <tenant-id>` \u6216\u5728\u5DF2\u7ED1\u5B9A\u5E94\u7528\u76EE\u5F55\u4E2D\u91CD\u8BD5\u3002");importAssetSdk=createTenantScopedSdk(credentials2,tenantId2,{capability:"asset_library"})}return uploadTenantAssetBinary(importAssetSdk,input)}})}if(subcommand==="version"){let nestedSubcommand=args.rest[1]??"help";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(`version:${nestedSubcommand}`);return}if(nestedSubcommand==="help"){process7.stdout.write(["platform app version","","\u53EF\u7528\u5B50\u547D\u4EE4\uFF1A"," platform app version create \u5728\u5F53\u524D app \u4E0B\u521B\u5EFA\u65B0\u7684\u6E90\u7801\u7248\u672C"," platform app version list \u67E5\u770B\u5F53\u524D app \u4E0B\u5DF2\u6709\u6E90\u7801\u7248\u672C",""].join(`
2665
2666
  `));return}if(nestedSubcommand==="create"){let credentials2=await loadStoredCredentialsEnsuringFresh();if(!credentials2)throw new Error("\u672A\u627E\u5230\u672C\u5730\u51ED\u636E\uFF0C\u8BF7\u5148\u6267\u884C `platform login`\u3002");let binding=tryReadCurrentBinding2()?.binding,tenantId2=readOption2(args,"tenant")??binding?.tenant_id??resolveTenantContext(args),appId2=readOption2(args,"app")??binding?.app_id,templateKey=normalizeAppTemplateOption(readOption2(args,"template"));if(!tenantId2||!appId2)throw new Error("`platform app version create` \u9700\u8981\u5728\u5DF2\u7ED1\u5B9A\u7684\u5E94\u7528\u76EE\u5F55\u6267\u884C\uFF0C\u6216\u663E\u5F0F\u4F20\u5165 `--tenant` \u4E0E `--app`\u3002");if(!templateKey)throw new Error("`platform app version create` \u9700\u8981\u663E\u5F0F\u4F20\u5165 `--template <template-key>`\u3002");let response=await createControlApiSdk({accessToken:selectApiToken(credentials2),tenantId:tenantId2,capability:"dashboard",requestClass:"control"}).createTenantAppSourceVersionFromTemplate(appId2,{template_key:templateKey,message:readOption2(args,"message")});syncSelectedAppContextFromBinding({tenant_id:response.tenant_id,app_id:response.app_id,env:binding?.env??"preview",app_name:binding?.app_name,app_display_name:binding?.app_display_name}),process7.stdout.write([`\u6E90\u7801\u7248\u672C\u5DF2\u521B\u5EFA\uFF1A${response.source_version_id}`,`tenant/app: ${response.tenant_id}/${response.app_id}`,`\u6A21\u677F: ${response.template_key}`,`\u6587\u4EF6\u6570: ${response.files_count}`,response.message?`\u8BF4\u660E: ${response.message}`:"\u8BF4\u660E: -","\u4E0B\u4E00\u6B65\u5EFA\u8BAE\uFF1A",` 1. platform app checkout --tenant ${response.tenant_id} --app ${response.app_id} --source-version ${response.source_version_id} --dir <project-name>`," 2. \u5728\u65B0\u76EE\u5F55\u4E2D\u7EE7\u7EED\u672C\u5730\u4FEE\u6539"," 3. \u5B8C\u6210\u540E\u6267\u884C `platform app submit` \u63D0\u4EA4\u540E\u7EED\u8FED\u4EE3",""].join(`
2666
2667
  `));return}if(nestedSubcommand==="list")return runApp({...args,rest:["versions",...args.rest.slice(2)]});throw new Error("`platform app version` \u76EE\u524D\u652F\u6301 `create` \u6216 `list`\u3002")}if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAppHelp(subcommand);return}let context=loadStoredCliContext();if(subcommand==="current"){let sourceContextResult=tryReadCurrentSourceContext(),sourceContext=sourceContextResult?.sourceContext,hasProjectContext=!!(sourceContext?.tenant_id&&sourceContext.app_id);if(!(hasProjectContext?sourceContext?.app_id:context?.selected_app_id)){process7.stdout.write(`\u5F53\u524D\u672A\u9009\u62E9\u5E94\u7528\u4E0A\u4E0B\u6587\u3002
2667
2668
  `);return}process7.stdout.write((hasProjectContext?[`\u5F53\u524D\u5E94\u7528: ${sourceContext?.app_id}`,`\u5E94\u7528\u5C55\u793A\u540D: ${sourceContext?.app_display_name??sourceContext?.app_name??"-"}`,`\u79DF\u6237: ${sourceContext?.tenant_id??"-"}`,`\u73AF\u5883: ${sourceContext?.env??"preview"}`,`checkout \u57FA\u7EBF\u6E90\u7801\u7248\u672C: ${sourceContext?.base_source_version_id??"-"}`,`\u6700\u8FD1\u63D0\u4EA4\u6E90\u7801\u7248\u672C: ${sourceContext?.last_submitted_source_version_id??"-"}`,`\u6700\u8FD1 preview \u6E90\u7801\u7248\u672C: ${sourceContext?.last_preview_source_version_id??"-"}`,"\u4E0A\u4E0B\u6587\u6765\u6E90: \u5F53\u524D\u76EE\u5F55 .platform/source-context.json",`\u76EE\u5F55\u7ED1\u5B9A\u6587\u4EF6: ${sourceContextResult?.path??"-"}`,context?.selected_app_id?`\u5168\u5C40\u515C\u5E95\u4E0A\u4E0B\u6587: ${getCliContextPath()}`:"\u5168\u5C40\u515C\u5E95\u4E0A\u4E0B\u6587: -",""]:[`\u5F53\u524D\u5E94\u7528: ${context?.selected_app_id}`,`\u5E94\u7528\u5C55\u793A\u540D: ${context?.selected_app_display_name??context?.selected_app_name??"-"}`,`\u79DF\u6237: ${context?.selected_app_tenant_id??"-"}`,`\u73AF\u5883: ${context?.selected_app_env??"preview"}`,`checkout \u57FA\u7EBF\u6E90\u7801\u7248\u672C: ${sourceContext?.base_source_version_id??"-"}`,`\u6700\u8FD1\u63D0\u4EA4\u6E90\u7801\u7248\u672C: ${sourceContext?.last_submitted_source_version_id??"-"}`,`\u6700\u8FD1 preview \u6E90\u7801\u7248\u672C: ${sourceContext?.last_preview_source_version_id??"-"}`,"\u4E0A\u4E0B\u6587\u6765\u6E90: \u5168\u5C40 CLI context",`\u4E0A\u4E0B\u6587\u6587\u4EF6: ${getCliContextPath()}`,sourceContextResult?.path?`\u5F53\u524D\u76EE\u5F55 source-context: ${sourceContextResult.path}`:"\u5F53\u524D\u76EE\u5F55 source-context: -",""]).join(`
@@ -2714,7 +2715,7 @@ ${normalized}`}function countExecutableSqlStatements(sql){return stripSqlComment
2714
2715
  - \u65E0`,"\u9AD8\u7EA7\u6A21\u5F0F\u63D0\u793A: \u82E5\u4F60\u8981\u9A8C\u8BC1\u5E73\u53F0\u539F\u751F\u6784\u5EFA\u3001\u771F\u5B9E preview\u3001rollback\uFF0C\u8BF7\u6539\u8D70\u5B8C\u6574\u8054\u8C03\u73AF\u5883\u3002",""].join(`
2715
2716
  `));try{autoRestartEnabled?await runDevSupervisor({command:runtime.command,cwd:runtime.cwd,env:runtime.env,watchRoot:runtime.cwd,onWatching:message=>{process7.stdout.write(`[dev] ${message}
2716
2717
  `)}}):await runSingleDevProcess(runtime.command,runtime.cwd,runtime.env)}finally{await cleanupRemoteBindings?.()}}async function runSingleDevProcess(command,cwd,env){await runDevSupervisor({command,cwd,env})}async function ensureLocalDevDependencies(cwd){let installPlan=detectLocalDependencyInstallPlan(cwd);if(!installPlan)return null;let renderedCommand=[installPlan.command,...installPlan.args].join(" ");return process7.stdout.write(`\u68C0\u6D4B\u5230\u5F53\u524D\u5DE5\u4F5C\u533A\u7F3A\u5C11 node_modules\uFF1B\u6B63\u5728\u6309 ${installPlan.lockfile} \u6267\u884C\u4F9D\u8D56\u5B89\u88C5\uFF1A${renderedCommand}
2717
- `),await new Promise((resolve17,reject)=>{let child=spawn5(installPlan.command,installPlan.args,{cwd,env:process7.env,stdio:"inherit",shell:!1});child.on("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF0C\u72B6\u6001\u7801 ${code2}`));return}resolve17()})}),`\u68C0\u6D4B\u5230\u5F53\u524D\u5DE5\u4F5C\u533A\u7F3A\u5C11 node_modules\uFF1BCLI \u5DF2\u6309 ${installPlan.lockfile} \u81EA\u52A8\u5B8C\u6210\u4F9D\u8D56\u5B89\u88C5\u3002`}async function runAuth(args){let subcommand=args.rest[0]??"discover";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAuthHelp(args.rest[0]??"");return}if(!["discover","configure","bind","inspect","role","user-role"].includes(subcommand))throw new Error(`\u672A\u77E5 auth \u5B50\u547D\u4EE4: ${subcommand}`);let credentials=await loadStoredCredentialsEnsuringFresh(),tenantId=resolveTenantContext(args),appId=resolveAppIdFromContext(args);if(!tenantId||!appId)throw new Error("`platform auth` \u9700\u8981 `--tenant` \u6216\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u4EE5\u53CA `--app`\u3001\u5F53\u524D\u76EE\u5F55\u7ED1\u5B9A\u6216\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587\u3002");let sdk=createTenantScopedSdk(credentials,tenantId,{capability:"end_user_auth"}),jsonMode=args.options.json===!0;if(subcommand==="role"){let action2=args.rest[1]??"list";if(!["list","create","inspect","update"].includes(action2))throw new Error(`\u672A\u77E5 auth role \u5B50\u547D\u4EE4: ${action2}`);if(action2==="list"){let response3=await sdk.listTenantAppEndUserRoles(appId);if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
2718
+ `),await new Promise((resolve19,reject)=>{let child=spawn5(installPlan.command,installPlan.args,{cwd,env:process7.env,stdio:"inherit",shell:!1});child.on("error",error=>{reject(error instanceof Error?error:new Error(String(error)))}),child.on("exit",(code2,signal)=>{if(signal){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u88AB\u4FE1\u53F7 ${signal} \u7EC8\u6B62`));return}if(code2&&code2!==0){reject(new Error(`\u4F9D\u8D56\u5B89\u88C5\u5931\u8D25\uFF0C\u72B6\u6001\u7801 ${code2}`));return}resolve19()})}),`\u68C0\u6D4B\u5230\u5F53\u524D\u5DE5\u4F5C\u533A\u7F3A\u5C11 node_modules\uFF1BCLI \u5DF2\u6309 ${installPlan.lockfile} \u81EA\u52A8\u5B8C\u6210\u4F9D\u8D56\u5B89\u88C5\u3002`}async function runAuth(args){let subcommand=args.rest[0]??"discover";if(hasFlag2(args,"help")||hasFlag2(args,"h")){printAuthHelp(args.rest[0]??"");return}if(!["discover","configure","bind","inspect","role","user-role"].includes(subcommand))throw new Error(`\u672A\u77E5 auth \u5B50\u547D\u4EE4: ${subcommand}`);let credentials=await loadStoredCredentialsEnsuringFresh(),tenantId=resolveTenantContext(args),appId=resolveAppIdFromContext(args);if(!tenantId||!appId)throw new Error("`platform auth` \u9700\u8981 `--tenant` \u6216\u9ED8\u8BA4\u79DF\u6237\u4E0A\u4E0B\u6587\uFF0C\u4EE5\u53CA `--app`\u3001\u5F53\u524D\u76EE\u5F55\u7ED1\u5B9A\u6216\u5DF2\u9009\u5E94\u7528\u4E0A\u4E0B\u6587\u3002");let sdk=createTenantScopedSdk(credentials,tenantId,{capability:"end_user_auth"}),jsonMode=args.options.json===!0;if(subcommand==="role"){let action2=args.rest[1]??"list";if(!["list","create","inspect","update"].includes(action2))throw new Error(`\u672A\u77E5 auth role \u5B50\u547D\u4EE4: ${action2}`);if(action2==="list"){let response3=await sdk.listTenantAppEndUserRoles(appId);if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
2718
2719
  `);return}printAppRoleList(response3.items);return}if(action2==="create"){let roleKey2=readOption2(args,"key"),displayName=readOption2(args,"name");if(!roleKey2||!displayName)throw new Error("`platform auth role create` \u9700\u8981 `--key <role-key>` \u548C `--name <display-name>`\u3002");let response3=await sdk.createTenantAppEndUserRole(appId,{role_key:roleKey2,display_name:displayName,description:readOption2(args,"description"),status:normalizeAppRoleStatus(readOption2(args,"status"))});if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
2719
2720
  `);return}printAppRoleDetail(response3);return}let roleKey=readOption2(args,"role");if(!roleKey)throw new Error("`platform auth role inspect/update` \u9700\u8981 `--role <role-key>`\u3002");if(action2==="inspect"){let response3=await sdk.getTenantAppEndUserRole(appId,roleKey);if(jsonMode){process7.stdout.write(`${JSON.stringify(response3,null,2)}
2720
2721
  `);return}printAppRoleDetail(response3);return}let hasDescription=Object.prototype.hasOwnProperty.call(args.options,"description"),clearDescription=hasFlag2(args,"clear-description"),payload={display_name:readOption2(args,"name"),description:clearDescription?null:hasDescription?readOption2(args,"description")??null:void 0,status:normalizeAppRoleStatus(readOption2(args,"status"))};if(payload.display_name===void 0&&payload.description===void 0&&payload.status===void 0)throw new Error("`platform auth role update` \u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u53D8\u66F4\u53C2\u6570\uFF1A`--name`\u3001`--description`\u3001`--clear-description` \u6216 `--status`\u3002");let response2=await sdk.updateTenantAppEndUserRole(appId,roleKey,payload);if(jsonMode){process7.stdout.write(`${JSON.stringify(response2,null,2)}