@litingwei621/test-deveco-cli-common 1.3.7 → 1.3.10-Test.1

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.
package/dist/cli.js CHANGED
@@ -1,112 +1,112 @@
1
1
  #!/usr/bin/env node
2
- var hk=Object.defineProperty;var yk=(r,e)=>{for(var t in e)hk(r,t,{get:e[t],enumerable:!0})};import*as Lu from"path";import{program as ie}from"commander";import{red as hB}from"colorette";var es={LOGIN_TIMEOUT_MS:6e5,HTTP_TIMEOUT_MS:2e4,TOKEN_VALIDITY_DAYS:30},Ga={USER_AGENT:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",ACCEPT_LANGUAGE:"zh-CN"};var be={APP_ID:"1009",CONFIG_DIR_NAME:".config",APP_NAME:"deveco-cli",TOKEN_FILE_NAME:"token.enc",KEY_FILE_NAME:"token.dek",API_VERSION:"1.0.0",AUTH_SOURCE_DEVECO_CODE:"deveco-code"},oe={LOGIN_URL:"https://devecostudio.huawei.com",CN_LOGIN_URL:"https://cn.devecostudio.huawei.com",AUTH_APPLY_PATH:"console/DevEcoIDE/apply",TEMP_TOKEN_CHECK_PATH:"authrouter/auth/api/temptoken/check",JWT_TOKEN_CHECK_PATH:"authrouter/auth/api/jwToken/check",LOGIN_SUCCESS_PATH:"console/DevEcoCLI/loginSuccess",LOGIN_FAILED_PATH:"console/DevEcoCLI/loginFailed",LOGOUT_PATH:"authrouter/auth/api/logout",AGC_TEAM_LIST_URL:"https://connect-api.cloud.huawei.com/api/ups/user-permission-service/v1/user-team-list"},Vn={ALGORITHM:"aes-256-gcm",KEY_LENGTH:32,IV_LENGTH:12,KEK_VERSIONS:["kek-v1","kek-v2","kek-v3"]},ts={TMS_URL:"https://terms-drcn.platform.dbankcloud.cn/agreementservice/user",PRIVACY_ID:"20000257",PRIVACY_URL:"https://legal.cloud.huawei.com/terms/scope/huawei/deveco-cli/privacy-statement.htm?code=CN&language=zh-CN&branchid=0&contenttag=default"},rs={baseUrl:oe.LOGIN_URL,authUrl:oe.AUTH_APPLY_PATH,tempTokenCheckUrl:oe.TEMP_TOKEN_CHECK_PATH,jwtTokenCheckUrl:oe.JWT_TOKEN_CHECK_PATH,successRedirectUrl:oe.LOGIN_SUCCESS_PATH,failedRedirectUrl:oe.LOGIN_FAILED_PATH,logoutUrl:oe.LOGOUT_PATH,agcTeamListUrl:oe.AGC_TEAM_LIST_URL,appId:be.APP_ID,timeout:es.LOGIN_TIMEOUT_MS,countryCode:"CN"};import{Command as kx}from"commander";import{green as Wc,red as fw,yellow as Vc}from"colorette";import pw from"json5";import*as Ss from"fs";import*as gw from"path";import K from"fs";import*as H from"path";import tr from"json5";import*as _u from"fs";import*as Ne from"path";function m(r){if(process.env.DEVECO_CLI_DEBUG){let e=typeof r=="function"?r():r;console.log(`[DEBUG] ${e}`)}}var P=class r{static ASCII_CONTROL_MAX=31;static ASCII_DELETE=127;static parsePositiveInteger(e,t="value"){let n=e.trim();if(!/^\d+$/.test(n))throw new Error(`${t} must be a positive integer`);let i=Number.parseInt(n,10);if(!Number.isInteger(i)||i<=0)throw new Error(`${t} must be a positive integer`);return i}static getLastLines(e,t){return!t||t<=0?e:e.split(/\r?\n/).slice(-t).join(`
2
+ var JR=Object.defineProperty;var KR=(r,e)=>{for(var t in e)JR(r,t,{get:e[t],enumerable:!0})};import*as fp from"path";import{program as se}from"commander";import{red as J2}from"colorette";var ps={LOGIN_TIMEOUT_MS:6e5,HTTP_TIMEOUT_MS:2e4,TOKEN_VALIDITY_DAYS:30},dc={USER_AGENT:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",ACCEPT_LANGUAGE:"zh-CN"};var Se={APP_ID:"1009",CONFIG_DIR_NAME:".config",APP_NAME:"deveco-cli",TOKEN_FILE_NAME:"token.enc",KEY_FILE_NAME:"token.dek",API_VERSION:"1.0.0",AUTH_SOURCE_DEVECO_CODE:"deveco-code"},oe={LOGIN_URL:"https://devecostudio.huawei.com",CN_LOGIN_URL:"https://cn.devecostudio.huawei.com",AUTH_APPLY_PATH:"console/DevEcoIDE/apply",TEMP_TOKEN_CHECK_PATH:"authrouter/auth/api/temptoken/check",JWT_TOKEN_CHECK_PATH:"authrouter/auth/api/jwToken/check",LOGIN_SUCCESS_PATH:"console/DevEcoCLI/loginSuccess",LOGIN_FAILED_PATH:"console/DevEcoCLI/loginFailed",LOGOUT_PATH:"authrouter/auth/api/logout",AGC_TEAM_LIST_URL:"https://connect-api.cloud.huawei.com/api/ups/user-permission-service/v1/user-team-list"},zn={ALGORITHM:"aes-256-gcm",KEY_LENGTH:32,IV_LENGTH:12,KEK_VERSIONS:["kek-v1","kek-v2","kek-v3"]},fs={TMS_URL:"https://terms-drcn.platform.dbankcloud.cn/agreementservice/user",PRIVACY_ID:"20000257",PRIVACY_URL:"https://legal.cloud.huawei.com/terms/scope/huawei/deveco-cli/privacy-statement.htm?code=CN&language=zh-CN&branchid=0&contenttag=default"},ms={baseUrl:oe.LOGIN_URL,authUrl:oe.AUTH_APPLY_PATH,tempTokenCheckUrl:oe.TEMP_TOKEN_CHECK_PATH,jwtTokenCheckUrl:oe.JWT_TOKEN_CHECK_PATH,successRedirectUrl:oe.LOGIN_SUCCESS_PATH,failedRedirectUrl:oe.LOGIN_FAILED_PATH,logoutUrl:oe.LOGOUT_PATH,agcTeamListUrl:oe.AGC_TEAM_LIST_URL,appId:Se.APP_ID,timeout:ps.LOGIN_TIMEOUT_MS,countryCode:"CN"};import{Command as nA}from"commander";import{green as al,red as av,yellow as cl}from"colorette";import ov from"json5";import*as Os from"fs";import*as cv from"path";import X from"fs";import*as H from"path";import or from"json5";import*as mp from"fs";import*as _e from"path";function f(r){if(process.env.DEVECO_CLI_DEBUG){let e=typeof r=="function"?r():r;console.log(`[DEBUG] ${e}`)}}var P=class r{static ASCII_CONTROL_MAX=31;static ASCII_DELETE=127;static parsePositiveInteger(e,t="value"){let n=e.trim();if(!/^\d+$/.test(n))throw new Error(`${t} must be a positive integer`);let i=Number.parseInt(n,10);if(!Number.isInteger(i)||i<=0)throw new Error(`${t} must be a positive integer`);return i}static getLastLines(e,t){return!t||t<=0?e:e.split(/\r?\n/).slice(-t).join(`
3
3
  `)}static parseDurationToSeconds(e,t="value"){let i=e.trim().toLowerCase().match(/^(\d+(?:\.\d+)?)([sm])?$/);if(!i)throw new Error(`${t} must be like 30s, 5m or 2.5m (only s/m supported).`);let o=i[1];if((i[2]??"s")==="s")return r.parsePositiveInteger(o,t);if(!/^\d+(?:\.\d)?$/.test(o))throw new Error(`${t} supports a maximum of 1 decimal place for minutes (e.g. 2.5m).`);let a=Number.parseFloat(o);if(!Number.isFinite(a)||a<=0)throw new Error(`${t} must be a positive duration.`);return Math.round(a*60)}static filterLogsByRelativeWindow(e,t,n,i=new Date){if(!t&&!n)return e;let[o,s]=r.resolveTimeBounds(t,n,i),a=e.split(/\r?\n/),c=[],l=!1;for(let d of a){let g=r.extractTimestampFromLogLine(d,i);g&&(l=r.isWithinBounds(g,o,s)),l&&c.push(d)}return c.join(`
4
- `)}static resolveTimeBounds(e,t,n){let i=e?new Date(n.getTime()-e*1e3):null,o=t?new Date(n.getTime()-t*1e3):null;return i&&o?i<o?[i,o]:[o,i]:i?[i,n]:o?[null,o]:[null,null]}static isWithinBounds(e,t,n){let i=e.getTime(),o=t?Math.floor(t.getTime()/1e3)*1e3:null,s=n?Math.floor(n.getTime()/1e3)*1e3+999:null;return!(o!==null&&i<o||s!==null&&i>s)}static extractTimestampFromLogLine(e,t){let n=e.match(/(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?/);if(!n)return null;let i=t.getFullYear(),o=Number.parseInt(n[1],10)-1,s=Number.parseInt(n[2],10),a=Number.parseInt(n[3],10),c=Number.parseInt(n[4],10),l=Number.parseInt(n[5],10),d=n[6]??"0",g=Number.parseInt(d.padEnd(3,"0").slice(0,3),10),y=new Date(i,o,s,a,c,l,g);return y.getTime()>t.getTime()+1440*60*1e3&&y.setFullYear(i-1),y}static assertBundleName(e){if(!/^[A-Za-z0-9_.]{1,128}$/.test(e))throw new Error(`Invalid bundleName: ${JSON.stringify(e)}`)}static assertBundleNameStrict(e){if(e.length<7||e.length>128)throw new Error(`Bundle name length must be 7-128 characters. Current: ${e.length}`);if(e.includes(".."))throw new Error('Bundle name cannot contain consecutive dots (e.g., "com..example").');let t=e.split(".");if(t.length<3)throw new Error("Bundle name must contain at least 3 dot-separated segments.");let n=/^[a-zA-Z0-9_]+$/;for(let i=0;i<t.length;i++){let o=t[i];if(!n.test(o))throw new Error(`Segment "${o}" contains invalid characters. Only letters, digits, and underscores allowed.`);if(i===0){if(!/^[a-zA-Z]/.test(o))throw new Error(`First segment "${o}" must start with a letter (a-z, A-Z).`)}else if(!/^[a-zA-Z0-9]/.test(o))throw new Error(`Segment "${o}" must start with a letter or digit.`);if(!/[a-zA-Z0-9]$/.test(o))throw new Error(`Segment "${o}" must end with a letter or digit.`)}}static assertModuleName(e){this.assertSafeName(e,"module name")}static assertAbilityName(e){this.assertSafeName(e,"ability name")}static assertSafeName(e,t){if(!/^[A-Za-z0-9_.]+$/.test(e))throw new Error(`Invalid ${t}: ${JSON.stringify(e)}`)}static assertHilogToken(e,t){if(!/^[A-Za-z0-9_.:\\-]{1,64}$/.test(e))throw new Error(`Invalid ${t}: ${JSON.stringify(e)}`)}static assertHilogKeyword(e){if(e.length===0||e.length>128)throw new Error(`Invalid keyword: ${JSON.stringify(e)}`);if([...e].some(n=>{let i=n.charCodeAt(0);return i<=r.ASCII_CONTROL_MAX||i===r.ASCII_DELETE}))throw new Error(`Invalid keyword: ${JSON.stringify(e)}`)}static quotePosixShellArg(e){let n=`'${e.replace(/'/g,"'\\''")}'`;return m(`quotePosixShellArg: ${e} -> ${n}`),n}static assertCrashFilename(e){if(!/^\w+-[\w.]+-\d+-\d+$/.test(e))throw new Error(`Invalid crash log filename: ${JSON.stringify(e)}`)}static assertHilogLevel(e){if(!/^[DIWEF]$/.test(e))throw new Error(`Invalid log level: ${e}`)}static resolvePathWithinRoot(e,t){if(Ne.isAbsolute(t))throw new Error(`Absolute paths are not allowed: ${t}`);let n=Ne.resolve(Ne.normalize(e),t);return r.ensurePathWithinRoot(e,n)}static ensurePathWithinRoot(e,t){let n=Ne.normalize(e),i=Ne.relative(n,t);if(i.split(Ne.sep)[0]===".."||Ne.isAbsolute(i))throw new Error(`Path escapes project root: ${t}`);return t}static isPathEscaping(e){let t=e.replace(/\\/g,"/");return t===".."||t.startsWith("../")||Ne.isAbsolute(e)}static isPathContained(e,t){let n=Ne.resolve(t,e),i=Ne.relative(t,n);return r.isPathEscaping(i)?{contained:!1,reason:`Path traversal project root directory: ${e}`}:{contained:!0}}static isPathContainedWithSymlink(e,t){let n=r.isPathContained(e,t);if(!n.contained)return n;let i;try{i=_u.realpathSync(t)}catch{return{contained:!1,reason:`Project root directory does not exist or cannot be resolved: ${t}`}}let o=Ne.resolve(i,e),s;try{s=_u.realpathSync(o)}catch{return{contained:!1,reason:`Path does not exist or cannot be resolved: ${o}`}}return r.isPathContained(s,i)}};import Wh from"crypto";import se from"fs";import ic from"os";import pt from"path";import vk from"https";var ph={devecoApiTraceUpload:"https://cn.devecostudio.huawei.com/codeGenie/cli/trace/upload"};var qa=class r{static ENDPOINT=ph.devecoApiTraceUpload;static SENDER="deveco-cli";async upload(e,t){let n={"Content-Type":"application/json",sender:r.SENDER,deviceid:t.replace(/-/g,""),"Content-Length":String(Buffer.byteLength(e,"utf8"))};try{let{body:i}=await this.httpPost(r.ENDPOINT,n,Buffer.from(e,"utf8"),6e4);return r.isSuccess(i)}catch{return!1}}static isSuccess(e){try{let t=JSON.parse(e),n=t?.code??t?.errorCode;return String(n)==="200"}catch{return!1}}async httpPost(e,t,n,i){let o=new URL(e);return new Promise((s,a)=>{let c=vk.request({protocol:o.protocol,hostname:o.hostname,port:o.port||(o.protocol==="https:"?443:80),path:o.pathname+o.search,method:"POST",headers:t,timeout:i},l=>{let d=[];l.on("data",g=>d.push(g)),l.on("end",()=>{s({code:l.statusCode??0,body:Buffer.concat(d).toString("utf8")})})});c.on("timeout",()=>{c.destroy(new Error("request timeout"))}),c.on("error",a),c.write(n),c.end()})}};var mh={identity:r=>r,camelCase:r=>r,snakeCase:r=>r.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase()},$u=class{constructor(e={}){this.config=e}serialize(e){let t=this.transform(e);return this.config.pretty?JSON.stringify(t,null,2):JSON.stringify(t)}toObject(e){return this.transform(e)}transform(e){if(e==null)return e;if(Array.isArray(e))return e.map(o=>this.transform(o));if(typeof e!="object")return e;let t=this.config.namingStrategy??mh.identity,n=this.config.fieldNames??{},i={};for(let[o,s]of Object.entries(e)){let a=n[o]??t(o);i[a]=this.transform(s)}return i}},fh=new $u({namingStrategy:mh.snakeCase,fieldNames:{}});import ns from"crypto";import za from"fs";import bk from"path";var Ja="aes-256-gcm",Sk=12,Ek="deveco-cli-trace-file",Pk="trace-file-secret",hh=32;function gh(r){try{let e=za.readFileSync(r,"utf8").trim();return e&&Buffer.from(e,"base64").length===hh?e:null}catch{return null}}function yh(r){let e=bk.join(r,Pk),t=gh(e);if(t)return Fu(t);let n=ns.randomBytes(hh).toString("base64");try{za.mkdirSync(r,{recursive:!0});try{za.writeFileSync(e,n,{flag:"wx"})}catch{let i=gh(e);if(i)return Fu(i);za.writeFileSync(e,n)}}catch{}return Fu(n)}function Fu(r){return ns.createHash("sha256").update(Ek).update(r).digest()}function wh(r,e){let t=ns.randomBytes(Sk),n=ns.createCipheriv(Ja,e,t),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o={version:1,algorithm:Ja,ciphertext:i.toString("base64"),iv:t.toString("base64"),authTag:n.getAuthTag().toString("base64")};return JSON.stringify(o)}function vh(r,e){let t;try{t=JSON.parse(r)}catch{return null}if(!Ck(t))return r;try{let n=ns.createDecipheriv(Ja,e,Buffer.from(t.iv,"base64"));return n.setAuthTag(Buffer.from(t.authTag,"base64")),Buffer.concat([n.update(Buffer.from(t.ciphertext,"base64")),n.final()]).toString("utf8")}catch{return null}}function Ck(r){if(!r||typeof r!="object")return!1;let e=r;return e.version===1&&e.algorithm===Ja&&typeof e.ciphertext=="string"&&typeof e.iv=="string"&&typeof e.authTag=="string"}import*as Y from"fs";import*as tc from"path";import re from"fs";import{spawn as kk}from"child_process";import*as Ya from"os";import*as B from"path";import Dk from"json5";var ju="Huawei";var Ch=3;function Ka(r){if(!re.existsSync(r)||!re.statSync(r).isDirectory())return!1;let e=re.existsSync(B.join(r,"build-profile.json5")),t=re.existsSync(B.join(r,"hvigorfile.js"))||re.existsSync(B.join(r,"hvigorfile.ts"));if(!e||!t)return!1;try{let n=re.readFileSync(B.join(r,"build-profile.json5"),"utf-8");return Dk.parse(n).app!==void 0}catch{return!1}}function Hu(r,e,t){if(e>=t)return null;let n=Rk(r),i=xk(n);if(i)return i;for(let o of n){let s=Hu(o,e+1,t);if(s)return s}return null}function Rk(r){try{let e=re.readdirSync(r,{withFileTypes:!0}),t=[];for(let n of e)n.isDirectory()&&t.push(B.join(r,n.name));return t}catch{return[]}}function xk(r){for(let e of r)if(Ka(e))return e;return null}function Cr(r){if(!r||r.trim()==="")return null;let e=B.resolve(r),t;try{t=re.realpathSync(e)}catch{t=e}if(!re.existsSync(t))return null;if(Ka(t))return t;let n=t;for(let i=1;i<=3;i++){let o=B.dirname(n);if(o===n)break;if(Ka(o))return o;n=o}if(re.statSync(t).isDirectory()){let i=Hu(t,0,Ch);if(i)return i}return null}function Xa(r){if(!r||r.trim()==="")return null;let e=B.resolve(r),t;try{t=re.realpathSync(e)}catch{t=e}return!re.existsSync(t)||!re.statSync(t).isDirectory()?null:Ka(t)?t:Hu(t,0,Ch)}var bh="DevEco Studio";function kh(){if(process.platform==="win32"){let r=[B.join("C:\\Program Files",ju,bh),B.join("C:\\Program Files (x86)",ju,bh)];return Sh(r)}if(process.platform==="darwin"){let r=["/Applications/DevEco Studio.app",B.join(process.env.HOME??"","Applications","DevEco Studio.app")];return Sh(r)}return null}function Sh(r){for(let e of r)if(re.existsSync(e))return e;return null}function Oi(r,e){let t=e?B.join("standardIndex","index.js"):"index.js";return re.existsSync(B.join(r,"ace-server"))?B.join(r,"ace-server","out",t):B.join(r,"out",t)}function Za(r){return re.existsSync(Oi(r,!0))}var Ak=5e3,Ik=64*1024,Eh=new Map;function Dh(r,e){let t=Tk(r),n=Eh.get(t);if(n)return n;let i=Ok(r,e).catch(()=>!1);return Eh.set(t,i),i}function Tk(r){let e=B.resolve(r).replace(/\\/g,"/");return process.platform==="win32"?e.toLowerCase():e}function Ph(r){try{let e=JSON.parse(r.trim());return Array.isArray(e.protocols)?e.protocols.includes("--socket"):null}catch{return null}}function Ok(r,e){let t=Oi(r,!0);if(!re.existsSync(t))return Promise.resolve(!1);let n=e||process.execPath||"node",i=[t,"--list-protocols"];return h.debug(`Executing: ${n} ${i.join(" ")}`),new Promise(o=>{let s=kk(n,i,{stdio:["ignore","pipe","ignore"],windowsHide:!0}),a="",c=!1,l=g=>{c||(c=!0,clearTimeout(d),s.exitCode===null&&s.signalCode===null&&s.kill(),o(g))},d=setTimeout(()=>l(!1),Ak);s.stdout?.on("data",g=>{a=(a+g.toString("utf8")).slice(-Ik);let y=Ph(a);y!==null&&l(y)}),s.on("error",()=>l(!1)),s.on("close",()=>l(Ph(a)??!1))})}var Nk=[".idea",".deveco","cxx","compile_commands.json"];function Gn(r){return B.join(r,...Nk)}function Rh(r){return new Promise(e=>setTimeout(e,r))}var Mk=new Set(["c","cc","cpp","cxx","h","hh","hpp","hxx"]);function qn(r){let e=B.extname(r).replace(/^\./,"").toLowerCase();return e.length>0&&Mk.has(e)}function Qa(r){return B.extname(r).replace(/^\./,"").toLowerCase()==="c"?"c":"cpp"}function xe(r){let e=r.replace(/\\/g,"/");return process.platform==="win32"&&/^[a-zA-Z]:/.test(e)&&(e=e[0].toUpperCase()+e.slice(1)),e}function Lk(r){return xe(r)}function Nt(r){let e=Lk(r);return e.startsWith("/")?`file://${e}`:`file:///${e}`}function Qr(){if(process.platform==="win32"){let r=process.env.LOCALAPPDATA??B.join(Ya.homedir(),"AppData","Local");return B.join(r,"devecocli-mcp-server","logs")}return process.platform==="darwin"?B.join(Ya.homedir(),"Library","Logs","devecocli-mcp-server"):B.join(Ya.homedir(),".local","share","devecocli-mcp-server","logs")}function xh(r,e){let t=_k(e),n=$k(t,r);if(n!==null)return n;let i=Date.now(),s=`${r.replace(/:/g,"\\:")}=${i}`,a=Fk(t,r,s);return jk(e,a),i}function _k(r){let e;try{e=re.readFileSync(r,"utf8")}catch{e=""}return e.length>0?e.split(/\r?\n/):[]}function $k(r,e){for(let t of r){let n=t.indexOf("=");if(n<=0||t.slice(0,n).replace(/\\:/g,":")!==e)continue;let o=parseInt(t.slice(n+1),10);return Number.isFinite(o)&&o>0?o:null}return null}function Fk(r,e,t){let n=!1,i=r.map(o=>{if(n)return o;let s=o.indexOf("=");return s<=0?o:o.slice(0,s).replace(/\\:/g,":")===e?(n=!0,t):o});return n||i.push(t),i}function jk(r,e){try{re.mkdirSync(B.dirname(r),{recursive:!0})}catch{}try{re.writeFileSync(r,e.join(`
4
+ `)}static resolveTimeBounds(e,t,n){let i=e?new Date(n.getTime()-e*1e3):null,o=t?new Date(n.getTime()-t*1e3):null;return i&&o?i<o?[i,o]:[o,i]:i?[i,n]:o?[null,o]:[null,null]}static isWithinBounds(e,t,n){let i=e.getTime(),o=t?Math.floor(t.getTime()/1e3)*1e3:null,s=n?Math.floor(n.getTime()/1e3)*1e3+999:null;return!(o!==null&&i<o||s!==null&&i>s)}static extractTimestampFromLogLine(e,t){let n=e.match(/(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?/);if(!n)return null;let i=t.getFullYear(),o=Number.parseInt(n[1],10)-1,s=Number.parseInt(n[2],10),a=Number.parseInt(n[3],10),c=Number.parseInt(n[4],10),l=Number.parseInt(n[5],10),d=n[6]??"0",g=Number.parseInt(d.padEnd(3,"0").slice(0,3),10),y=new Date(i,o,s,a,c,l,g);return y.getTime()>t.getTime()+1440*60*1e3&&y.setFullYear(i-1),y}static assertBundleName(e){if(!/^[A-Za-z0-9_.]{1,128}$/.test(e))throw new Error(`Invalid bundleName: ${JSON.stringify(e)}`)}static assertBundleNameStrict(e){if(e.length<7||e.length>128)throw new Error(`Bundle name length must be 7-128 characters. Current: ${e.length}`);if(e.includes(".."))throw new Error('Bundle name cannot contain consecutive dots (e.g., "com..example").');let t=e.split(".");if(t.length<3)throw new Error("Bundle name must contain at least 3 dot-separated segments.");let n=/^[a-zA-Z0-9_]+$/;for(let i=0;i<t.length;i++){let o=t[i];if(!n.test(o))throw new Error(`Segment "${o}" contains invalid characters. Only letters, digits, and underscores allowed.`);if(i===0){if(!/^[a-zA-Z]/.test(o))throw new Error(`First segment "${o}" must start with a letter (a-z, A-Z).`)}else if(!/^[a-zA-Z0-9]/.test(o))throw new Error(`Segment "${o}" must start with a letter or digit.`);if(!/[a-zA-Z0-9]$/.test(o))throw new Error(`Segment "${o}" must end with a letter or digit.`)}}static assertModuleName(e){this.assertSafeName(e,"module name")}static assertAbilityName(e){this.assertSafeName(e,"ability name")}static assertSafeName(e,t){if(!/^[A-Za-z0-9_.]+$/.test(e))throw new Error(`Invalid ${t}: ${JSON.stringify(e)}`)}static assertHilogToken(e,t){if(!/^[A-Za-z0-9_.:\\-]{1,64}$/.test(e))throw new Error(`Invalid ${t}: ${JSON.stringify(e)}`)}static assertHilogKeyword(e){if(e.length===0||e.length>128)throw new Error(`Invalid keyword: ${JSON.stringify(e)}`);if([...e].some(n=>{let i=n.charCodeAt(0);return i<=r.ASCII_CONTROL_MAX||i===r.ASCII_DELETE}))throw new Error(`Invalid keyword: ${JSON.stringify(e)}`)}static quotePosixShellArg(e){let n=`'${e.replace(/'/g,"'\\''")}'`;return f(`quotePosixShellArg: ${e} -> ${n}`),n}static assertCrashFilename(e){if(!/^\w+-[\w.]+-\d+-\d+$/.test(e))throw new Error(`Invalid crash log filename: ${JSON.stringify(e)}`)}static assertHilogLevel(e){if(!/^[DIWEF]$/.test(e))throw new Error(`Invalid log level: ${e}`)}static resolvePathWithinRoot(e,t){if(_e.isAbsolute(t))throw new Error(`Absolute paths are not allowed: ${t}`);let n=_e.resolve(_e.normalize(e),t);return r.ensurePathWithinRoot(e,n)}static ensurePathWithinRoot(e,t){let n=_e.normalize(e),i=_e.relative(n,t);if(i.split(_e.sep)[0]===".."||_e.isAbsolute(i))throw new Error(`Path escapes project root: ${t}`);return t}static isPathEscaping(e){let t=e.replace(/\\/g,"/");return t===".."||t.startsWith("../")||_e.isAbsolute(e)}static isPathContained(e,t){let n=_e.resolve(t,e),i=_e.relative(t,n);return r.isPathEscaping(i)?{contained:!1,reason:`Path traversal project root directory: ${e}`}:{contained:!0}}static isPathContainedWithSymlink(e,t){let n=r.isPathContained(e,t);if(!n.contained)return n;let i;try{i=mp.realpathSync(t)}catch{return{contained:!1,reason:`Project root directory does not exist or cannot be resolved: ${t}`}}let o=_e.resolve(i,e),s;try{s=mp.realpathSync(o)}catch{return{contained:!1,reason:`Path does not exist or cannot be resolved: ${o}`}}return r.isPathContained(s,i)}};import Ly from"crypto";import ae from"fs";import Pc from"os";import ft from"path";import XR from"https";var oy={devecoApiTraceUpload:"https://cn.devecostudio.huawei.com/codeGenie/cli/trace/upload"};var uc=class r{static ENDPOINT=oy.devecoApiTraceUpload;static SENDER="deveco-cli";async upload(e,t){let n={"Content-Type":"application/json",sender:r.SENDER,deviceid:t.replace(/-/g,""),"Content-Length":String(Buffer.byteLength(e,"utf8"))};try{let{body:i}=await this.httpPost(r.ENDPOINT,n,Buffer.from(e,"utf8"),6e4);return r.isSuccess(i)}catch{return!1}}static isSuccess(e){try{let t=JSON.parse(e),n=t?.code??t?.errorCode;return String(n)==="200"}catch{return!1}}async httpPost(e,t,n,i){let o=new URL(e);return new Promise((s,a)=>{let c=XR.request({protocol:o.protocol,hostname:o.hostname,port:o.port||(o.protocol==="https:"?443:80),path:o.pathname+o.search,method:"POST",headers:t,timeout:i},l=>{let d=[];l.on("data",g=>d.push(g)),l.on("end",()=>{s({code:l.statusCode??0,body:Buffer.concat(d).toString("utf8")})})});c.on("timeout",()=>{c.destroy(new Error("request timeout"))}),c.on("error",a),c.write(n),c.end()})}};var sy={identity:r=>r,camelCase:r=>r,snakeCase:r=>r.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toLowerCase()},gp=class{constructor(e={}){this.config=e}serialize(e){let t=this.transform(e);return this.config.pretty?JSON.stringify(t,null,2):JSON.stringify(t)}toObject(e){return this.transform(e)}transform(e){if(e==null)return e;if(Array.isArray(e))return e.map(o=>this.transform(o));if(typeof e!="object")return e;let t=this.config.namingStrategy??sy.identity,n=this.config.fieldNames??{},i={};for(let[o,s]of Object.entries(e)){let a=n[o]??t(o);i[a]=this.transform(s)}return i}},ay=new gp({namingStrategy:sy.snakeCase,fieldNames:{}});import gs from"crypto";import pc from"fs";import ZR from"path";var fc="aes-256-gcm",QR=12,ex="deveco-cli-trace-file",tx="trace-file-secret",ly=32;function cy(r){try{let e=pc.readFileSync(r,"utf8").trim();return e&&Buffer.from(e,"base64").length===ly?e:null}catch{return null}}function dy(r){let e=ZR.join(r,tx),t=cy(e);if(t)return hp(t);let n=gs.randomBytes(ly).toString("base64");try{pc.mkdirSync(r,{recursive:!0});try{pc.writeFileSync(e,n,{flag:"wx"})}catch{let i=cy(e);if(i)return hp(i);pc.writeFileSync(e,n)}}catch{}return hp(n)}function hp(r){return gs.createHash("sha256").update(ex).update(r).digest()}function uy(r,e){let t=gs.randomBytes(QR),n=gs.createCipheriv(fc,e,t),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o={version:1,algorithm:fc,ciphertext:i.toString("base64"),iv:t.toString("base64"),authTag:n.getAuthTag().toString("base64")};return JSON.stringify(o)}function py(r,e){let t;try{t=JSON.parse(r)}catch{return null}if(!rx(t))return r;try{let n=gs.createDecipheriv(fc,e,Buffer.from(t.iv,"base64"));return n.setAuthTag(Buffer.from(t.authTag,"base64")),Buffer.concat([n.update(Buffer.from(t.ciphertext,"base64")),n.final()]).toString("utf8")}catch{return null}}function rx(r){if(!r||typeof r!="object")return!1;let e=r;return e.version===1&&e.algorithm===fc&&typeof e.ciphertext=="string"&&typeof e.iv=="string"&&typeof e.authTag=="string"}import*as Y from"fs";import*as bc from"path";import ne from"fs";import{spawn as nx}from"child_process";import*as mc from"os";import*as B from"path";import ix from"json5";var yp="Huawei";var yy=3;function gc(r){if(!ne.existsSync(r)||!ne.statSync(r).isDirectory())return!1;let e=ne.existsSync(B.join(r,"build-profile.json5")),t=ne.existsSync(B.join(r,"hvigorfile.js"))||ne.existsSync(B.join(r,"hvigorfile.ts"));if(!e||!t)return!1;try{let n=ne.readFileSync(B.join(r,"build-profile.json5"),"utf-8");return ix.parse(n).app!==void 0}catch{return!1}}function wp(r,e,t){if(e>=t)return null;let n=ox(r),i=sx(n);if(i)return i;for(let o of n){let s=wp(o,e+1,t);if(s)return s}return null}function ox(r){try{let e=ne.readdirSync(r,{withFileTypes:!0}),t=[];for(let n of e)n.isDirectory()&&t.push(B.join(r,n.name));return t}catch{return[]}}function sx(r){for(let e of r)if(gc(e))return e;return null}function Ir(r){if(!r||r.trim()==="")return null;let e=B.resolve(r),t;try{t=ne.realpathSync(e)}catch{t=e}if(!ne.existsSync(t))return null;if(gc(t))return t;let n=t;for(let i=1;i<=3;i++){let o=B.dirname(n);if(o===n)break;if(gc(o))return o;n=o}if(ne.statSync(t).isDirectory()){let i=wp(t,0,yy);if(i)return i}return null}function hc(r){if(!r||r.trim()==="")return null;let e=B.resolve(r),t;try{t=ne.realpathSync(e)}catch{t=e}return!ne.existsSync(t)||!ne.statSync(t).isDirectory()?null:gc(t)?t:wp(t,0,yy)}var fy="DevEco Studio";function wy(){if(process.platform==="win32"){let r=[B.join("C:\\Program Files",yp,fy),B.join("C:\\Program Files (x86)",yp,fy)];return my(r)}if(process.platform==="darwin"){let r=["/Applications/DevEco Studio.app",B.join(process.env.HOME??"","Applications","DevEco Studio.app")];return my(r)}return null}function my(r){for(let e of r)if(ne.existsSync(e))return e;return null}function Hi(r,e){let t=e?B.join("standardIndex","index.js"):"index.js";return ne.existsSync(B.join(r,"ace-server"))?B.join(r,"ace-server","out",t):B.join(r,"out",t)}function yc(r){return ne.existsSync(Hi(r,!0))}var ax=5e3,cx=64*1024,gy=new Map;function vy(r,e){let t=lx(r),n=gy.get(t);if(n)return n;let i=dx(r,e).catch(()=>!1);return gy.set(t,i),i}function lx(r){let e=B.resolve(r).replace(/\\/g,"/");return process.platform==="win32"?e.toLowerCase():e}function hy(r){try{let e=JSON.parse(r.trim());return Array.isArray(e.protocols)?e.protocols.includes("--socket"):null}catch{return null}}function dx(r,e){let t=Hi(r,!0);if(!ne.existsSync(t))return Promise.resolve(!1);let n=e||process.execPath||"node",i=[t,"--list-protocols"];return h.debug(`Executing: ${n} ${i.join(" ")}`),new Promise(o=>{let s=nx(n,i,{stdio:["ignore","pipe","ignore"],windowsHide:!0}),a="",c=!1,l=g=>{c||(c=!0,clearTimeout(d),s.exitCode===null&&s.signalCode===null&&s.kill(),o(g))},d=setTimeout(()=>l(!1),ax);s.stdout?.on("data",g=>{a=(a+g.toString("utf8")).slice(-cx);let y=hy(a);y!==null&&l(y)}),s.on("error",()=>l(!1)),s.on("close",()=>l(hy(a)??!1))})}var ux=[".idea",".deveco","cxx","compile_commands.json"];function Jn(r){return B.join(r,...ux)}function by(r){return new Promise(e=>setTimeout(e,r))}var px=new Set(["c","cc","cpp","cxx","h","hh","hpp","hxx"]);function Kn(r){let e=B.extname(r).replace(/^\./,"").toLowerCase();return e.length>0&&px.has(e)}function wc(r){return B.extname(r).replace(/^\./,"").toLowerCase()==="c"?"c":"cpp"}function Ie(r){let e=r.replace(/\\/g,"/");return process.platform==="win32"&&/^[a-zA-Z]:/.test(e)&&(e=e[0].toUpperCase()+e.slice(1)),e}function fx(r){return Ie(r)}function Mt(r){let e=fx(r);return e.startsWith("/")?`file://${e}`:`file:///${e}`}function rn(){if(process.platform==="win32"){let r=process.env.LOCALAPPDATA??B.join(mc.homedir(),"AppData","Local");return B.join(r,"devecocli-mcp-server","logs")}return process.platform==="darwin"?B.join(mc.homedir(),"Library","Logs","devecocli-mcp-server"):B.join(mc.homedir(),".local","share","devecocli-mcp-server","logs")}function Sy(r,e){let t=mx(e),n=gx(t,r);if(n!==null)return n;let i=Date.now(),s=`${r.replace(/:/g,"\\:")}=${i}`,a=hx(t,r,s);return yx(e,a),i}function mx(r){let e;try{e=ne.readFileSync(r,"utf8")}catch{e=""}return e.length>0?e.split(/\r?\n/):[]}function gx(r,e){for(let t of r){let n=t.indexOf("=");if(n<=0||t.slice(0,n).replace(/\\:/g,":")!==e)continue;let o=parseInt(t.slice(n+1),10);return Number.isFinite(o)&&o>0?o:null}return null}function hx(r,e,t){let n=!1,i=r.map(o=>{if(n)return o;let s=o.indexOf("=");return s<=0?o:o.slice(0,s).replace(/\\:/g,":")===e?(n=!0,t):o});return n||i.push(t),i}function yx(r,e){try{ne.mkdirSync(B.dirname(r),{recursive:!0})}catch{}try{ne.writeFileSync(r,e.join(`
5
5
  `)+`
6
- `,"utf8")}catch{}}function Uu(r,e,t="[Cleanup]"){try{let n=B.dirname(r);if(!re.existsSync(n))return;let i=Date.now();for(let o of re.readdirSync(n,{withFileTypes:!0}))o.isDirectory()&&Hk(B.join(n,o.name),i,e,t)}catch{}}function Hk(r,e,t,n){try{let{mtimeMs:i}=re.statSync(r);if(e-i<=t)return;re.rmSync(r,{recursive:!0,force:!0});let o=Math.floor((e-i)/1e3);console.error(`${n} Removed expired dir (age ${Math.floor(o/86400)}d ${Math.floor(o%86400/3600)}h): ${r}`)}catch(i){console.error(`${n} Failed to remove expired dir ${r}: ${i}`)}}var Ah="mcp-server.log",Uk="mcp-server",Bk={maxSize:10*1024*1024,maxFiles:4},Bu=class r{fd=null;logDir=null;currentLogFile=null;mode;rotationOptions;currentFileSize=0;currentDate="";isRotating=!1;minLevel;static LEVEL_ORDER={debug:0,info:1,warn:2,error:3};constructor(e,t){this.rotationOptions={...Bk,...t},this.minLevel=e?"debug":"info",e?(this.mode="console",this.logDir=null,this.currentLogFile=null):(this.mode="file",this.logDir=Qr(),this.currentLogFile=tc.join(this.logDir,Ah),Y.existsSync(this.logDir)||Y.mkdirSync(this.logDir,{recursive:!0}),this.cleanupOrphanLogFiles(),this.openLogFile())}getCurrentDateString(){let e=new Date,t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${i}`}getRotatedFileName(e,t){return tc.join(this.logDir,`${Uk}-${e}.log.${t}`)}fileExists(e){try{return Y.accessSync(e,Y.constants.F_OK),!0}catch{return!1}}cleanupOrphanLogFiles(){if(this.logDir)try{let e=Y.readdirSync(this.logDir),t=[];for(let i of e)if(i===Ah||/^mcp-server-\d{4}-\d{2}-\d{2}\.log\.\d+$/.test(i)){let o=tc.join(this.logDir,i),s=Y.statSync(o);t.push({name:i,mtime:s.mtime,path:o})}t.sort((i,o)=>o.mtime.getTime()-i.mtime.getTime());let n=1+this.rotationOptions.maxFiles;for(let i=n;i<t.length;i++)try{Y.unlinkSync(t[i].path)}catch{}}catch{}}rotateLog(){if(!(this.isRotating||!this.logDir||!this.currentLogFile)){this.isRotating=!0;try{if(this.closeLogFile(),!this.fileExists(this.currentLogFile)){this.isRotating=!1,this.openLogFile();return}let e=this.getCurrentDateString(),t=this.getRotatedFileName(e,this.rotationOptions.maxFiles);this.fileExists(t)&&Y.unlinkSync(t);for(let i=this.rotationOptions.maxFiles-1;i>=1;i--){let o=this.getRotatedFileName(e,i),s=this.getRotatedFileName(e,i+1);this.fileExists(o)&&Y.renameSync(o,s)}let n=this.getRotatedFileName(e,1);Y.renameSync(this.currentLogFile,n),this.cleanupOrphanLogFiles(),this.openLogFile()}catch{this.openLogFile()}finally{this.isRotating=!1}}}openLogFile(){if(this.currentLogFile){this.currentDate=this.getCurrentDateString();try{if(this.fileExists(this.currentLogFile)){let e=Y.statSync(this.currentLogFile);this.currentFileSize=e.size}else this.currentFileSize=0}catch{this.currentFileSize=0}try{this.fd=Y.openSync(this.currentLogFile,"a")}catch{this.fd=null}}}closeLogFile(){if(this.fd!==null){try{Y.closeSync(this.fd)}catch{}this.fd=null}}checkRotation(e){let t=this.getCurrentDateString();this.currentDate&&this.currentDate!==t&&(this.rotateLog(),this.currentDate=t),this.currentFileSize+=e,this.currentFileSize>=this.rotationOptions.maxSize&&this.rotateLog()}write(e,t,...n){if(this.mode==="silent"||r.LEVEL_ORDER[e]<r.LEVEL_ORDER[this.minLevel])return;let i=n.map(c=>c instanceof Error?`${c.name}: ${c.message}`:typeof c=="object"?JSON.stringify(c,null,2):String(c)).join(" "),o=i?`${t} ${i}`:t,a=`[${new Date().toLocaleString("sv-SE",{timeZone:"Asia/Shanghai",hour12:!1})+"."+String(new Date().getMilliseconds()).padStart(3,"0")}] [MCP/${e.toUpperCase()}] [pid=${process.pid}] ${o}
7
- `;if(this.mode==="file"&&this.currentLogFile){if(this.fd===null&&this.openLogFile(),this.fd!==null)try{let c=Buffer.from(a);Y.writeSync(this.fd,c),this.checkRotation(c.byteLength)}catch{this.closeLogFile(),this.openLogFile()}}else this.mode==="console"&&process.stderr.write(a)}debug(e,...t){this.write("debug",e,...t)}info(e,...t){this.write("info",e,...t)}warn(e,...t){this.write("warn",e,...t)}error(e,...t){this.write("error",e,...t)}dispose(){this.closeLogFile()}flush(){if(!(this.mode!=="file"||this.fd===null))try{Y.fsyncSync(this.fd)}catch{}}getLogFilePath(){return this.currentLogFile}getLogDirectory(){return this.logDir}},bt=null;function zn(r=!1){bt&&bt.dispose(),bt=new Bu(r)}function Ih(){bt&&(bt.dispose(),bt=null)}function Th(){bt&&bt.flush()}function Oh(){return bt?.getLogFilePath()??null}function Nh(){return bt?.getLogDirectory()??null}function ec(){return bt||zn(!1),bt}var h={debug:(r,...e)=>ec().debug(r,...e),info:(r,...e)=>ec().info(r,...e),warn:(r,...e)=>ec().warn(r,...e),error:(r,...e)=>ec().error(r,...e)};import is from"fs";import Wu from"path";var os=300*1e3,ss=3600*1e3,Vu=10080*60*1e3,Ni=8*1024*1024,Gu=3600*1e3,Mh=".pending",Wk=/\.reclaim-\d+-\d+$/;function Qe(){let r=process.env.DEVECO_CLI_DISABLE_TELEMETRY;return r==="1"||r==="true"}var Vk="upload-state.json";function _h(r){return Wu.join(r,Vk)}function Gk(){return{firstEventAt:null,lastUploadAt:null,lastRetryAt:null}}function rc(r){try{let e=is.readFileSync(_h(r),"utf8"),t=JSON.parse(e);return{firstEventAt:typeof t.firstEventAt=="number"?t.firstEventAt:null,lastUploadAt:typeof t.lastUploadAt=="number"?t.lastUploadAt:null,lastRetryAt:typeof t.lastRetryAt=="number"?t.lastRetryAt:null}}catch{return Gk()}}function qu(r,e){try{is.writeFileSync(_h(r),JSON.stringify(e),"utf8")}catch{}}function $h(r){let e=rc(r);e.firstEventAt===null&&(e.firstEventAt=Date.now(),qu(r,e))}function Fh(r){let e=rc(r);e.lastUploadAt=Date.now(),e.firstEventAt=null,qu(r,e)}function jh(r){let e=rc(r);e.lastRetryAt=Date.now(),qu(r,e)}function zu(r){let e=r.match(/^telemetry-(\d{4})-(\d{2})-(\d{2})\.txt$/);if(!e)return null;let t=Date.parse(`${e[1]}-${e[2]}-${e[3]}T00:00:00`);return Number.isFinite(t)?t:null}function Ju(r){if(!r.startsWith("telemetry-"))return null;let e=Wk.exec(r),t=e?r.slice(0,e.index):r;if(!t.endsWith(Mh))return null;let n=t.slice(0,-Mh.length);return n.endsWith(".txt")?n:null}function Yu(r){return Ju(r)!==null}function qk(r,e=Date.now()){try{return e-is.statSync(r).mtimeMs>=Gu}catch{return!1}}function Lh(r,e=Date.now()){let t;try{t=is.readdirSync(r)}catch{return!1}return t.some(n=>Yu(n)&&qk(Wu.join(r,n),e))}function zk(r,e=Date.now()){if(Lh(r,e))return!0;let t=Wu.join(r,"failed");if(Lh(t,e))return!0;let n;try{n=is.readdirSync(t)}catch{return!1}for(let i of n){if(!i.startsWith("telemetry-")||!i.endsWith(".txt"))continue;let o=zu(i);if(o!==null&&e-o<=Vu)return!0}return!1}function Hh(r,e=Date.now()){let t=rc(r);return!!(t.firstEventAt!==null&&e-t.firstEventAt>=os||zk(r,e)&&(t.lastRetryAt===null||e-t.lastRetryAt>=ss))}import Jk from"crypto";import nc from"fs";import Yk from"path";var Kk="install-id";function Xk(r){return Yk.join(r,Kk)}function Uh(r){try{let e=nc.readFileSync(r,"utf8").trim();return Zk(e)?e:null}catch{return null}}function Zk(r){return/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(r)}function Bh(r){let e=Xk(r),t=Uh(e);if(t)return t;let n=Jk.randomUUID();try{nc.mkdirSync(r,{recursive:!0});try{nc.writeFileSync(e,n,{flag:"wx"})}catch{let i=Uh(e);if(i)return i;nc.writeFileSync(e,n)}}catch{}return n}var as=class r{static MAX_BATCH=200;static MAX_PAYLOAD_BYTES=Math.floor(1.7*1024*1024);static TRACE_OS_VERSION="1.0";static COUNTRY_CODE="CN";static EVENT_PREFIX="devecocli_";uploader=new qa;storageDir="";failedDir="";installId="";disabled=Qe();traceFileKey=Buffer.alloc(0);sessionId=Wh.randomUUID();cliVersion="";devecoStudioVersion=null;sourceType="";cltVersion=null;nodeVersion="";initialTimer=null;intervalTimer=null;retryInitialTimer=null;retryTimer=null;flushChain=Promise.resolve();constructor(){h.debug(`[telemetry] instance created, sessionId=${this.sessionId}`)}init(e){this.storageDir=e,this.failedDir=pt.join(e,"failed"),this.cliVersion="1.3.7",this.nodeVersion=process.version,this.installId=Bh(e).replace(/-/g,""),this.traceFileKey=yh(e),se.mkdirSync(e,{recursive:!0}),se.mkdirSync(this.failedDir,{recursive:!0}),h.debug(`[telemetry] init: dir=${e}, failedDir=${this.failedDir}, cliVersion=${this.cliVersion}, os=${this.resolveOsName()}, arch=${this.resolveOsArch()}, node=${this.nodeVersion}`)}setStudioVersion(e){this.devecoStudioVersion=e,h.debug(`[telemetry] studio version set: ${e}`)}setSourceType(e){this.sourceType=e,h.debug(`[telemetry] sourceType set: ${e}`)}setCltVersion(e){this.cltVersion=e,h.debug(`[telemetry] CLT version set: ${e}`)}async track(e,t){if(this.disabled)return typeof t=="function"?t():void 0;if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");if(!t){await this.record(e,0,!0,null);return}if(typeof t!="function"){let o=t;await this.record(e,o.duration_ms,o.success,o.error_code);return}let n=t,i=Date.now();try{let o=await n(),s=Date.now()-i;return await this.record(e,s,!0,null),o}catch(o){let s=Date.now()-i,a=this.toErrorCode(o);throw await this.record(e,s,!1,a),o}}async record(e,t,n,i){let o=this.buildTraceEvent(e,t,n,i);try{let s=wh(JSON.stringify(o),this.traceFileKey);await se.promises.appendFile(this.currentFile(),s+`
8
- `,"utf8"),$h(this.storageDir)}catch{}}buildTraceEvent(e,t,n,i){let o=`${r.EVENT_PREFIX}${e.event}`,s=fh.toObject(e);return s&&typeof s=="object"&&delete s.event,{countryCode:r.COUNTRY_CODE,event:o,eventtime:String(Date.now()),properties:{uid:this.installId,trace_uuid:Wh.randomUUID(),trace_os_version:r.TRACE_OS_VERSION,os_arch:this.resolveOsArch(),action:o,trace_os_name:this.resolveOsName(),version:`${this.cliVersion}_${this.resolveOsSuffix()}`,deveco_studio_version:this.formatVersion(this.devecoStudioVersion),command_line_version:this.formatVersion(this.cltVersion),source_type:this.sourceType,session_id:this.sessionId,node_version:this.nodeVersion,ram:this.resolveTotalRam(),duration_ms:t,success:n,error_code:i,event_detail:s}}}toErrorCode(e){return e instanceof Error?e.code??e.name:"UnknownError"}resolveOsArch(){let e=ic.arch();return e==="x64"?"amd64":e}resolveOsName(){switch(process.platform){case"win32":{let e=ic.release().split(".");return(parseInt(e[e.length-1],10)||0)>=22e3?"Windows 11":"Windows 10"}case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}resolveOsSuffix(){switch(process.platform){case"win32":return"windows";case"darwin":return ic.arch()==="arm64"?"mac_arm":"mac";default:return"linux"}}resolveTotalRam(){return`${Math.round(ic.totalmem()/1024)}KB`}formatVersion(e){return e?`${e}_${this.resolveOsSuffix()}`:""}dateString(){let e=new Date,t=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${e.getFullYear()}-${t}-${n}`}currentFile(){return pt.join(this.storageDir,`telemetry-${this.dateString()}.txt`)}startScheduler(){if(this.stopScheduler(),this.disabled){h.debug("[telemetry] scheduler not started (telemetry disabled)");return}h.debug(`[telemetry] scheduler started (flush every ${os/1e3}s, retry failed every ${ss/1e3}s)`),this.initialTimer=setTimeout(()=>{this.flush().catch(()=>{}),this.intervalTimer=setInterval(()=>{this.flush().catch(()=>{})},os)},os),this.retryInitialTimer=setTimeout(()=>{this.retryFailed().catch(()=>{}),this.retryTimer=setInterval(()=>{this.retryFailed().catch(()=>{})},ss)},ss)}stopScheduler(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.intervalTimer&&(clearInterval(this.intervalTimer),this.intervalTimer=null),this.retryInitialTimer&&(clearTimeout(this.retryInitialTimer),this.retryInitialTimer=null),this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=null),h.debug("[telemetry] scheduler stopped")}async flush(){return this.disabled?!0:this.runExclusive(()=>this.performFlush())}async performFlush(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");let e=await this.listPendingFiles(),t=!0;for(let n of e)await this.flushFile(n)||(t=!1);return Fh(this.storageDir),t}async retryFailed(){return this.disabled?!0:this.runExclusive(()=>this.performRetryFailed())}async performRetryFailed(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");await this.reclaimStalePending();let e=Date.now(),t;try{t=await se.promises.readdir(this.failedDir)}catch{return!0}let n=t.filter(o=>o.startsWith("telemetry-")&&o.endsWith(".txt")).map(o=>pt.join(this.failedDir,o)),i=!0;for(let o of n){let s=pt.basename(o),a=zu(s);if(a!==null){if(e-a>Vu){try{await se.promises.unlink(o)}catch{}continue}await this.flushFile(o)||(i=!1)}}return i||h.warn("[telemetry] retry failed"),jh(this.storageDir),i}async reclaimStalePending(){let e=Date.now();for(let t of[this.storageDir,this.failedDir]){let n;try{n=await se.promises.readdir(t)}catch{continue}for(let i of n)Yu(i)&&await this.reclaimOrphan(pt.join(t,i),e)}}async reclaimOrphan(e,t){let n;try{let l=await se.promises.stat(e);if(t-l.mtimeMs<Gu)return;n=l.size}catch{return}let i=pt.dirname(e),o=Ju(pt.basename(e));if(o===null)return;let s=await this.claimOrphan(e,i,o);if(s===null)return;let a=pt.join(i,o),c=Ni-await this.fileSize(a);if(n>c){try{await se.promises.unlink(s)}catch{}h.warn(`[telemetry] dropped stale orphan pending: ${s} (${n} bytes > budget ${c})`);return}if(await this.mergeOrphanInto(s,a)){h.warn(`[telemetry] reclaimed orphan pending: ${s} (${n} bytes)`);return}h.warn(`[telemetry] merge failed, kept orphan pending for retry: ${s} (${n} bytes)`)}async claimOrphan(e,t,n){let i=pt.join(t,`${n}.pending.reclaim-${process.pid}-${Date.now()}`);try{await se.promises.rename(e,i)}catch{return null}return await this.touch(i),i}async mergeOrphanInto(e,t){try{await se.promises.appendFile(t,await se.promises.readFile(e))}catch(n){return h.warn(`[telemetry] merge orphan pending failed: ${e} -> ${t}: ${n instanceof Error?n.message:String(n)}`),!1}try{await se.promises.unlink(e)}catch(n){h.warn(`[telemetry] merged but failed to remove orphan pending: ${e}: ${n instanceof Error?n.message:String(n)}`)}return!0}async fileSize(e){try{return(await se.promises.stat(e)).size}catch{return 0}}async touch(e){let t=new Date;try{await se.promises.utimes(e,t,t)}catch{}}runExclusive(e){let t=()=>e(),n=this.flushChain.then(t,t);return this.flushChain=n.then(()=>{},()=>{}),n}async listPendingFiles(){let e;try{e=await se.promises.readdir(this.storageDir)}catch{return[]}return e.filter(t=>t.startsWith("telemetry-")&&t.endsWith(".txt")).map(t=>pt.join(this.storageDir,t)).sort()}async flushFile(e){let t=await this.fileSize(e);if(t>Ni){h.warn(`[telemetry] ${pt.basename(e)} is ${t} bytes (> ${Ni}), dropped without uploading`);try{await se.promises.unlink(e)}catch{}return!0}let n=e+".pending";try{await se.promises.rename(e,n)}catch{return!1}await this.touch(n);let i;try{i=await se.promises.readFile(n,"utf8")}catch{return!1}let o=i.split(`
9
- `).map(s=>s.trim()).filter(Boolean);if(o.length===0){try{await se.promises.unlink(n)}catch{}return!0}return this.uploadInBatches(n,o)}collectDecryptBatch(e,t){let n=[],i=16,o=t;for(;o<e.length&&n.length<r.MAX_BATCH;){let s=vh(e[o],this.traceFileKey);if(s===null){o++;continue}let a=Buffer.byteLength(s,"utf8")+1;if(n.length>0&&i+a>r.MAX_PAYLOAD_BYTES)break;n.push(s),i+=a,o++}return{batch:n,next:o}}async uploadInBatches(e,t){let n=0;for(;n<t.length;){let i=n,{batch:o,next:s}=this.collectDecryptBatch(t,n);n=s;let a=this.buildPayloadItems(o);if(a.length===0)continue;let c=JSON.stringify(a),l=!1;try{l=await this.uploader.upload(c,this.installId)}catch{}if(!l){h.warn("[telemetry] upload failed");let d=t.slice(i).join(`
6
+ `,"utf8")}catch{}}function vp(r,e,t="[Cleanup]"){try{let n=B.dirname(r);if(!ne.existsSync(n))return;let i=Date.now();for(let o of ne.readdirSync(n,{withFileTypes:!0}))o.isDirectory()&&wx(B.join(n,o.name),i,e,t)}catch{}}function wx(r,e,t,n){try{let{mtimeMs:i}=ne.statSync(r);if(e-i<=t)return;ne.rmSync(r,{recursive:!0,force:!0});let o=Math.floor((e-i)/1e3);console.error(`${n} Removed expired dir (age ${Math.floor(o/86400)}d ${Math.floor(o%86400/3600)}h): ${r}`)}catch(i){console.error(`${n} Failed to remove expired dir ${r}: ${i}`)}}var Ey="mcp-server.log",vx="mcp-server",bx={maxSize:10*1024*1024,maxFiles:4},bp=class r{fd=null;logDir=null;currentLogFile=null;mode;rotationOptions;currentFileSize=0;currentDate="";isRotating=!1;minLevel;static LEVEL_ORDER={debug:0,info:1,warn:2,error:3};constructor(e,t){this.rotationOptions={...bx,...t},this.minLevel=e?"debug":"info",e?(this.mode="console",this.logDir=null,this.currentLogFile=null):(this.mode="file",this.logDir=rn(),this.currentLogFile=bc.join(this.logDir,Ey),Y.existsSync(this.logDir)||Y.mkdirSync(this.logDir,{recursive:!0}),this.cleanupOrphanLogFiles(),this.openLogFile())}getCurrentDateString(){let e=new Date,t=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0");return`${t}-${n}-${i}`}getRotatedFileName(e,t){return bc.join(this.logDir,`${vx}-${e}.log.${t}`)}fileExists(e){try{return Y.accessSync(e,Y.constants.F_OK),!0}catch{return!1}}cleanupOrphanLogFiles(){if(this.logDir)try{let e=Y.readdirSync(this.logDir),t=[];for(let i of e)if(i===Ey||/^mcp-server-\d{4}-\d{2}-\d{2}\.log\.\d+$/.test(i)){let o=bc.join(this.logDir,i),s=Y.statSync(o);t.push({name:i,mtime:s.mtime,path:o})}t.sort((i,o)=>o.mtime.getTime()-i.mtime.getTime());let n=1+this.rotationOptions.maxFiles;for(let i=n;i<t.length;i++)try{Y.unlinkSync(t[i].path)}catch{}}catch{}}rotateLog(){if(!(this.isRotating||!this.logDir||!this.currentLogFile)){this.isRotating=!0;try{if(this.closeLogFile(),!this.fileExists(this.currentLogFile)){this.isRotating=!1,this.openLogFile();return}let e=this.getCurrentDateString(),t=this.getRotatedFileName(e,this.rotationOptions.maxFiles);this.fileExists(t)&&Y.unlinkSync(t);for(let i=this.rotationOptions.maxFiles-1;i>=1;i--){let o=this.getRotatedFileName(e,i),s=this.getRotatedFileName(e,i+1);this.fileExists(o)&&Y.renameSync(o,s)}let n=this.getRotatedFileName(e,1);Y.renameSync(this.currentLogFile,n),this.cleanupOrphanLogFiles(),this.openLogFile()}catch{this.openLogFile()}finally{this.isRotating=!1}}}openLogFile(){if(this.currentLogFile){this.currentDate=this.getCurrentDateString();try{if(this.fileExists(this.currentLogFile)){let e=Y.statSync(this.currentLogFile);this.currentFileSize=e.size}else this.currentFileSize=0}catch{this.currentFileSize=0}try{this.fd=Y.openSync(this.currentLogFile,"a")}catch{this.fd=null}}}closeLogFile(){if(this.fd!==null){try{Y.closeSync(this.fd)}catch{}this.fd=null}}checkRotation(e){let t=this.getCurrentDateString();this.currentDate&&this.currentDate!==t&&(this.rotateLog(),this.currentDate=t),this.currentFileSize+=e,this.currentFileSize>=this.rotationOptions.maxSize&&this.rotateLog()}write(e,t,...n){if(this.mode==="silent"||r.LEVEL_ORDER[e]<r.LEVEL_ORDER[this.minLevel])return;let i=n.map(c=>c instanceof Error?`${c.name}: ${c.message}`:typeof c=="object"?JSON.stringify(c,null,2):String(c)).join(" "),o=i?`${t} ${i}`:t,a=`[${new Date().toLocaleString("sv-SE",{timeZone:"Asia/Shanghai",hour12:!1})+"."+String(new Date().getMilliseconds()).padStart(3,"0")}] [MCP/${e.toUpperCase()}] [pid=${process.pid}] ${o}
7
+ `;if(this.mode==="file"&&this.currentLogFile){if(this.fd===null&&this.openLogFile(),this.fd!==null)try{let c=Buffer.from(a);Y.writeSync(this.fd,c),this.checkRotation(c.byteLength)}catch{this.closeLogFile(),this.openLogFile()}}else this.mode==="console"&&process.stderr.write(a)}debug(e,...t){this.write("debug",e,...t)}info(e,...t){this.write("info",e,...t)}warn(e,...t){this.write("warn",e,...t)}error(e,...t){this.write("error",e,...t)}dispose(){this.closeLogFile()}flush(){if(!(this.mode!=="file"||this.fd===null))try{Y.fsyncSync(this.fd)}catch{}}getLogFilePath(){return this.currentLogFile}getLogDirectory(){return this.logDir}},St=null;function Yn(r=!1){St&&St.dispose(),St=new bp(r)}function Py(){St&&(St.dispose(),St=null)}function Cy(){St&&St.flush()}function ky(){return St?.getLogFilePath()??null}function Ry(){return St?.getLogDirectory()??null}function vc(){return St||Yn(!1),St}var h={debug:(r,...e)=>vc().debug(r,...e),info:(r,...e)=>vc().info(r,...e),warn:(r,...e)=>vc().warn(r,...e),error:(r,...e)=>vc().error(r,...e)};import hs from"fs";import Sp from"path";var ys=300*1e3,ws=3600*1e3,Ep=10080*60*1e3,Ui=8*1024*1024,Pp=3600*1e3,xy=".pending",Sx=/\.reclaim-\d+-\d+$/;function et(){let r=process.env.DEVECO_CLI_DISABLE_TELEMETRY;return r==="1"||r==="true"}var Ex="upload-state.json";function Iy(r){return Sp.join(r,Ex)}function Px(){return{firstEventAt:null,lastUploadAt:null,lastRetryAt:null}}function Sc(r){try{let e=hs.readFileSync(Iy(r),"utf8"),t=JSON.parse(e);return{firstEventAt:typeof t.firstEventAt=="number"?t.firstEventAt:null,lastUploadAt:typeof t.lastUploadAt=="number"?t.lastUploadAt:null,lastRetryAt:typeof t.lastRetryAt=="number"?t.lastRetryAt:null}}catch{return Px()}}function Cp(r,e){try{hs.writeFileSync(Iy(r),JSON.stringify(e),"utf8")}catch{}}function Ay(r){let e=Sc(r);e.firstEventAt===null&&(e.firstEventAt=Date.now(),Cp(r,e))}function Ty(r){let e=Sc(r);e.lastUploadAt=Date.now(),e.firstEventAt=null,Cp(r,e)}function Ny(r){let e=Sc(r);e.lastRetryAt=Date.now(),Cp(r,e)}function kp(r){let e=r.match(/^telemetry-(\d{4})-(\d{2})-(\d{2})\.txt$/);if(!e)return null;let t=Date.parse(`${e[1]}-${e[2]}-${e[3]}T00:00:00`);return Number.isFinite(t)?t:null}function Rp(r){if(!r.startsWith("telemetry-"))return null;let e=Sx.exec(r),t=e?r.slice(0,e.index):r;if(!t.endsWith(xy))return null;let n=t.slice(0,-xy.length);return n.endsWith(".txt")?n:null}function xp(r){return Rp(r)!==null}function Cx(r,e=Date.now()){try{return e-hs.statSync(r).mtimeMs>=Pp}catch{return!1}}function Dy(r,e=Date.now()){let t;try{t=hs.readdirSync(r)}catch{return!1}return t.some(n=>xp(n)&&Cx(Sp.join(r,n),e))}function kx(r,e=Date.now()){if(Dy(r,e))return!0;let t=Sp.join(r,"failed");if(Dy(t,e))return!0;let n;try{n=hs.readdirSync(t)}catch{return!1}for(let i of n){if(!i.startsWith("telemetry-")||!i.endsWith(".txt"))continue;let o=kp(i);if(o!==null&&e-o<=Ep)return!0}return!1}function Oy(r,e=Date.now()){let t=Sc(r);return!!(t.firstEventAt!==null&&e-t.firstEventAt>=ys||kx(r,e)&&(t.lastRetryAt===null||e-t.lastRetryAt>=ws))}import Rx from"crypto";import Ec from"fs";import xx from"path";var Dx="install-id";function Ix(r){return xx.join(r,Dx)}function _y(r){try{let e=Ec.readFileSync(r,"utf8").trim();return Ax(e)?e:null}catch{return null}}function Ax(r){return/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(r)}function My(r){let e=Ix(r),t=_y(e);if(t)return t;let n=Rx.randomUUID();try{Ec.mkdirSync(r,{recursive:!0});try{Ec.writeFileSync(e,n,{flag:"wx"})}catch{let i=_y(e);if(i)return i;Ec.writeFileSync(e,n)}}catch{}return n}var vs=class r{static MAX_BATCH=200;static MAX_PAYLOAD_BYTES=Math.floor(1.7*1024*1024);static TRACE_OS_VERSION="1.0";static COUNTRY_CODE="CN";static EVENT_PREFIX="devecocli_";uploader=new uc;storageDir="";failedDir="";installId="";disabled=et();traceFileKey=Buffer.alloc(0);sessionId=Ly.randomUUID();cliVersion="";devecoStudioVersion=null;sourceType="";cltVersion=null;nodeVersion="";initialTimer=null;intervalTimer=null;retryInitialTimer=null;retryTimer=null;flushChain=Promise.resolve();constructor(){h.debug(`[telemetry] instance created, sessionId=${this.sessionId}`)}init(e){this.storageDir=e,this.failedDir=ft.join(e,"failed"),this.cliVersion="1.3.10-Test.1",this.nodeVersion=process.version,this.installId=My(e).replace(/-/g,""),this.traceFileKey=dy(e),ae.mkdirSync(e,{recursive:!0}),ae.mkdirSync(this.failedDir,{recursive:!0}),h.debug(`[telemetry] init: dir=${e}, failedDir=${this.failedDir}, cliVersion=${this.cliVersion}, os=${this.resolveOsName()}, arch=${this.resolveOsArch()}, node=${this.nodeVersion}`)}setStudioVersion(e){this.devecoStudioVersion=e,h.debug(`[telemetry] studio version set: ${e}`)}setSourceType(e){this.sourceType=e,h.debug(`[telemetry] sourceType set: ${e}`)}setCltVersion(e){this.cltVersion=e,h.debug(`[telemetry] CLT version set: ${e}`)}async track(e,t){if(this.disabled)return typeof t=="function"?t():void 0;if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");if(!t){await this.record(e,0,!0,null);return}if(typeof t!="function"){let o=t;await this.record(e,o.duration_ms,o.success,o.error_code);return}let n=t,i=Date.now();try{let o=await n(),s=Date.now()-i;return await this.record(e,s,!0,null),o}catch(o){let s=Date.now()-i,a=this.toErrorCode(o);throw await this.record(e,s,!1,a),o}}async record(e,t,n,i){let o=this.buildTraceEvent(e,t,n,i);try{let s=uy(JSON.stringify(o),this.traceFileKey);await ae.promises.appendFile(this.currentFile(),s+`
8
+ `,"utf8"),Ay(this.storageDir)}catch{}}buildTraceEvent(e,t,n,i){let o=`${r.EVENT_PREFIX}${e.event}`,s=ay.toObject(e);return s&&typeof s=="object"&&delete s.event,{countryCode:r.COUNTRY_CODE,event:o,eventtime:String(Date.now()),properties:{uid:this.installId,trace_uuid:Ly.randomUUID(),trace_os_version:r.TRACE_OS_VERSION,os_arch:this.resolveOsArch(),action:o,trace_os_name:this.resolveOsName(),version:`${this.cliVersion}_${this.resolveOsSuffix()}`,deveco_studio_version:this.formatVersion(this.devecoStudioVersion),command_line_version:this.formatVersion(this.cltVersion),source_type:this.sourceType,session_id:this.sessionId,node_version:this.nodeVersion,ram:this.resolveTotalRam(),duration_ms:t,success:n,error_code:i,event_detail:s}}}toErrorCode(e){return e instanceof Error?e.code??e.name:"UnknownError"}resolveOsArch(){let e=Pc.arch();return e==="x64"?"amd64":e}resolveOsName(){switch(process.platform){case"win32":{let e=Pc.release().split(".");return(parseInt(e[e.length-1],10)||0)>=22e3?"Windows 11":"Windows 10"}case"darwin":return"macOS";case"linux":return"Linux";default:return process.platform}}resolveOsSuffix(){switch(process.platform){case"win32":return"windows";case"darwin":return Pc.arch()==="arm64"?"mac_arm":"mac";default:return"linux"}}resolveTotalRam(){return`${Math.round(Pc.totalmem()/1024)}KB`}formatVersion(e){return e?`${e}_${this.resolveOsSuffix()}`:""}dateString(){let e=new Date,t=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0");return`${e.getFullYear()}-${t}-${n}`}currentFile(){return ft.join(this.storageDir,`telemetry-${this.dateString()}.txt`)}startScheduler(){if(this.stopScheduler(),this.disabled){h.debug("[telemetry] scheduler not started (telemetry disabled)");return}h.debug(`[telemetry] scheduler started (flush every ${ys/1e3}s, retry failed every ${ws/1e3}s)`),this.initialTimer=setTimeout(()=>{this.flush().catch(()=>{}),this.intervalTimer=setInterval(()=>{this.flush().catch(()=>{})},ys)},ys),this.retryInitialTimer=setTimeout(()=>{this.retryFailed().catch(()=>{}),this.retryTimer=setInterval(()=>{this.retryFailed().catch(()=>{})},ws)},ws)}stopScheduler(){this.initialTimer&&(clearTimeout(this.initialTimer),this.initialTimer=null),this.intervalTimer&&(clearInterval(this.intervalTimer),this.intervalTimer=null),this.retryInitialTimer&&(clearTimeout(this.retryInitialTimer),this.retryInitialTimer=null),this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=null),h.debug("[telemetry] scheduler stopped")}async flush(){return this.disabled?!0:this.runExclusive(()=>this.performFlush())}async performFlush(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");let e=await this.listPendingFiles(),t=!0;for(let n of e)await this.flushFile(n)||(t=!1);return Ty(this.storageDir),t}async retryFailed(){return this.disabled?!0:this.runExclusive(()=>this.performRetryFailed())}async performRetryFailed(){if(!this.storageDir)throw new Error("Telemetry not initialized. Call init() first.");await this.reclaimStalePending();let e=Date.now(),t;try{t=await ae.promises.readdir(this.failedDir)}catch{return!0}let n=t.filter(o=>o.startsWith("telemetry-")&&o.endsWith(".txt")).map(o=>ft.join(this.failedDir,o)),i=!0;for(let o of n){let s=ft.basename(o),a=kp(s);if(a!==null){if(e-a>Ep){try{await ae.promises.unlink(o)}catch{}continue}await this.flushFile(o)||(i=!1)}}return i||h.warn("[telemetry] retry failed"),Ny(this.storageDir),i}async reclaimStalePending(){let e=Date.now();for(let t of[this.storageDir,this.failedDir]){let n;try{n=await ae.promises.readdir(t)}catch{continue}for(let i of n)xp(i)&&await this.reclaimOrphan(ft.join(t,i),e)}}async reclaimOrphan(e,t){let n;try{let l=await ae.promises.stat(e);if(t-l.mtimeMs<Pp)return;n=l.size}catch{return}let i=ft.dirname(e),o=Rp(ft.basename(e));if(o===null)return;let s=await this.claimOrphan(e,i,o);if(s===null)return;let a=ft.join(i,o),c=Ui-await this.fileSize(a);if(n>c){try{await ae.promises.unlink(s)}catch{}h.warn(`[telemetry] dropped stale orphan pending: ${s} (${n} bytes > budget ${c})`);return}if(await this.mergeOrphanInto(s,a)){h.warn(`[telemetry] reclaimed orphan pending: ${s} (${n} bytes)`);return}h.warn(`[telemetry] merge failed, kept orphan pending for retry: ${s} (${n} bytes)`)}async claimOrphan(e,t,n){let i=ft.join(t,`${n}.pending.reclaim-${process.pid}-${Date.now()}`);try{await ae.promises.rename(e,i)}catch{return null}return await this.touch(i),i}async mergeOrphanInto(e,t){try{await ae.promises.appendFile(t,await ae.promises.readFile(e))}catch(n){return h.warn(`[telemetry] merge orphan pending failed: ${e} -> ${t}: ${n instanceof Error?n.message:String(n)}`),!1}try{await ae.promises.unlink(e)}catch(n){h.warn(`[telemetry] merged but failed to remove orphan pending: ${e}: ${n instanceof Error?n.message:String(n)}`)}return!0}async fileSize(e){try{return(await ae.promises.stat(e)).size}catch{return 0}}async touch(e){let t=new Date;try{await ae.promises.utimes(e,t,t)}catch{}}runExclusive(e){let t=()=>e(),n=this.flushChain.then(t,t);return this.flushChain=n.then(()=>{},()=>{}),n}async listPendingFiles(){let e;try{e=await ae.promises.readdir(this.storageDir)}catch{return[]}return e.filter(t=>t.startsWith("telemetry-")&&t.endsWith(".txt")).map(t=>ft.join(this.storageDir,t)).sort()}async flushFile(e){let t=await this.fileSize(e);if(t>Ui){h.warn(`[telemetry] ${ft.basename(e)} is ${t} bytes (> ${Ui}), dropped without uploading`);try{await ae.promises.unlink(e)}catch{}return!0}let n=e+".pending";try{await ae.promises.rename(e,n)}catch{return!1}await this.touch(n);let i;try{i=await ae.promises.readFile(n,"utf8")}catch{return!1}let o=i.split(`
9
+ `).map(s=>s.trim()).filter(Boolean);if(o.length===0){try{await ae.promises.unlink(n)}catch{}return!0}return this.uploadInBatches(n,o)}collectDecryptBatch(e,t){let n=[],i=16,o=t;for(;o<e.length&&n.length<r.MAX_BATCH;){let s=py(e[o],this.traceFileKey);if(s===null){o++;continue}let a=Buffer.byteLength(s,"utf8")+1;if(n.length>0&&i+a>r.MAX_PAYLOAD_BYTES)break;n.push(s),i+=a,o++}return{batch:n,next:o}}async uploadInBatches(e,t){let n=0;for(;n<t.length;){let i=n,{batch:o,next:s}=this.collectDecryptBatch(t,n);n=s;let a=this.buildPayloadItems(o);if(a.length===0)continue;let c=JSON.stringify(a),l=!1;try{l=await this.uploader.upload(c,this.installId)}catch{}if(!l){h.warn("[telemetry] upload failed");let d=t.slice(i).join(`
10
10
  `)+`
11
- `;return await this.moveToFailed(e,d),!1}}try{await se.promises.unlink(e)}catch{}return!0}buildPayloadItems(e){let t=[];for(let n of e)try{let i=JSON.parse(n);t.push({action:i.event,detail:JSON.stringify(i.properties),timestamp:Number(i.eventtime)||Date.now()})}catch{}return t}async moveToFailed(e,t){let n=pt.basename(e,".pending"),i=pt.join(this.failedDir,n),o=t.split(`
12
- `).filter(Boolean),s=Ni-await this.fileSize(i),a=this.takeNewestWithinBudget(o,s);a.length<o.length&&h.warn(`[telemetry] failed file capped at ${Ni} bytes, dropped ${o.length-a.length} older events`);try{a.length>0&&await se.promises.appendFile(i,a.join(`
11
+ `;return await this.moveToFailed(e,d),!1}}try{await ae.promises.unlink(e)}catch{}return!0}buildPayloadItems(e){let t=[];for(let n of e)try{let i=JSON.parse(n);t.push({action:i.event,detail:JSON.stringify(i.properties),timestamp:Number(i.eventtime)||Date.now()})}catch{}return t}async moveToFailed(e,t){let n=ft.basename(e,".pending"),i=ft.join(this.failedDir,n),o=t.split(`
12
+ `).filter(Boolean),s=Ui-await this.fileSize(i),a=this.takeNewestWithinBudget(o,s);a.length<o.length&&h.warn(`[telemetry] failed file capped at ${Ui} bytes, dropped ${o.length-a.length} older events`);try{a.length>0&&await ae.promises.appendFile(i,a.join(`
13
13
  `)+`
14
- `,"utf8")}catch{return}try{await se.promises.unlink(e)}catch{}}takeNewestWithinBudget(e,t){if(t<=0)return[];let n=[],i=0;for(let o=e.length-1;o>=0;o--){let s=Buffer.byteLength(e[o],"utf8")+1;if(i+s>t)break;i+=s,n.push(e[o])}return n.reverse(),n}};var D=new as;import{spawn as Qk}from"child_process";import{existsSync as eD}from"fs";import{dirname as tD,join as rD}from"path";import{fileURLToPath as nD}from"url";function iD(){let r=tD(nD(import.meta.url)),e=rD(r,"internal","telemetry-upload-background.js");return eD(e)?e:null}function Ku(r){if(Qe()||!Hh(r))return;let e=iD();if(!e){h.warn("[telemetry] background upload script not found, skipping spawn");return}try{Qk(process.execPath,[e],{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,DEVECO_CLI_SKIP_VERSION_CHECK:"1",DEVECO_CLI_TELEMETRY_UPLOAD:"1"}}).unref()}catch(t){h.warn("[telemetry] failed to spawn background upload:",t)}}var w=class extends Error{traceMessage;constructor(e,t,n){super(e,n),this.name="TraceError",this.traceMessage=t??e}};function X(r){if(r instanceof w)return r.traceMessage;if(r instanceof Error){let e=r.code;return typeof e=="string"&&e!==""?e:r.name}return"UnknownError"}var v={CommandExecuted:"Command_executed",McpToolCall:"serve_mcp",SkillOperation:"skills",Init:"mcp_config_operation",SkillConfigOperation:"skill_config_operation",DocOperation:"docs",ServeLsp:"serve_lsp",CheckCommand:"check",PluginOperation:"devecocli_plugin"};var Pe={OH_PACKAGE_JSON5:"oh-package.json5",BUILD_PROFILE_JSON5:"build-profile.json5",SYNC_OUTPUT_PATH:".hvigor/outputs/sync/output.json",LOCK_JSON5_PATH:"oh_modules/.ohpm/lock.json5",HVIGOR_CONFIG:"hvigor/hvigor-config.json5"};var W=class r{rootDir;profile;constructor(e,t){this.rootDir=e,this.profile=t}static discover(e){let t=e;for(;;){let n=r.tryLoadProjectProfile(t);if(n)return new r(t,n);let i=H.dirname(t);if(i===t)break;t=i}throw new Error("Not in a valid project directory (project-level build-profile.json5 not found).")}static tryLoadProjectProfile(e){let t=H.join(e,"build-profile.json5");if(!K.existsSync(t))return null;try{let n=K.readFileSync(t,"utf-8"),i=tr.parse(n);return i.app?i:null}catch(n){return console.error(`Error parsing ${t}:`,n),null}}getRunnableModuleNames(){return this.profile.modules.map(e=>e.name).filter(e=>this.getModuleType(e)!=="har").join(", ")}getModuleType(e){let t=this.profile.modules.find(o=>o.name===e);if(!t)throw new w(`Module '${e}' not found in project-level build-profile.json5.`,"Module not found in project-level build-profile.json5.");let n=P.resolvePathWithinRoot(this.rootDir,t.srcPath),i=H.join(n,"src","main","module.json5");if(!K.existsSync(i))return"entry";try{let o=K.readFileSync(i,"utf-8");return tr.parse(o)?.module?.type||"entry"}catch(o){return console.warn(`Warning: Failed to parse ${i}:`,o),"entry"}}findOwningModule(e){let t=H.normalize(e);for(let n of this.profile.modules){let i=H.normalize(H.join(this.rootDir,n.srcPath)),o=i+H.sep;if(t.startsWith(o)||t===i)return n.name}return null}getModuleProfile(e){let t=this.profile.modules.find(o=>o.name===e);if(!t)throw new w(`Module '${e}' not found in project-level build-profile.json5.`,"Module not found in project-level build-profile.json5.");let n=P.resolvePathWithinRoot(this.rootDir,t.srcPath),i=H.join(n,"build-profile.json5");if(!K.existsSync(i))throw new w(`Build profile for module '${e}' not found at ${i}.`,"Build profile for module not found at ${profilePath}.");try{let o=K.readFileSync(i,"utf-8");return tr.parse(o)}catch(o){throw new Error(`Failed to parse module build profile at ${i}: ${o instanceof Error?o.message:String(o)}`,{cause:o})}}getBundleName(e){if(e){let n=this.profile.app.products?.find(i=>i.name===e);if(n?.bundleName)return n.bundleName}let t=H.join(this.rootDir,"AppScope","app.json5");if(K.existsSync(t))try{let n=K.readFileSync(t,"utf-8"),i=tr.parse(n);if(i?.app?.bundleName)return i.app.bundleName}catch(n){console.warn(`Warning: Failed to parse ${t}:`,n)}throw new Error("Could not find bundleName in AppScope/app.json5.")}isAtomicService(){let e=H.join(this.rootDir,"AppScope","app.json5");if(!K.existsSync(e))return!1;try{let t=K.readFileSync(e,"utf-8");return tr.parse(t)?.app?.bundleType==="atomicService"}catch{return!1}}getMainAbility(e,t){if(t)return t;let n=this.profile.modules.find(s=>s.name===e);if(!n)return"EntryAbility";let i=P.resolvePathWithinRoot(this.rootDir,n.srcPath),o=H.join(i,"src","main","module.json5");if(!K.existsSync(o))return"EntryAbility";try{let s=K.readFileSync(o,"utf-8"),c=tr.parse(s)?.module?.abilities||[];if(c.length===0)return"EntryAbility";let l=c.find(d=>d.name==="EntryAbility");return l?l.name:c[0].name}catch(s){return console.warn(`Warning: Failed to parse ${o}:`,s),"EntryAbility"}}validateProduct(e){if(!/^[\da-zA-Z_-]+$/.test(e))throw new w(`Invalid product name '${e}'. Product names must only contain letters, digits, underscores, and hyphens.`,"Invalid product name.");if(!this.profile.app.products?.some(n=>n.name===e)){let n=this.profile.app.products?.map(i=>i.name).join(", ")||"none";throw new w(`Product '${e}' not found in project configuration. Available products: ${n}`,"Productnot found in project configuration.")}}getModuleDependencies(e){let t=this.profile.modules.find(i=>i.name===e);if(!t)return[];let n=this.readLockFinalLocalModuleDeps(e);return n!==null?n:this.readOhPackageLocalModuleDeps(t)}readLockFinalLocalModuleDeps(e){let t=H.join(this.rootDir,Pe.LOCK_JSON5_PATH);if(!K.existsSync(t))return null;let n;try{n=tr.parse(K.readFileSync(t,"utf-8"))}catch(d){return m(`Failed to parse lock.json5: ${d instanceof Error?d.message:String(d)}`),null}let i=n,o=i?.modules;if(!o||typeof o!="object")return null;let s=Object.values(o).find(d=>typeof d=="object"&&d!==null&&d.name===e);if(!s)return null;let a=this.buildOverrideMap(i.overrides),c=[],l=new Set;for(let d of["dependencies","dynamicDependencies"]){let g=s[d];!g||typeof g!="object"||this.collectLocalDeps(g,a,y=>this.resolveLockDepByVersion(y),c,l)}return c}resolveLockDepByVersion(e){if(typeof e!="object"||e===null)return null;let t=e.version;return typeof t=="string"?this.resolveLocalDepToModule(t):null}resolveDepModule(e,t,n){if(t?.has(e)){let i=t.get(e);if(i){let o=this.resolveLocalDepToModule(i);if(o)return o}}return n()}buildOverrideMap(e){if(!e||typeof e!="object")return null;let t=new Map;for(let[n,i]of Object.entries(e))typeof i=="string"&&t.set(n,i);return t.size>0?t:null}resolveLocalDepToModule(e){let t=r.stripLocalDep(e);if(!t)return null;let n=H.resolve(this.rootDir,t),i;try{i=P.ensurePathWithinRoot(this.rootDir,n)}catch{return null}let o=this.profile.modules.find(s=>H.resolve(this.rootDir,s.srcPath)===i);return o?o.name:null}static stripLocalDep(e){return!e.startsWith("file:")&&!e.startsWith(".")&&!e.startsWith("..")?null:e.startsWith("file:")?e.substring(5):e}readOhPackageLocalModuleDeps(e){let t=H.join(P.resolvePathWithinRoot(this.rootDir,e.srcPath),Pe.OH_PACKAGE_JSON5);if(!K.existsSync(t))return[];let n=this.readRootOverrideMap(),i=[],o=new Set;try{let s=tr.parse(K.readFileSync(t,"utf-8"));for(let a of["dependencies","dynamicDependencies"]){let c=s?.[a];!c||typeof c!="object"||this.collectLocalDeps(c,n,l=>this.resolveOhPackageDepByValue(l,e),i,o)}}catch(s){m(`Failed to get module dependencies: ${s instanceof Error?s.message:String(s)}`)}return i}readRootOverrideMap(){let e=H.join(this.rootDir,Pe.OH_PACKAGE_JSON5);if(!K.existsSync(e))return null;try{let t=tr.parse(K.readFileSync(e,"utf-8"));return this.buildOverrideMap(t?.overrides)}catch{return null}}resolveOhPackageDepByValue(e,t){return typeof e=="string"?this.resolveLocalDepModuleName(e,t):null}collectLocalDeps(e,t,n,i,o){for(let[s,a]of Object.entries(e)){let c=this.resolveDepModule(s,t,()=>n(a));c&&!o.has(c)&&(o.add(c),i.push(c))}}resolveLocalDepModuleName(e,t){let n=r.stripLocalDep(e);if(!n)return null;let i=H.join(t.srcPath,n),o=P.resolvePathWithinRoot(this.rootDir,i),s=this.profile.modules.find(a=>H.resolve(this.rootDir,a.srcPath)===o);return s?s.name:null}collectNonHarDependentModuleList(e){let t=[],n=[],i=new Set;for(n.push(e),i.add(e);n.length>0;){let o=n.shift();this.getModuleType(o)!=="har"&&t.push(o);let a=this.getModuleDependencies(o);for(let c of a)i.has(c)||(n.push(c),i.add(c))}return t}resolveModuleMetadata(e,t,n){this.validateProduct(n);let i=this.profile.modules.find(l=>l.name===e);if(!i){let l=this.getRunnableModuleNames();throw new w(`Module '${e}' not found. Available modules: ${l}`,"Module not found.")}let o=this.getModuleType(e)==="shared",s=o?"hspName":"hapName",a=this.buildOutputPath(i.srcPath,n,["intermediates",o?"hsp_metadata":"hap_metadata",t,"output_metadata.json"]);if(!K.existsSync(a))throw new w(`Build metadata not found for module '${e}' at ${a}. Build the project first.`,"Build metadata not found for module. Build the project first.");let c=this.parseOutputMetadata(a,s);return{moduleNode:i,isShared:o,metadataPath:a,metadata:c}}findArtifactPath(e,t,n,i="default"){let{moduleNode:o,isShared:s,metadata:a}=this.resolveModuleMetadata(e,t,i),{packageName:c,isSigned:l}=a,d=c;if(!l){let E=this.getSignedHapName(c,o.srcPath,i,t);E&&(d=E)}let g=s?"-signed.hsp":"-signed.hap";if(!n&&!d.endsWith(g))throw new w(`Target device is a real device, but the artifact for '${e}' is not signed. Real devices cannot install unsigned packages.`,"Target device is a real device, but the artifact is not signed.");let y=this.buildOutputPath(o.srcPath,i,["outputs",t,d]);if(!K.existsSync(y))throw new w(`Generated package file not found in ${y}.`,"Generated package file not found.");return y}findRemoteHspPaths(e,t,n="default"){let{moduleNode:i,metadata:o}=this.resolveModuleMetadata(e,t,n),s=[],a=new Set;for(let{hspPath:c}of o.dependRemoteHsps){if(a.has(c))continue;a.add(c);let l=H.isAbsolute(c)?c:this.buildOutputPath(i.srcPath,n,["outputs",t,c]);if(!K.existsSync(l))throw new w(`Remote HSP dependency not found: ${l}`,"Remote HSP dependency not found.");s.push(l)}return s}resolveModuleSpecsForProduct(e){let t=[];for(let n of this.profile.modules){let i=n.targets;if(!i||i.length===0){t.push(`${n.name}@default`);continue}let o=i.filter(s=>!s.applyToProducts||s.applyToProducts.includes(e));if(o.length!==0)for(let s of o)t.push(`${n.name}@${s.name}`)}return t}listBuildArtifacts(e,t){let n=[];for(let i of e){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i,a=o!==-1?i.substring(o+1):"default",c=this.profile.modules.find(d=>d.name===s);if(!c)continue;let l=this.buildOutputPath(c.srcPath,t,["outputs",a]);if(K.existsSync(l))for(let d of K.readdirSync(l))(d.endsWith(".hap")||d.endsWith(".hsp")||d.endsWith(".har"))&&n.push(H.join(l,d))}return n}listProjectAppArtifacts(e){let t=P.ensurePathWithinRoot(this.rootDir,H.resolve(this.rootDir,"build","outputs",e));if(!K.existsSync(t))return[];let n=[],i=o=>{for(let s of K.readdirSync(o,{withFileTypes:!0})){let a=H.join(o,s.name);s.isDirectory()?i(a):s.name.endsWith(".app")&&n.push(a)}};return i(t),n}collectBuildArtifacts(e,t,n){let i=t;if(!e){let s=new Set(t);i=[...t,...this.profile.modules.map(a=>`${a.name}@default`).filter(a=>!s.has(a))]}let o=this.listBuildArtifacts(i,n);return e&&o.push(...this.listProjectAppArtifacts(n)),o}getSignedHapName(e,t,n,i){let o=null;if(e.endsWith("-unsigned.hap")?o=e.replace("-unsigned.hap","-signed.hap"):e.endsWith("-unsigned.hsp")&&(o=e.replace("-unsigned.hsp","-signed.hsp")),!o)return null;let s=this.buildOutputPath(t,n,["outputs",i,o]);return K.existsSync(s)?o:null}buildOutputPath(e,t,n){let i=P.resolvePathWithinRoot(this.rootDir,e),o=H.resolve(i,"build",t,...n);return P.ensurePathWithinRoot(this.rootDir,o)}collectRemoteHsps(e){return e.flatMap(t=>{let n=t.dependRemoteHsps;return Array.isArray(n)?n.filter(i=>!!(i.hspName&&i.hspPath)).map(i=>({hspName:i.hspName,hspPath:i.hspPath})):[]})}parseOutputMetadata(e,t){let n;try{let c=K.readFileSync(e,"utf-8");n=tr.parse(c)}catch(c){throw new Error(`Failed to parse output metadata at ${e}: ${c instanceof Error?c.message:String(c)}`,{cause:c})}let i,o=!1,s=Array.isArray(n)?n:[n];for(let c of s)i||(i=c[t]),o||(o=c.isSigned===!0);if(!i)throw new w(`Could not find ${t} in output_metadata.json at ${e}`,"Could not find metadataKey in output_metadata.json at metadataPath.");this.validatePackageName(i);let a=this.collectRemoteHsps(s);return{packageName:i,isSigned:o,dependRemoteHsps:a}}validatePackageName(e){let t=H.basename(e);if(t!==e)throw new w(`Invalid traversal name: '${e}'. It must contain path characters.`,"Invalid traversal name.");if(!t.endsWith(".hap")&&!t.endsWith(".hsp"))throw new w(`Invalid package name '${t}'.It must be a .hap or .hsp file.`,"Invalid package name.")}};import vp from"fs/promises";import tn from"path";function St(r){if(!/^[A-Za-z0-9._-]+$/.test(r)||r==="."||r==="..")throw new Error(`Unsafe skill name: ${JSON.stringify(r)}`)}import tp from"fs";import Jn from"path";import{homedir as qh}from"os";import Be from"fs/promises";import mt from"path";import{randomUUID as Vh}from"crypto";async function Me(r){try{return await Be.lstat(r)}catch(e){if(e.code==="ENOENT")return;throw e}}async function Ce(r){let e=mt.resolve(r),t=mt.dirname(e);try{return mt.join(await Be.realpath(t),mt.basename(e))}catch(n){if(n.code!=="ENOENT"||t===e)throw n;return mt.join(await Ce(t),mt.basename(e))}}async function Xu(r,e){let t=`${e}.backup-${Vh()}`,n=await Me(e);n&&await Be.rename(e,t);try{await Be.rename(r,e)}catch(i){throw n&&await Be.rename(t,e),i}n&&await Be.rm(t,{recursive:!0,force:!0})}function fe(r,e){let t=n=>mt.resolve(n).replace(/^\\\\\?\\/,"").replace(/[\\/]+$/,"");return process.platform==="win32"?t(r).toLowerCase()===t(e).toLowerCase():t(r)===t(e)}function Mi(r,e){let t=(n,i)=>{let o=mt.relative(n,i);return o===""||!o.startsWith(`..${mt.sep}`)&&o!==".."&&!mt.isAbsolute(o)};return t(r,e)||t(e,r)}async function oc(r,e,t=!1){let n=await Be.realpath(r);if(!(await Be.stat(n)).isDirectory())throw new Error(`Skill source is not a directory: ${r}`);let i=await Ce(e),o=await Me(i);if(fe(n,i))return rr(i,"same-source");let s=o?await Be.realpath(i).catch(()=>i):i;if(o?.isSymbolicLink()&&fe(n,s))return rr(i,"correct-link");let a=await Zu(i,t);if(a)return a;if(Mi(n,i)||o&&Mi(n,s))throw new Error(`Skill source and destination overlap: ${r}, ${e}`);await Be.mkdir(mt.dirname(i),{recursive:!0});let c=`${i}.install-${Vh()}`;try{let l=await oD(n,c);return await Xu(c,i),{success:!0,path:i,...l}}finally{await Be.rm(c,{recursive:!0,force:!0})}}function rr(r,e){return{success:!0,skipped:!0,path:r,reason:e}}async function Zu(r,e){if(!e&&await Me(r))return rr(r,"already-exists")}async function oD(r,e){try{let t=process.platform==="win32"?r:mt.relative(mt.dirname(e),r);return await Be.symlink(t,e,process.platform==="win32"?"junction":"dir"),{mode:"symlink"}}catch(t){return await Be.rm(e,{recursive:!0,force:!0}),await Be.cp(r,e,{recursive:!0,dereference:!0,errorOnExist:!0,force:!1}),{mode:"copy",fallbackReason:t.code??String(t)}}}async function sc(r){let e=await Ce(r),t=await Me(e);return t?(await Be.rm(e,{recursive:!t.isSymbolicLink(),force:!0}),{success:!0,path:e}):rr(e,"not-installed")}var Gh={amp:{displayName:"Amp",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},antigravity:{displayName:"Antigravity",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/antigravity/skills"},"antigravity-cli":{displayName:"Antigravity CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/antigravity-cli/skills"},astrbot:{displayName:"AstrBot",skillsDir:"data/skills",globalSkillsDir:"~/.astrbot/data/skills"},atomcode:{displayName:"atomcode",skillsDir:".atomcode/skills",globalSkillsDir:"~/.atomcode/skills",detect:["~/.atomcode"]},augment:{displayName:"Augment",skillsDir:".augment/skills",globalSkillsDir:"~/.augment/skills"},bob:{displayName:"IBM Bob",skillsDir:".bob/skills",globalSkillsDir:"~/.bob/skills"},"claude-code":{displayName:"Claude Code",skillsDir:".claude/skills",globalSkillsDir:"~/.claude/skills",detect:["~/.claude"]},cline:{displayName:"Cline",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},"codearts-agent":{displayName:"CodeArts Agent",skillsDir:".codeartsdoer/skills",globalSkillsDir:"~/.codeartsdoer/skills"},codebuddy:{displayName:"CodeBuddy",skillsDir:".codebuddy/skills",globalSkillsDir:"~/.codebuddy/skills",detect:["~/.codebuddy"]},codex:{displayName:"Codex",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills",detect:["~/.codex"],legacySkillsDirs:[".codex/skills"],legacyGlobalSkillsDirs:["~/.codex/skills"]},continue:{displayName:"Continue",skillsDir:".continue/skills",globalSkillsDir:"~/.continue/skills"},crush:{displayName:"Crush",skillsDir:".crush/skills",globalSkillsDir:"~/.config/crush/skills"},cursor:{displayName:"Cursor",skillsDir:".agents/skills",globalSkillsDir:"~/.cursor/skills",detect:["~/.cursor"],legacySkillsDirs:[".cursor/skills"]},deepagents:{displayName:"Deep Agents",skillsDir:".agents/skills",globalSkillsDir:"~/.deepagents/agent/skills"},deveco:{displayName:"deveco",skillsDir:".deveco/skills",globalSkillsDir:"~/.config/deveco/skills",detect:["~/.config/deveco"]},devin:{displayName:"Devin for Terminal",skillsDir:".devin/skills",globalSkillsDir:"~/.config/devin/skills"},droid:{displayName:"Droid",skillsDir:".agents/skills",globalSkillsDir:"~/.factory/skills"},dsh:{displayName:"deepseek harness",skillsDir:".dsh/skills",globalSkillsDir:"~/.dsh/skills",detect:["~/.dsh"]},"gemini-cli":{displayName:"Gemini CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/skills"},"github-copilot":{displayName:"GitHub Copilot",skillsDir:".agents/skills",globalSkillsDir:"~/.copilot/skills"},goose:{displayName:"Goose",skillsDir:".goose/skills",globalSkillsDir:"~/.config/goose/skills"},grok:{displayName:"Grok Build",skillsDir:".grok/skills",globalSkillsDir:"~/.grok/skills"},"hermes-agent":{displayName:"Hermes Agent",skillsDir:".hermes/skills",globalSkillsDir:"~/.hermes/skills"},"iflow-cli":{displayName:"iFlow CLI",skillsDir:".iflow/skills",globalSkillsDir:"~/.iflow/skills"},junie:{displayName:"Junie",skillsDir:".junie/skills",globalSkillsDir:"~/.junie/skills"},kilo:{displayName:"Kilo Code",skillsDir:".agents/skills",globalSkillsDir:"~/.kilo/skills"},"kimi-code-cli":{displayName:"Kimi Code CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},"kiro-cli":{displayName:"Kiro CLI",skillsDir:".kiro/skills",globalSkillsDir:"~/.kiro/skills"},kode:{displayName:"Kode",skillsDir:".kode/skills",globalSkillsDir:"~/.kode/skills"},lingma:{displayName:"Lingma",skillsDir:".lingma/skills",globalSkillsDir:"~/.lingma/skills"},"minimax-code":{displayName:"MiniMax Code",skillsDir:".minimax/skills",globalSkillsDir:"~/.minimax/skills"},"mistral-vibe":{displayName:"Mistral Vibe",skillsDir:".vibe/skills",globalSkillsDir:"~/.vibe/skills"},neovate:{displayName:"Neovate",skillsDir:".neovate/skills",globalSkillsDir:"~/.neovate/skills"},ona:{displayName:"Ona",skillsDir:".ona/skills",globalSkillsDir:"~/.ona/skills"},openclaw:{displayName:"OpenClaw",skillsDir:"skills",globalSkillsDir:"~/.openclaw/skills"},opencode:{displayName:"OpenCode",skillsDir:".agents/skills",globalSkillsDir:"~/.config/opencode/skills",detect:["~/.config/opencode"],legacySkillsDirs:[".opencode/skills"]},openhands:{displayName:"OpenHands",skillsDir:".openhands/skills",globalSkillsDir:"~/.openhands/skills"},pi:{displayName:"Pi",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills",detect:["~/.pi/agent"],legacySkillsDirs:[".pi/skills"],legacyGlobalSkillsDirs:["~/.pi/agent/skills"]},qoder:{displayName:"Qoder",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder/skills",detect:["~/.qoder"]},"qoder-cn":{displayName:"Qoder CN",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder-cn/skills"},"qwen-code":{displayName:"Qwen Code",skillsDir:".qwen/skills",globalSkillsDir:"~/.qwen/skills"},reasonix:{displayName:"Reasonix",skillsDir:".reasonix/skills",globalSkillsDir:"~/.reasonix/skills"},replit:{displayName:"Replit",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},trae:{displayName:"Trae",skillsDir:".trae/skills",globalSkillsDir:"~/.trae/skills"},"trae-cn":{displayName:"Trae CN",skillsDir:".trae/skills",globalSkillsDir:"~/.trae-cn/skills",detect:["~/.trae-cn"],legacySkillsDirs:[".trae-cn/skills"]},universal:{displayName:"Universal",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},warp:{displayName:"Warp",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},windsurf:{displayName:"Windsurf",skillsDir:".windsurf/skills",globalSkillsDir:"~/.codeium/windsurf/skills"},zcode:{displayName:"ZCode",skillsDir:".zcode/skills",globalSkillsDir:"~/.zcode/skills"},zed:{displayName:"Zed",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"}};var Qu="https://matrix.openharmony.cn",Et={TAGS_API_URL:`${Qu}/api/model_base/model/tags?serviceType=skill`,SKILLS_API_URL:`${Qu}/api/registry/skill/skills`,SKILL_API_BASE:`${Qu}/api/registry/skill`,DEFAULT_PAGE_SIZE:20,DEFAULT_MAX_PAGES:100,SUCCESS_CODE:"20000"},ep=".agents/skills",cs=Gh;function Li(r){return Jn.resolve(r==="~"||r.startsWith("~/")?Jn.join(qh(),r.slice(1)):r)}function Le(){return Object.keys(cs)}function ac(r){return[...new Set((r??"").split(",").map(e=>e.trim()).filter(Boolean))]}function Mt(r){let e=Object.prototype.hasOwnProperty.call(cs,r)?cs[r]:void 0;if(!e)throw new Error(`Invalid agent: ${r}, Valid options are: ${Le().join(", ")}`);return e}function rp(r){return Li(Mt(r).globalSkillsDir)}function np(r,e){return Jn.join(r,Mt(e).skillsDir)}function nr(r){return Jn.join(r??qh(),ep)}function Lt(r,e){return e?np(e,r):rp(r)}function cc(r,e){let t=Lt(r,e);return fe(t,nr(e))}function zh(r,e){let t=Mt(r),n=e?(t.legacySkillsDirs??[]).map(o=>Jn.join(e,o)):(t.legacyGlobalSkillsDirs??[]).map(Li),i=[Lt(r,e)];return n.filter(o=>i.some(s=>fe(s,o))?!1:(i.push(o),!0))}function ip(r,e){let t=Mt(e).skillsDir.split("/")[0];return t.startsWith(".")&&tp.existsSync(Jn.join(r,t))}function Yn(r,e){let t=Mt(r);if(t.detect)return t.detect.some(o=>tp.existsSync(Li(o)));let n=rp(r);return![nr(),rp("universal")].some(o=>fe(o,n))&&tp.existsSync(Jn.dirname(n))?!0:!!(e&&t.skillsDir!==ep&&ip(e,r))}import lc from"path";function Jh(r){let e=[];r.agents.length&&e.push({agents:[...new Set(r.agents)]});let t=new Map;for(let{project:n,agent:i}of r.projectAgents){let o=t.get(n)??[];o.push(i),t.set(n,o)}for(let[n,i]of t)e.push({project:n,agents:[...new Set(i)]});return e}async function aD(r,e,t,n){let i=[];for(let o of zh(r,e.project)){let s=await Ce(lc.join(o,t));!n.some(a=>fe(a,s))&&await Me(s)&&i.push(s)}return i}async function dc(r,e,t=!0){let n=await Ce(lc.join(nr(r.project),e)),i=[];for(let o of r.agents){let s=Lt(o,r.project),a=await Ce(lc.join(s,e)),c=await aD(o,r,e,[n,a]),l=!!(r.project&&!t&&!cc(o,r.project)&&c.length===0&&!ip(r.project,o)),d=i.find(g=>fe(g.path,a));d?(d.legacy.push(...c.filter(g=>!d.legacy.some(y=>fe(y,g)))),d.skipped&&=l):i.push({path:a,legacy:c,skipped:l})}return i}async function Yh(r,e,t=!0){let n=await dc(r,e,t);if(n.every(o=>o.skipped))return n;let i=await Ce(lc.join(nr(r.project),e));return n.some(o=>fe(o.path,i))||n.unshift({path:i,legacy:[],skipped:!1}),n}import _i from"fs/promises";import $t from"path";import{randomUUID as MD}from"crypto";import{lock as LD}from"proper-lockfile";import*as ls from"fs";import*as Qh from"path";import{homedir as cD}from"os";import*as Kh from"fs";import*as et from"path";function op(r,e){let t=et.relative(e,r);return t===""||!et.isAbsolute(t)&&!t.startsWith(`..${et.sep}`)&&t!==".."}function en(r){let e=et.resolve(r),t=[],n=e;for(;;)try{let i=Kh.realpathSync(n);return t.length===0?i:et.join(i,...t.reverse())}catch(i){if(i.code!=="ENOENT")throw i;let o=et.dirname(n);if(o===n)return e;t.push(et.basename(n)),n=o}}function Xh(r,e){let t=en(e),n=en(r);return op(n,t)?n:null}function sp(r){let e=r.trim();return(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))&&(e=e.slice(1,-1).trim()),e}function uc(r){let e=sp(r);if(!e)throw new Error("Path must not be empty.");return en(e)}var lD="deveco-cli",Zh,ap=class extends Error{constructor(e){super(e),this.name="CliDataDirError"}};function dD(){let r=process.env.DEVECO_CLI_DATA_DIR,t=(r===void 0||r===""?"":sp(r))||Qh.join(cD(),".local","share",lD);try{return uc(t)}catch(n){throw new ap(n instanceof Error?n.message:String(n))}}function $(){if(Zh!==void 0)return Zh;let r=dD();try{if(ls.existsSync(r))return ls.realpathSync(r)}catch{}return r}import xD from"adm-zip";import AD from"crypto";import{timingSafeEqual as ID}from"crypto";import pp from"fs";import _t from"path";import{fileURLToPath as TD}from"url";import{homedir as ir}from"os";import tt from"path";var or="deveco-mcp",pc={"trae-cn":".trae-cn",opencode:".config/opencode",pi:".pi/agent",deveco:".config/deveco",cursor:".cursor",codebuddy:".codebuddy",qoder:".qoder","claude-code":".claude",codex:".codex",atomcode:".atomcode",dsh:".dsh"};var kr={opencode:{name:"opencode",displayName:"OpenCode",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".config","opencode","opencode.json"),projectConfigPath:".opencode/opencode.json",mcpServersKey:"mcp",format:"opencode"},pi:{name:"pi",displayName:"Pi Coding Agent",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".pi","agent","mcp.json"),projectConfigPath:".pi/mcp.json",mcpServersKey:"mcpServers",format:"standard"},"trae-cn":{name:"trae-cn",displayName:"Trae-CN",supportsGlobal:!0,globalConfigPath:tt.join(process.platform==="win32"?tt.join(process.env.APPDATA??tt.join(ir(),"AppData","Roaming"),"Trae CN","User"):tt.join(ir(),"Library","Application Support","Trae CN","User"),"mcp.json"),projectConfigPath:".trae/mcp.json",mcpServersKey:"mcpServers",format:"standard"},cursor:{name:"cursor",displayName:"Cursor",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".cursor","mcp.json"),projectConfigPath:".cursor/mcp.json",mcpServersKey:"mcpServers",format:"standard"},codebuddy:{name:"codebuddy",displayName:"Codebuddy",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".codebuddy","mcp.json"),projectConfigPath:".codebuddy/mcp.json",mcpServersKey:"mcpServers",format:"codebuddy"},qoder:{name:"qoder",displayName:"Qoder",supportsGlobal:!0,globalConfigPath:tt.join(process.platform==="win32"?tt.join(process.env.APPDATA??tt.join(ir(),"AppData","Roaming"),"Qoder","SharedClientCache"):tt.join(ir(),"Library","Application Support","Qoder","SharedClientCache"),"mcp.json"),projectConfigPath:".mcp.json",mcpServersKey:"mcpServers",format:"standard"},"claude-code":{name:"claude-code",displayName:"Claude Code",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".claude.json"),projectConfigPath:".mcp.json",mcpServersKey:"mcpServers",format:"claude-code"},codex:{name:"codex",displayName:"Codex",supportsGlobal:!0,globalConfigPath:tt.join(ir(),".codex","config.toml"),projectConfigPath:".codex/config.toml",mcpServersKey:"mcp_servers",format:"codex"}};function ty(r){return{type:"local",command:["devecocli","serve","mcp"],environment:{PROJECT_PATH:r??"."},enabled:!0}}function ey(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"."},enabled:!0}}function uD(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"."}}}function ry(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"${workspaceFolder}"}}}function mc(r,e){return r.format==="opencode"?ty(e):r.format==="claude-code"||r.format==="codex"?ey(e):r.format==="codebuddy"?uD(e):ry(e)}var cp="https://developer.huawei.com/consumer/cn/download/";import ED from"axios";var pD={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443};function mD(r){try{return new URL(r)}catch{return null}}function ny(r){var e=(typeof r=="string"?mD(r):r)||{},t=e.protocol,n=e.host,i=e.port;if(typeof n!="string"||!n||typeof t!="string"||(t=t.split(":",1)[0],n=n.replace(/:\d*$/,""),i=parseInt(i)||pD[t]||0,!fD(n,i)))return"";var o=lp(t+"_proxy")||lp("all_proxy");return o&&o.indexOf("://")===-1&&(o=t+"://"+o),o}function fD(r,e){var t=lp("no_proxy").toLowerCase();return t?t==="*"?!1:t.split(/[,\s]/).every(function(n){if(!n)return!0;var i=n.match(/^(.+):(\d+)$/),o=i?i[1]:n,s=i?parseInt(i[2]):0;return s&&s!==e?!0:/^[.*]/.test(o)?(o.charAt(0)==="*"&&(o=o.slice(1)),!r.endsWith(o)):r!==o}):!0}function lp(r){return process.env[r.toLowerCase()]||process.env[r.toUpperCase()]||""}import{spawn as sy}from"child_process";import*as Kn from"fs";import*as ay from"os";import*as fc from"path";var cy=6e4;async function gD(){if(process.platform!=="win32")return null;let r="HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",e=await iy(r,"ProxyServer");if(!e)return null;let t=await iy(r,"ProxyEnable");return t!=="1"&&t!=="0x1"?null:e.trim()}function iy(r,e){return new Promise(t=>{let n=sy("reg.exe",["query",r,"/v",e],{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),i="";n.stdout.on("data",o=>{i+=o.toString()}),n.on("error",()=>t(null)),n.on("close",o=>{if(o!==0){t(null);return}let s=/REG_\w+\s+(\S+)/.exec(i);t(s?s[1]:null)})})}function hD(){let r=process.env.HTTPS_PROXY??process.env.HTTP_PROXY??"";if(!r)return null;try{return new URL(r).host}catch{return r}}function yD(){return`${process.env.SystemRoot??"C:\\Windows"}\\System32\\curl.exe`}function oy(r){let e={},t=0,n="";for(let i of r.split(/\r?\n/)){let o=i.trim();if(!o)continue;let s=/^HTTP\/\d(?:\.\d)?\s+(\d{3})\s*(.*)$/.exec(o);if(s){t=parseInt(s[1],10),n=s[2]??"";continue}let a=/^([^:]+):\s*(.*)$/.exec(o);a&&(e[a[1].toLowerCase()]=a[2])}return{statusCode:t,statusText:n,headers:e}}function wD(r,e,t,n){let i=["--silent","--show-error","--location","--ssl-no-revoke","--insecure","-x",`http://${e}`,"--proxy-ntlm","--proxy-user",":","--max-time",String(Math.max(1,Math.floor((r.timeoutMs??cy)/1e3)))];return r.method&&r.method!=="GET"&&i.push("-X",r.method),r.data!==void 0&&i.push("--data-binary",r.data),i.push(...vD(r.headers,r.data!==void 0)),n?(i.push("--dump-header",t),i.push("--output",n)):i.push("--include"),i.push(r.url),i}function vD(r,e){let t=new Set(["content-length","host","connection","proxy-authorization","proxy-connection","accept-encoding"]),n=[],i=!1;for(let[o,s]of Object.entries(r??{})){let a=o.toLowerCase();a==="content-type"&&(i=!0),t.has(a)||n.push("-H",`${o}: ${s}`)}return e&&!i&&n.push("-H","Content-Type: application/json"),n}function bD(r,e,t){if(t){let l=Kn.readFileSync(e,"utf8"),d=Kn.readFileSync(t),g=oy(l);return{statusCode:g.statusCode,statusText:g.statusText,body:d.toString("base64"),headers:g.headers,bodyBuffer:d}}let n=r.lastIndexOf("HTTP/");if(n===-1)return null;let i=r.slice(n),o=i.indexOf(`\r
14
+ `,"utf8")}catch{return}try{await ae.promises.unlink(e)}catch{}}takeNewestWithinBudget(e,t){if(t<=0)return[];let n=[],i=0;for(let o=e.length-1;o>=0;o--){let s=Buffer.byteLength(e[o],"utf8")+1;if(i+s>t)break;i+=s,n.push(e[o])}return n.reverse(),n}};var R=new vs;import{spawn as Tx}from"child_process";import{existsSync as Nx}from"fs";import{dirname as Ox,join as _x}from"path";import{fileURLToPath as Mx}from"url";function Lx(){let r=Ox(Mx(import.meta.url)),e=_x(r,"internal","telemetry-upload-background.js");return Nx(e)?e:null}function Dp(r){if(et()||!Oy(r))return;let e=Lx();if(!e){h.warn("[telemetry] background upload script not found, skipping spawn");return}try{Tx(process.execPath,[e],{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,DEVECO_CLI_SKIP_VERSION_CHECK:"1",DEVECO_CLI_TELEMETRY_UPLOAD:"1"}}).unref()}catch(t){h.warn("[telemetry] failed to spawn background upload:",t)}}var w=class extends Error{traceMessage;constructor(e,t,n){super(e,n),this.name="TraceError",this.traceMessage=t??e}};function Z(r){if(r instanceof w)return r.traceMessage;if(r instanceof Error){let e=r.code;return typeof e=="string"&&e!==""?e:r.name}return"UnknownError"}var v={CommandExecuted:"Command_executed",McpToolCall:"serve_mcp",SkillOperation:"skills",Init:"mcp_config_operation",SkillConfigOperation:"skill_config_operation",DocOperation:"docs",ServeLsp:"serve_lsp",CheckCommand:"check",PluginOperation:"devecocli_plugin"};var Ce={OH_PACKAGE_JSON5:"oh-package.json5",BUILD_PROFILE_JSON5:"build-profile.json5",SYNC_OUTPUT_PATH:".hvigor/outputs/sync/output.json",LOCK_JSON5_PATH:"oh_modules/.ohpm/lock.json5",HVIGOR_CONFIG:"hvigor/hvigor-config.json5"};var W=class r{rootDir;profile;constructor(e,t){this.rootDir=e,this.profile=t}static discover(e){let t=e;for(;;){let n=r.tryLoadProjectProfile(t);if(n)return new r(t,n);let i=H.dirname(t);if(i===t)break;t=i}throw new Error("Not in a valid project directory (project-level build-profile.json5 not found).")}static tryLoadProjectProfile(e){let t=H.join(e,"build-profile.json5");if(!X.existsSync(t))return null;try{let n=X.readFileSync(t,"utf-8"),i=or.parse(n);return i.app?i:null}catch(n){return console.error(`Error parsing ${t}:`,n),null}}getRunnableModuleNames(){return this.profile.modules.map(e=>e.name).filter(e=>this.getModuleType(e)!=="har").join(", ")}getModuleType(e){let t=this.profile.modules.find(o=>o.name===e);if(!t)throw new w(`Module '${e}' not found in project-level build-profile.json5.`,"Module not found in project-level build-profile.json5.");let n=P.resolvePathWithinRoot(this.rootDir,t.srcPath),i=H.join(n,"src","main","module.json5");if(!X.existsSync(i))return"entry";try{let o=X.readFileSync(i,"utf-8");return or.parse(o)?.module?.type||"entry"}catch(o){return console.warn(`Warning: Failed to parse ${i}:`,o),"entry"}}findOwningModule(e){let t=H.normalize(e);for(let n of this.profile.modules){let i=H.normalize(H.join(this.rootDir,n.srcPath)),o=i+H.sep;if(t.startsWith(o)||t===i)return n.name}return null}getModuleProfile(e){let t=this.profile.modules.find(o=>o.name===e);if(!t)throw new w(`Module '${e}' not found in project-level build-profile.json5.`,"Module not found in project-level build-profile.json5.");let n=P.resolvePathWithinRoot(this.rootDir,t.srcPath),i=H.join(n,"build-profile.json5");if(!X.existsSync(i))throw new w(`Build profile for module '${e}' not found at ${i}.`,"Build profile for module not found at ${profilePath}.");try{let o=X.readFileSync(i,"utf-8");return or.parse(o)}catch(o){throw new Error(`Failed to parse module build profile at ${i}: ${o instanceof Error?o.message:String(o)}`,{cause:o})}}getBundleName(e){if(e){let n=this.profile.app.products?.find(i=>i.name===e);if(n?.bundleName)return n.bundleName}let t=H.join(this.rootDir,"AppScope","app.json5");if(X.existsSync(t))try{let n=X.readFileSync(t,"utf-8"),i=or.parse(n);if(i?.app?.bundleName)return i.app.bundleName}catch(n){console.warn(`Warning: Failed to parse ${t}:`,n)}throw new Error("Could not find bundleName in AppScope/app.json5.")}isAtomicService(){let e=H.join(this.rootDir,"AppScope","app.json5");if(!X.existsSync(e))return!1;try{let t=X.readFileSync(e,"utf-8");return or.parse(t)?.app?.bundleType==="atomicService"}catch{return!1}}getMainAbility(e,t){if(t)return t;let n=this.profile.modules.find(s=>s.name===e);if(!n)return"EntryAbility";let i=P.resolvePathWithinRoot(this.rootDir,n.srcPath),o=H.join(i,"src","main","module.json5");if(!X.existsSync(o))return"EntryAbility";try{let s=X.readFileSync(o,"utf-8"),c=or.parse(s)?.module?.abilities||[];if(c.length===0)return"EntryAbility";let l=c.find(d=>d.name==="EntryAbility");return l?l.name:c[0].name}catch(s){return console.warn(`Warning: Failed to parse ${o}:`,s),"EntryAbility"}}validateProduct(e){if(!/^[\da-zA-Z_-]+$/.test(e))throw new w(`Invalid product name '${e}'. Product names must only contain letters, digits, underscores, and hyphens.`,"Invalid product name.");if(!this.profile.app.products?.some(n=>n.name===e)){let n=this.profile.app.products?.map(i=>i.name).join(", ")||"none";throw new w(`Product '${e}' not found in project configuration. Available products: ${n}`,"Productnot found in project configuration.")}}getModuleDependencies(e){let t=this.profile.modules.find(i=>i.name===e);if(!t)return[];let n=this.readLockFinalLocalModuleDeps(e);return n!==null?n:this.readOhPackageLocalModuleDeps(t)}readLockFinalLocalModuleDeps(e){let t=H.join(this.rootDir,Ce.LOCK_JSON5_PATH);if(!X.existsSync(t))return null;let n;try{n=or.parse(X.readFileSync(t,"utf-8"))}catch(d){return f(`Failed to parse lock.json5: ${d instanceof Error?d.message:String(d)}`),null}let i=n,o=i?.modules;if(!o||typeof o!="object")return null;let s=Object.values(o).find(d=>typeof d=="object"&&d!==null&&d.name===e);if(!s)return null;let a=this.buildOverrideMap(i.overrides),c=[],l=new Set;for(let d of["dependencies","dynamicDependencies"]){let g=s[d];!g||typeof g!="object"||this.collectLocalDeps(g,a,y=>this.resolveLockDepByVersion(y),c,l)}return c}resolveLockDepByVersion(e){if(typeof e!="object"||e===null)return null;let t=e.version;return typeof t=="string"?this.resolveLocalDepToModule(t):null}resolveDepModule(e,t,n){if(t?.has(e)){let i=t.get(e);if(i){let o=this.resolveLocalDepToModule(i);if(o)return o}}return n()}buildOverrideMap(e){if(!e||typeof e!="object")return null;let t=new Map;for(let[n,i]of Object.entries(e))typeof i=="string"&&t.set(n,i);return t.size>0?t:null}resolveLocalDepToModule(e){let t=r.stripLocalDep(e);if(!t)return null;let n=H.resolve(this.rootDir,t),i;try{i=P.ensurePathWithinRoot(this.rootDir,n)}catch{return null}let o=this.profile.modules.find(s=>H.resolve(this.rootDir,s.srcPath)===i);return o?o.name:null}static stripLocalDep(e){return!e.startsWith("file:")&&!e.startsWith(".")&&!e.startsWith("..")?null:e.startsWith("file:")?e.substring(5):e}readOhPackageLocalModuleDeps(e){let t=H.join(P.resolvePathWithinRoot(this.rootDir,e.srcPath),Ce.OH_PACKAGE_JSON5);if(!X.existsSync(t))return[];let n=this.readRootOverrideMap(),i=[],o=new Set;try{let s=or.parse(X.readFileSync(t,"utf-8"));for(let a of["dependencies","dynamicDependencies"]){let c=s?.[a];!c||typeof c!="object"||this.collectLocalDeps(c,n,l=>this.resolveOhPackageDepByValue(l,e),i,o)}}catch(s){f(`Failed to get module dependencies: ${s instanceof Error?s.message:String(s)}`)}return i}readRootOverrideMap(){let e=H.join(this.rootDir,Ce.OH_PACKAGE_JSON5);if(!X.existsSync(e))return null;try{let t=or.parse(X.readFileSync(e,"utf-8"));return this.buildOverrideMap(t?.overrides)}catch{return null}}resolveOhPackageDepByValue(e,t){return typeof e=="string"?this.resolveLocalDepModuleName(e,t):null}collectLocalDeps(e,t,n,i,o){for(let[s,a]of Object.entries(e)){let c=this.resolveDepModule(s,t,()=>n(a));c&&!o.has(c)&&(o.add(c),i.push(c))}}resolveLocalDepModuleName(e,t){let n=r.stripLocalDep(e);if(!n)return null;let i=H.join(t.srcPath,n),o=P.resolvePathWithinRoot(this.rootDir,i),s=this.profile.modules.find(a=>H.resolve(this.rootDir,a.srcPath)===o);return s?s.name:null}collectNonHarDependentModuleList(e){let t=[],n=[],i=new Set;for(n.push(e),i.add(e);n.length>0;){let o=n.shift();this.getModuleType(o)!=="har"&&t.push(o);let a=this.getModuleDependencies(o);for(let c of a)i.has(c)||(n.push(c),i.add(c))}return t}resolveModuleMetadata(e,t,n){this.validateProduct(n);let i=this.profile.modules.find(l=>l.name===e);if(!i){let l=this.getRunnableModuleNames();throw new w(`Module '${e}' not found. Available modules: ${l}`,"Module not found.")}let o=this.getModuleType(e)==="shared",s=o?"hspName":"hapName",a=this.buildOutputPath(i.srcPath,n,["intermediates",o?"hsp_metadata":"hap_metadata",t,"output_metadata.json"]);if(!X.existsSync(a))throw new w(`Build metadata not found for module '${e}' at ${a}. Build the project first.`,"Build metadata not found for module. Build the project first.");let c=this.parseOutputMetadata(a,s);return{moduleNode:i,isShared:o,metadataPath:a,metadata:c}}findArtifactPath(e,t,n,i="default"){let{moduleNode:o,isShared:s,metadata:a}=this.resolveModuleMetadata(e,t,i),{packageName:c,isSigned:l}=a,d=c;if(!l){let E=this.getSignedHapName(c,o.srcPath,i,t);E&&(d=E)}let g=s?"-signed.hsp":"-signed.hap";if(!n&&!d.endsWith(g))throw new w(`Target device is a real device, but the artifact for '${e}' is not signed. Real devices cannot install unsigned packages.`,"Target device is a real device, but the artifact is not signed.");let y=this.buildOutputPath(o.srcPath,i,["outputs",t,d]);if(!X.existsSync(y))throw new w(`Generated package file not found in ${y}.`,"Generated package file not found.");return y}findRemoteHspPaths(e,t,n="default"){let{moduleNode:i,metadata:o}=this.resolveModuleMetadata(e,t,n),s=[],a=new Set;for(let{hspPath:c}of o.dependRemoteHsps){if(a.has(c))continue;a.add(c);let l=H.isAbsolute(c)?c:this.buildOutputPath(i.srcPath,n,["outputs",t,c]);if(!X.existsSync(l))throw new w(`Remote HSP dependency not found: ${l}`,"Remote HSP dependency not found.");s.push(l)}return s}resolveModuleSpecsForProduct(e){let t=[];for(let n of this.profile.modules){let i=n.targets;if(!i||i.length===0){t.push(`${n.name}@default`);continue}let o=i.filter(s=>!s.applyToProducts||s.applyToProducts.includes(e));if(o.length!==0)for(let s of o)t.push(`${n.name}@${s.name}`)}return t}listBuildArtifacts(e,t){let n=[];for(let i of e){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i,a=o!==-1?i.substring(o+1):"default",c=this.profile.modules.find(d=>d.name===s);if(!c)continue;let l=this.buildOutputPath(c.srcPath,t,["outputs",a]);if(X.existsSync(l))for(let d of X.readdirSync(l))(d.endsWith(".hap")||d.endsWith(".hsp")||d.endsWith(".har"))&&n.push(H.join(l,d))}return n}listProjectAppArtifacts(e){let t=P.ensurePathWithinRoot(this.rootDir,H.resolve(this.rootDir,"build","outputs",e));if(!X.existsSync(t))return[];let n=[],i=o=>{for(let s of X.readdirSync(o,{withFileTypes:!0})){let a=H.join(o,s.name);s.isDirectory()?i(a):s.name.endsWith(".app")&&n.push(a)}};return i(t),n}collectBuildArtifacts(e,t,n){let i=t;if(!e){let s=new Set(t);i=[...t,...this.profile.modules.map(a=>`${a.name}@default`).filter(a=>!s.has(a))]}let o=this.listBuildArtifacts(i,n);return e&&o.push(...this.listProjectAppArtifacts(n)),o}getSignedHapName(e,t,n,i){let o=null;if(e.endsWith("-unsigned.hap")?o=e.replace("-unsigned.hap","-signed.hap"):e.endsWith("-unsigned.hsp")&&(o=e.replace("-unsigned.hsp","-signed.hsp")),!o)return null;let s=this.buildOutputPath(t,n,["outputs",i,o]);return X.existsSync(s)?o:null}buildOutputPath(e,t,n){let i=P.resolvePathWithinRoot(this.rootDir,e),o=H.resolve(i,"build",t,...n);return P.ensurePathWithinRoot(this.rootDir,o)}collectRemoteHsps(e){return e.flatMap(t=>{let n=t.dependRemoteHsps;return Array.isArray(n)?n.filter(i=>!!(i.hspName&&i.hspPath)).map(i=>({hspName:i.hspName,hspPath:i.hspPath})):[]})}parseOutputMetadata(e,t){let n;try{let c=X.readFileSync(e,"utf-8");n=or.parse(c)}catch(c){throw new Error(`Failed to parse output metadata at ${e}: ${c instanceof Error?c.message:String(c)}`,{cause:c})}let i,o=!1,s=Array.isArray(n)?n:[n];for(let c of s)i||(i=c[t]),o||(o=c.isSigned===!0);if(!i)throw new w(`Could not find ${t} in output_metadata.json at ${e}`,"Could not find metadataKey in output_metadata.json at metadataPath.");this.validatePackageName(i);let a=this.collectRemoteHsps(s);return{packageName:i,isSigned:o,dependRemoteHsps:a}}validatePackageName(e){let t=H.basename(e);if(t!==e)throw new w(`Invalid traversal name: '${e}'. It must contain path characters.`,"Invalid traversal name.");if(!t.endsWith(".hap")&&!t.endsWith(".hsp"))throw new w(`Invalid package name '${t}'.It must be a .hap or .hsp file.`,"Invalid package name.")}};import Yp from"fs/promises";import on from"path";function Et(r){if(!/^[A-Za-z0-9._-]+$/.test(r)||r==="."||r==="..")throw new Error(`Unsafe skill name: ${JSON.stringify(r)}`)}import Op from"fs";import Xn from"path";import{homedir as jy}from"os";import We from"fs/promises";import mt from"path";import{randomUUID as Fy}from"crypto";async function Me(r){try{return await We.lstat(r)}catch(e){if(e.code==="ENOENT")return;throw e}}async function ke(r){let e=mt.resolve(r),t=mt.dirname(e);try{return mt.join(await We.realpath(t),mt.basename(e))}catch(n){if(n.code!=="ENOENT"||t===e)throw n;return mt.join(await ke(t),mt.basename(e))}}async function Ip(r,e){let t=`${e}.backup-${Fy()}`,n=await Me(e);n&&await We.rename(e,t);try{await We.rename(r,e)}catch(i){throw n&&await We.rename(t,e),i}n&&await We.rm(t,{recursive:!0,force:!0})}function ge(r,e){let t=n=>mt.resolve(n).replace(/^\\\\\?\\/,"").replace(/[\\/]+$/,"");return process.platform==="win32"?t(r).toLowerCase()===t(e).toLowerCase():t(r)===t(e)}function Bi(r,e){let t=(n,i)=>{let o=mt.relative(n,i);return o===""||!o.startsWith(`..${mt.sep}`)&&o!==".."&&!mt.isAbsolute(o)};return t(r,e)||t(e,r)}async function Cc(r,e,t=!1){let n=await We.realpath(r);if(!(await We.stat(n)).isDirectory())throw new Error(`Skill source is not a directory: ${r}`);let i=await ke(e),o=await Me(i);if(ge(n,i))return sr(i,"same-source");let s=o?await We.realpath(i).catch(()=>i):i;if(o?.isSymbolicLink()&&ge(n,s))return sr(i,"correct-link");let a=await Ap(i,t);if(a)return a;if(Bi(n,i)||o&&Bi(n,s))throw new Error(`Skill source and destination overlap: ${r}, ${e}`);await We.mkdir(mt.dirname(i),{recursive:!0});let c=`${i}.install-${Fy()}`;try{let l=await Fx(n,c);return await Ip(c,i),{success:!0,path:i,...l}}finally{await We.rm(c,{recursive:!0,force:!0})}}function sr(r,e){return{success:!0,skipped:!0,path:r,reason:e}}async function Ap(r,e){if(!e&&await Me(r))return sr(r,"already-exists")}async function Fx(r,e){try{let t=process.platform==="win32"?r:mt.relative(mt.dirname(e),r);return await We.symlink(t,e,process.platform==="win32"?"junction":"dir"),{mode:"symlink"}}catch(t){return await We.rm(e,{recursive:!0,force:!0}),await We.cp(r,e,{recursive:!0,dereference:!0,errorOnExist:!0,force:!1}),{mode:"copy",fallbackReason:t.code??String(t)}}}async function kc(r){let e=await ke(r),t=await Me(e);return t?(await We.rm(e,{recursive:!t.isSymbolicLink(),force:!0}),{success:!0,path:e}):sr(e,"not-installed")}var $y={amp:{displayName:"Amp",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},antigravity:{displayName:"Antigravity",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/antigravity/skills"},"antigravity-cli":{displayName:"Antigravity CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/antigravity-cli/skills"},astrbot:{displayName:"AstrBot",skillsDir:"data/skills",globalSkillsDir:"~/.astrbot/data/skills"},atomcode:{displayName:"atomcode",skillsDir:".atomcode/skills",globalSkillsDir:"~/.atomcode/skills",detect:["~/.atomcode"]},augment:{displayName:"Augment",skillsDir:".augment/skills",globalSkillsDir:"~/.augment/skills"},bob:{displayName:"IBM Bob",skillsDir:".bob/skills",globalSkillsDir:"~/.bob/skills"},"claude-code":{displayName:"Claude Code",skillsDir:".claude/skills",globalSkillsDir:"~/.claude/skills",detect:["~/.claude"]},cline:{displayName:"Cline",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},"codearts-agent":{displayName:"CodeArts Agent",skillsDir:".codeartsdoer/skills",globalSkillsDir:"~/.codeartsdoer/skills"},codebuddy:{displayName:"CodeBuddy",skillsDir:".codebuddy/skills",globalSkillsDir:"~/.codebuddy/skills",detect:["~/.codebuddy"]},codex:{displayName:"Codex",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills",detect:["~/.codex"],legacySkillsDirs:[".codex/skills"],legacyGlobalSkillsDirs:["~/.codex/skills"]},continue:{displayName:"Continue",skillsDir:".continue/skills",globalSkillsDir:"~/.continue/skills"},crush:{displayName:"Crush",skillsDir:".crush/skills",globalSkillsDir:"~/.config/crush/skills"},cursor:{displayName:"Cursor",skillsDir:".agents/skills",globalSkillsDir:"~/.cursor/skills",detect:["~/.cursor"],legacySkillsDirs:[".cursor/skills"]},deepagents:{displayName:"Deep Agents",skillsDir:".agents/skills",globalSkillsDir:"~/.deepagents/agent/skills"},deveco:{displayName:"deveco",skillsDir:".deveco/skills",globalSkillsDir:"~/.config/deveco/skills",detect:["~/.config/deveco"]},devin:{displayName:"Devin for Terminal",skillsDir:".devin/skills",globalSkillsDir:"~/.config/devin/skills"},droid:{displayName:"Droid",skillsDir:".agents/skills",globalSkillsDir:"~/.factory/skills"},dsh:{displayName:"deepseek harness",skillsDir:".dsh/skills",globalSkillsDir:"~/.dsh/skills",detect:["~/.dsh"]},"gemini-cli":{displayName:"Gemini CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.gemini/skills"},"github-copilot":{displayName:"GitHub Copilot",skillsDir:".agents/skills",globalSkillsDir:"~/.copilot/skills"},goose:{displayName:"Goose",skillsDir:".goose/skills",globalSkillsDir:"~/.config/goose/skills"},grok:{displayName:"Grok Build",skillsDir:".grok/skills",globalSkillsDir:"~/.grok/skills"},"hermes-agent":{displayName:"Hermes Agent",skillsDir:".hermes/skills",globalSkillsDir:"~/.hermes/skills"},"iflow-cli":{displayName:"iFlow CLI",skillsDir:".iflow/skills",globalSkillsDir:"~/.iflow/skills"},junie:{displayName:"Junie",skillsDir:".junie/skills",globalSkillsDir:"~/.junie/skills"},kilo:{displayName:"Kilo Code",skillsDir:".agents/skills",globalSkillsDir:"~/.kilo/skills"},"kimi-code-cli":{displayName:"Kimi Code CLI",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},"kiro-cli":{displayName:"Kiro CLI",skillsDir:".kiro/skills",globalSkillsDir:"~/.kiro/skills"},kode:{displayName:"Kode",skillsDir:".kode/skills",globalSkillsDir:"~/.kode/skills"},lingma:{displayName:"Lingma",skillsDir:".lingma/skills",globalSkillsDir:"~/.lingma/skills"},"minimax-code":{displayName:"MiniMax Code",skillsDir:".minimax/skills",globalSkillsDir:"~/.minimax/skills"},"mistral-vibe":{displayName:"Mistral Vibe",skillsDir:".vibe/skills",globalSkillsDir:"~/.vibe/skills"},neovate:{displayName:"Neovate",skillsDir:".neovate/skills",globalSkillsDir:"~/.neovate/skills"},ona:{displayName:"Ona",skillsDir:".ona/skills",globalSkillsDir:"~/.ona/skills"},openclaw:{displayName:"OpenClaw",skillsDir:"skills",globalSkillsDir:"~/.openclaw/skills"},opencode:{displayName:"OpenCode",skillsDir:".agents/skills",globalSkillsDir:"~/.config/opencode/skills",detect:["~/.config/opencode"],legacySkillsDirs:[".opencode/skills"]},openhands:{displayName:"OpenHands",skillsDir:".openhands/skills",globalSkillsDir:"~/.openhands/skills"},pi:{displayName:"Pi",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills",detect:["~/.pi/agent"],legacySkillsDirs:[".pi/skills"],legacyGlobalSkillsDirs:["~/.pi/agent/skills"]},qoder:{displayName:"Qoder",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder/skills",detect:["~/.qoder"]},"qoder-cn":{displayName:"Qoder CN",skillsDir:".qoder/skills",globalSkillsDir:"~/.qoder-cn/skills"},"qwen-code":{displayName:"Qwen Code",skillsDir:".qwen/skills",globalSkillsDir:"~/.qwen/skills"},reasonix:{displayName:"Reasonix",skillsDir:".reasonix/skills",globalSkillsDir:"~/.reasonix/skills"},replit:{displayName:"Replit",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},trae:{displayName:"Trae",skillsDir:".trae/skills",globalSkillsDir:"~/.trae/skills"},"trae-cn":{displayName:"Trae CN",skillsDir:".trae/skills",globalSkillsDir:"~/.trae-cn/skills",detect:["~/.trae-cn"],legacySkillsDirs:[".trae-cn/skills"]},universal:{displayName:"Universal",skillsDir:".agents/skills",globalSkillsDir:"~/.config/agents/skills"},warp:{displayName:"Warp",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"},windsurf:{displayName:"Windsurf",skillsDir:".windsurf/skills",globalSkillsDir:"~/.codeium/windsurf/skills"},zcode:{displayName:"ZCode",skillsDir:".zcode/skills",globalSkillsDir:"~/.zcode/skills"},zed:{displayName:"Zed",skillsDir:".agents/skills",globalSkillsDir:"~/.agents/skills"}};var Tp="https://matrix.openharmony.cn",Pt={TAGS_API_URL:`${Tp}/api/model_base/model/tags?serviceType=skill`,SKILLS_API_URL:`${Tp}/api/registry/skill/skills`,SKILL_API_BASE:`${Tp}/api/registry/skill`,DEFAULT_PAGE_SIZE:20,DEFAULT_MAX_PAGES:100,SUCCESS_CODE:"20000"},Np=".agents/skills",bs=$y;function Wi(r){return Xn.resolve(r==="~"||r.startsWith("~/")?Xn.join(jy(),r.slice(1)):r)}function Le(){return Object.keys(bs)}function Rc(r){return[...new Set((r??"").split(",").map(e=>e.trim()).filter(Boolean))]}function Lt(r){let e=Object.prototype.hasOwnProperty.call(bs,r)?bs[r]:void 0;if(!e)throw new Error(`Invalid agent: ${r}, Valid options are: ${Le().join(", ")}`);return e}function _p(r){return Wi(Lt(r).globalSkillsDir)}function Mp(r,e){return Xn.join(r,Lt(e).skillsDir)}function ar(r){return Xn.join(r??jy(),Np)}function Ft(r,e){return e?Mp(e,r):_p(r)}function Zn(r,e){let t=Ft(r,e);return ge(t,ar(e))}function Hy(r,e){let t=Lt(r),n=e?(t.legacySkillsDirs??[]).map(o=>Xn.join(e,o)):(t.legacyGlobalSkillsDirs??[]).map(Wi),i=[Ft(r,e)];return n.filter(o=>i.some(s=>ge(s,o))?!1:(i.push(o),!0))}function Vi(r,e){let t=Lt(e).skillsDir.split("/")[0];return t.startsWith(".")&&Op.existsSync(Xn.join(r,t))}function Qn(r,e){let t=Lt(r);if(t.detect)return t.detect.some(o=>Op.existsSync(Wi(o)));let n=_p(r);return![ar(),_p("universal")].some(o=>ge(o,n))&&Op.existsSync(Xn.dirname(n))?!0:!!(e&&t.skillsDir!==Np&&Vi(e,r))}import xc from"path";function Uy(r){let e=[];r.agents.length&&e.push({agents:[...new Set(r.agents)]});let t=new Map;for(let{project:n,agent:i}of r.projectAgents){let o=t.get(n)??[];o.push(i),t.set(n,o)}for(let[n,i]of t)e.push({project:n,agents:[...new Set(i)]});return e}async function jx(r,e,t,n){let i=[];for(let o of Hy(r,e.project)){let s=await ke(xc.join(o,t));!n.some(a=>ge(a,s))&&await Me(s)&&i.push(s)}return i}async function Dc(r,e,t=!0){let n=await ke(xc.join(ar(r.project),e)),i=[];for(let o of r.agents){let s=Ft(o,r.project),a=await ke(xc.join(s,e)),c=await jx(o,r,e,[n,a]),l=!!(r.project&&!t&&!Zn(o,r.project)&&c.length===0&&!Vi(r.project,o)),d=i.find(g=>ge(g.path,a));d?(d.legacy.push(...c.filter(g=>!d.legacy.some(y=>ge(y,g)))),d.skipped&&=l):i.push({path:a,legacy:c,skipped:l})}return i}async function By(r,e,t=!0){let n=await Dc(r,e,t);if(n.every(o=>o.skipped))return n;let i=await ke(xc.join(ar(r.project),e));return n.some(o=>ge(o.path,i))||n.unshift({path:i,legacy:[],skipped:!1}),n}import Gi from"fs/promises";import jt from"path";import{randomUUID as pD}from"crypto";import{lock as fD}from"proper-lockfile";import*as Ss from"fs";import*as qy from"path";import{homedir as Hx}from"os";import*as Wy from"fs";import*as tt from"path";function Lp(r,e){let t=tt.relative(e,r);return t===""||!tt.isAbsolute(t)&&!t.startsWith(`..${tt.sep}`)&&t!==".."}function nn(r){let e=tt.resolve(r),t=[],n=e;for(;;)try{let i=Wy.realpathSync(n);return t.length===0?i:tt.join(i,...t.reverse())}catch(i){if(i.code!=="ENOENT")throw i;let o=tt.dirname(n);if(o===n)return e;t.push(tt.basename(n)),n=o}}function Vy(r,e){let t=nn(e),n=nn(r);return Lp(n,t)?n:null}function Fp(r){let e=r.trim();return(e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'"))&&(e=e.slice(1,-1).trim()),e}function Ic(r){let e=Fp(r);if(!e)throw new Error("Path must not be empty.");return nn(e)}var Ux="deveco-cli",Gy,$p=class extends Error{constructor(e){super(e),this.name="CliDataDirError"}};function Bx(){let r=process.env.DEVECO_CLI_DATA_DIR,t=(r===void 0||r===""?"":Fp(r))||qy.join(Hx(),".local","share",Ux);try{return Ic(t)}catch(n){throw new $p(n instanceof Error?n.message:String(n))}}function $(){if(Gy!==void 0)return Gy;let r=Bx();try{if(Ss.existsSync(r))return Ss.realpathSync(r)}catch{}return r}import sD from"adm-zip";import aD from"crypto";import{timingSafeEqual as cD}from"crypto";import Wp from"fs";import $t from"path";import{fileURLToPath as lD}from"url";import{homedir as cr}from"os";import rt from"path";var lr="deveco-mcp",Ac={"trae-cn":".trae-cn",opencode:".config/opencode",pi:".pi/agent",deveco:".config/deveco",cursor:".cursor",codebuddy:".codebuddy",qoder:".qoder","claude-code":".claude",codex:".codex",atomcode:".atomcode",dsh:".dsh"};var Ar={opencode:{name:"opencode",displayName:"OpenCode",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".config","opencode","opencode.json"),projectConfigPath:".opencode/opencode.json",mcpServersKey:"mcp",format:"opencode"},pi:{name:"pi",displayName:"Pi Coding Agent",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".pi","agent","mcp.json"),projectConfigPath:".pi/mcp.json",mcpServersKey:"mcpServers",format:"standard"},"trae-cn":{name:"trae-cn",displayName:"Trae-CN",supportsGlobal:!0,globalConfigPath:rt.join(process.platform==="win32"?rt.join(process.env.APPDATA??rt.join(cr(),"AppData","Roaming"),"Trae CN","User"):rt.join(cr(),"Library","Application Support","Trae CN","User"),"mcp.json"),projectConfigPath:".trae/mcp.json",mcpServersKey:"mcpServers",format:"standard"},cursor:{name:"cursor",displayName:"Cursor",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".cursor","mcp.json"),projectConfigPath:".cursor/mcp.json",mcpServersKey:"mcpServers",format:"standard"},codebuddy:{name:"codebuddy",displayName:"Codebuddy",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".codebuddy","mcp.json"),projectConfigPath:".codebuddy/mcp.json",mcpServersKey:"mcpServers",format:"codebuddy"},qoder:{name:"qoder",displayName:"Qoder",supportsGlobal:!0,globalConfigPath:rt.join(process.platform==="win32"?rt.join(process.env.APPDATA??rt.join(cr(),"AppData","Roaming"),"Qoder","SharedClientCache"):rt.join(cr(),"Library","Application Support","Qoder","SharedClientCache"),"mcp.json"),projectConfigPath:".mcp.json",mcpServersKey:"mcpServers",format:"standard"},"claude-code":{name:"claude-code",displayName:"Claude Code",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".claude.json"),projectConfigPath:".mcp.json",mcpServersKey:"mcpServers",format:"claude-code"},codex:{name:"codex",displayName:"Codex",supportsGlobal:!0,globalConfigPath:rt.join(cr(),".codex","config.toml"),projectConfigPath:".codex/config.toml",mcpServersKey:"mcp_servers",format:"codex"}};function Jy(r){return{type:"local",command:["devecocli","serve","mcp"],environment:{PROJECT_PATH:r??"."},enabled:!0}}function zy(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"."},enabled:!0}}function Wx(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"."}}}function Ky(r){return{type:"stdio",command:"devecocli",args:["serve","mcp"],env:{PROJECT_PATH:r??"${workspaceFolder}"}}}function Tc(r,e){return r.format==="opencode"?Jy(e):r.format==="claude-code"||r.format==="codex"?zy(e):r.format==="codebuddy"?Wx(e):Ky(e)}var jp="https://developer.huawei.com/consumer/cn/download/";import eD from"axios";var Vx={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443};function Gx(r){try{return new URL(r)}catch{return null}}function Yy(r){var e=(typeof r=="string"?Gx(r):r)||{},t=e.protocol,n=e.host,i=e.port;if(typeof n!="string"||!n||typeof t!="string"||(t=t.split(":",1)[0],n=n.replace(/:\d*$/,""),i=parseInt(i)||Vx[t]||0,!qx(n,i)))return"";var o=Hp(t+"_proxy")||Hp("all_proxy");return o&&o.indexOf("://")===-1&&(o=t+"://"+o),o}function qx(r,e){var t=Hp("no_proxy").toLowerCase();return t?t==="*"?!1:t.split(/[,\s]/).every(function(n){if(!n)return!0;var i=n.match(/^(.+):(\d+)$/),o=i?i[1]:n,s=i?parseInt(i[2]):0;return s&&s!==e?!0:/^[.*]/.test(o)?(o.charAt(0)==="*"&&(o=o.slice(1)),!r.endsWith(o)):r!==o}):!0}function Hp(r){return process.env[r.toLowerCase()]||process.env[r.toUpperCase()]||""}import{spawn as Qy}from"child_process";import*as ei from"fs";import*as ew from"os";import*as Nc from"path";var tw=6e4;async function zx(){if(process.platform!=="win32")return null;let r="HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",e=await Xy(r,"ProxyServer");if(!e)return null;let t=await Xy(r,"ProxyEnable");return t!=="1"&&t!=="0x1"?null:e.trim()}function Xy(r,e){return new Promise(t=>{let n=Qy("reg.exe",["query",r,"/v",e],{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),i="";n.stdout.on("data",o=>{i+=o.toString()}),n.on("error",()=>t(null)),n.on("close",o=>{if(o!==0){t(null);return}let s=/REG_\w+\s+(\S+)/.exec(i);t(s?s[1]:null)})})}function Jx(){let r=process.env.HTTPS_PROXY??process.env.HTTP_PROXY??"";if(!r)return null;try{return new URL(r).host}catch{return r}}function Kx(){return`${process.env.SystemRoot??"C:\\Windows"}\\System32\\curl.exe`}function Zy(r){let e={},t=0,n="";for(let i of r.split(/\r?\n/)){let o=i.trim();if(!o)continue;let s=/^HTTP\/\d(?:\.\d)?\s+(\d{3})\s*(.*)$/.exec(o);if(s){t=parseInt(s[1],10),n=s[2]??"";continue}let a=/^([^:]+):\s*(.*)$/.exec(o);a&&(e[a[1].toLowerCase()]=a[2])}return{statusCode:t,statusText:n,headers:e}}function Yx(r,e,t,n){let i=["--silent","--show-error","--location","--ssl-no-revoke","--insecure","-x",`http://${e}`,"--proxy-ntlm","--proxy-user",":","--max-time",String(Math.max(1,Math.floor((r.timeoutMs??tw)/1e3)))];return r.method&&r.method!=="GET"&&i.push("-X",r.method),r.data!==void 0&&i.push("--data-binary",r.data),i.push(...Xx(r.headers,r.data!==void 0)),n?(i.push("--dump-header",t),i.push("--output",n)):i.push("--include"),i.push(r.url),i}function Xx(r,e){let t=new Set(["content-length","host","connection","proxy-authorization","proxy-connection","accept-encoding"]),n=[],i=!1;for(let[o,s]of Object.entries(r??{})){let a=o.toLowerCase();a==="content-type"&&(i=!0),t.has(a)||n.push("-H",`${o}: ${s}`)}return e&&!i&&n.push("-H","Content-Type: application/json"),n}function Zx(r,e,t){if(t){let l=ei.readFileSync(e,"utf8"),d=ei.readFileSync(t),g=Zy(l);return{statusCode:g.statusCode,statusText:g.statusText,body:d.toString("base64"),headers:g.headers,bodyBuffer:d}}let n=r.lastIndexOf("HTTP/");if(n===-1)return null;let i=r.slice(n),o=i.indexOf(`\r
15
15
  \r
16
- `);if(o===-1)return null;let s=i.slice(0,o),a=i.slice(o+4),c=oy(s);return{statusCode:c.statusCode,statusText:c.statusText,body:a,headers:c.headers}}async function ly(r){if(process.platform!=="win32")return null;let e=hD()??await gD();if(!e)return null;let t;r.binary&&(t=Kn.mkdtempSync(fc.join(ay.tmpdir(),"curl-")));let n=t?fc.join(t,"header.tmp"):void 0,i=t?fc.join(t,"body.tmp"):void 0;try{let o=wD(r,e,n,i),s=await SD(o,r.timeoutMs);return!s||s.code!==0?null:bD(s.stdout,n,i)}catch{return null}finally{t&&Kn.rmSync(t,{recursive:!0,force:!0})}}function SD(r,e){let t=yD();return new Promise(n=>{let i=sy(t,r,{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),o="",s=!1,a=setTimeout(()=>{s||(s=!0,i.kill())},e??cy);i.stdout.on("data",c=>{o+=c.toString()}),i.on("error",()=>{s||(s=!0,clearTimeout(a),n(null))}),i.on("close",c=>{if(clearTimeout(a),s){n(null);return}s=!0,n({code:c??-1,stdout:o})})})}function PD(r){let e=new URL(r);return{protocol:e.protocol,host:e.hostname,port:e.port?Number.parseInt(e.port,10):e.protocol==="https:"?443:80,auth:{username:decodeURIComponent(e.username),password:decodeURIComponent(e.password)}}}var dp=class{client;constructor(){let e={timeout:es.HTTP_TIMEOUT_MS,headers:{"User-Agent":Ga.USER_AGENT,"accept-language":Ga.ACCEPT_LANGUAGE},transformResponse:[t=>t]};this.client=ED.create(e),this.client.interceptors.request.use(t=>{let n=ny(t.url??"");return t.proxy=n?PD(n):!1,t}),this.client.interceptors.response.use(t=>t,t=>{let n=`Network connection failed (${t.code}). Please check your proxy configuration or network settings`,i=new Error(`${t.message}
17
- ${n}`);throw i.code=t.code,i.response=t.response,i})}async get(e,t){try{let n=await this.client.request({method:"GET",url:e,params:t?.params,headers:t?.headers,timeout:t?.timeout});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"GET",t)}}async post(e,t){try{let n=await this.client.request({method:"POST",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"POST",t)}}convertResponse(e){return{data:typeof e.data=="string"?e.data:JSON.stringify(e.data),statusCode:e.status,statusText:e.statusText??"",headers:e.headers}}parseJson(e){try{return JSON.parse(e.data)}catch(t){throw new Error(`Failed to parse JSON response: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async getBinary(e,t){try{let n=await this.client.request({method:"GET",url:e,responseType:"arraybuffer",headers:t?.headers,timeout:t?.timeout});if(n.status!==200)throw new Error(`HTTP ${n.status}`);return Buffer.from(n.data)}catch(n){let i=await this.tryCurlFallback(n,e,"GET",t,!0);if(i?.bodyBuffer){if(i.statusCode!==200)throw new Error(`HTTP ${i.statusCode}`);return i.bodyBuffer}throw n}}async postAllowFailure(e,t){try{let n=await this.client.request({method:"POST",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"POST",t)}}async deleteAllowFailure(e,t){try{let n=await this.client.request({method:"DELETE",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"DELETE",t)}}async getBinaryAllowFailure(e,t){try{let n=await this.client.request({method:"GET",url:e,responseType:"arraybuffer",headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});let i=Buffer.from(n.data),o=i.toString("utf8");return{statusCode:n.status,statusText:n.statusText??"",buffer:i,body:o}}catch(n){let i=await this.tryCurlFallback(n,e,"GET",t,!0);if(i?.bodyBuffer)return{statusCode:i.statusCode,statusText:i.statusText,buffer:i.bodyBuffer,body:i.bodyBuffer.toString("utf8")};throw n}}async withCurlFallback(e,t,n,i){let o=await this.tryCurlFallback(e,t,n,i,!1);if(o)return{data:o.body,statusCode:o.statusCode,statusText:o.statusText,headers:o.headers};throw e}async tryCurlFallback(e,t,n,i,o=!1){if(process.platform!=="win32"||!(e instanceof Error)||!CD(e))return null;let s,a=t;return n==="GET"?i?.params&&(a=kD(t,i.params)):i?.params!==void 0&&i.params!==null&&(s=typeof i.params=="string"?i.params:JSON.stringify(i.params)),ly({url:a,method:n,data:s,headers:i?.headers,timeoutMs:i?.timeout,binary:o})}},F=new dp;function CD(r){if(r.response?.status===407)return!0;let e=r.message??"";return/proxy auth(?:oriz|entic)/i.test(e)?!0:r.code==="SELF_SIGNED_CERT_IN_CHAIN"||r.code==="DEPTH_ZERO_SELF_SIGNED_CERT"||r.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"||r.code==="CERT_HAS_EXPIRED"||r.code==="ERR_TLS_CERT_ALTNAME_INVALID"}function kD(r,e){if(!e||typeof e!="object")return r;let t=new URLSearchParams;for(let[o,s]of Object.entries(e))if(s!=null)if(Array.isArray(s))for(let a of s)t.append(`${o}[]`,String(a));else t.append(o,String(s));let n=t.toString();if(!n)return r;let i=r.includes("?")?"&":"?";return`${r}${i}${n}`}import*as dy from"fs";import*as uy from"path";var py=["DevEco"];async function ds(){let r=await F.get(Et.TAGS_API_URL),t=yc(r,"Tags API").data.skill.filter(n=>n.name==="HMOS");if(t.length===0)throw new Error("No HMOS tag found.");return t.map(n=>n.id)}async function DD(r){let e=[],t=Et.DEFAULT_PAGE_SIZE,n=Et.DEFAULT_MAX_PAGES,i=1;for(;i<=n;){let o=await F.post(Et.SKILLS_API_URL,{headers:{"Content-Type":"application/json"},params:{pageNum:i,pageSize:t,tagIds:[r]}}),s=yc(o,"Skills API");if(e.push(...s.data.list),s.data.list.length<t)break;i++}return e}async function gc(r){let e=new Map,t=r.map(i=>DD(i)),n=await Promise.all(t);for(let i of n)for(let o of i)e.has(o.id)||e.set(o.id,o);return Array.from(e.values()).filter(i=>i.tags?.every(o=>!py.includes(o.name)))}async function RD(r,e){let t=await F.post(Et.SKILLS_API_URL,{headers:{"Content-Type":"application/json"},params:{pageNum:1,pageSize:Et.DEFAULT_PAGE_SIZE,keyword:r,tagIds:[e]}});return yc(t,"Skills API").data.list}async function hc(r,e){let t=new Map,n=e.map(o=>RD(r,o)),i=await Promise.all(n);for(let o of i)for(let s of o)t.has(s.id)||t.set(s.id,s);return Array.from(t.values()).filter(o=>o.tags?.every(s=>!py.includes(s.name)))}function up(r){St(r);let e=[];for(let t of Le()){let n=Lt(t);if(!Yn(t))continue;let i=uy.join(n,r);dy.existsSync(i)&&e.push(Mt(t).displayName)}return e.sort()}function yc(r,e){if(r.statusCode!==200)throw new Error(`${e} Request failed: HTTP ${r.statusCode}`);let t=F.parseJson(r);if(t.code!==Et.SUCCESS_CODE)throw new Error(`${e} Error returned: ${t.code} - ${t.message}`);return t}async function my(r){St(r);let e=`${Et.SKILL_API_BASE}/${r}/checksum`,t=await F.get(e);return yc(t,"Checksum API").data}var fy=pp.promises;function gy(r,e){let t=_t.resolve(e),n=_t.resolve(r),i=_t.relative(n,t);if(i.startsWith("..")||_t.isAbsolute(i))throw new Error(`Path traversal detected: ${e}.`)}function mp(r){return _t.isAbsolute(r)?r:_t.resolve(process.cwd(),r)}function OD(r){return AD.createHash("sha256").update(r).digest("hex")}async function ND(r,e){if(r.length!==e.size)throw new Error("Skill zip integrity verification failed: Size mismatch");let n=OD(r),i=e.sha256.toLowerCase(),o=Buffer.from(n,"hex"),s=Buffer.from(i,"hex");if(o.length!==s.length||!ID(o,s))throw new Error("Skill zip integrity verification failed: SHA256 mismatch")}async function fp(r){St(r);let e=`${Et.SKILL_API_BASE}/${r}/install?format=zip`,t=await F.getBinary(e),n=await my(r);return await ND(t,n),t}async function hy(r,e,t){St(t);let n=new xD(r),i=n.getEntries();try{await fy.stat(e)}catch{await fy.mkdir(e,{recursive:!0})}let o=_t.join(e,t);gy(e,o);for(let s of i){let a=_t.join(o,s.entryName);gy(o,a)}n.extractAllTo(o,!0)}function Xn(){let e=_t.dirname(TD(import.meta.url));for(;;){let t=_t.join(e,"skills","deveco-cli");if(pp.existsSync(t)&&pp.statSync(t).isDirectory())return t;let n=_t.dirname(e);if(n===e)break;e=n}throw new Error("skills/deveco-cli directory not found in deveco-cli package. Reinstall deveco-cli.")}function yy(r){return r?$t.join(r,".deveco-cli","skills"):$t.join($(),"skills")}function _D(r,e){return St(r),$t.join(yy(e),"store",r)}async function wy(r,e){let t=e??$(),n=await _i.realpath(t).catch(s=>{if(s.code==="ENOENT")return Ce(t);throw s}),i=$t.join(n,$t.relative(t,r)),o=await Ce(i);if(!fe(i,o))throw new Error(`Skill storage parent redirects outside its managed location: ${i}`);return o}async function gp(r,e){return wy(_D(r,e),e)}async function us(r,e,t){St(r);let n=e.customPath??yy(e.project),i=e.customPath?await Ce($t.join(n,`.${r}.lock`)):await wy($t.join(n,"locks",`${r}.lock`),e.project);await _i.mkdir($t.dirname(i),{recursive:!0});let o=await LD(n,{realpath:!1,lockfilePath:i,stale:3e4,update:1e4,retries:{retries:100,minTimeout:50,maxTimeout:200}});try{return await t()}finally{await o()}}async function vy(r){let e=await _i.lstat(r);if(!e.isDirectory()||e.isSymbolicLink()||!(await _i.stat($t.join(r,"SKILL.md"))).isFile())throw new Error(`Invalid Skill store: ${r}`)}async function by(r,e,t,n,i){let o=await gp(r,t),s=await Me(o);if(!i&&!s&&(await Promise.all(n.map(c=>Me(c.path)))).every(Boolean))return{results:n.map(c=>rr(c.path,"already-exists"))};for(let a of n)for(let c of[a.path,...a.legacy])if(Mi(o,c))throw new Error(`Skill store and destination overlap: ${o}, ${c}`);if(!i&&s){try{await vy(o)}catch(a){throw new Error(`Cannot reuse Skill store ${o}; use --force to replace: ${a.message}`,{cause:a})}return{source:o,results:[]}}return{source:o,results:[await Ey(r,e,o)]}}async function Sy(r,e,t,n){let i=await Ce(t);return await Zu(i,n)??Ey(r,e,i)}async function Ey(r,e,t){await _i.mkdir($t.dirname(t),{recursive:!0});let n=`${t}.extract-${MD()}`;try{await hy(e,n,r);let i=$t.join(n,r);return await vy(i),await Xu(i,t),{success:!0,path:t,reason:"shared-entity-updated"}}finally{await _i.rm(n,{recursive:!0,force:!0})}}function ps(r,e){return{success:!1,path:r,error:e instanceof Error?e.message:String(e)}}async function hp(r,e,t){let n=[];for(let i of Jh(e))try{n.push(...await us(r,i,()=>t(i)))}catch(o){n.push(ps(tn.join(nr(i.project),r),o))}return n}async function wp(r){return vp.realpath(r).catch(e=>{if(e.code==="ENOENT"||e.code==="ELOOP")return r;throw e})}async function $D(r,e){let t=await vp.realpath(e);for(let n of r.legacy){let i=await Me(n);if(i&&!i.isSymbolicLink()&&Mi(t,n))throw new Error(`Skill source and legacy destination overlap: ${e}, ${n}`);await sc(n)}}async function FD(r,e,t,n){let i=[];for(let o of Le()){let s=Lt(o,e.project);if(e.agents.includes(o)||cc(o,e.project)&&!Yn(o,e.project))continue;let a=await Ce(tn.join(s,r)),c=await Me(a);c&&(fe(a,t)&&Yn(o,e.project)||n&&c.isSymbolicLink()&&fe(await wp(a),n))&&i.push(Mt(o).displayName)}return[...new Set(i)]}function jD(r,e){let t=`still used by ${e.join(", ")}`;return console.log(`Skill ${tn.basename(r)} in ${tn.dirname(r)} is kept: ${t}.`),rr(r,t)}async function yp(r,e,t,n){try{if(!await Me(r))return;let i=await FD(e,t,r,n);return i.length?jD(r,i):await sc(r)}catch(i){return ps(r,i)}}var sr=class{async installBundledSkill(e,t,n=!1){return await vp.access(tn.join(e,"SKILL.md")),t.customPath?this.installCustom("deveco-cli",e,t.customPath,n):hp("deveco-cli",t,i=>this.installScope("deveco-cli",e,i,t.explicitAgents,n))}async installArchiveSkill(e,t,n,i=!1){return St(e),n.customPath?this.installCustom(e,t,n.customPath,i):hp(e,n,o=>this.installScope(e,t,o,n.explicitAgents,i))}async installCustom(e,t,n,i){let o=tn.join(n,e);try{return await us(e,{customPath:n},async()=>[typeof t=="string"?await oc(t,o,i):await Sy(e,t,o,i)])}catch(s){return[ps(o,s)]}}async installScope(e,t,n,i=!0,o=!1){let s=await Yh(n,e,i),a=s.filter(l=>!l.skipped),c=s.filter(l=>l.skipped).map(l=>rr(l.path,"agent-project-root-missing"));if(!a.length)return c;try{let l=typeof t=="string"?{source:t,results:[]}:await by(e,t,n.project,a,o);return[...c,...l.results,...l.source?await this.installSkillEntries(l.source,a,o):[]]}catch(l){return[...c,...a.map(d=>ps(d.path,l))]}}async installSkillEntries(e,t,n){let i=[];for(let o of t)try{i.push(await oc(e,o.path,n)),n&&await $D(o,e)}catch(s){i.push(ps(o.path,s))}return i}async migrateBundledSkill(e,t){await us("deveco-cli",t,()=>this.migrateBundledScope(e,t))}async migrateBundledScope(e,t){let n,i=[];for(let o of t.agents)try{for(let s of await dc({...t,agents:[o]},"deveco-cli"))await this.migrateBundledDestination(e,s,i)}catch(s){n=s,console.error(`Skill migration failed for ${o}: ${s.message}`)}if(n)throw n}async migrateBundledDestination(e,t,n){let i=await Me(t.path);(!i||!i.isDirectory()&&!i.isSymbolicLink())&&!t.legacy.length||n.some(o=>fe(o,t.path))||((await oc(e,t.path)).reason==="already-exists"&&console.warn(`Skill migration skipped: ${t.path} (already exists; run devecocli init --force to replace).`),n.push(t.path))}async removeSkill(e,t){if(St(e),t.customPath){let n=tn.join(t.customPath,e);return us(e,t,async()=>[await sc(n)])}return hp(e,t,n=>this.removeScope(e,n,t.explicitAgents))}async removeScope(e,t,n=!0){let i=await Ce(tn.join(nr(t.project),e)),o=await this.removeAgentEntries(e,t,i,n);if(o.every(s=>s.success)){let s=await yp(i,e,t,await wp(i));s&&o.push(s)}if(o.every(s=>s.success)){let s=await gp(e,t.project),a=await yp(s,e,{...t,agents:[]},await wp(s));a&&o.push(a)}return o.length||(console.log(`Skill ${e} not found for the selected agents.`),o.push(rr(i,"not-installed"))),o}async removeAgentEntries(e,t,n,i){let o=new Set;for(let a of await dc(t,e,i))if(!a.skipped)for(let c of[a.path,...a.legacy])fe(c,n)||o.add(c);let s=[];for(let a of o){let c=await yp(a,e,t);c&&s.push(c)}return s}};import wc from"fs/promises";import Py from"path";function HD(r){return`'${process.platform==="win32"?r.replace(/'/g,"''"):r.replace(/'/g,"'\\''")}'`}async function UD(r,e){try{if(!(await Me(r))?.isSymbolicLink())return;let n=await wc.realpath(r);return fe(n,e)?void 0:{path:r,reason:`points to ${n}`,repair:!0}}catch(t){let n=t.code,i=n==="ENOENT"||n==="ELOOP"||n==="ENOTDIR";return{path:r,reason:i?"broken link":`cannot check: ${t.message}`,repair:i}}}var bp=class{checked=new Set;async warnInvalidBundledLinks(e){try{let t=await wc.realpath(e),n=process.platform==="win32"?t.toLowerCase():t;if(this.checked.has(n))return;this.checked.add(n);let i=await wc.realpath(Xn());if(!(await wc.stat(Py.join(i,"SKILL.md"))).isFile())throw new Error(`Skill source has no SKILL.md: ${i}`);let o=await this.checkKnownEntries(t,i);this.reportIssues(t,o)}catch(t){console.warn(`Cannot check project Skill links for ${e}: ${t.message}`)}}async checkKnownEntries(e,t){let n=new Set([nr(e),...Le().map(s=>np(e,s))]),i=[],o=[];for(let s of n){let a=Py.join(s,"deveco-cli");try{let c=await Ce(a);if(i.some(d=>fe(d,c)))continue;i.push(c);let l=await UD(c,t);l&&o.push(l)}catch(c){o.push({path:a,reason:`cannot check: ${c.message}`,repair:!1})}}return o}reportIssues(e,t){for(let n of t)console.warn(`Project Skill link: ${n.path} (${n.reason}).`);t.some(n=>n.repair)&&(console.warn(`Run: devecocli init --project ${HD(e)} -f`),console.warn("Existing copies and local edits in the selected installation scope will be replaced."))}},rt=new bp;import Cp from"fs";import xy from"path";import{cyan as tR}from"colorette";import{spawn as KD}from"child_process";import*as Ry from"fs";import*as bc from"path";import{yellow as XD,cyan as ZD}from"colorette";import QD from"proper-lockfile";import{compare as BD}from"semver";function Pt(r,e){return BD(r,e)}function $i(r,e){let t=Math.max(r.split(".").length,e.split(".").length);for(let n=0;n<t;n++){let i=Number(r.split(".")[n]??0)-Number(e.split(".")[n]??0);if(i)return i}return 0}function Fi(){return process.env.DEVECO_CLI_WRAPPER_NAME?process.env.DEVECO_CLI_WRAPPER_NAME:"@litingwei621/test-deveco-cli-common"}function ar(){return process.env.DEVECO_CLI_WRAPPER_VERSION?process.env.DEVECO_CLI_WRAPPER_VERSION:"1.3.7"}function rn(){return"latest"}function Ft(){return Number.isFinite(1),1}var Dr="@deveco/deveco-cli-knowledgebase";function ji(){let r=process.env.DEVECO_CLI_DISABLE_UPDATE;return r==="check"||r==="all"?r:"off"}import*as ms from"fs";import*as fs from"path";var WD={lastCheckedTimestamp:null,latestVersion:null,blockedVersions:[],checkError:null,latestDocsVersion:null,latestDocsApiVersion:null,latestCompatibleDocsVersion:null,checkedAgainstDocsApi:null},Sp=new Map,nn=class r{static CHECK_WINDOW_HOUR=21;static ONE_DAY_MS=1440*60*1e3;cacheFilePath;lockFilePath;constructor(e){this.cacheFilePath=fs.join(e,"cache.json"),this.lockFilePath=fs.join(e,"check.lock")}async writeSuccess(e,t=[],n,i,o){let s=this.read();await this.write({lastCheckedTimestamp:Date.now(),latestVersion:e,blockedVersions:t,checkError:null,checkedAgainstVersion:n,checkedAgainstTag:i,latestDocsVersion:o?o.latestDocsVersion:s.latestDocsVersion??null,latestDocsApiVersion:o?o.latestDocsApiVersion:s.latestDocsApiVersion??null,latestCompatibleDocsVersion:o?o.latestCompatibleDocsVersion:s.latestCompatibleDocsVersion??null,checkedAgainstDocsApi:o?o.checkedAgainstDocsApi:s.checkedAgainstDocsApi??null})}async writeError(e){let t=this.read();await this.write({...t,lastCheckedTimestamp:Date.now(),checkError:e})}getLatestVersion(){return this.read().latestVersion}getBlockedVersions(){return[...this.read().blockedVersions]}getCheckedAgainstVersion(){return this.read().checkedAgainstVersion}getCheckedAgainstTag(){return this.read().checkedAgainstTag}getLatestDocsVersion(){return this.read().latestDocsVersion??null}getLatestDocsApiVersion(){return this.read().latestDocsApiVersion??null}getLatestCompatibleDocsVersion(){return this.read().latestCompatibleDocsVersion??null}getCheckedAgainstDocsApi(){return this.read().checkedAgainstDocsApi??null}isCheckNeeded(){let{lastCheckedTimestamp:e}=this.read();if(!e||e>Date.now())return!0;let t=new Date().setHours(r.CHECK_WINDOW_HOUR,0,0,0),n=t>Date.now()?t-r.ONE_DAY_MS:t;return e<n}getLockPath(){return this.lockFilePath}read(){let e=Sp.get(this.cacheFilePath);if(e)return e;try{let t=ms.readFileSync(this.cacheFilePath,"utf-8"),n=JSON.parse(t);return Sp.set(this.cacheFilePath,n),n}catch{return{...WD}}}async write(e){m(()=>`Writing update cache: lastChecked=${e.lastCheckedTimestamp}, latest=${e.latestVersion}, blocked=[${e.blockedVersions.join(",")}], error=${e.checkError}`),await ms.promises.mkdir(fs.dirname(this.cacheFilePath),{recursive:!0}),await ms.promises.writeFile(this.cacheFilePath,JSON.stringify(e,null,2),"utf-8"),Sp.set(this.cacheFilePath,e)}};import{createRequire as VD}from"module";import{dirname as GD,join as Hi}from"path";import{pathToFileURL as qD}from"url";import{readFile as Cy,access as Ep}from"fs/promises";import*as ky from"semver";var zD=VD(import.meta.url);async function JD(){try{let r=zD.resolve("@deveco/deveco-cli-knowledgebase/package.json"),e=JSON.parse(await Cy(r,"utf8"));return{version:e.version,apiVersion:e.apiVersion??0,dir:GD(r)}}catch{return null}}async function Dy(){let r=$(),e=Hi(r,"doc-data","current.json"),t;try{t=JSON.parse(await Cy(e,"utf8"))}catch{return null}let n=Hi(r,"doc-data",t.version);try{return await Ep(Hi(n,"dist","engine","index.js")),await Ep(Hi(n,"docs.zip")),await Ep(Hi(n,"index.zip")),{version:t.version,apiVersion:t.apiVersion,dir:n}}catch{return null}}async function YD(){return[await Dy(),await JD()].filter(e=>e!==null).sort((e,t)=>ky.rcompare(e.version,t.version))}async function Ui(){let r=Ft(),e=await Dy();return e&&e.apiVersion<=r?e.version:null}async function vc(){let r=Ft(),e=await YD(),t=!1;for(let n of e){if(n.apiVersion>r){m(`docs: skip candidate v${n.version} (apiVersion ${n.apiVersion} > ${r})`);continue}t=!0;try{let i=Hi(n.dir,"dist","engine","index.js");return await import(qD(i).href)}catch(i){m(`docs: candidate v${n.version} load failed: ${i instanceof Error?i.message:String(i)}`)}}throw e.length>0&&!t?new Error("Documentation package version is incompatible, please upgrade CLI"):new Error("No available documentation package, please run `devecocli docs update` or reinstall CLI")}var gs=class{constructor(e){this.actionCommand=e}cache=new nn(bc.join($(),"update"));async checkAndNotify(){if(!this.shouldSkip())try{let e=ar(),t=rn(),n=this.cache.getCheckedAgainstVersion(),i=this.cache.getCheckedAgainstTag(),o=i!=null&&i!==t,s=n!=null&&n!==e,a=[],c=o?null:this.cache.getLatestVersion();c&&Pt(c,e)>0&&a.push(XD(`New cli version ${c} available, run \`devecocli update\` to update`));let l=await this.buildDocsMessage();if(l.message&&a.push(l.message),a.length>0){console.log();for(let d of a)console.log(d)}(o||s||l.stale||this.cache.isCheckNeeded())&&await this.spawnBackgroundCheck()}catch(e){m(`Update check failed: ${e instanceof Error?e.message:String(e)}`)}}async buildDocsMessage(){let e=Ft(),t=this.cache.getCheckedAgainstDocsApi();if(t!=null&&t!==e)return{message:null,stale:!0};let n=this.cache.getLatestCompatibleDocsVersion();if(!n)return{message:null,stale:!1};let i=await Ui();return i&&Pt(n,i)<=0?{message:null,stale:!1}:{message:ZD(`New docs version ${n} available, run \`devecocli docs update\` to upgrade`),stale:!1}}shouldSkip(){let e=this.actionCommand;for(;e;){if(e.name()==="update")return!0;e=e.parent}return!1}async spawnBackgroundCheck(){if(!process.argv[1]?.endsWith(".ts"))try{await eR(this.cache.getLockPath(),()=>{let e=[process.argv[1],"update","_check"];m(`Executing: ${process.execPath} ${e.join(" ")}`),KD(process.execPath,e,{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,DEVECO_CLI_SKIP_VERSION_CHECK:"1"}}).unref()})}catch{m("Update check lock held by another process, skipping")}}};async function eR(r,e){await Ry.promises.mkdir(bc.dirname(r),{recursive:!0});let t=await QD.lock(r,{stale:6e4,retries:0,realpath:!1});try{await e()}finally{await t()}}var Pp=Cp.promises;async function Sc(r){let e=ac(r);for(let t of e)Mt(t);return e}async function Ec(r){return Le().filter(e=>Yn(e,r))}async function rR(){let r=Xn();await new sr().migrateBundledSkill(r,{agents:Le()})}async function Ay(){try{let r=xy.join($(),"skills","migration-version"),e=await Pp.readFile(r,"utf8").catch(n=>{if(n.code==="ENOENT")return"";throw n}),t=ar();if(e.trim()===t)return;await rR(),await Pp.mkdir(xy.dirname(r),{recursive:!0}),await Pp.writeFile(r,t,"utf8")}catch{}}function Bi(r){let e=r.filter(i=>i.success&&!i.skipped).length,t=r.filter(i=>i.skipped).length,n=r.filter(i=>!i.success).length;console.log(),console.log(tR("Finished:"));for(let i of r){if(!i.path)continue;let o=i.reason==="already-exists"?"already exists; use --force to replace":i.reason,s=i.fallbackReason?" (link failed: "+i.fallbackReason+")":o??i.error?" ("+(o??i.error)+")":"",a=i.success?i.skipped?"skipped":i.mode??(i.reason==="shared-entity-updated"?"updated":"removed"):"failed";console.log(" "+a+": "+i.path+s)}console.log(` Success: ${e}`),console.log(` Skipped: ${t}`),console.log(` Failed: ${n}`),n>0&&(process.exitCode=1)}function Rr(r,e,t){if(!Cp.existsSync(r)){if(t)return;throw new Error(`${e} "${r}" not found`)}if(!Cp.statSync(r).isDirectory())throw new Error(`"${r}" is not a directory`)}function Wi(r,e,t){if(r&&(e||t))throw new Error("Cannot use `--path` with `--project` or `--agent`");return{resolvedPath:r?mp(r):void 0,resolvedProject:e?mp(e):void 0}}async function Vi(r,e,t){if(e)return{agents:[],projectAgents:[],customPath:e};let n=r.agent?await Sc(r.agent):await Ec(t);if(!n.length)throw new Error("No agents found. Install an AI agent (cursor, opencode, etc.) or use `--path` for a custom location.");return t?{agents:[],explicitAgents:!!r.agent,projectAgents:n.map(i=>({project:t,agent:i}))}:{agents:n,projectAgents:[],explicitAgents:!!r.agent}}import nR from"fs";import Pc from"path";import{cyan as iR}from"colorette";import*as Cc from"smol-toml";var Gi=nR.promises;async function oR(r){try{let e=await Gi.readFile(r,"utf8");return e.trim()===""?{}:JSON.parse(e)}catch(e){if(e.code==="ENOENT")return{};throw new Error(`Failed to read configuration file ${r}: ${e.message}`,{cause:e})}}async function sR(r){try{let e=await Gi.readFile(r,"utf8");return e.trim()===""?{}:Cc.parse(e)}catch(e){if(e.code==="ENOENT")return{};throw new Error(`Failed to read TOML config file ${r}: ${e.message}`,{cause:e})}}async function aR(r,e){let t=Pc.dirname(r);await Gi.mkdir(t,{recursive:!0});let n=JSON.stringify(e,null,2);await Gi.writeFile(r,n,"utf8")}async function cR(r,e){let t=Pc.dirname(r);await Gi.mkdir(t,{recursive:!0});let n=Cc.stringify(e);await Gi.writeFile(r,n,"utf8")}function Iy(r,e,t){let n=r[e];return!n||typeof n!="object"?!1:t in n}function Ty(r,e,t,n,i){(!r[e]||typeof r[e]!="object")&&(r[e]={});let o=r[e];return t in o&&!i?!1:(o[t]=n,!0)}async function Oy(r,e){return r.format==="codex"?sR(e):oR(e)}async function Ny(r,e,t){return r.format==="codex"?cR(e,t):aR(e,t)}async function kp(r,e,t=!1){let n=kr[r];if(!n)return{success:!1,error:`Unknown agent: ${r}. Supported agents: ${Object.keys(kr).join(", ")}`};if(!n.supportsGlobal)return{success:!1,error:`${n.displayName} does not support global MCP configuration. Use --project to configure project-level MCP.`};try{let i=await Oy(n,n.globalConfigPath);if(Iy(i,n.mcpServersKey,or)&&!t)return console.log(`MCP server ${or} already configured in ${n.globalConfigPath}.`),{success:!0,skipped:!0,configPath:n.globalConfigPath,agentName:r,installType:"global"};let o=mc(n,void 0);return Ty(i,n.mcpServersKey,or,o,t),await Ny(n,n.globalConfigPath,i),console.log(`MCP server ${or} configured in ${n.globalConfigPath}.`),{success:!0,configPath:n.globalConfigPath,agentName:r,installType:"global"}}catch(i){return{success:!1,error:`Failed to configure MCP for ${n.displayName}: ${i.message}`}}}async function kc(r,e,t=!1){let n=kr[r];if(!n)return{success:!1,error:`Unknown agent: ${r}. Supported agents: ${Object.keys(kr).join(", ")}`};let i=Pc.isAbsolute(n.projectConfigPath)?n.projectConfigPath:Pc.join(e,n.projectConfigPath);try{let o=await Oy(n,i);if(Iy(o,n.mcpServersKey,or)&&!t)return console.log(`MCP server ${or} already configured in ${i}.`),{success:!0,skipped:!0,configPath:i,agentName:r,installType:"project"};let s=mc(n,e);return Ty(o,n.mcpServersKey,or,s,t),await Ny(n,i,o),console.log(`MCP server ${or} configured in ${i}.`),{success:!0,configPath:i,agentName:r,installType:"project"}}catch(o){return{success:!1,error:`Failed to configure MCP for ${n.displayName}: ${o.message}`}}}function Dp(r){let e=r.filter(i=>i.success&&!i.skipped).length,t=r.filter(i=>i.skipped).length,n=r.filter(i=>!i.success).length;console.log(),console.log(iR("Finished:")),console.log(` Success: ${e}`),console.log(` Skipped: ${t}`),console.log(` Failed: ${n}`);for(let i of r)!i.success&&i.error&&console.error(` - ${i.agentName??"unknown"}: ${i.error}`);n>0&&(process.exitCode=1)}import lR from"fs";import dR from"path";import{homedir as uR}from"os";async function Rp(r,e){let t=[],n=r.agent?ac(r.agent):Object.keys(pc);for(let i of n){if(!Object.prototype.hasOwnProperty.call(pc,i))throw new Error(`Invalid MCP agent: ${i}`);(r.agent||lR.existsSync(dR.join(uR(),pc[i])))&&t.push(i)}if(!t.length)throw new Error("No agents supporting MCP configuration found; use --skill");return e?{agents:[],projectAgents:t.map(i=>({project:e,agent:i}))}:{agents:t,projectAgents:[]}}import{spawnSync as jy}from"child_process";import _e from"fs";import*as nt from"os";import*as A from"path";import Rc from"fs";import*as xc from"os";import*as hs from"path";import fR from"regedit";import{execFileSync as pR}from"child_process";import My from"fs";import*as Ly from"os";import*as xp from"path";function Dc(r,e){let t=xp.join(r,"Contents","Info.plist");if(!My.existsSync(t)){m(`[ToolProvider] Info.plist not found at: ${t}`);return}for(let[n,i]of[["/usr/libexec/PlistBuddy",["-c",`Print :${e}`,t]],["plutil",["-extract",e,"raw","-o","-",t]]])try{let o=pR(n,i,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(o&&!o.includes("Does Not Exist"))return o}catch{}}function mR(r){let e=Dc(r,"CFBundleShortVersionString");if(!e)return Dc(r,"CFBundleVersion");let t=e.split(".").slice(0,3).join(""),n=[Dc(r,"CFBundleVersion"),Dc(r,"CFBundleGetInfoString")?.match(/DS-[\d.]+/)?.[0]];for(let i of n){let o=i?.split(".").at(-1)?.replace(new RegExp(`^${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}`),"");if(o&&/^\d+$/.test(o))return`${e}.${o}`}return e}function on(r){if(Ly.platform()==="darwin")return mR(r);let e=xp.join(r,"product-info.json");try{let t=JSON.parse(My.readFileSync(e,"utf8")).version;return typeof t=="string"&&t.trim()?t.trim():void 0}catch{return}}var gR="DevEco Studio",hR=["Contents","Resources","product-info.json"],yR="name";function wR(r){return r.filter(e=>{try{return Rc.statSync(e).isDirectory()}catch{return!1}})}function vR(r){let e=hs.join(r,...hR);if(Rc.existsSync(e))try{let n=JSON.parse(Rc.readFileSync(e,"utf8"))[yR];return typeof n=="string"&&n.trim()?n.trim():void 0}catch{return}}function bR(r){return vR(r)===gR}function SR(){let r=[];for(let e of[hs.join(xc.homedir(),"Applications"),"/Applications"])try{r.push(...Rc.readdirSync(e).filter(t=>t.endsWith(".app")).map(t=>hs.join(e,t)).filter(bR))}catch{}return r}function _y(r){return new Promise((e,t)=>fR.list(r,(n,i)=>n?t(n):e(i)))}async function $y(r,e,t){let i=((await _y([r]))[r]?.keys??[]).filter(e).map(s=>`${r}\\${s}`);if(i.length===0)return[];let o=await _y(i);return i.flatMap(s=>{let a=o[s]?.values?.[t]?.value;return a?[a]:[]})}async function ER(){let r=[hs.join("C:","Program Files","Huawei","DevEco Studio")];for(let e of["HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"])try{r.push(...await $y(e,t=>t.normalize("NFKC").trim().toLowerCase().startsWith("deveco studio"),"InstallLocation"))}catch{}for(let e of["HKLM\\SOFTWARE\\Huawei\\DevEco Studio","HKLM\\SOFTWARE\\WOW6432Node\\Huawei\\DevEco Studio"])try{r.push(...await $y(e,()=>!0,""))}catch{}return r}async function Fy(){let r=xc.platform();if(r==="linux")throw new Error("DevEco Studio is not available on Linux. Set DEVECO_CLI_CLT_PATH to a Command Line Tools installation.");let e=r==="darwin"?SR():await ER(),t=wR(e).flatMap(n=>{let i=on(n);return i?(m(`[ToolProvider] ${n} => version ${i}`),[{root:n,version:i}]):(m(`[ToolProvider] Skipping ${n}: could not read version`),[])});if(!t.length)throw new Error("DevEco Studio installation not found in default locations. Set DEVECO_CLI_STUDIO_PATH to a DevEco Studio installation, or set DEVECO_CLI_CLT_PATH to a Command Line Tools installation.");return t.reduce((n,i)=>$i(i.version,n.version)>0?i:n)}var PR=/^#\s*Version:\s*(\S+)/,CR="26.0.0.810";function kR(r){try{let e=JSON.parse(_e.readFileSync(r,"utf8")),t=Number(e.apiVersion??e.data?.apiVersion);return Number.isInteger(t)&&t>=17?t:void 0}catch(e){m(`[ToolProvider] Failed to parse API level from ${r}: ${e instanceof Error?e.message:String(e)}`);return}}function DR(r){let e=A.join(r,"default","openharmony");return[A.join(r,"default","sdk-pkg.json"),...["toolchains","native","previewer"].map(t=>A.join(e,t,"oh-uni-package.json"))]}var C=class r{constructor(e,t,n,i,o,s,a,c,l,d){this._sourceType=e;this._toolchainRoot=t;this._devecoStudioPath=n;this._nodePath=i;this._ohpmJsPath=o;this._hvigorJsPath=s;this._javaPath=a;this._sdkPath=c;this._hdcPath=l;this._emulatorPath=d}static installSourcePromise;get sourceType(){return this._sourceType}get toolchainRoot(){return this._toolchainRoot}get devecoStudioPath(){return this._devecoStudioPath}get nodePath(){return this._nodePath}get ohpmJsPath(){return this._ohpmJsPath}get hvigorJsPath(){return this._hvigorJsPath}get codelinterPath(){return r.resolveCodelinterPath(this._toolchainRoot,this._sourceType)}get arktsLangServerPath(){let e=r.buildToolPaths(this._toolchainRoot,this._sourceType).arktsLangServerCandidates;for(let t of e)if(_e.existsSync(t.marker))return t.root;return null}get clangdPath(){let e=r.buildToolPaths(this._toolchainRoot,this._sourceType).clangdPath;return _e.existsSync(e)?e:null}get javaPath(){return this._javaPath??""}get sdkPath(){return this._sdkPath}get hdcPath(){return this._hdcPath}get emulatorPath(){return this._emulatorPath}get emulatorLauncherPath(){return this.emulatorPath}assertJava(){if(this._sourceType==="clt"&&(this._javaPath=r.resolveCltJava(!0)),!this._javaPath)throw new Error("Java runtime is required to run hvigor. Set JAVA_HOME or add Java to PATH.")}assertStudio(){if(this._sourceType==="clt")throw new Error("This operation requires DevEco Studio. Set DEVECO_CLI_STUDIO_PATH to a DevEco Studio installation.")}assertLsp(){this.assertStudio()}static compareVersion(e,t){return $i(e,t)}static async checkVersion(){let e=await r.resolveInstallSource();(e.sourceType==="clt"?r.fromCLT(e.toolchainRoot):r.fromIDE(e.toolchainRoot,e.sourceType)).assertVersion()}static async new(){let e=await r.resolveInstallSource();return e.sourceType==="clt"?r.fromCLT(e.toolchainRoot):r.fromIDE(e.toolchainRoot,e.sourceType)}static fromCLT(e){let t=r.buildToolPaths(e,"clt");return r.assertBuiltPathsInsideRoot(e,t,!1),new r("clt",e,void 0,t.nodePath,t.ohpmJsPath,t.hvigorJsPath,r.resolveCltJava(!1),t.sdkPath,t.hdcPath,t.emulatorPath)}static fromIDE(e,t="studio"){let n=r.buildToolPaths(e,"studio");return r.assertBuiltPathsInsideRoot(e,n,!0),new r(t,e,e,n.nodePath,n.ohpmJsPath,n.hvigorJsPath,n.javaPath,n.sdkPath,n.hdcPath,n.emulatorPath)}assertVersion(){if(this._sourceType==="clt"){this.assertCltVersion();return}this.assertIdeVersion()}readVersion(){return this._sourceType==="clt"?r.readCltVersion(this._toolchainRoot):on(this._toolchainRoot)}assertCltVersion(e="26.0.0"){if(this._sourceType!=="clt")throw new Error("This operation requires Command Line Tools.");r.assertMinimumVersion(r.readCltVersion(this._toolchainRoot),"Command Line Tools","version.txt",e,this._toolchainRoot)}assertIdeVersion(e="6.0.0"){this.assertStudio(),r.assertMinimumVersion(on(this._toolchainRoot),"DevEco Studio","product-info.json / Info.plist",e,this._toolchainRoot)}require(e){if(this._sourceType==="clt"){this.requireClt(e.clt);return}this.requireIde(e.studio)}requireClt(e){if(e===!1)throw new Error("This operation is not supported in Command Line Tools mode.");typeof e=="string"&&this.assertCltVersion(e)}requireIde(e){if(e===!1)throw new Error("This operation is not supported in DevEco Studio mode.");typeof e=="string"&&this.assertIdeVersion(e)}static assertMinimumVersion(e,t,n,i,o){if(!e)throw new w(`Failed to determine ${t} version from ${n} at ${o}`,`Failed to determine ${t} version from ${n}`);if(!/^\d+(?:\.\d+){1,3}$/.test(e))throw new w(`Invalid ${t} version "${e}" from ${n} at ${o}`,`Invalid ${t} version "${e}" from ${n}`);if($i(e,i)<0)throw new Error(`The detected ${t} version is ${e}, which is below the minimum required version ${i}. Upgrade before using deveco-cli:
18
- ${cp}`)}static resolveCodelinterPath(e,t){let n=r.buildToolPaths(e,t).codelinterCandidates,i=n.find(r.isFile);if(!i){let a=t==="studio"?"Code Linter not found in DevEco Studio.":"Code Linter not found in DevEco Command Line Tools.";throw new w(`${a}
16
+ `);if(o===-1)return null;let s=i.slice(0,o),a=i.slice(o+4),c=Zy(s);return{statusCode:c.statusCode,statusText:c.statusText,body:a,headers:c.headers}}async function rw(r){if(process.platform!=="win32")return null;let e=Jx()??await zx();if(!e)return null;let t;r.binary&&(t=ei.mkdtempSync(Nc.join(ew.tmpdir(),"curl-")));let n=t?Nc.join(t,"header.tmp"):void 0,i=t?Nc.join(t,"body.tmp"):void 0;try{let o=Yx(r,e,n,i),s=await Qx(o,r.timeoutMs);return!s||s.code!==0?null:Zx(s.stdout,n,i)}catch{return null}finally{t&&ei.rmSync(t,{recursive:!0,force:!0})}}function Qx(r,e){let t=Kx();return new Promise(n=>{let i=Qy(t,r,{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),o="",s=!1,a=setTimeout(()=>{s||(s=!0,i.kill())},e??tw);i.stdout.on("data",c=>{o+=c.toString()}),i.on("error",()=>{s||(s=!0,clearTimeout(a),n(null))}),i.on("close",c=>{if(clearTimeout(a),s){n(null);return}s=!0,n({code:c??-1,stdout:o})})})}function tD(r){let e=new URL(r);return{protocol:e.protocol,host:e.hostname,port:e.port?Number.parseInt(e.port,10):e.protocol==="https:"?443:80,auth:{username:decodeURIComponent(e.username),password:decodeURIComponent(e.password)}}}var Up=class{client;constructor(){let e={timeout:ps.HTTP_TIMEOUT_MS,headers:{"User-Agent":dc.USER_AGENT,"accept-language":dc.ACCEPT_LANGUAGE},transformResponse:[t=>t]};this.client=eD.create(e),this.client.interceptors.request.use(t=>{let n=Yy(t.url??"");return t.proxy=n?tD(n):!1,t}),this.client.interceptors.response.use(t=>t,t=>{let n=`Network connection failed (${t.code}). Please check your proxy configuration or network settings`,i=new Error(`${t.message}
17
+ ${n}`);throw i.code=t.code,i.response=t.response,i})}async get(e,t){try{let n=await this.client.request({method:"GET",url:e,params:t?.params,headers:t?.headers,timeout:t?.timeout});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"GET",t)}}async post(e,t){try{let n=await this.client.request({method:"POST",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"POST",t)}}convertResponse(e){return{data:typeof e.data=="string"?e.data:JSON.stringify(e.data),statusCode:e.status,statusText:e.statusText??"",headers:e.headers}}parseJson(e){try{return JSON.parse(e.data)}catch(t){throw new Error(`Failed to parse JSON response: ${t instanceof Error?t.message:String(t)}`,{cause:t})}}async getBinary(e,t){try{let n=await this.client.request({method:"GET",url:e,responseType:"arraybuffer",headers:t?.headers,timeout:t?.timeout});if(n.status!==200)throw new Error(`HTTP ${n.status}`);return Buffer.from(n.data)}catch(n){let i=await this.tryCurlFallback(n,e,"GET",t,!0);if(i?.bodyBuffer){if(i.statusCode!==200)throw new Error(`HTTP ${i.statusCode}`);return i.bodyBuffer}throw n}}async postAllowFailure(e,t){try{let n=await this.client.request({method:"POST",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"POST",t)}}async deleteAllowFailure(e,t){try{let n=await this.client.request({method:"DELETE",url:e,data:t?.params,headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});return this.convertResponse(n)}catch(n){return this.withCurlFallback(n,e,"DELETE",t)}}async getBinaryAllowFailure(e,t){try{let n=await this.client.request({method:"GET",url:e,responseType:"arraybuffer",headers:t?.headers,timeout:t?.timeout,validateStatus:()=>!0});if(n.status===407)throw Object.assign(new Error("407 Proxy Authentication Required"),{response:{status:407}});let i=Buffer.from(n.data),o=i.toString("utf8");return{statusCode:n.status,statusText:n.statusText??"",buffer:i,body:o}}catch(n){let i=await this.tryCurlFallback(n,e,"GET",t,!0);if(i?.bodyBuffer)return{statusCode:i.statusCode,statusText:i.statusText,buffer:i.bodyBuffer,body:i.bodyBuffer.toString("utf8")};throw n}}async withCurlFallback(e,t,n,i){let o=await this.tryCurlFallback(e,t,n,i,!1);if(o)return{data:o.body,statusCode:o.statusCode,statusText:o.statusText,headers:o.headers};throw e}async tryCurlFallback(e,t,n,i,o=!1){if(process.platform!=="win32"||!(e instanceof Error)||!rD(e))return null;let s,a=t;return n==="GET"?i?.params&&(a=nD(t,i.params)):i?.params!==void 0&&i.params!==null&&(s=typeof i.params=="string"?i.params:JSON.stringify(i.params)),rw({url:a,method:n,data:s,headers:i?.headers,timeoutMs:i?.timeout,binary:o})}},j=new Up;function rD(r){if(r.response?.status===407)return!0;let e=r.message??"";return/proxy auth(?:oriz|entic)/i.test(e)?!0:r.code==="SELF_SIGNED_CERT_IN_CHAIN"||r.code==="DEPTH_ZERO_SELF_SIGNED_CERT"||r.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"||r.code==="CERT_HAS_EXPIRED"||r.code==="ERR_TLS_CERT_ALTNAME_INVALID"}function nD(r,e){if(!e||typeof e!="object")return r;let t=new URLSearchParams;for(let[o,s]of Object.entries(e))if(s!=null)if(Array.isArray(s))for(let a of s)t.append(`${o}[]`,String(a));else t.append(o,String(s));let n=t.toString();if(!n)return r;let i=r.includes("?")?"&":"?";return`${r}${i}${n}`}import*as nw from"fs";import*as iw from"path";var ow=["DevEco"];async function Es(){let r=await j.get(Pt.TAGS_API_URL),t=Mc(r,"Tags API").data.skill.filter(n=>n.name==="HMOS");if(t.length===0)throw new Error("No HMOS tag found.");return t.map(n=>n.id)}async function iD(r){let e=[],t=Pt.DEFAULT_PAGE_SIZE,n=Pt.DEFAULT_MAX_PAGES,i=1;for(;i<=n;){let o=await j.post(Pt.SKILLS_API_URL,{headers:{"Content-Type":"application/json"},params:{pageNum:i,pageSize:t,tagIds:[r]}}),s=Mc(o,"Skills API");if(e.push(...s.data.list),s.data.list.length<t)break;i++}return e}async function Oc(r){let e=new Map,t=r.map(i=>iD(i)),n=await Promise.all(t);for(let i of n)for(let o of i)e.has(o.id)||e.set(o.id,o);return Array.from(e.values()).filter(i=>i.tags?.every(o=>!ow.includes(o.name)))}async function oD(r,e){let t=await j.post(Pt.SKILLS_API_URL,{headers:{"Content-Type":"application/json"},params:{pageNum:1,pageSize:Pt.DEFAULT_PAGE_SIZE,keyword:r,tagIds:[e]}});return Mc(t,"Skills API").data.list}async function _c(r,e){let t=new Map,n=e.map(o=>oD(r,o)),i=await Promise.all(n);for(let o of i)for(let s of o)t.has(s.id)||t.set(s.id,s);return Array.from(t.values()).filter(o=>o.tags?.every(s=>!ow.includes(s.name)))}function Bp(r){Et(r);let e=[];for(let t of Le()){let n=Ft(t);if(!Qn(t))continue;let i=iw.join(n,r);nw.existsSync(i)&&e.push(Lt(t).displayName)}return e.sort()}function Mc(r,e){if(r.statusCode!==200)throw new Error(`${e} Request failed: HTTP ${r.statusCode}`);let t=j.parseJson(r);if(t.code!==Pt.SUCCESS_CODE)throw new Error(`${e} Error returned: ${t.code} - ${t.message}`);return t}async function sw(r){Et(r);let e=`${Pt.SKILL_API_BASE}/${r}/checksum`,t=await j.get(e);return Mc(t,"Checksum API").data}var aw=Wp.promises;function cw(r,e){let t=$t.resolve(e),n=$t.resolve(r),i=$t.relative(n,t);if(i.startsWith("..")||$t.isAbsolute(i))throw new Error(`Path traversal detected: ${e}.`)}function Vp(r){return $t.isAbsolute(r)?r:$t.resolve(process.cwd(),r)}function dD(r){return aD.createHash("sha256").update(r).digest("hex")}async function uD(r,e){if(r.length!==e.size)throw new Error("Skill zip integrity verification failed: Size mismatch");let n=dD(r),i=e.sha256.toLowerCase(),o=Buffer.from(n,"hex"),s=Buffer.from(i,"hex");if(o.length!==s.length||!cD(o,s))throw new Error("Skill zip integrity verification failed: SHA256 mismatch")}async function Gp(r){Et(r);let e=`${Pt.SKILL_API_BASE}/${r}/install?format=zip`,t=await j.getBinary(e),n=await sw(r);return await uD(t,n),t}async function lw(r,e,t){Et(t);let n=new sD(r),i=n.getEntries();try{await aw.stat(e)}catch{await aw.mkdir(e,{recursive:!0})}let o=$t.join(e,t);cw(e,o);for(let s of i){let a=$t.join(o,s.entryName);cw(o,a)}n.extractAllTo(o,!0)}function ti(){let e=$t.dirname(lD(import.meta.url));for(;;){let t=$t.join(e,"skills","deveco-cli");if(Wp.existsSync(t)&&Wp.statSync(t).isDirectory())return t;let n=$t.dirname(e);if(n===e)break;e=n}throw new Error("skills/deveco-cli directory not found in deveco-cli package. Reinstall deveco-cli.")}function dw(r){return r?jt.join(r,".deveco-cli","skills"):jt.join($(),"skills")}function mD(r,e){return Et(r),jt.join(dw(e),"store",r)}async function uw(r,e){let t=e??$(),n=await Gi.realpath(t).catch(s=>{if(s.code==="ENOENT")return ke(t);throw s}),i=jt.join(n,jt.relative(t,r)),o=await ke(i);if(!ge(i,o))throw new Error(`Skill storage parent redirects outside its managed location: ${i}`);return o}async function qp(r,e){return uw(mD(r,e),e)}async function Ps(r,e,t){Et(r);let n=e.customPath??dw(e.project),i=e.customPath?await ke(jt.join(n,`.${r}.lock`)):await uw(jt.join(n,"locks",`${r}.lock`),e.project);await Gi.mkdir(jt.dirname(i),{recursive:!0});let o=await fD(n,{realpath:!1,lockfilePath:i,stale:3e4,update:1e4,retries:{retries:100,minTimeout:50,maxTimeout:200}});try{return await t()}finally{await o()}}async function pw(r){let e=await Gi.lstat(r);if(!e.isDirectory()||e.isSymbolicLink()||!(await Gi.stat(jt.join(r,"SKILL.md"))).isFile())throw new Error(`Invalid Skill store: ${r}`)}async function fw(r,e,t,n,i){let o=await qp(r,t),s=await Me(o);if(!i&&!s&&(await Promise.all(n.map(c=>Me(c.path)))).every(Boolean))return{results:n.map(c=>sr(c.path,"already-exists"))};for(let a of n)for(let c of[a.path,...a.legacy])if(Bi(o,c))throw new Error(`Skill store and destination overlap: ${o}, ${c}`);if(!i&&s){try{await pw(o)}catch(a){throw new Error(`Cannot reuse Skill store ${o}; use --force to replace: ${a.message}`,{cause:a})}return{source:o,results:[]}}return{source:o,results:[await gw(r,e,o)]}}async function mw(r,e,t,n){let i=await ke(t);return await Ap(i,n)??gw(r,e,i)}async function gw(r,e,t){await Gi.mkdir(jt.dirname(t),{recursive:!0});let n=`${t}.extract-${pD()}`;try{await lw(e,n,r);let i=jt.join(n,r);return await pw(i),await Ip(i,t),{success:!0,path:t,reason:"shared-entity-updated"}}finally{await Gi.rm(n,{recursive:!0,force:!0})}}function Cs(r,e){return{success:!1,path:r,error:e instanceof Error?e.message:String(e)}}async function zp(r,e,t){let n=[];for(let i of Uy(e))try{n.push(...await Ps(r,i,()=>t(i)))}catch(o){n.push(Cs(on.join(ar(i.project),r),o))}return n}async function Kp(r){return Yp.realpath(r).catch(e=>{if(e.code==="ENOENT"||e.code==="ELOOP")return r;throw e})}async function gD(r,e){let t=await Yp.realpath(e);for(let n of r.legacy){let i=await Me(n);if(i&&!i.isSymbolicLink()&&Bi(t,n))throw new Error(`Skill source and legacy destination overlap: ${e}, ${n}`);await kc(n)}}async function hD(r,e,t,n){let i=[];for(let o of Le()){let s=Ft(o,e.project);if(e.agents.includes(o)||Zn(o,e.project)&&!Qn(o,e.project))continue;let a=await ke(on.join(s,r)),c=await Me(a);c&&(ge(a,t)&&Qn(o,e.project)||n&&c.isSymbolicLink()&&ge(await Kp(a),n))&&i.push(Lt(o).displayName)}return[...new Set(i)]}function yD(r,e){let t=`still used by ${e.join(", ")}`;return console.log(`Skill ${on.basename(r)} in ${on.dirname(r)} is kept: ${t}.`),sr(r,t)}async function Jp(r,e,t,n){try{if(!await Me(r))return;let i=await hD(e,t,r,n);return i.length?yD(r,i):await kc(r)}catch(i){return Cs(r,i)}}var dr=class{async installBundledSkill(e,t,n=!1){return await Yp.access(on.join(e,"SKILL.md")),t.customPath?this.installCustom("deveco-cli",e,t.customPath,n):zp("deveco-cli",t,i=>this.installScope("deveco-cli",e,i,t.explicitAgents,n))}async installArchiveSkill(e,t,n,i=!1){return Et(e),n.customPath?this.installCustom(e,t,n.customPath,i):zp(e,n,o=>this.installScope(e,t,o,n.explicitAgents,i))}async installCustom(e,t,n,i){let o=on.join(n,e);try{return await Ps(e,{customPath:n},async()=>[typeof t=="string"?await Cc(t,o,i):await mw(e,t,o,i)])}catch(s){return[Cs(o,s)]}}async installScope(e,t,n,i=!0,o=!1){let s=await By(n,e,i),a=s.filter(l=>!l.skipped),c=s.filter(l=>l.skipped).map(l=>sr(l.path,"agent-project-root-missing"));if(!a.length)return c;try{let l=typeof t=="string"?{source:t,results:[]}:await fw(e,t,n.project,a,o);return[...c,...l.results,...l.source?await this.installSkillEntries(l.source,a,o):[]]}catch(l){return[...c,...a.map(d=>Cs(d.path,l))]}}async installSkillEntries(e,t,n){let i=[];for(let o of t)try{i.push(await Cc(e,o.path,n)),n&&await gD(o,e)}catch(s){i.push(Cs(o.path,s))}return i}async migrateBundledSkill(e,t){await Ps("deveco-cli",t,()=>this.migrateBundledScope(e,t))}async migrateBundledScope(e,t){let n,i=[];for(let o of t.agents)try{for(let s of await Dc({...t,agents:[o]},"deveco-cli"))await this.migrateBundledDestination(e,s,i)}catch(s){n=s,console.error(`Skill migration failed for ${o}: ${s.message}`)}if(n)throw n}async migrateBundledDestination(e,t,n){let i=await Me(t.path);(!i||!i.isDirectory()&&!i.isSymbolicLink())&&!t.legacy.length||n.some(o=>ge(o,t.path))||((await Cc(e,t.path)).reason==="already-exists"&&console.warn(`Skill migration skipped: ${t.path} (already exists; run devecocli init --force to replace).`),n.push(t.path))}async removeSkill(e,t){if(Et(e),t.customPath){let n=on.join(t.customPath,e);return Ps(e,t,async()=>[await kc(n)])}return zp(e,t,n=>this.removeScope(e,n,t.explicitAgents))}async removeScope(e,t,n=!0){let i=await ke(on.join(ar(t.project),e)),o=await this.removeAgentEntries(e,t,i,n);if(o.every(s=>s.success)){let s=await Jp(i,e,t,await Kp(i));s&&o.push(s)}if(o.every(s=>s.success)){let s=await qp(e,t.project),a=await Jp(s,e,{...t,agents:[]},await Kp(s));a&&o.push(a)}return o.length||(console.log(`Skill ${e} not found for the selected agents.`),o.push(sr(i,"not-installed"))),o}async removeAgentEntries(e,t,n,i){let o=new Set;for(let a of await Dc(t,e,i))if(!a.skipped)for(let c of[a.path,...a.legacy])ge(c,n)||o.add(c);let s=[];for(let a of o){let c=await Jp(a,e,t);c&&s.push(c)}return s}};import Lc from"fs/promises";import hw from"path";function wD(r){return`'${process.platform==="win32"?r.replace(/'/g,"''"):r.replace(/'/g,"'\\''")}'`}async function vD(r,e){try{if(!(await Me(r))?.isSymbolicLink())return;let n=await Lc.realpath(r);return ge(n,e)?void 0:{path:r,reason:`points to ${n}`,repair:!0}}catch(t){let n=t.code,i=n==="ENOENT"||n==="ELOOP"||n==="ENOTDIR";return{path:r,reason:i?"broken link":`cannot check: ${t.message}`,repair:i}}}var Xp=class{checked=new Set;async warnInvalidBundledLinks(e){try{let t=await Lc.realpath(e),n=process.platform==="win32"?t.toLowerCase():t;if(this.checked.has(n))return;this.checked.add(n);let i=await Lc.realpath(ti());if(!(await Lc.stat(hw.join(i,"SKILL.md"))).isFile())throw new Error(`Skill source has no SKILL.md: ${i}`);let o=await this.checkKnownEntries(t,i);this.reportIssues(t,o)}catch(t){console.warn(`Cannot check project Skill links for ${e}: ${t.message}`)}}async checkKnownEntries(e,t){let n=new Set([ar(e),...Le().map(s=>Mp(e,s))]),i=[],o=[];for(let s of n){let a=hw.join(s,"deveco-cli");try{let c=await ke(a);if(i.some(d=>ge(d,c)))continue;i.push(c);let l=await vD(c,t);l&&o.push(l)}catch(c){o.push({path:a,reason:`cannot check: ${c.message}`,repair:!1})}}return o}reportIssues(e,t){for(let n of t)console.warn(`Project Skill link: ${n.path} (${n.reason}).`);t.some(n=>n.repair)&&(console.warn(`Run: devecocli init --project ${wD(e)} -f`),console.warn("Existing copies and local edits in the selected installation scope will be replaced."))}},nt=new Xp;import tf from"fs";import Sw from"path";import{cyan as OD}from"colorette";import{spawn as DD}from"child_process";import*as bw from"fs";import*as $c from"path";import{yellow as ID,cyan as AD}from"colorette";import TD from"proper-lockfile";import{compare as bD}from"semver";function Ct(r,e){return bD(r,e)}function qi(r,e){let t=Math.max(r.split(".").length,e.split(".").length);for(let n=0;n<t;n++){let i=Number(r.split(".")[n]??0)-Number(e.split(".")[n]??0);if(i)return i}return 0}function zi(){return process.env.DEVECO_CLI_WRAPPER_NAME?process.env.DEVECO_CLI_WRAPPER_NAME:"@litingwei621/test-deveco-cli-common"}function ur(){return process.env.DEVECO_CLI_WRAPPER_VERSION?process.env.DEVECO_CLI_WRAPPER_VERSION:"1.3.10-Test.1"}function sn(){return"latest"}function Ht(){return Number.isFinite(1),1}var Ut="@deveco/deveco-cli-knowledgebase";function Ji(){let r=process.env.DEVECO_CLI_DISABLE_UPDATE;return r==="check"||r==="all"?r:"off"}import*as ks from"fs";import*as Rs from"path";var SD={lastCheckedTimestamp:null,latestVersion:null,blockedVersions:[],checkError:null,latestDocsVersion:null,latestDocsApiVersion:null,latestCompatibleDocsVersion:null,checkedAgainstDocsApi:null},Zp=new Map,an=class r{static CHECK_WINDOW_HOUR=21;static ONE_DAY_MS=1440*60*1e3;cacheFilePath;lockFilePath;constructor(e){this.cacheFilePath=Rs.join(e,"cache.json"),this.lockFilePath=Rs.join(e,"check.lock")}async writeSuccess(e,t=[],n,i,o){let s=this.read();await this.write({lastCheckedTimestamp:Date.now(),latestVersion:e,blockedVersions:t,checkError:null,checkedAgainstVersion:n,checkedAgainstTag:i,latestDocsVersion:o?o.latestDocsVersion:s.latestDocsVersion??null,latestDocsApiVersion:o?o.latestDocsApiVersion:s.latestDocsApiVersion??null,latestCompatibleDocsVersion:o?o.latestCompatibleDocsVersion:s.latestCompatibleDocsVersion??null,checkedAgainstDocsApi:o?o.checkedAgainstDocsApi:s.checkedAgainstDocsApi??null})}async writeError(e){let t=this.read();await this.write({...t,lastCheckedTimestamp:Date.now(),checkError:e})}getLatestVersion(){return this.read().latestVersion}getBlockedVersions(){return[...this.read().blockedVersions]}getCheckedAgainstVersion(){return this.read().checkedAgainstVersion}getCheckedAgainstTag(){return this.read().checkedAgainstTag}getLatestDocsVersion(){return this.read().latestDocsVersion??null}getLatestDocsApiVersion(){return this.read().latestDocsApiVersion??null}getLatestCompatibleDocsVersion(){return this.read().latestCompatibleDocsVersion??null}getCheckedAgainstDocsApi(){return this.read().checkedAgainstDocsApi??null}isCheckNeeded(){let{lastCheckedTimestamp:e}=this.read();if(!e||e>Date.now())return!0;let t=new Date().setHours(r.CHECK_WINDOW_HOUR,0,0,0),n=t>Date.now()?t-r.ONE_DAY_MS:t;return e<n}getLockPath(){return this.lockFilePath}read(){let e=Zp.get(this.cacheFilePath);if(e)return e;try{let t=ks.readFileSync(this.cacheFilePath,"utf-8"),n=JSON.parse(t);return Zp.set(this.cacheFilePath,n),n}catch{return{...SD}}}async write(e){f(()=>`Writing update cache: lastChecked=${e.lastCheckedTimestamp}, latest=${e.latestVersion}, blocked=[${e.blockedVersions.join(",")}], error=${e.checkError}`),await ks.promises.mkdir(Rs.dirname(this.cacheFilePath),{recursive:!0}),await ks.promises.writeFile(this.cacheFilePath,JSON.stringify(e,null,2),"utf-8"),Zp.set(this.cacheFilePath,e)}};import{createRequire as ED}from"module";import{dirname as PD,join as Ki}from"path";import{pathToFileURL as CD}from"url";import{readFile as yw,access as Qp}from"fs/promises";import*as ww from"semver";var kD=ED(import.meta.url);async function RD(){try{let r=kD.resolve(`${Ut}/package.json`),e=JSON.parse(await yw(r,"utf8"));return{version:e.version,apiVersion:e.apiVersion??0,dir:PD(r)}}catch{return null}}async function vw(){let r=$(),e=Ki(r,"doc-data","current.json"),t;try{t=JSON.parse(await yw(e,"utf8"))}catch{return null}let n=Ki(r,"doc-data",t.version);try{return await Qp(Ki(n,"dist","engine","index.js")),await Qp(Ki(n,"docs.zip")),await Qp(Ki(n,"index.zip")),{version:t.version,apiVersion:t.apiVersion,dir:n}}catch{return null}}async function xD(){return[await vw(),await RD()].filter(e=>e!==null).sort((e,t)=>ww.rcompare(e.version,t.version))}async function Yi(){let r=Ht(),e=await vw();return e&&e.apiVersion<=r?e.version:null}async function Fc(){let r=Ht(),e=await xD(),t=!1;for(let n of e){if(n.apiVersion>r){f(`docs: skip candidate v${n.version} (apiVersion ${n.apiVersion} > ${r})`);continue}t=!0;try{let i=Ki(n.dir,"dist","engine","index.js");return await import(CD(i).href)}catch(i){f(`docs: candidate v${n.version} load failed: ${i instanceof Error?i.message:String(i)}`)}}throw e.length>0&&!t?new Error("Documentation package version is incompatible, please upgrade CLI"):new Error("No available documentation package, please run `devecocli docs update` or reinstall CLI")}var xs=class{constructor(e){this.actionCommand=e}cache=new an($c.join($(),"update"));async checkAndNotify(){if(!this.shouldSkip())try{let e=ur(),t=sn(),n=this.cache.getCheckedAgainstVersion(),i=this.cache.getCheckedAgainstTag(),o=i!=null&&i!==t,s=n!=null&&n!==e,a=[],c=o?null:this.cache.getLatestVersion();c&&Ct(c,e)>0&&a.push(ID(`New cli version ${c} available, run \`devecocli update\` to update`));let l=await this.buildDocsMessage();if(l.message&&a.push(l.message),a.length>0){console.log();for(let d of a)console.log(d)}(o||s||l.stale||this.cache.isCheckNeeded())&&await this.spawnBackgroundCheck()}catch(e){f(`Update check failed: ${e instanceof Error?e.message:String(e)}`)}}async buildDocsMessage(){let e=Ht(),t=this.cache.getCheckedAgainstDocsApi();if(t!=null&&t!==e)return{message:null,stale:!0};let n=this.cache.getLatestCompatibleDocsVersion();if(!n)return{message:null,stale:!1};let i=await Yi();return i&&Ct(n,i)<=0?{message:null,stale:!1}:{message:AD(`New docs version ${n} available, run \`devecocli docs update\` to upgrade`),stale:!1}}shouldSkip(){let e=this.actionCommand;for(;e;){if(e.name()==="update")return!0;e=e.parent}return!1}async spawnBackgroundCheck(){if(!process.argv[1]?.endsWith(".ts"))try{await ND(this.cache.getLockPath(),()=>{let e=[process.argv[1],"update","_check"];f(`Executing: ${process.execPath} ${e.join(" ")}`),DD(process.execPath,e,{detached:!0,stdio:["ignore","ignore","ignore"],env:{...process.env,DEVECO_CLI_SKIP_VERSION_CHECK:"1"}}).unref()})}catch{f("Update check lock held by another process, skipping")}}};async function ND(r,e){await bw.promises.mkdir($c.dirname(r),{recursive:!0});let t=await TD.lock(r,{stale:6e4,retries:0,realpath:!1});try{await e()}finally{await t()}}var ef=tf.promises;async function jc(r){let e=Rc(r);for(let t of e)Lt(t);return e}async function Hc(r){return Le().filter(e=>Qn(e,r))}async function _D(){let r=ti();await new dr().migrateBundledSkill(r,{agents:Le()})}async function Ew(){try{let r=Sw.join($(),"skills","migration-version"),e=await ef.readFile(r,"utf8").catch(n=>{if(n.code==="ENOENT")return"";throw n}),t=ur();if(e.trim()===t)return;await _D(),await ef.mkdir(Sw.dirname(r),{recursive:!0}),await ef.writeFile(r,t,"utf8")}catch{}}function Xi(r){let e=r.filter(i=>i.success&&!i.skipped).length,t=r.filter(i=>i.skipped).length,n=r.filter(i=>!i.success).length;console.log(),console.log(OD("Finished:"));for(let i of r){if(!i.path)continue;let o=i.reason==="already-exists"?"already exists; use --force to replace":i.reason,s=i.fallbackReason?" (link failed: "+i.fallbackReason+")":o??i.error?" ("+(o??i.error)+")":"",a=i.success?i.skipped?"skipped":i.mode??(i.reason==="shared-entity-updated"?"updated":"removed"):"failed";console.log(" "+a+": "+i.path+s)}console.log(` Success: ${e}`),console.log(` Skipped: ${t}`),console.log(` Failed: ${n}`),n>0&&(process.exitCode=1)}function Tr(r,e,t){if(!tf.existsSync(r)){if(t)return;throw new Error(`${e} "${r}" not found`)}if(!tf.statSync(r).isDirectory())throw new Error(`"${r}" is not a directory`)}function Zi(r,e,t){if(r&&(e||t))throw new Error("Cannot use `--path` with `--project` or `--agent`");return{resolvedPath:r?Vp(r):void 0,resolvedProject:e?Vp(e):void 0}}async function Qi(r,e,t){if(e)return{agents:[],projectAgents:[],customPath:e};let n=r.agent?await jc(r.agent):await Hc(t);if(!n.length)throw new Error("No agents found. Install an AI agent (cursor, opencode, etc.) or use `--path` for a custom location.");return t?{agents:[],explicitAgents:!!r.agent,projectAgents:n.map(i=>({project:t,agent:i}))}:{agents:n,projectAgents:[],explicitAgents:!!r.agent}}import MD from"fs";import Uc from"path";import{cyan as LD}from"colorette";import*as Bc from"smol-toml";var eo=MD.promises;async function FD(r){try{let e=await eo.readFile(r,"utf8");return e.trim()===""?{}:JSON.parse(e)}catch(e){if(e.code==="ENOENT")return{};throw new Error(`Failed to read configuration file ${r}: ${e.message}`,{cause:e})}}async function $D(r){try{let e=await eo.readFile(r,"utf8");return e.trim()===""?{}:Bc.parse(e)}catch(e){if(e.code==="ENOENT")return{};throw new Error(`Failed to read TOML config file ${r}: ${e.message}`,{cause:e})}}async function jD(r,e){let t=Uc.dirname(r);await eo.mkdir(t,{recursive:!0});let n=JSON.stringify(e,null,2);await eo.writeFile(r,n,"utf8")}async function HD(r,e){let t=Uc.dirname(r);await eo.mkdir(t,{recursive:!0});let n=Bc.stringify(e);await eo.writeFile(r,n,"utf8")}function Pw(r,e,t){let n=r[e];return!n||typeof n!="object"?!1:t in n}function Cw(r,e,t,n,i){(!r[e]||typeof r[e]!="object")&&(r[e]={});let o=r[e];return t in o&&!i?!1:(o[t]=n,!0)}async function kw(r,e){return r.format==="codex"?$D(e):FD(e)}async function Rw(r,e,t){return r.format==="codex"?HD(e,t):jD(e,t)}async function rf(r,e,t=!1){let n=Ar[r];if(!n)return{success:!1,error:`Unknown agent: ${r}. Supported agents: ${Object.keys(Ar).join(", ")}`};if(!n.supportsGlobal)return{success:!1,error:`${n.displayName} does not support global MCP configuration. Use --project to configure project-level MCP.`};try{let i=await kw(n,n.globalConfigPath);if(Pw(i,n.mcpServersKey,lr)&&!t)return console.log(`MCP server ${lr} already configured in ${n.globalConfigPath}.`),{success:!0,skipped:!0,configPath:n.globalConfigPath,agentName:r,installType:"global"};let o=Tc(n,void 0);return Cw(i,n.mcpServersKey,lr,o,t),await Rw(n,n.globalConfigPath,i),console.log(`MCP server ${lr} configured in ${n.globalConfigPath}.`),{success:!0,configPath:n.globalConfigPath,agentName:r,installType:"global"}}catch(i){return{success:!1,error:`Failed to configure MCP for ${n.displayName}: ${i.message}`}}}async function Wc(r,e,t=!1){let n=Ar[r];if(!n)return{success:!1,error:`Unknown agent: ${r}. Supported agents: ${Object.keys(Ar).join(", ")}`};let i=Uc.isAbsolute(n.projectConfigPath)?n.projectConfigPath:Uc.join(e,n.projectConfigPath);try{let o=await kw(n,i);if(Pw(o,n.mcpServersKey,lr)&&!t)return console.log(`MCP server ${lr} already configured in ${i}.`),{success:!0,skipped:!0,configPath:i,agentName:r,installType:"project"};let s=Tc(n,e);return Cw(o,n.mcpServersKey,lr,s,t),await Rw(n,i,o),console.log(`MCP server ${lr} configured in ${i}.`),{success:!0,configPath:i,agentName:r,installType:"project"}}catch(o){return{success:!1,error:`Failed to configure MCP for ${n.displayName}: ${o.message}`}}}function nf(r){let e=r.filter(i=>i.success&&!i.skipped).length,t=r.filter(i=>i.skipped).length,n=r.filter(i=>!i.success).length;console.log(),console.log(LD("Finished:")),console.log(` Success: ${e}`),console.log(` Skipped: ${t}`),console.log(` Failed: ${n}`);for(let i of r)!i.success&&i.error&&console.error(` - ${i.agentName??"unknown"}: ${i.error}`);n>0&&(process.exitCode=1)}import UD from"fs";import BD from"path";import{homedir as WD}from"os";async function of(r,e){let t=[],n=r.agent?Rc(r.agent):Object.keys(Ac);for(let i of n){if(!Object.prototype.hasOwnProperty.call(Ac,i))throw new Error(`Invalid MCP agent: ${i}`);(r.agent||UD.existsSync(BD.join(WD(),Ac[i])))&&t.push(i)}if(!t.length)throw new Error("No agents supporting MCP configuration found; use --skill");return e?{agents:[],projectAgents:t.map(i=>({project:e,agent:i}))}:{agents:t,projectAgents:[]}}import{spawnSync as Nw}from"child_process";import Fe from"fs";import*as it from"os";import*as I from"path";import Gc from"fs";import*as qc from"os";import*as Ds from"path";import qD from"regedit";import{execFileSync as VD}from"child_process";import xw from"fs";import*as Dw from"os";import*as sf from"path";function Vc(r,e){let t=sf.join(r,"Contents","Info.plist");if(!xw.existsSync(t)){f(`[ToolProvider] Info.plist not found at: ${t}`);return}for(let[n,i]of[["/usr/libexec/PlistBuddy",["-c",`Print :${e}`,t]],["plutil",["-extract",e,"raw","-o","-",t]]])try{let o=VD(n,i,{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(o&&!o.includes("Does Not Exist"))return o}catch{}}function GD(r){let e=Vc(r,"CFBundleShortVersionString");if(!e)return Vc(r,"CFBundleVersion");let t=e.split(".").slice(0,3).join(""),n=[Vc(r,"CFBundleVersion"),Vc(r,"CFBundleGetInfoString")?.match(/DS-[\d.]+/)?.[0]];for(let i of n){let o=i?.split(".").at(-1)?.replace(new RegExp(`^${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}`),"");if(o&&/^\d+$/.test(o))return`${e}.${o}`}return e}function cn(r){if(Dw.platform()==="darwin")return GD(r);let e=sf.join(r,"product-info.json");try{let t=JSON.parse(xw.readFileSync(e,"utf8")).version;return typeof t=="string"&&t.trim()?t.trim():void 0}catch{return}}var zD="DevEco Studio",JD=["Contents","Resources","product-info.json"],KD="name";function YD(r){return r.filter(e=>{try{return Gc.statSync(e).isDirectory()}catch{return!1}})}function XD(r){let e=Ds.join(r,...JD);if(Gc.existsSync(e))try{let n=JSON.parse(Gc.readFileSync(e,"utf8"))[KD];return typeof n=="string"&&n.trim()?n.trim():void 0}catch{return}}function ZD(r){return XD(r)===zD}function QD(){let r=[];for(let e of[Ds.join(qc.homedir(),"Applications"),"/Applications"])try{r.push(...Gc.readdirSync(e).filter(t=>t.endsWith(".app")).map(t=>Ds.join(e,t)).filter(ZD))}catch{}return r}function Iw(r){return new Promise((e,t)=>qD.list(r,(n,i)=>n?t(n):e(i)))}async function Aw(r,e,t){let i=((await Iw([r]))[r]?.keys??[]).filter(e).map(s=>`${r}\\${s}`);if(i.length===0)return[];let o=await Iw(i);return i.flatMap(s=>{let a=o[s]?.values?.[t]?.value;return a?[a]:[]})}async function eI(){let r=[Ds.join("C:","Program Files","Huawei","DevEco Studio")];for(let e of["HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"])try{r.push(...await Aw(e,t=>t.normalize("NFKC").trim().toLowerCase().startsWith("deveco studio"),"InstallLocation"))}catch{}for(let e of["HKLM\\SOFTWARE\\Huawei\\DevEco Studio","HKLM\\SOFTWARE\\WOW6432Node\\Huawei\\DevEco Studio"])try{r.push(...await Aw(e,()=>!0,""))}catch{}return r}async function Tw(){let r=qc.platform();if(r==="linux")throw new Error("DevEco Studio is not available on Linux. Set DEVECO_CLI_CLT_PATH to a Command Line Tools installation.");let e=r==="darwin"?QD():await eI(),t=YD(e).flatMap(n=>{let i=cn(n);return i?(f(`[ToolProvider] ${n} => version ${i}`),[{root:n,version:i}]):(f(`[ToolProvider] Skipping ${n}: could not read version`),[])});if(!t.length)throw new Error("DevEco Studio installation not found in default locations. Set DEVECO_CLI_STUDIO_PATH to a DevEco Studio installation, or set DEVECO_CLI_CLT_PATH to a Command Line Tools installation.");return t.reduce((n,i)=>qi(i.version,n.version)>0?i:n)}var tI=/^#\s*Version:\s*(\S+)/,rI="26.0.0.810";function nI(r){try{let e=JSON.parse(Fe.readFileSync(r,"utf8")),t=Number(e.apiVersion??e.data?.apiVersion);return Number.isInteger(t)&&t>=17?t:void 0}catch(e){f(`[ToolProvider] Failed to parse API level from ${r}: ${e instanceof Error?e.message:String(e)}`);return}}function iI(r){let e=I.join(r,"default","openharmony");return[I.join(r,"default","sdk-pkg.json"),...["toolchains","native","previewer"].map(t=>I.join(e,t,"oh-uni-package.json"))]}var C=class r{constructor(e,t,n,i,o,s,a,c,l,d){this._sourceType=e;this._toolchainRoot=t;this._devecoStudioPath=n;this._nodePath=i;this._ohpmJsPath=o;this._hvigorJsPath=s;this._javaPath=a;this._sdkPath=c;this._hdcPath=l;this._emulatorPath=d}static installSourcePromise;get sourceType(){return this._sourceType}get toolchainRoot(){return this._toolchainRoot}get devecoStudioPath(){return this._devecoStudioPath}get nodePath(){return this._nodePath}get ohpmJsPath(){return this._ohpmJsPath}get hvigorJsPath(){return this._hvigorJsPath}get codelinterPath(){return r.resolveCodelinterPath(this._toolchainRoot,this._sourceType)}get arktsLangServerPath(){let e=r.buildToolPaths(this._toolchainRoot,this._sourceType).arktsLangServerCandidates;for(let t of e)if(Fe.existsSync(t.marker))return t.root;return null}get clangdPath(){let e=r.buildToolPaths(this._toolchainRoot,this._sourceType).clangdPath;return Fe.existsSync(e)?e:null}get javaPath(){return this._javaPath??""}get sdkPath(){return this._sdkPath}get hdcPath(){return this._hdcPath}get emulatorPath(){return this._emulatorPath}get emulatorLauncherPath(){return this.emulatorPath}assertJava(){if(this._sourceType==="clt"&&(this._javaPath=r.resolveCltJava(!0)),!this._javaPath)throw new Error("Java runtime is required to run hvigor. Set JAVA_HOME or add Java to PATH.")}assertStudio(){if(this._sourceType==="clt")throw new Error("This operation requires DevEco Studio. Set DEVECO_CLI_STUDIO_PATH to a DevEco Studio installation.")}assertLsp(){this.assertStudio()}static compareVersion(e,t){return qi(e,t)}static async checkVersion(){let e=await r.resolveInstallSource();(e.sourceType==="clt"?r.fromCLT(e.toolchainRoot):r.fromIDE(e.toolchainRoot,e.sourceType)).assertVersion()}static async new(){let e=await r.resolveInstallSource();return e.sourceType==="clt"?r.fromCLT(e.toolchainRoot):r.fromIDE(e.toolchainRoot,e.sourceType)}static fromCLT(e){let t=r.buildToolPaths(e,"clt");return r.assertBuiltPathsInsideRoot(e,t,!1),new r("clt",e,void 0,t.nodePath,t.ohpmJsPath,t.hvigorJsPath,r.resolveCltJava(!1),t.sdkPath,t.hdcPath,t.emulatorPath)}static fromIDE(e,t="studio"){let n=r.buildToolPaths(e,"studio");return r.assertBuiltPathsInsideRoot(e,n,!0),new r(t,e,e,n.nodePath,n.ohpmJsPath,n.hvigorJsPath,n.javaPath,n.sdkPath,n.hdcPath,n.emulatorPath)}assertVersion(){if(this._sourceType==="clt"){this.assertCltVersion();return}this.assertIdeVersion()}readVersion(){return this._sourceType==="clt"?r.readCltVersion(this._toolchainRoot):cn(this._toolchainRoot)}assertCltVersion(e="26.0.0"){if(this._sourceType!=="clt")throw new Error("This operation requires Command Line Tools.");r.assertMinimumVersion(r.readCltVersion(this._toolchainRoot),"Command Line Tools","version.txt",e,this._toolchainRoot)}assertIdeVersion(e="6.0.0"){this.assertStudio(),r.assertMinimumVersion(cn(this._toolchainRoot),"DevEco Studio","product-info.json / Info.plist",e,this._toolchainRoot)}require(e){if(this._sourceType==="clt"){this.requireClt(e.clt);return}this.requireIde(e.studio)}requireClt(e){if(e===!1)throw new Error("This operation is not supported in Command Line Tools mode.");typeof e=="string"&&this.assertCltVersion(e)}requireIde(e){if(e===!1)throw new Error("This operation is not supported in DevEco Studio mode.");typeof e=="string"&&this.assertIdeVersion(e)}static assertMinimumVersion(e,t,n,i,o){if(!e)throw new w(`Failed to determine ${t} version from ${n} at ${o}`,`Failed to determine ${t} version from ${n}`);if(!/^\d+(?:\.\d+){1,3}$/.test(e))throw new w(`Invalid ${t} version "${e}" from ${n} at ${o}`,`Invalid ${t} version "${e}" from ${n}`);if(qi(e,i)<0)throw new Error(`The detected ${t} version is ${e}, which is below the minimum required version ${i}. Upgrade before using deveco-cli:
18
+ ${jp}`)}static resolveCodelinterPath(e,t){let n=r.buildToolPaths(e,t).codelinterCandidates,i=n.find(r.isFile);if(!i){let a=t==="studio"?"Code Linter not found in DevEco Studio.":"Code Linter not found in DevEco Command Line Tools.";throw new w(`${a}
19
19
  Searched paths:
20
20
  ${n.join(`
21
- `)}`,a)}let o=en(e),s=en(i);return r.assertInsideRoot(s,o,"codelinter"),s}static isValidRoot(e,t){if(!r.isDirectory(e))return!1;if(t==="clt")return _e.existsSync(A.join(e,"version.txt"));let n=nt.platform()==="darwin"?A.join(e,"Contents"):e,i=nt.platform()==="darwin"?A.join(n,"Info.plist"):A.join(n,"product-info.json");if(!_e.existsSync(i))return!1;let o=r.buildToolPaths(e,"studio");return[o.nodePath,o.ohpmJsPath,o.hvigorJsPath].every(_e.existsSync)}static buildToolPaths(e,t){return t==="clt"?r.buildCltToolPaths(e):r.buildStudioToolPaths(e)}static buildCltToolPaths(e){let t=nt.platform()==="win32",n=t?".exe":"",i=A.join(e,"sdk");return{nodePath:t?A.join(e,"tool","node","node.exe"):A.join(e,"tool","node","bin","node"),ohpmJsPath:A.join(e,"ohpm","bin","pm-cli.js"),hvigorJsPath:A.join(e,"hvigor","bin","hvigorw.js"),javaPath:"",sdkPath:i,hdcPath:A.join(i,"default","openharmony","toolchains",`hdc${n}`),emulatorPath:A.join(e,"emulator",t?"Emulator.exe":"Emulator"),clangdPath:r.clangdPathFor(i),arktsLangServerCandidates:[{root:A.join(e,"arkts-lsp","lib"),marker:A.join(e,"arkts-lsp","lib","out","index.js")}],codelinterCandidates:r.codelinterCandidatesFor(e,"clt")}}static buildStudioToolPaths(e){let t=nt.platform()==="darwin",n=nt.platform()==="win32",i=t?A.join(e,"Contents"):e,o=A.join(i,"tools"),s=A.join(i,"sdk"),a=n?".exe":"";return{nodePath:n?A.join(o,"node","node.exe"):A.join(o,"node","bin","node"),ohpmJsPath:A.join(o,"ohpm","bin","pm-cli.js"),hvigorJsPath:A.join(o,"hvigor","bin","hvigorw.js"),javaPath:n?A.join(e,"jbr","bin","java.exe"):t?A.join(i,"jbr","Contents","Home","bin","java"):A.join(i,"jbr","bin","java"),sdkPath:s,hdcPath:A.join(s,"default","openharmony","toolchains",`hdc${a}`),emulatorPath:A.join(o,"emulator",n?"Emulator.exe":"Emulator"),clangdPath:r.clangdPathFor(s),arktsLangServerCandidates:r.studioArktsLangServerCandidates(e),codelinterCandidates:r.codelinterCandidatesFor(e,"studio")}}static codelinterCandidatesFor(e,t){if(t==="clt")return[A.join(e,"codelinter","index.js"),A.join(e,"codelinter","run","index.js"),A.join(e,"tool","codelinter","bin","codelinter.js"),A.join(e,"tool","codelinter","codelinter.js")];let n=nt.platform()==="darwin"?["Contents"]:[];return[A.join(e,...n,"plugins","codelinter","run","index.js"),A.join(e,...n,"plugins","codelinter","index.js"),A.join(e,...n,"tools","codelinter","bin","codelinter.js"),A.join(e,...n,"tools","codelinter","codelinter.js")]}static studioArktsLangServerCandidates(e){if(nt.platform()==="linux")return[];let t=nt.platform()==="darwin"?["Contents"]:[],n=A.join(e,...t,"plugins","openharmony");return[{root:n,marker:A.join(n,"ace-server","out","index.js")}]}static clangdPathFor(e){return A.join(e,"default","openharmony","native","llvm","bin",nt.platform()==="win32"?"clangd.exe":"clangd")}static isFile(e){try{return _e.statSync(e).isFile()}catch{return!1}}static isDirectory(e){try{return _e.existsSync(e)&&_e.statSync(e).isDirectory()}catch{return!1}}static resolveInstallSource(){return r.installSourcePromise||(r.installSourcePromise=r.resolveInstallSourceUncached()),r.installSourcePromise}static async resolveInstallSourceUncached(){let e=[["DEVECO_CLI_STUDIO_PATH","studio","studio"],["DEVECO_CLI_CLT_PATH","clt","clt"],["DEVECO_HOME","studio","studio"],["DEVECO_PATH","studio","studio"]];for(let[n,i,o]of e){let s=process.env[n]?.trim();if(s){let a=r.resolveExplicitRoot(s,i,n);return m(`[ToolProvider] Using ${n} \u2192 ${a}`),{sourceType:o,toolchainRoot:a}}}let t=await Fy();return m(`[ToolProvider] Using auto \u2192 ${t.root} (${t.version})`),{sourceType:"studio",toolchainRoot:t.root}}static resolveExplicitRoot(e,t,n){let i;try{i=uc(e)}catch(o){throw new Error(`Invalid ${n}: ${o instanceof Error?o.message:String(o)}`,{cause:o})}return t==="studio"&&nt.platform()==="darwin"&&(i=r.normalizeMacStudioRoot(i)),r.isValidRoot(i,t)?i:r.throwInvalidSource(i,t,n,e)}static assertBuiltPathsInsideRoot(e,t,n){let i=en(e),o=[["node",t.nodePath],["ohpm",t.ohpmJsPath],["hvigor",t.hvigorJsPath],["sdk",t.sdkPath],["hdc",t.hdcPath],["emulator",t.emulatorPath]];n&&t.javaPath&&o.push(["java",t.javaPath]);for(let[s,a]of o)r.assertInsideRoot(a,i,s)}static assertInsideRoot(e,t,n){if(Xh(e,t)===null)throw new Error(`Unsafe toolchain path: ${n} resolves outside the toolchain root`)}static throwInvalidSource(e,t,n,i){throw t==="clt"&&r.isValidRoot(e,"studio")?new Error(`${n} must point to Command Line Tools, not a DevEco Studio installation; use DEVECO_CLI_STUDIO_PATH instead`):t==="studio"&&r.isValidRoot(e,"clt")?new Error(`${n} must point to a DevEco Studio installation, not Command Line Tools; use DEVECO_CLI_CLT_PATH instead`):new Error(`Invalid ${n}: ${i}`)}static normalizeMacStudioRoot(e){let t=`${A.sep}Contents`,n=A.normalize(e);return n.endsWith(t)?n.slice(0,-t.length):n}static readCltVersion(e){try{return _e.readFileSync(A.join(e,"version.txt"),"utf-8").split(/\r?\n/).map(t=>t.match(PR)?.[1]?.trim()).find(Boolean)}catch{return}}static resolveCltJava(e){let t=process.env.JAVA_HOME?.trim(),i=[t&&(r.javaIn(A.join(t,"bin"))??r.javaIn(t)),...r.locateJavaFromPath()].filter(o=>!!o);if(!e)return i[0]?_e.realpathSync(i[0]):"";for(let o of i)if(r.isUsableJava(o))return _e.realpathSync(o);throw new Error("No Java runtime found in CLT mode. Set JAVA_HOME to a JDK/JBR installation directory (or point JAVA_HOME at the JDK bin directory), or add the JDK bin directory to PATH.")}static locateJavaFromPath(){let e=nt.platform()==="win32",t=e?"where.exe":"which",n=e?["java"]:["-a","java"];m(`Executing: ${t} ${n.join(" ")}`);let i=jy(t,n,{encoding:"utf8",stdio:"pipe",timeout:2e3,windowsHide:!0});return i.error||i.status!==0?[]:i.stdout.split(/\r?\n/).map(o=>o.trim()).filter(Boolean)}static javaIn(e){return(nt.platform()==="win32"?["java.exe","java.cmd"]:["java"]).map(n=>A.join(e,n)).find(_e.existsSync)}static isUsableJava(e){let t=["-version"];m(`Executing: ${e} ${t.join(" ")}`);let n=jy(e,t,{encoding:"utf8",stdio:"pipe",timeout:2e3,windowsHide:!0});return!n.error&&n.status===0}getMaxApiLevel(){for(let e of DR(this.sdkPath)){let t=kR(e);if(t!==void 0)return t}return 23}getSdkPlatformVersion(){let e=A.join(this.sdkPath,"default","sdk-pkg.json"),t;try{t=JSON.parse(_e.readFileSync(e,"utf8"))}catch(o){throw new Error(`Failed to read SDK metadata: ${e}`,{cause:o})}let n=t.data?.platformVersion,i=typeof n=="string"?n.trim():"";if(!i)throw new Error(`Missing data.platformVersion in SDK metadata: ${e}`);return i}detectApiLevel(){return this.getMaxApiLevel()}_apiscanPaths;getApiscanPaths(){if(this._apiscanPaths)return this._apiscanPaths;let e=nt.platform();if(e!=="darwin"&&e!=="win32")throw new Error(`Unsupported platform: ${e}. compat only supports macOS and Windows.`);if(!this._devecoStudioPath)throw new Error("DevEco Studio is required for compatibility checking. Set DEVECO_CLI_STUDIO_PATH or install DevEco Studio.");let t=e==="darwin"?"Contents":"",n=A.join(this._devecoStudioPath,t,"plugins","harmony","arkanalyzer-apiscan"),i=A.join(n,"resources","apiChange"),o=A.join(n,"api-change-scan.js");if(!_e.existsSync(i)||!_e.existsSync(o)){let s=on(this._toolchainRoot)??"unknown";throw new Error(`A required component is missing. The detected DevEco Studio version is ${s}. The minimum required version is ${CR}. Upgrade before using 'check compat' at ${cp}`)}return this._apiscanPaths={apiChangeDir:i,scriptPath:o},this._apiscanPaths}};import{execa as HR}from"execa";import*as qy from"net";import*as sn from"path";import*as Tc from"fs";import*as Oc from"os";import{execFile as Tp,spawn as Hy}from"child_process";import{existsSync as RR,readdirSync as xR,readFileSync as AR}from"fs";var Ic="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",Ap,Ip="---MEMORY-SAMPLE-DELIMITER---";function By(){return Ap===void 0&&(Ap=RR(Ic)),Ap}function ft(r){return new Promise(e=>{let t=process.platform==="win32",n=t?"tasklist":"ps",i=t?["/fi",`PID eq ${r}`,"/fo","csv","/nh"]:["-o","rss=","-p",String(r)];m(`Executing: ${n} ${i.join(" ")}`),Tp(n,i,{timeout:5e3,windowsHide:!0},(o,s)=>{if(o){e(null);return}e(t?jR(s):FR(s))})})}async function IR(){return process.platform==="linux"?Ac():process.platform==="darwin"?TR():process.platform==="win32"?OR():[]}function Ac(){let r=[],e;try{e=xR("/proc")}catch{return r}for(let t of e){if(!/^\d+$/.test(t))continue;let n=Number(t);try{let i=AR(`/proc/${n}/status`,"utf8"),o=i.match(/VmRSS:\s+(\d+)\s+kB/),s=i.match(/^PPid:\s+(\d+)/m);if(!o||!s)continue;r.push({pid:n,ppid:Number(s[1]),rssBytes:Number(o[1])*1024})}catch{}}return r}function TR(){return new Promise(r=>{Tp("ps",["-ax","-o","pid=,ppid=,rss="],{timeout:5e3,windowsHide:!0},(e,t)=>{if(e){r([]);return}r(Wy(t))})})}function Wy(r){let e=[];for(let t of r.trim().split(`
22
- `)){let n=t.trim().split(/\s+/);if(n.length<3)continue;let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]);isNaN(i)||isNaN(o)||isNaN(s)||e.push({pid:i,ppid:o,rssBytes:s*1024})}return e}function OR(){return new Promise(r=>{if(!By()){r([]);return}Tp(Ic,["-NoProfile","-Command",'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId),$($_.ParentProcessId),$($_.WorkingSetSize)" }'],{timeout:5e3,windowsHide:!0},(t,n)=>{if(t){r([]);return}r(Vy(n))})})}function Vy(r){let e=[];for(let t of r.trim().split(`
23
- `)){let n=t.trim();if(!n)continue;let i=n.split(",");if(i.length<3)continue;let o=Number(i[0]),s=Number(i[1]),a=Number(i[2]);isNaN(o)||isNaN(s)||isNaN(a)||e.push({pid:o,ppid:s,rssBytes:a})}return e}function Gy(r,e){let t=new Map,n=new Map;for(let a of r){t.set(a.pid,a.rssBytes);let c=n.get(a.ppid);c?c.push(a.pid):n.set(a.ppid,[a.pid])}let i=0,o=new Set,s=[e];for(;s.length>0;){let a=s.shift();if(o.has(a))continue;o.add(a),i+=t.get(a)??0;let c=n.get(a);c&&s.push(...c)}return i}async function NR(r){let e=await IR();return Gy(e,r)}function MR(r){if(process.platform==="darwin"){let e=(r/1e3).toFixed(1),t=`while true; do ps -ax -o pid=,ppid=,rss=; echo '${Ip}'; sleep ${e}; done`;return m(`Executing: sh -c ${t}`),Hy("sh",["-c",t],{stdio:["ignore","pipe","ignore"],windowsHide:!0})}if(process.platform==="win32"&&By()){let e=`while ($true) { Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId),$($_.ParentProcessId),$($_.WorkingSetSize)" }; Write-Output '${Ip}'; Start-Sleep -Milliseconds ${r} }`;return m(`Executing: ${Ic} -NoProfile -Command ${e}`),Hy(Ic,["-NoProfile","-Command",e],{stdio:["ignore","pipe","ignore"],windowsHide:!0})}return null}function ae(r){return`${(r/1024/1024).toFixed(2)}MB`}async function Uy(r,e){if(!r)return process.memoryUsage().rss;if(e)return NR(r);let t=await ft(r);return t?Number(t)*1024:0}function qi(r,e=2e3,t=!1){let n=0,i=!1,o=a=>{if(i||!r)return;let c=t?Gy(a,r):a.find(l=>l.pid===r)?.rssBytes??0;c>n&&(n=c)};if(!r)return _R(e);if(process.platform==="linux")return $R(e,o,()=>n);let s=MR(e);return s?(LR(s,o),{stop:async()=>{i=!0;try{s.kill()}catch{}let a=await Uy(r,t);return Math.max(n,a)}}):{stop:async()=>{i=!0;let a=await Uy(r,t);return Math.max(n,a)}}}function LR(r,e){let t=process.platform==="darwin"?Wy:Vy,n="";r.stdout?.on("data",i=>{n+=i.toString();let o=n.split(Ip);n=o.pop()??"";for(let s of o)e(t(s))}),r.on("error",()=>{})}function _R(r){let e=process.memoryUsage().rss,t=setInterval(()=>{let n=process.memoryUsage().rss;n>e&&(e=n)},r);return{stop:async()=>(clearInterval(t),Math.max(e,process.memoryUsage().rss))}}function $R(r,e,t){e(Ac());let n=setInterval(()=>e(Ac()),r);return{stop:async()=>(clearInterval(n),e(Ac()),t())}}function FR(r){let e=r.trim().match(/^(\d+)$/);return e?e[1]:null}function jR(r){let e=r.match(/"([^"]+?)\s*K"/i);return e&&e[1].replace(/\D/g,"")||null}var Nc="module",gt=class{toolProvider;projectRoot;env;silent;constructor(e,t,n=!1){this.toolProvider=e,this.projectRoot=t,this.silent=n;let i=sn.dirname(e.javaPath),o=`${i}${sn.delimiter}${process.env.PATH||""}`,s={...process.env,PATH:o,DEVECO_SDK_HOME:e.sdkPath},a=Oc.platform()==="darwin"&&e.javaPath==="/usr/bin/java";e.sourceType==="clt"&&e.javaPath&&!a&&(s.JAVA_HOME=sn.dirname(i)),this.env=s}async sync(e,t){let n=["--sync","-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(n)}async buildProduct(e,t){let n=["assembleApp","-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(n)}async buildModules(e,t,n,i){let o=[...Array.from(i),"--mode","module","-p",`module=${n.join(",")}`,"-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(o)}async clean(e,t){let n=["clean","--mode",e??Nc];return t&&t.length>0&&n.push("-p",`module=${t.join(",")}`),this.runHvigor(n)}async stopDaemon(){return this.runHvigor(["--stop-daemon"])}async ensureDaemonRunning(){if(this.findProjectDaemon()){m("[HvigorAdapter] Daemon already running.");return}m("[HvigorAdapter] No daemon running, starting via --sync --daemon (no hap build)."),await this.runHvigor(["--sync","--daemon"])}isDaemonRunning(e){return this.findProjectDaemon(e)!==null}async isDaemonAlive(e){let t=this.findProjectDaemon(e);return t?this.isPortListening(t.port):!1}isPortListening(e){return new Promise(t=>{let n=new qy.Socket;n.setTimeout(2e3),n.once("connect",()=>{n.destroy(),t(!0)}),n.once("error",()=>t(!1)),n.once("timeout",()=>{n.destroy(),t(!1)}),n.connect(e,"127.0.0.1")})}findProjectDaemon(e){let t=this.getDaemonRegistryPath();if(!Tc.existsSync(t))return null;try{let n=Tc.readFileSync(t,"utf-8"),i=JSON.parse(n),o=e??this.projectRoot,s=Object.values(i).filter(a=>a.cwdPath===o&&(a.state==="idle"||a.state==="half_busy"||a.state==="busy")&&this.isProcessAlive(a.pid));return s.length>0?s[s.length-1]:null}catch{return null}}getDaemonRegistryPath(){let e=process.env.HVIGOR_USER_HOME||sn.join(Oc.homedir(),".hvigor");return sn.join(e,"daemon","cache","daemon-sec.json")}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}async compileNative(e,t){let n=["--mode","module"];return t&&n.push("-p",`module=${t}`),n.push("-p",`product=${e}`,"compileNative"),this.runHvigor(n)}async runHvigor(e){let t=this.toolProvider.nodePath,n=[this.toolProvider.hvigorJsPath,...e];m(`Executing: ${t} ${n.join(" ")}`);let i=this.silent&&!process.env.DEVECO_CLI_DEBUG?"pipe":"inherit",o=HR(t,n,{cwd:this.projectRoot,env:this.env,stdout:i,stderr:i}),s=Qe()?void 0:qi(o.pid,2e3,!0),a="";try{await o}finally{if(s){let c=await s.stop();c>0&&(a=ae(c),m(`Hvigor peak memory: ${a}`))}}return a}};import{execa as UR}from"execa";var zi=class{toolProvider;projectRoot;peakMemoryMb="";constructor(e,t){this.toolProvider=e,this.projectRoot=t}async install(){let e=this.toolProvider.nodePath,t=[this.toolProvider.ohpmJsPath,"install"];m(`Executing: ${e} ${t.join(" ")}`);let n=UR(e,t,{cwd:this.projectRoot,env:{...process.env,DEVECO_SDK_HOME:this.toolProvider.sdkPath},stdout:"inherit",stderr:"inherit"}),i=Qe()?void 0:qi(n.pid,2e3,!1);try{await n}finally{if(i){let o=await i.stop();o>0&&(this.peakMemoryMb=ae(o))}}}};import{mkdir as BR}from"fs/promises";import{dirname as WR,resolve as VR}from"path";import{execa as GR}from"execa";import{lock as Op,check as tz}from"proper-lockfile";function Np(r){return VR(r,".hvigor",".build-lock")}function qR(r){let e=!1;return()=>{e||(e=!0,r?.())}}async function zy(r){let e=WR(Np(r));if(await BR(e,{recursive:!0}),process.platform==="win32")try{await GR("attrib",["+h",e])}catch{}}async function zR(r,e){let t=new AbortController,n=qR(e);await zy(r);let i={lockfilePath:Np(r),realpath:!1,stale:5e3,update:2e3,onCompromised:()=>t.abort()};try{return{release:await Op(r,{...i,retries:0}),signal:t.signal}}catch(s){if(s&&typeof s=="object"&&"code"in s&&s.code!=="ELOCKED")throw s}return n(),{release:await Op(r,{...i,retries:{forever:!0,minTimeout:1e3,maxTimeout:1e3}}),signal:t.signal}}async function xr(r,e,t){let{release:n,signal:i}=await zR(r,t);try{return await e(i)}finally{await n()}}async function Mc(r,e){let t=new AbortController;await zy(r);let n={lockfilePath:Np(r),realpath:!1,stale:5e3,update:2e3,onCompromised:()=>t.abort()},i;try{i=await Op(r,{...n,retries:0})}catch(o){if(o&&typeof o=="object"&&"code"in o&&o.code==="ELOCKED")return{acquired:!1};throw o}try{return{acquired:!0,result:await e(t.signal)}}finally{await i()}}import ys from"fs";import*as q from"path";import Jy from"fs";import*as Yy from"path";import JR from"json5";function YR(r,e){try{let n=JR.parse(Jy.readFileSync(r,"utf-8")).modules?.find(i=>i.name===e);return n?.srcPath?n.srcPath.replace(/^\.\//,""):null}catch(t){return m(`[apply] resolveModuleSrcPath fallback (module=${e}): ${t.message}`),null}}function jt(r,e){let t=Yy.join(r,"build-profile.json5");return Jy.existsSync(t)?YR(t,e)??e:e}var cr=class r{static generate(e,t,n,i){let o=jt(e,t),s=q.join(e,o),a=q.join(s,"build","config"),c=r.buildConfig(e,s,n,i);ys.mkdirSync(a,{recursive:!0}),ys.writeFileSync(q.join(a,"buildConfig.json"),JSON.stringify(c,null,2),"utf-8"),m(`[BuildConfigManager] buildConfig.json written to ${a}`);let l=q.join(s,"build",n,"intermediates","loader_out",n,"ets");ys.mkdirSync(l,{recursive:!0})}static remove(e,t){let n=jt(e,t),i=q.join(e,n,"build","config","buildConfig.json");ys.existsSync(i)&&(ys.unlinkSync(i),m(`[BuildConfigManager] buildConfig.json removed: ${i}`))}static removeAll(e){for(let t of e.profile.modules)r.remove(e.rootDir,t.name)}static async withBuildConfig(e,t,n,i,o){for(let s of t)r.generate(e,s,n,i);try{return await o()}finally{for(let s of t)r.remove(e,s)}}static buildConfig(e,t,n,i){let o=q.dirname(i.nodePath)+q.sep,s=q.join(t,"build",n),a=q.join(s,"intermediates"),c=q.join(a,"loader_out",n),l=q.join(a,"res",n);return{compileConfig:{deviceType:"default",buildMode:"debug",compilerType:"ark",note:"false",logLevel:"3",hapMode:"false",img2bin:"true",Path:o,projectProfilePath:q.join(e,"build-profile.json5"),localPropertiesPath:q.join(e,"local.properties"),appResource:q.join(l,"ResourceTable.txt"),cachePath:q.join(s,"cache",n,`${n}@CompileArkTS`,"esmodule","debug"),aceBuildJson:q.join(a,"loader",n,"loader.json"),aceModuleJsonPath:q.join(l,"module.json"),aceSoPath:q.join(c,"nativeDependencies.txt"),aceModuleRoot:q.join(t,"src","main","ets"),aceModuleBuild:q.join(c,"ets"),aceProfilePath:q.join(l,"resources","base","profile"),aceSuperVisualPath:q.join(t,"src","main","supervisual"),watchMode:"true"},patchConfig:{enableMap:"false",mode:"hotReload",oldMapFilePath:q.join(c,"ets"),changedFileList:q.join(a,"patch",n,"changedFileList.json"),patchAbcPath:q.join(a,"patch",n,"ets"),removeChangedFileListInSdk:"true"}}}};import*as Ar from"fs";import*as lr from"path";import KR from"json5";var XR=1e3;function Ji(r,e,t){let n=ZR(r,e,t);return n.required?(m(`[ProjectCheck] ${t} check: ${n.reason}`),n):null}function Lc(r){m(`[ProjectCheck] Checking sync required at project root: ${r}`);let e=lr.join(r,Pe.SYNC_OUTPUT_PATH);if(!Ar.existsSync(e)){let a={required:!0,reason:`sync baseline file not found: ${e}`};return m(`[ProjectCheck] ${a.reason}`),a}let t=Ar.statSync(e).mtimeMs,n=lr.join(r,Pe.LOCK_JSON5_PATH);if(!Ar.existsSync(n)){let a={required:!0,reason:`oh_modules lock not found: ${n}`};return m(`[ProjectCheck] ${a.reason}`),a}let i=QR(r);if(i===null)return{required:!0,reason:"failed to parse build-profile.json5"};let o=Ji(lr.join(r,Pe.OH_PACKAGE_JSON5),t,"root");if(o||(o=Ji(lr.join(r,Pe.BUILD_PROFILE_JSON5),t,"build-profile"),o)||(o=Ji(lr.join(r,Pe.HVIGOR_CONFIG),t,"hvigor-config"),o)||(o=Ji(lr.join(r,Pe.HVIGOR_CONFIG),t,"hvigor-config"),o))return o;for(let a of i)if(o=Ji(lr.join(r,a.srcPath,Pe.OH_PACKAGE_JSON5),t,a.name),o||(o=Ji(lr.join(r,a.srcPath,Pe.BUILD_PROFILE_JSON5),t,a.name),o))return o;let s=`all configuration files are up-to-date (sync baseline: ${new Date(t).toISOString()})`;return m(`[ProjectCheck] ${s}`),{required:!1,reason:s}}function ZR(r,e,t){if(!Ar.existsSync(r))return{required:!1,reason:`${t}: source not found, skip`};let n=Ar.statSync(r).mtimeMs;return n-e>XR?{required:!0,reason:`${t}: source mtime (${new Date(n).toISOString()}) is newer than sync baseline (${new Date(e).toISOString()})`}:{required:!1,reason:`${t}: up-to-date`}}function QR(r){let e=lr.join(r,Pe.BUILD_PROFILE_JSON5);try{let t=Ar.readFileSync(e,"utf-8");if(!t.trim())return null;let n=KR.parse(t);if(typeof n!="object"||n===null)return null;let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):null}catch{return null}}import*as Z from"fs";import*as z from"path";import*as Ky from"util";var Mp="";function $c(r){if(!r||r==="auto"||r==="stdout"||r==="none"){Mp="";return}Mp=r}function Xy(){return Mp||(Nh()??"")}function _c(r,...e){if(e.length===0)return r;try{return Ky.format(r,...e)}catch{return[r,...e.map(t=>typeof t=="string"?t:JSON.stringify(t))].join(" ")}}var f={info(r,...e){h.info(`[lsp] ${_c(r,...e)}`)},warn(r,...e){h.warn(`[lsp] ${_c(r,...e)}`)},error(r,...e){h.error(`[lsp] ${_c(r,...e)}`)},debug(r,...e){h.debug(`[lsp] ${_c(r,...e)}`)}};import*as ws from"fs";import*as vs from"os";import*as Ki from"path";import ex from"json5";var b={INITIALIZE:"initialize",INITIALIZED:"initialized",SHUTDOWN:"shutdown",EXIT:"exit",DID_OPEN:"textDocument/didOpen",DID_CHANGE:"textDocument/didChange",DID_CLOSE:"textDocument/didClose",PUBLISH_DIAGNOSTICS:"textDocument/publishDiagnostics",HOVER:"textDocument/hover",DEFINITION:"textDocument/definition",DECLARATION:"textDocument/declaration",REFERENCES:"textDocument/references",IMPLEMENTATION:"textDocument/implementation",COMPLETION:"textDocument/completion",COMPLETION_ITEM_RESOLVE:"completionItem/resolve",SIGNATURE_HELP:"textDocument/signatureHelp",CODE_ACTION:"textDocument/codeAction",PREPARE_RENAME:"textDocument/prepareRename",RENAME:"textDocument/rename",DOCUMENT_HIGHLIGHT:"textDocument/documentHighlight",DOCUMENT_LINK:"textDocument/documentLink",INLAY_HINT:"textDocument/inlayHint",DOCUMENT_SYMBOL:"textDocument/documentSymbol",WORKSPACE_SYMBOL:"workspace/symbol",DIAGNOSTIC:"textDocument/diagnostic",WORKSPACE_DIAGNOSTIC:"workspace/diagnostic",PREPARE_CALL_HIERARCHY:"textDocument/prepareCallHierarchy",INCOMING_CALLS:"callHierarchy/incomingCalls",OUTGOING_CALLS:"callHierarchy/outgoingCalls",PREPARE_TYPE_HIERARCHY:"textDocument/prepareTypeHierarchy",SUPERTYPES:"typeHierarchy/supertypes",SUBTYPES:"typeHierarchy/subtypes",WORKSPACE_DID_CHANGE_CONFIGURATION:"workspace/didChangeConfiguration",WORKSPACE_DID_CHANGE_WATCHED_FILES:"workspace/didChangeWatchedFiles",DID_CREATE_FILES:"workspace/didCreateFiles",DID_DELETE_FILES:"workspace/didDeleteFiles",PROGRESS:"$/progress",WINDOW_SHOW_MESSAGE:"window/showMessage",WINDOW_LOG_MESSAGE:"window/logMessage",ARKTS_INITIALIZED:"arkts/initialized",ARKTS_INITIALIZATION_FAILED:"arkts/initializationFailed",ARKTS_INDEXING_PROGRESS:"arkts/indexingProgress",ARKTS_SYNC_PROJECT:"arkts/syncProject",ARKTS_SYNC_COMPLETED:"arkts/syncCompleted",ARKTS_REINITIALIZING:"arkts/reinitializing",ARKTS_ERROR:"arkts/error",CPP_INITIALIZED:"cpp/initialized",CPP_INITIALIZATION_FAILED:"cpp/initializationFailed",CPP_INDEXING_PROGRESS:"cpp/indexingProgress",CPP_SYNC_PROJECT:"cpp/syncProject",CPP_SYNC_COMPLETED:"cpp/syncCompleted",CPP_REINITIALIZING:"cpp/reinitializing",CPP_ERROR:"cpp/error",BROADCAST:"lsp/broadcast"},L="2.0",Yi={MODULE_INIT_FINISH:"aceProject/onModuleInitFinish",INDEXING_PROGRESS_UPDATE:"aceProject/onIndexingProgressUpdate"};var Zy=8192,Lp=100,Qy=.03,ew=.7,it=900*1e3;function ht(r){if(!ws.existsSync(r))return null;try{let e=ws.readFileSync(r,"utf-8");return e.trim()?ex.parse(e):null}catch{return null}}function Fc(r,e){let t=Math.floor(vs.totalmem()/1048576),n=Math.floor(t*ew),i,o;e!==void 0&&Number.isFinite(e)&&e>0?(i=e,o=`override(${e})`):(i=Zy,r>Lp&&(i+=(r-Lp)*Qy*1024),o=`formula(moduleCount=${r})`);let s=n>0&&i>n;s&&(i=n);let a=Math.round(i);return f.info(`[computeLspServerMaxSize] source=${o}, physicalTotal=${t}MB, physicalCap(70%)=${n}MB, finalSize=${a}MB${s?" (capped)":""}`),a}function Ht(r){if(r.startsWith("file:"))return r;try{let e=Ki.resolve(r),t=new URL(`file://${e}`).toString();if(vs.platform()==="win32"){let n=t.match(/^file:\/\/\/([A-Za-z]):/);if(n){let i=n[1].toUpperCase(),o=t.substring(`file:///${n[1]}:`.length);t=`file:///${i}%3A${o}`}}return t}catch{return r}}function Xi(r){return r&&r.replace(/\\/g,"/")}function ge(r){let e=Ki.normalize(r).replace(/\\/g,"/");if(vs.platform()==="win32"){let t=e.match(/^([A-Za-z]):/);t&&(e=`${t[1].toUpperCase()}:${e.substring(2)}`)}return e}function Zn(r){return r||process.execPath||"node"}function bs(r){let e=ge(r.lspLogPath),t=["--expose-gc",`--max-old-space-size=${r.serverMaxSize}`,"--report-on-fatalerror","--report-uncaught-exception",`--report-filename=nodejs_error_${Date.now()}.txt`,`--report-dir=${e}`,r.serverPath,r.transportFlag??"--stdio",`--logger-path=${e}`,"--logger-level=TRACE"];return r.projectPath&&t.push(`--projectPath=${ge(r.projectPath)}`),r.sdkPath&&t.push(`--sdkPath=${ge(r.sdkPath)}`),t}function tw(r){return Ki.join(r,"build-profile.json5")}var Ir=class{constructor(e){this.projectRoot=e}getAllModuleInfo(){let e=tw(this.projectRoot);try{let t=ht(e);if(typeof t!="object"||t===null)return[];let n=t.modules;return Array.isArray(n)?n.filter(i=>{if(typeof i!="object"||i===null)return!1;let o=i;return typeof o.name=="string"&&typeof o.srcPath=="string"}):[]}catch(t){return f.warn(`[ConfigFileWatcher] Failed to parse build-profile.json5: ${t instanceof Error?t.message:String(t)}`),[]}}};import{spawn as tx}from"child_process";import*as Hc from"fs";var rx=600*1e3;function nx(r,e,t){let n=t.split(/\s+/).filter(i=>i.length>0);return[r,[e,...n]]}function ix(r,e){let t=[],n=[],i="",o="";return r.stdout?.on("data",s=>{let a=s.toString();t.push(a),i=rw(i+a,e)}),r.stderr?.on("data",s=>{let a=s.toString();n.push(a),o=rw(o+a,c=>{f.info("[hvigor:err] %s",c),e?.(c)})}),{stdout:t,stderr:n,flush:()=>{i&&e?.(i),o&&(f.info("[hvigor:err] %s",o),e?.(o))}}}function rw(r,e){let t=r.split(/\r?\n/),n=t.pop()??"";for(let i of t)i&&e?.(i);return n}function jc(r){return r.join("")}function ox(r,e,t){if(e)return{success:!1,output:"Build process killed by signal "+e+`.
21
+ `)}`,a)}let o=nn(e),s=nn(i);return r.assertInsideRoot(s,o,"codelinter"),s}static isValidRoot(e,t){if(!r.isDirectory(e))return!1;if(t==="clt")return Fe.existsSync(I.join(e,"version.txt"));let n=it.platform()==="darwin"?I.join(e,"Contents"):e,i=it.platform()==="darwin"?I.join(n,"Info.plist"):I.join(n,"product-info.json");if(!Fe.existsSync(i))return!1;let o=r.buildToolPaths(e,"studio");return[o.nodePath,o.ohpmJsPath,o.hvigorJsPath].every(Fe.existsSync)}static buildToolPaths(e,t){return t==="clt"?r.buildCltToolPaths(e):r.buildStudioToolPaths(e)}static buildCltToolPaths(e){let t=it.platform()==="win32",n=t?".exe":"",i=I.join(e,"sdk");return{nodePath:t?I.join(e,"tool","node","node.exe"):I.join(e,"tool","node","bin","node"),ohpmJsPath:I.join(e,"ohpm","bin","pm-cli.js"),hvigorJsPath:I.join(e,"hvigor","bin","hvigorw.js"),javaPath:"",sdkPath:i,hdcPath:I.join(i,"default","openharmony","toolchains",`hdc${n}`),emulatorPath:I.join(e,"emulator",t?"Emulator.exe":"Emulator"),clangdPath:r.clangdPathFor(i),arktsLangServerCandidates:[{root:I.join(e,"arkts-lsp","lib"),marker:I.join(e,"arkts-lsp","lib","out","index.js")}],codelinterCandidates:r.codelinterCandidatesFor(e,"clt")}}static buildStudioToolPaths(e){let t=it.platform()==="darwin",n=it.platform()==="win32",i=t?I.join(e,"Contents"):e,o=I.join(i,"tools"),s=I.join(i,"sdk"),a=n?".exe":"";return{nodePath:n?I.join(o,"node","node.exe"):I.join(o,"node","bin","node"),ohpmJsPath:I.join(o,"ohpm","bin","pm-cli.js"),hvigorJsPath:I.join(o,"hvigor","bin","hvigorw.js"),javaPath:n?I.join(e,"jbr","bin","java.exe"):t?I.join(i,"jbr","Contents","Home","bin","java"):I.join(i,"jbr","bin","java"),sdkPath:s,hdcPath:I.join(s,"default","openharmony","toolchains",`hdc${a}`),emulatorPath:I.join(o,"emulator",n?"Emulator.exe":"Emulator"),clangdPath:r.clangdPathFor(s),arktsLangServerCandidates:r.studioArktsLangServerCandidates(e),codelinterCandidates:r.codelinterCandidatesFor(e,"studio")}}static codelinterCandidatesFor(e,t){if(t==="clt")return[I.join(e,"codelinter","index.js"),I.join(e,"codelinter","run","index.js"),I.join(e,"tool","codelinter","bin","codelinter.js"),I.join(e,"tool","codelinter","codelinter.js")];let n=it.platform()==="darwin"?["Contents"]:[];return[I.join(e,...n,"plugins","codelinter","run","index.js"),I.join(e,...n,"plugins","codelinter","index.js"),I.join(e,...n,"tools","codelinter","bin","codelinter.js"),I.join(e,...n,"tools","codelinter","codelinter.js")]}static studioArktsLangServerCandidates(e){if(it.platform()==="linux")return[];let t=it.platform()==="darwin"?["Contents"]:[],n=I.join(e,...t,"plugins","openharmony");return[{root:n,marker:I.join(n,"ace-server","out","index.js")}]}static clangdPathFor(e){return I.join(e,"default","openharmony","native","llvm","bin",it.platform()==="win32"?"clangd.exe":"clangd")}static isFile(e){try{return Fe.statSync(e).isFile()}catch{return!1}}static isDirectory(e){try{return Fe.existsSync(e)&&Fe.statSync(e).isDirectory()}catch{return!1}}static resolveInstallSource(){return r.installSourcePromise||(r.installSourcePromise=r.resolveInstallSourceUncached()),r.installSourcePromise}static async resolveInstallSourceUncached(){let e=[["DEVECO_CLI_STUDIO_PATH","studio","studio"],["DEVECO_CLI_CLT_PATH","clt","clt"],["DEVECO_HOME","studio","studio"],["DEVECO_PATH","studio","studio"]];for(let[n,i,o]of e){let s=process.env[n]?.trim();if(s){let a=r.resolveExplicitRoot(s,i,n);return f(`[ToolProvider] Using ${n} \u2192 ${a}`),{sourceType:o,toolchainRoot:a}}}let t=await Tw();return f(`[ToolProvider] Using auto \u2192 ${t.root} (${t.version})`),{sourceType:"studio",toolchainRoot:t.root}}static resolveExplicitRoot(e,t,n){let i;try{i=Ic(e)}catch(o){throw new Error(`Invalid ${n}: ${o instanceof Error?o.message:String(o)}`,{cause:o})}return t==="studio"&&it.platform()==="darwin"&&(i=r.normalizeMacStudioRoot(i)),r.isValidRoot(i,t)?i:r.throwInvalidSource(i,t,n,e)}static assertBuiltPathsInsideRoot(e,t,n){let i=nn(e),o=[["node",t.nodePath],["ohpm",t.ohpmJsPath],["hvigor",t.hvigorJsPath],["sdk",t.sdkPath],["hdc",t.hdcPath],["emulator",t.emulatorPath]];n&&t.javaPath&&o.push(["java",t.javaPath]);for(let[s,a]of o)r.assertInsideRoot(a,i,s)}static assertInsideRoot(e,t,n){if(Vy(e,t)===null)throw new Error(`Unsafe toolchain path: ${n} resolves outside the toolchain root`)}static throwInvalidSource(e,t,n,i){throw t==="clt"&&r.isValidRoot(e,"studio")?new Error(`${n} must point to Command Line Tools, not a DevEco Studio installation; use DEVECO_CLI_STUDIO_PATH instead`):t==="studio"&&r.isValidRoot(e,"clt")?new Error(`${n} must point to a DevEco Studio installation, not Command Line Tools; use DEVECO_CLI_CLT_PATH instead`):new Error(`Invalid ${n}: ${i}`)}static normalizeMacStudioRoot(e){let t=`${I.sep}Contents`,n=I.normalize(e);return n.endsWith(t)?n.slice(0,-t.length):n}static readCltVersion(e){try{return Fe.readFileSync(I.join(e,"version.txt"),"utf-8").split(/\r?\n/).map(t=>t.match(tI)?.[1]?.trim()).find(Boolean)}catch{return}}static resolveCltJava(e){let t=process.env.JAVA_HOME?.trim(),i=[t&&(r.javaIn(I.join(t,"bin"))??r.javaIn(t)),...r.locateJavaFromPath()].filter(o=>!!o);if(!e)return i[0]?Fe.realpathSync(i[0]):"";for(let o of i)if(r.isUsableJava(o))return Fe.realpathSync(o);throw new Error("No Java runtime found in CLT mode. Set JAVA_HOME to a JDK/JBR installation directory (or point JAVA_HOME at the JDK bin directory), or add the JDK bin directory to PATH.")}static locateJavaFromPath(){let e=it.platform()==="win32",t=e?"where.exe":"which",n=e?["java"]:["-a","java"];f(`Executing: ${t} ${n.join(" ")}`);let i=Nw(t,n,{encoding:"utf8",stdio:"pipe",timeout:2e3,windowsHide:!0});return i.error||i.status!==0?[]:i.stdout.split(/\r?\n/).map(o=>o.trim()).filter(Boolean)}static javaIn(e){return(it.platform()==="win32"?["java.exe","java.cmd"]:["java"]).map(n=>I.join(e,n)).find(Fe.existsSync)}static isUsableJava(e){let t=["-version"];f(`Executing: ${e} ${t.join(" ")}`);let n=Nw(e,t,{encoding:"utf8",stdio:"pipe",timeout:2e3,windowsHide:!0});return!n.error&&n.status===0}getMaxApiLevel(){for(let e of iI(this.sdkPath)){let t=nI(e);if(t!==void 0)return t}return 23}getSdkPlatformVersion(){let e=I.join(this.sdkPath,"default","sdk-pkg.json"),t;try{t=JSON.parse(Fe.readFileSync(e,"utf8"))}catch(o){throw new Error(`Failed to read SDK metadata: ${e}`,{cause:o})}let n=t.data?.platformVersion,i=typeof n=="string"?n.trim():"";if(!i)throw new Error(`Missing data.platformVersion in SDK metadata: ${e}`);return i}detectApiLevel(){return this.getMaxApiLevel()}_apiscanPaths;getApiscanPaths(){if(this._apiscanPaths)return this._apiscanPaths;let e=it.platform();if(e!=="darwin"&&e!=="win32")throw new Error(`Unsupported platform: ${e}. compat only supports macOS and Windows.`);if(!this._devecoStudioPath)throw new Error("DevEco Studio is required for compatibility checking. Set DEVECO_CLI_STUDIO_PATH or install DevEco Studio.");let t=e==="darwin"?"Contents":"",n=I.join(this._devecoStudioPath,t,"plugins","harmony","arkanalyzer-apiscan"),i=I.join(n,"resources","apiChange"),o=I.join(n,"api-change-scan.js");if(!Fe.existsSync(i)||!Fe.existsSync(o)){let s=cn(this._toolchainRoot)??"unknown";throw new Error(`A required component is missing. The detected DevEco Studio version is ${s}. The minimum required version is ${rI}. Upgrade before using 'check compat' at ${jp}`)}return this._apiscanPaths={apiChangeDir:i,scriptPath:o},this._apiscanPaths}};import{execa as wI}from"execa";import*as jw from"net";import*as ln from"path";import*as Kc from"fs";import*as Yc from"os";import{execFile as lf,spawn as Ow}from"child_process";import{existsSync as oI,readdirSync as sI,readFileSync as aI}from"fs";var Jc="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",af,cf="---MEMORY-SAMPLE-DELIMITER---";function Mw(){return af===void 0&&(af=oI(Jc)),af}function gt(r){return new Promise(e=>{let t=process.platform==="win32",n=t?"tasklist":"ps",i=t?["/fi",`PID eq ${r}`,"/fo","csv","/nh"]:["-o","rss=","-p",String(r)];f(`Executing: ${n} ${i.join(" ")}`),lf(n,i,{timeout:5e3,windowsHide:!0},(o,s)=>{if(o){e(null);return}e(t?yI(s):hI(s))})})}async function cI(){return process.platform==="linux"?zc():process.platform==="darwin"?lI():process.platform==="win32"?dI():[]}function zc(){let r=[],e;try{e=sI("/proc")}catch{return r}for(let t of e){if(!/^\d+$/.test(t))continue;let n=Number(t);try{let i=aI(`/proc/${n}/status`,"utf8"),o=i.match(/VmRSS:\s+(\d+)\s+kB/),s=i.match(/^PPid:\s+(\d+)/m);if(!o||!s)continue;r.push({pid:n,ppid:Number(s[1]),rssBytes:Number(o[1])*1024})}catch{}}return r}function lI(){return new Promise(r=>{lf("ps",["-ax","-o","pid=,ppid=,rss="],{timeout:5e3,windowsHide:!0},(e,t)=>{if(e){r([]);return}r(Lw(t))})})}function Lw(r){let e=[];for(let t of r.trim().split(`
22
+ `)){let n=t.trim().split(/\s+/);if(n.length<3)continue;let i=Number(n[0]),o=Number(n[1]),s=Number(n[2]);isNaN(i)||isNaN(o)||isNaN(s)||e.push({pid:i,ppid:o,rssBytes:s*1024})}return e}function dI(){return new Promise(r=>{if(!Mw()){r([]);return}lf(Jc,["-NoProfile","-Command",'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId),$($_.ParentProcessId),$($_.WorkingSetSize)" }'],{timeout:5e3,windowsHide:!0},(t,n)=>{if(t){r([]);return}r(Fw(n))})})}function Fw(r){let e=[];for(let t of r.trim().split(`
23
+ `)){let n=t.trim();if(!n)continue;let i=n.split(",");if(i.length<3)continue;let o=Number(i[0]),s=Number(i[1]),a=Number(i[2]);isNaN(o)||isNaN(s)||isNaN(a)||e.push({pid:o,ppid:s,rssBytes:a})}return e}function $w(r,e){let t=new Map,n=new Map;for(let a of r){t.set(a.pid,a.rssBytes);let c=n.get(a.ppid);c?c.push(a.pid):n.set(a.ppid,[a.pid])}let i=0,o=new Set,s=[e];for(;s.length>0;){let a=s.shift();if(o.has(a))continue;o.add(a),i+=t.get(a)??0;let c=n.get(a);c&&s.push(...c)}return i}async function uI(r){let e=await cI();return $w(e,r)}function pI(r){if(process.platform==="darwin"){let e=(r/1e3).toFixed(1),t=`while true; do ps -ax -o pid=,ppid=,rss=; echo '${cf}'; sleep ${e}; done`;return f(`Executing: sh -c ${t}`),Ow("sh",["-c",t],{stdio:["ignore","pipe","ignore"],windowsHide:!0})}if(process.platform==="win32"&&Mw()){let e=`while ($true) { Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId),$($_.ParentProcessId),$($_.WorkingSetSize)" }; Write-Output '${cf}'; Start-Sleep -Milliseconds ${r} }`;return f(`Executing: ${Jc} -NoProfile -Command ${e}`),Ow(Jc,["-NoProfile","-Command",e],{stdio:["ignore","pipe","ignore"],windowsHide:!0})}return null}function ce(r){return`${(r/1024/1024).toFixed(2)}MB`}async function _w(r,e){if(!r)return process.memoryUsage().rss;if(e)return uI(r);let t=await gt(r);return t?Number(t)*1024:0}function to(r,e=2e3,t=!1){let n=0,i=!1,o=a=>{if(i||!r)return;let c=t?$w(a,r):a.find(l=>l.pid===r)?.rssBytes??0;c>n&&(n=c)};if(!r)return mI(e);if(process.platform==="linux")return gI(e,o,()=>n);let s=pI(e);return s?(fI(s,o),{stop:async()=>{i=!0;try{s.kill()}catch{}let a=await _w(r,t);return Math.max(n,a)}}):{stop:async()=>{i=!0;let a=await _w(r,t);return Math.max(n,a)}}}function fI(r,e){let t=process.platform==="darwin"?Lw:Fw,n="";r.stdout?.on("data",i=>{n+=i.toString();let o=n.split(cf);n=o.pop()??"";for(let s of o)e(t(s))}),r.on("error",()=>{})}function mI(r){let e=process.memoryUsage().rss,t=setInterval(()=>{let n=process.memoryUsage().rss;n>e&&(e=n)},r);return{stop:async()=>(clearInterval(t),Math.max(e,process.memoryUsage().rss))}}function gI(r,e,t){e(zc());let n=setInterval(()=>e(zc()),r);return{stop:async()=>(clearInterval(n),e(zc()),t())}}function hI(r){let e=r.trim().match(/^(\d+)$/);return e?e[1]:null}function yI(r){let e=r.match(/"([^"]+?)\s*K"/i);return e&&e[1].replace(/\D/g,"")||null}var Xc="module",ht=class{toolProvider;projectRoot;env;silent;constructor(e,t,n=!1){this.toolProvider=e,this.projectRoot=t,this.silent=n;let i=ln.dirname(e.javaPath),o=`${i}${ln.delimiter}${process.env.PATH||""}`,s={...process.env,PATH:o,DEVECO_SDK_HOME:e.sdkPath},a=Yc.platform()==="darwin"&&e.javaPath==="/usr/bin/java";e.sourceType==="clt"&&e.javaPath&&!a&&(s.JAVA_HOME=ln.dirname(i)),this.env=s}async sync(e,t){let n=["--sync","-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(n)}async buildProduct(e,t){let n=["assembleApp","-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(n)}async buildModules(e,t,n,i){let o=[...Array.from(i),"--mode","module","-p",`module=${n.join(",")}`,"-p",`product=${e}`,"-p",`buildMode=${t}`];return this.runHvigor(o)}async clean(e,t){let n=["clean","--mode",e??Xc];return t&&t.length>0&&n.push("-p",`module=${t.join(",")}`),this.runHvigor(n)}async stopDaemon(){return this.runHvigor(["--stop-daemon"])}async ensureDaemonRunning(){if(this.findProjectDaemon()){f("[HvigorAdapter] Daemon already running.");return}f("[HvigorAdapter] No daemon running, starting via --sync --daemon (no hap build)."),await this.runHvigor(["--sync","--daemon"])}isDaemonRunning(e){return this.findProjectDaemon(e)!==null}async isDaemonAlive(e){let t=this.findProjectDaemon(e);return t?this.isPortListening(t.port):!1}isPortListening(e){return new Promise(t=>{let n=new jw.Socket;n.setTimeout(2e3),n.once("connect",()=>{n.destroy(),t(!0)}),n.once("error",()=>t(!1)),n.once("timeout",()=>{n.destroy(),t(!1)}),n.connect(e,"127.0.0.1")})}findProjectDaemon(e){let t=this.getDaemonRegistryPath();if(!Kc.existsSync(t))return null;try{let n=Kc.readFileSync(t,"utf-8"),i=JSON.parse(n),o=e??this.projectRoot,s=Object.values(i).filter(a=>a.cwdPath===o&&(a.state==="idle"||a.state==="half_busy"||a.state==="busy")&&this.isProcessAlive(a.pid));return s.length>0?s[s.length-1]:null}catch{return null}}getDaemonRegistryPath(){let e=process.env.HVIGOR_USER_HOME||ln.join(Yc.homedir(),".hvigor");return ln.join(e,"daemon","cache","daemon-sec.json")}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}async compileNative(e,t){let n=["--mode","module"];return t&&n.push("-p",`module=${t}`),n.push("-p",`product=${e}`,"compileNative"),this.runHvigor(n)}async runHvigor(e){let t=this.toolProvider.nodePath,n=[this.toolProvider.hvigorJsPath,...e];f(`Executing: ${t} ${n.join(" ")}`);let i=this.silent&&!process.env.DEVECO_CLI_DEBUG?"pipe":"inherit",o=wI(t,n,{cwd:this.projectRoot,env:this.env,stdout:i,stderr:i}),s=et()?void 0:to(o.pid,2e3,!0),a="";try{await o}finally{if(s){let c=await s.stop();c>0&&(a=ce(c),f(`Hvigor peak memory: ${a}`))}}return a}};import{execa as vI}from"execa";var ro=class{toolProvider;projectRoot;peakMemoryMb="";constructor(e,t){this.toolProvider=e,this.projectRoot=t}async install(){let e=this.toolProvider.nodePath,t=[this.toolProvider.ohpmJsPath,"install"];f(`Executing: ${e} ${t.join(" ")}`);let n=vI(e,t,{cwd:this.projectRoot,env:{...process.env,DEVECO_SDK_HOME:this.toolProvider.sdkPath},stdout:"inherit",stderr:"inherit"}),i=et()?void 0:to(n.pid,2e3,!1);try{await n}finally{if(i){let o=await i.stop();o>0&&(this.peakMemoryMb=ce(o))}}}};import{mkdir as bI}from"fs/promises";import{dirname as SI,resolve as EI}from"path";import{execa as PI}from"execa";import{lock as df,check as NY}from"proper-lockfile";function uf(r){return EI(r,".hvigor",".build-lock")}function CI(r){let e=!1;return()=>{e||(e=!0,r?.())}}async function Hw(r){let e=SI(uf(r));if(await bI(e,{recursive:!0}),process.platform==="win32")try{await PI("attrib",["+h",e])}catch{}}async function kI(r,e){let t=new AbortController,n=CI(e);await Hw(r);let i={lockfilePath:uf(r),realpath:!1,stale:5e3,update:2e3,onCompromised:()=>t.abort()};try{return{release:await df(r,{...i,retries:0}),signal:t.signal}}catch(s){if(s&&typeof s=="object"&&"code"in s&&s.code!=="ELOCKED")throw s}return n(),{release:await df(r,{...i,retries:{forever:!0,minTimeout:1e3,maxTimeout:1e3}}),signal:t.signal}}async function Nr(r,e,t){let{release:n,signal:i}=await kI(r,t);try{return await e(i)}finally{await n()}}async function Zc(r,e){let t=new AbortController;await Hw(r);let n={lockfilePath:uf(r),realpath:!1,stale:5e3,update:2e3,onCompromised:()=>t.abort()},i;try{i=await df(r,{...n,retries:0})}catch(o){if(o&&typeof o=="object"&&"code"in o&&o.code==="ELOCKED")return{acquired:!1};throw o}try{return{acquired:!0,result:await e(t.signal)}}finally{await i()}}import Is from"fs";import*as q from"path";import Uw from"fs";import*as Bw from"path";import RI from"json5";function xI(r,e){try{let n=RI.parse(Uw.readFileSync(r,"utf-8")).modules?.find(i=>i.name===e);return n?.srcPath?n.srcPath.replace(/^\.\//,""):null}catch(t){return f(`[apply] resolveModuleSrcPath fallback (module=${e}): ${t.message}`),null}}function Bt(r,e){let t=Bw.join(r,"build-profile.json5");return Uw.existsSync(t)?xI(t,e)??e:e}var pr=class r{static generate(e,t,n,i){let o=Bt(e,t),s=q.join(e,o),a=q.join(s,"build","config"),c=r.buildConfig(e,s,n,i);Is.mkdirSync(a,{recursive:!0}),Is.writeFileSync(q.join(a,"buildConfig.json"),JSON.stringify(c,null,2),"utf-8"),f(`[BuildConfigManager] buildConfig.json written to ${a}`);let l=q.join(s,"build",n,"intermediates","loader_out",n,"ets");Is.mkdirSync(l,{recursive:!0})}static remove(e,t){let n=Bt(e,t),i=q.join(e,n,"build","config","buildConfig.json");Is.existsSync(i)&&(Is.unlinkSync(i),f(`[BuildConfigManager] buildConfig.json removed: ${i}`))}static removeAll(e){for(let t of e.profile.modules)r.remove(e.rootDir,t.name)}static async withBuildConfig(e,t,n,i,o){for(let s of t)r.generate(e,s,n,i);try{return await o()}finally{for(let s of t)r.remove(e,s)}}static buildConfig(e,t,n,i){let o=q.dirname(i.nodePath)+q.sep,s=q.join(t,"build",n),a=q.join(s,"intermediates"),c=q.join(a,"loader_out",n),l=q.join(a,"res",n);return{compileConfig:{deviceType:"default",buildMode:"debug",compilerType:"ark",note:"false",logLevel:"3",hapMode:"false",img2bin:"true",Path:o,projectProfilePath:q.join(e,"build-profile.json5"),localPropertiesPath:q.join(e,"local.properties"),appResource:q.join(l,"ResourceTable.txt"),cachePath:q.join(s,"cache",n,`${n}@CompileArkTS`,"esmodule","debug"),aceBuildJson:q.join(a,"loader",n,"loader.json"),aceModuleJsonPath:q.join(l,"module.json"),aceSoPath:q.join(c,"nativeDependencies.txt"),aceModuleRoot:q.join(t,"src","main","ets"),aceModuleBuild:q.join(c,"ets"),aceProfilePath:q.join(l,"resources","base","profile"),aceSuperVisualPath:q.join(t,"src","main","supervisual"),watchMode:"true"},patchConfig:{enableMap:"false",mode:"hotReload",oldMapFilePath:q.join(c,"ets"),changedFileList:q.join(a,"patch",n,"changedFileList.json"),patchAbcPath:q.join(a,"patch",n,"ets"),removeChangedFileListInSdk:"true"}}}};import*as Or from"fs";import*as fr from"path";import DI from"json5";var II=1e3;function no(r,e,t){let n=AI(r,e,t);return n.required?(f(`[ProjectCheck] ${t} check: ${n.reason}`),n):null}function Qc(r){f(`[ProjectCheck] Checking sync required at project root: ${r}`);let e=fr.join(r,Ce.SYNC_OUTPUT_PATH);if(!Or.existsSync(e)){let a={required:!0,reason:`sync baseline file not found: ${e}`};return f(`[ProjectCheck] ${a.reason}`),a}let t=Or.statSync(e).mtimeMs,n=fr.join(r,Ce.LOCK_JSON5_PATH);if(!Or.existsSync(n)){let a={required:!0,reason:`oh_modules lock not found: ${n}`};return f(`[ProjectCheck] ${a.reason}`),a}let i=TI(r);if(i===null)return{required:!0,reason:"failed to parse build-profile.json5"};let o=no(fr.join(r,Ce.OH_PACKAGE_JSON5),t,"root");if(o||(o=no(fr.join(r,Ce.BUILD_PROFILE_JSON5),t,"build-profile"),o)||(o=no(fr.join(r,Ce.HVIGOR_CONFIG),t,"hvigor-config"),o)||(o=no(fr.join(r,Ce.HVIGOR_CONFIG),t,"hvigor-config"),o))return o;for(let a of i)if(o=no(fr.join(r,a.srcPath,Ce.OH_PACKAGE_JSON5),t,a.name),o||(o=no(fr.join(r,a.srcPath,Ce.BUILD_PROFILE_JSON5),t,a.name),o))return o;let s=`all configuration files are up-to-date (sync baseline: ${new Date(t).toISOString()})`;return f(`[ProjectCheck] ${s}`),{required:!1,reason:s}}function AI(r,e,t){if(!Or.existsSync(r))return{required:!1,reason:`${t}: source not found, skip`};let n=Or.statSync(r).mtimeMs;return n-e>II?{required:!0,reason:`${t}: source mtime (${new Date(n).toISOString()}) is newer than sync baseline (${new Date(e).toISOString()})`}:{required:!1,reason:`${t}: up-to-date`}}function TI(r){let e=fr.join(r,Ce.BUILD_PROFILE_JSON5);try{let t=Or.readFileSync(e,"utf-8");if(!t.trim())return null;let n=DI.parse(t);if(typeof n!="object"||n===null)return null;let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):null}catch{return null}}import*as Q from"fs";import*as z from"path";import*as Ww from"util";var pf="";function tl(r){if(!r||r==="auto"||r==="stdout"||r==="none"){pf="";return}pf=r}function Vw(){return pf||(Ry()??"")}function el(r,...e){if(e.length===0)return r;try{return Ww.format(r,...e)}catch{return[r,...e.map(t=>typeof t=="string"?t:JSON.stringify(t))].join(" ")}}var m={info(r,...e){h.info(`[lsp] ${el(r,...e)}`)},warn(r,...e){h.warn(`[lsp] ${el(r,...e)}`)},error(r,...e){h.error(`[lsp] ${el(r,...e)}`)},debug(r,...e){h.debug(`[lsp] ${el(r,...e)}`)}};import*as As from"fs";import*as Ts from"os";import*as oo from"path";import NI from"json5";var b={INITIALIZE:"initialize",INITIALIZED:"initialized",SHUTDOWN:"shutdown",EXIT:"exit",DID_OPEN:"textDocument/didOpen",DID_CHANGE:"textDocument/didChange",DID_CLOSE:"textDocument/didClose",PUBLISH_DIAGNOSTICS:"textDocument/publishDiagnostics",HOVER:"textDocument/hover",DEFINITION:"textDocument/definition",DECLARATION:"textDocument/declaration",REFERENCES:"textDocument/references",IMPLEMENTATION:"textDocument/implementation",COMPLETION:"textDocument/completion",COMPLETION_ITEM_RESOLVE:"completionItem/resolve",SIGNATURE_HELP:"textDocument/signatureHelp",CODE_ACTION:"textDocument/codeAction",PREPARE_RENAME:"textDocument/prepareRename",RENAME:"textDocument/rename",DOCUMENT_HIGHLIGHT:"textDocument/documentHighlight",DOCUMENT_LINK:"textDocument/documentLink",INLAY_HINT:"textDocument/inlayHint",DOCUMENT_SYMBOL:"textDocument/documentSymbol",WORKSPACE_SYMBOL:"workspace/symbol",DIAGNOSTIC:"textDocument/diagnostic",WORKSPACE_DIAGNOSTIC:"workspace/diagnostic",PREPARE_CALL_HIERARCHY:"textDocument/prepareCallHierarchy",INCOMING_CALLS:"callHierarchy/incomingCalls",OUTGOING_CALLS:"callHierarchy/outgoingCalls",PREPARE_TYPE_HIERARCHY:"textDocument/prepareTypeHierarchy",SUPERTYPES:"typeHierarchy/supertypes",SUBTYPES:"typeHierarchy/subtypes",WORKSPACE_DID_CHANGE_CONFIGURATION:"workspace/didChangeConfiguration",WORKSPACE_DID_CHANGE_WATCHED_FILES:"workspace/didChangeWatchedFiles",DID_CREATE_FILES:"workspace/didCreateFiles",DID_DELETE_FILES:"workspace/didDeleteFiles",PROGRESS:"$/progress",WINDOW_SHOW_MESSAGE:"window/showMessage",WINDOW_LOG_MESSAGE:"window/logMessage",ARKTS_INITIALIZED:"arkts/initialized",ARKTS_INITIALIZATION_FAILED:"arkts/initializationFailed",ARKTS_INDEXING_PROGRESS:"arkts/indexingProgress",ARKTS_SYNC_PROJECT:"arkts/syncProject",ARKTS_SYNC_COMPLETED:"arkts/syncCompleted",ARKTS_REINITIALIZING:"arkts/reinitializing",ARKTS_ERROR:"arkts/error",CPP_INITIALIZED:"cpp/initialized",CPP_INITIALIZATION_FAILED:"cpp/initializationFailed",CPP_INDEXING_PROGRESS:"cpp/indexingProgress",CPP_SYNC_PROJECT:"cpp/syncProject",CPP_SYNC_COMPLETED:"cpp/syncCompleted",CPP_REINITIALIZING:"cpp/reinitializing",CPP_ERROR:"cpp/error",BROADCAST:"lsp/broadcast"},L="2.0",io={MODULE_INIT_FINISH:"aceProject/onModuleInitFinish",INDEXING_PROGRESS_UPDATE:"aceProject/onIndexingProgressUpdate"};var Gw=8192,ff=100,qw=.03,zw=.7,ot=900*1e3;function yt(r){if(!As.existsSync(r))return null;try{let e=As.readFileSync(r,"utf-8");return e.trim()?NI.parse(e):null}catch{return null}}function rl(r,e){let t=Math.floor(Ts.totalmem()/1048576),n=Math.floor(t*zw),i,o;e!==void 0&&Number.isFinite(e)&&e>0?(i=e,o=`override(${e})`):(i=Gw,r>ff&&(i+=(r-ff)*qw*1024),o=`formula(moduleCount=${r})`);let s=n>0&&i>n;s&&(i=n);let a=Math.round(i);return m.info(`[computeLspServerMaxSize] source=${o}, physicalTotal=${t}MB, physicalCap(70%)=${n}MB, finalSize=${a}MB${s?" (capped)":""}`),a}function Wt(r){if(r.startsWith("file:"))return r;try{let e=oo.resolve(r),t=new URL(`file://${e}`).toString();if(Ts.platform()==="win32"){let n=t.match(/^file:\/\/\/([A-Za-z]):/);if(n){let i=n[1].toUpperCase(),o=t.substring(`file:///${n[1]}:`.length);t=`file:///${i}%3A${o}`}}return t}catch{return r}}function so(r){return r&&r.replace(/\\/g,"/")}function he(r){let e=oo.normalize(r).replace(/\\/g,"/");if(Ts.platform()==="win32"){let t=e.match(/^([A-Za-z]):/);t&&(e=`${t[1].toUpperCase()}:${e.substring(2)}`)}return e}function ri(r){return r||process.execPath||"node"}function Ns(r){let e=he(r.lspLogPath),t=["--expose-gc",`--max-old-space-size=${r.serverMaxSize}`,"--report-on-fatalerror","--report-uncaught-exception",`--report-filename=nodejs_error_${Date.now()}.txt`,`--report-dir=${e}`,r.serverPath,r.transportFlag??"--stdio",`--logger-path=${e}`,"--logger-level=TRACE"];return r.projectPath&&t.push(`--projectPath=${he(r.projectPath)}`),r.sdkPath&&t.push(`--sdkPath=${he(r.sdkPath)}`),t}function Jw(r){return oo.join(r,"build-profile.json5")}var _r=class{constructor(e){this.projectRoot=e}getAllModuleInfo(){let e=Jw(this.projectRoot);try{let t=yt(e);if(typeof t!="object"||t===null)return[];let n=t.modules;return Array.isArray(n)?n.filter(i=>{if(typeof i!="object"||i===null)return!1;let o=i;return typeof o.name=="string"&&typeof o.srcPath=="string"}):[]}catch(t){return m.warn(`[ConfigFileWatcher] Failed to parse build-profile.json5: ${t instanceof Error?t.message:String(t)}`),[]}}};import{spawn as OI}from"child_process";import*as il from"fs";var _I=600*1e3;function MI(r,e,t){let n=t.split(/\s+/).filter(i=>i.length>0);return[r,[e,...n]]}function LI(r,e){let t=[],n=[],i="",o="";return r.stdout?.on("data",s=>{let a=s.toString();t.push(a),i=Kw(i+a,e)}),r.stderr?.on("data",s=>{let a=s.toString();n.push(a),o=Kw(o+a,c=>{m.info("[hvigor:err] %s",c),e?.(c)})}),{stdout:t,stderr:n,flush:()=>{i&&e?.(i),o&&(m.info("[hvigor:err] %s",o),e?.(o))}}}function Kw(r,e){let t=r.split(/\r?\n/),n=t.pop()??"";for(let i of t)i&&e?.(i);return n}function nl(r){return r.join("")}function FI(r,e,t){if(e)return{success:!1,output:"Build process killed by signal "+e+`.
24
24
  Output so far:
25
- `+t,exitCode:-1};let n=r??-1;return{success:n===0,output:t,exitCode:n}}function sx(r,e,t,n){return new Promise(i=>{let o=tx(r[0],r[1],{cwd:e,env:t,windowsHide:!0,stdio:["ignore","pipe","pipe"]}),{stdout:s,stderr:a,flush:c}=ix(o,n),l=setTimeout(()=>{o.kill(),c();let d=[jc(s),jc(a)].filter(Boolean).join(`
25
+ `+t,exitCode:-1};let n=r??-1;return{success:n===0,output:t,exitCode:n}}function $I(r,e,t,n){return new Promise(i=>{let o=OI(r[0],r[1],{cwd:e,env:t,windowsHide:!0,stdio:["ignore","pipe","pipe"]}),{stdout:s,stderr:a,flush:c}=LI(o,n),l=setTimeout(()=>{o.kill(),c();let d=[nl(s),nl(a)].filter(Boolean).join(`
26
26
  `).trim();i({success:!1,output:`Build process timeout after 10 minutes.
27
27
  Output so far:
28
- `+d,exitCode:-1})},rx);o.on("close",(d,g)=>{clearTimeout(l),c();let y=[jc(s),jc(a)].filter(Boolean).join(`
29
- `).trim()||"";i(ox(d,g,y))}),o.on("error",d=>{clearTimeout(l),i({success:!1,output:`Build execution exception: ${d.message}`,exitCode:-1})})})}async function _p(r,e,t,n,i,o){let s={...process.env,DEVECO_SDK_HOME:n},a=nx(e,t,i);return await sx(a,r,s,o)}function ax(r,e,t){return{node_path:e,hvigor_path:t,sdk_path:r}}function cx(r){return!r.node_path||!Hc.existsSync(r.node_path)?`Node path not found or invalid: ${r.node_path}`:!r.hvigor_path||!Hc.existsSync(r.hvigor_path)?`Hvigor path not found or invalid: ${r.hvigor_path}`:!r.sdk_path||!Hc.existsSync(r.sdk_path)?`SDK path not found or invalid: ${r.sdk_path}`:null}var lx="--sync -p product=default";async function nw(r,e,t,n,i){try{let o=ax(e,t,n),s=cx(o);if(s!=null)return f.info(`Config validation failed: ${s}`),!1;let a=await _p(r,o.node_path,o.hvigor_path,e,lx,i);return f.info(`[hvigor] sync finished: success=${a.success}, exitCode=${a.exitCode}`),a.success}catch(o){return f.info(`syncProject failed: ${JSON.stringify(o)}`),!1}}function dx(r){let e=z.extname(r).replace(/^\./,"").toLowerCase();return["c","cpp","cxx","cc","h","hpp","hxx","hh"].includes(e)}function ux(r,e){let t=z.join(r,e.name);return e.isDirectory()?e.name===".cxx"||ow(t):dx(t)}function ow(r){if(!Z.existsSync(r))return!1;try{return Z.readdirSync(r,{withFileTypes:!0}).some(t=>ux(r,t))}catch{}return!1}function an(r){try{let t=new Ir(r).getAllModuleInfo(),n=[];for(let i of t){let o=z.resolve(r,i.srcPath);ow(o)&&n.push(i)}return n}catch(e){throw h.error(`[CppCompile] findCppModules threw: ${e instanceof Error?e.message:String(e)}`),e}}function px(r){let e=[],n=new Ir(r).getAllModuleInfo();for(let i of n){let o=z.resolve(r,i.srcPath),s=z.join(o,".cxx");Z.existsSync(s)&&sw(s,e)}return e}function sw(r,e){try{let t=Z.readdirSync(r,{withFileTypes:!0});for(let n of t){let i=z.join(r,n.name);n.isDirectory()?sw(i,e):n.name==="compile_commands.json"&&e.push(i)}}catch{}}function mx(r){let e=[];for(let t of r)try{let n=Z.readFileSync(t,"utf8"),i=JSON.parse(n);e.push(...i)}catch{}return e}function fx(r,e){let t=z.join(r,...gx.slice(0,-1));Z.mkdirSync(t,{recursive:!0});let n=z.join(t,"compile_commands.json");Z.writeFileSync(n,JSON.stringify(e,null,2),"utf8")}function $p(r){let e=px(r);if(e.length>0){let t=mx(e);fx(r,t),h.info(`[CppCompile] compile_commands.json generated, ${t.length} compile commands`)}else h.warn("[CppCompile] No compile_commands.json files found")}var gx=[".idea",".deveco","cxx","compile_commands.json"];async function hx(r,e,t,n,i){if(!n){h.warn(`[CppCompile] hvigorw.js path not injected (sdk '${e}')`);return}h.info(`[CppCompile] sdkPath: ${e}, hvigorPath: ${n}`);for(let o of i){let s=o.name;try{P.assertModuleName(s)}catch{h.warn(`[CppCompile] Skipping module with invalid name: ${s}`);continue}let a=["--mode","module","-p",`module=${o.name}`,"-p","product=default","compileNative"].join(" ");h.info(`[CppCompile] Running compileNative for module: ${o.name}`);let c=await _p(r,t,n,e,a);c.success?h.info(`[CppCompile] compileNative ${o.name} succeeded`):h.warn(`[CppCompile] compileNative ${o.name} failed: ${c.output}`)}}async function aw(r,e,t,n){let i=an(r);if(i.length===0){h.info("[CppCompile] No C++ modules found, skipping initialization");return}h.info(`[CppCompile] Found ${i.length} C++ module(s): ${i.map(o=>o.name).join(", ")}`),await hx(r,e,t,n,i),$p(r),Px(r,i)}function Uc(r,e){let t=r?.trim()??"";if(!t)return null;let n=t;if(/\{workspace\}/i.test(n)){if(!e)return h.warn("[CppCompile] {workspace} placeholder in compile_commands path but no project root resolved, falling back to default sync"),null;n=n.replace(/\{workspace\}/gi,e)}else if(!z.isAbsolute(n)){if(!e)return h.warn(`[CppCompile] Relative compile_commands path '${n}' requires a project root, falling back to default sync`),null;n=z.join(e,n)}let i=z.resolve(n);try{if(!Z.existsSync(i)||!Z.statSync(i).isFile())return h.warn(`[CppCompile] Custom compile_commands.json not found: ${i}, falling back to default sync`),null;let o=JSON.parse(Z.readFileSync(i,"utf8"));if(!Array.isArray(o))return h.warn(`[CppCompile] Custom compile_commands.json is not a JSON array: ${i}, falling back to default sync`),null}catch(o){return h.warn(`[CppCompile] Failed to read custom compile_commands.json (${i}): ${o}, falling back to default sync`),null}return z.dirname(i)}var yx=1e3,wx=["src","main","cpp","CMakeLists.txt"],vx=new Set([".cxx","build","node_modules",".preview",".hvigor",".idea"]),bx=new Set(["c","cpp","cxx","cc"]),Sx="cpp-source-manifest.json";function Ex(r){let e=z.extname(r).replace(/^\./,"").toLowerCase();return bx.has(e)}function iw(r,e){return Z.existsSync(r)?Z.statSync(r).mtimeMs-e>yx:!1}function cw(r){return z.join(z.dirname(Gn(r)),Sx)}function lw(r,e,t){let n;try{n=Z.readdirSync(r,{withFileTypes:!0})}catch{return}for(let i of n){let o=z.join(r,i.name);if(i.isDirectory()){if(vx.has(i.name))continue;lw(o,e,t)}else Ex(i.name)&&t.push(z.relative(e,o).replace(/\\/g,"/"))}}function dw(r,e){let t=[];for(let n of e){let i=z.resolve(r,n.srcPath);lw(i,r,t)}return t.sort()}function Px(r,e){let t=dw(r,e),n={files:t,updatedAt:Date.now()},i=cw(r);try{Z.mkdirSync(z.dirname(i),{recursive:!0}),Z.writeFileSync(i,JSON.stringify(n,null,2),"utf8"),h.info(`[CppCompile] C++ source manifest written, ${t.length} files`)}catch(o){h.warn(`[CppCompile] Failed to write C++ source manifest: ${o}`)}}function Cx(r,e){let t=cw(r);if(!Z.existsSync(t))return{required:!0,reason:"C++ source manifest not found, needs initialization"};let n;try{let o=JSON.parse(Z.readFileSync(t,"utf8"));n=Array.isArray(o.files)?o.files:[]}catch{return{required:!0,reason:"C++ source manifest corrupted, needs initialization"}}let i=dw(r,e);return i.length!==n.length||i.some((o,s)=>o!==n[s])?{required:!0,reason:`C++ source file set changed (recorded=${n.length}, actual=${i.length})`}:null}function uw(r){let e=Gn(r);if(!Z.existsSync(e))return{required:!0,reason:"C++ baseline (compile_commands.json) not found, needs initialization"};let t=Z.statSync(e).mtimeMs,n=an(r);if(n.length===0)return{required:!1,reason:"no C++ modules, skip compileNative"};for(let o of n){let s=z.resolve(r,o.srcPath);if(iw(z.join(s,"build-profile.json5"),t))return{required:!0,reason:`module '${o.name}': build-profile.json5 newer than baseline`};let a=z.join(s,...wx);if(iw(a,t))return{required:!0,reason:`module '${o.name}': CMakeLists.txt newer than baseline`}}let i=Cx(r,n);return i||{required:!1,reason:`C++ project up-to-date (baseline: ${new Date(t).toISOString()})`}}var mw=["assembleHap","assembleApp","assembleHsp","assembleHar"];function Dx(r,e){if(e.product&&r.validateProduct(e.product),e.buildMode){let t=["debug","release"],n=(r.profile.app.buildModeSet?.map(o=>o.name)??[]).filter(o=>!t.includes(o)),i=[...t,...n];if(!i.includes(e.buildMode))throw new Error(`Build mode '${e.buildMode}' not found. Available modes: ${i.join(", ")}`)}if(e.assembleType&&!mw.includes(e.assembleType))throw new Error(`Invalid assemble type '${e.assembleType}'. Valid types: ${mw.join(", ")}`);if(e.signingConfig){if(!/^[\da-zA-Z_-]+$/.test(e.signingConfig))throw new Error(`Invalid signing config name '${e.signingConfig}'. Only letters, digits, hyphens and underscores are allowed.`);let t=r.profile.app.signingConfigs?.map(n=>n.name)??[];if(!t.includes(e.signingConfig)){let n=t.length>0?`Available configs: ${t.join(", ")}.`:"No signing configs found in build-profile.json5.",i=e.signingConfig.endsWith("_release")?"Run `devecocli signature generate --type release` to generate release signing materials.":"Run `devecocli signature generate` to generate signing materials.";throw new Error(`Signing config '${e.signingConfig}' not found in build-profile.json5. ${n} ${i}`)}}}function hw(r,e){let t=r.profile.modules.map(i=>i.name),n=new Set(t);for(let i of e){let o=i.split("@",1)[0];if(!n.has(o))throw new Error(`Module '${o}' not found in project-level build-profile.json5. Available modules: ${t.join(", ")||"none"}`)}}function Rx(r,e){let t;if(e.modules&&e.modules.length>0)t=e.modules,hw(r,t);else{let i=r.profile.modules,o=i.filter(s=>r.getModuleType(s.name)==="entry");if(i.length===1)t=[i[0].name];else if(o.length===1)t=[o[0].name];else throw o.length>1?new w(`Multiple entry modules found (${o.map(s=>s.name).join(", ")}). Please specify which module to build with --modules.`,"Multiple entry modules found."):new w(`No entry module found and multiple modules available (${i.map(s=>s.name).join(", ")}). Please specify which module to build with --modules.`,"No entry module found and multiple modules available.")}let n=new Set;for(let i of t){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i,a=o!==-1?i.substring(o+1):"default";n.add(`${s}@${a}`)}return Array.from(n)}function Fp(r,e,t){let n=new Set;for(let i of e){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i;if(t){let a=r.getModuleType(s),c=a==="shared"?"assembleHsp":a==="har"?"assembleHar":"assembleHap";t!==c&&t!=="assembleApp"&&console.warn(Vc(`Warning: --assemble-type ${t} may not be compatible with module '${s}' (type: ${a}, expected: ${c}).`)),n.add(t)}else{let a=r.getModuleType(s);a==="shared"?n.add("assembleHsp"):a==="har"?n.add("assembleHar"):n.add("assembleHap")}}return n}function Bc(r,e){let t=e,n=`${r} failed`;console.error(fw(n));let i=t.stdout||t.message;throw i&&console.error(i),t.stderr&&console.error(t.stderr),new Error(n,{cause:e})}async function xx(r,e,t,n,i){if(!Lc(i).required)return console.log(`
28
+ `+d,exitCode:-1})},_I);o.on("close",(d,g)=>{clearTimeout(l),c();let y=[nl(s),nl(a)].filter(Boolean).join(`
29
+ `).trim()||"";i(FI(d,g,y))}),o.on("error",d=>{clearTimeout(l),i({success:!1,output:`Build execution exception: ${d.message}`,exitCode:-1})})})}async function mf(r,e,t,n,i,o){let s={...process.env,DEVECO_SDK_HOME:n},a=MI(e,t,i);return await $I(a,r,s,o)}function jI(r,e,t){return{node_path:e,hvigor_path:t,sdk_path:r}}function HI(r){return!r.node_path||!il.existsSync(r.node_path)?`Node path not found or invalid: ${r.node_path}`:!r.hvigor_path||!il.existsSync(r.hvigor_path)?`Hvigor path not found or invalid: ${r.hvigor_path}`:!r.sdk_path||!il.existsSync(r.sdk_path)?`SDK path not found or invalid: ${r.sdk_path}`:null}var UI="--sync -p product=default";async function Yw(r,e,t,n,i){try{let o=jI(e,t,n),s=HI(o);if(s!=null)return m.info(`Config validation failed: ${s}`),!1;let a=await mf(r,o.node_path,o.hvigor_path,e,UI,i);return m.info(`[hvigor] sync finished: success=${a.success}, exitCode=${a.exitCode}`),a.success}catch(o){return m.info(`syncProject failed: ${JSON.stringify(o)}`),!1}}function BI(r){let e=z.extname(r).replace(/^\./,"").toLowerCase();return["c","cpp","cxx","cc","h","hpp","hxx","hh"].includes(e)}function WI(r,e){let t=z.join(r,e.name);return e.isDirectory()?e.name===".cxx"||Zw(t):BI(t)}function Zw(r){if(!Q.existsSync(r))return!1;try{return Q.readdirSync(r,{withFileTypes:!0}).some(t=>WI(r,t))}catch{}return!1}function dn(r){try{let t=new _r(r).getAllModuleInfo(),n=[];for(let i of t){let o=z.resolve(r,i.srcPath);Zw(o)&&n.push(i)}return n}catch(e){throw h.error(`[CppCompile] findCppModules threw: ${e instanceof Error?e.message:String(e)}`),e}}function VI(r){let e=[],n=new _r(r).getAllModuleInfo();for(let i of n){let o=z.resolve(r,i.srcPath),s=z.join(o,".cxx");Q.existsSync(s)&&Qw(s,e)}return e}function Qw(r,e){try{let t=Q.readdirSync(r,{withFileTypes:!0});for(let n of t){let i=z.join(r,n.name);n.isDirectory()?Qw(i,e):n.name==="compile_commands.json"&&e.push(i)}}catch{}}function GI(r){let e=[];for(let t of r)try{let n=Q.readFileSync(t,"utf8"),i=JSON.parse(n);e.push(...i)}catch{}return e}function qI(r,e){let t=z.join(r,...zI.slice(0,-1));Q.mkdirSync(t,{recursive:!0});let n=z.join(t,"compile_commands.json");Q.writeFileSync(n,JSON.stringify(e,null,2),"utf8")}function gf(r){let e=VI(r);if(e.length>0){let t=GI(e);qI(r,t),h.info(`[CppCompile] compile_commands.json generated, ${t.length} compile commands`)}else h.warn("[CppCompile] No compile_commands.json files found")}var zI=[".idea",".deveco","cxx","compile_commands.json"];async function JI(r,e,t,n,i){if(!n){h.warn(`[CppCompile] hvigorw.js path not injected (sdk '${e}')`);return}h.info(`[CppCompile] sdkPath: ${e}, hvigorPath: ${n}`);for(let o of i){let s=o.name;try{P.assertModuleName(s)}catch{h.warn(`[CppCompile] Skipping module with invalid name: ${s}`);continue}let a=["--mode","module","-p",`module=${o.name}`,"-p","product=default","compileNative"].join(" ");h.info(`[CppCompile] Running compileNative for module: ${o.name}`);let c=await mf(r,t,n,e,a);c.success?h.info(`[CppCompile] compileNative ${o.name} succeeded`):h.warn(`[CppCompile] compileNative ${o.name} failed: ${c.output}`)}}async function ev(r,e,t,n){let i=dn(r);if(i.length===0){h.info("[CppCompile] No C++ modules found, skipping initialization");return}h.info(`[CppCompile] Found ${i.length} C++ module(s): ${i.map(o=>o.name).join(", ")}`),await JI(r,e,t,n,i),gf(r),tA(r,i)}function ol(r,e){let t=r?.trim()??"";if(!t)return null;let n=t;if(/\{workspace\}/i.test(n)){if(!e)return h.warn("[CppCompile] {workspace} placeholder in compile_commands path but no project root resolved, falling back to default sync"),null;n=n.replace(/\{workspace\}/gi,e)}else if(!z.isAbsolute(n)){if(!e)return h.warn(`[CppCompile] Relative compile_commands path '${n}' requires a project root, falling back to default sync`),null;n=z.join(e,n)}let i=z.resolve(n);try{if(!Q.existsSync(i)||!Q.statSync(i).isFile())return h.warn(`[CppCompile] Custom compile_commands.json not found: ${i}, falling back to default sync`),null;let o=JSON.parse(Q.readFileSync(i,"utf8"));if(!Array.isArray(o))return h.warn(`[CppCompile] Custom compile_commands.json is not a JSON array: ${i}, falling back to default sync`),null}catch(o){return h.warn(`[CppCompile] Failed to read custom compile_commands.json (${i}): ${o}, falling back to default sync`),null}return z.dirname(i)}var KI=1e3,YI=["src","main","cpp","CMakeLists.txt"],XI=new Set([".cxx","build","node_modules",".preview",".hvigor",".idea"]),ZI=new Set(["c","cpp","cxx","cc"]),QI="cpp-source-manifest.json";function eA(r){let e=z.extname(r).replace(/^\./,"").toLowerCase();return ZI.has(e)}function Xw(r,e){return Q.existsSync(r)?Q.statSync(r).mtimeMs-e>KI:!1}function tv(r){return z.join(z.dirname(Jn(r)),QI)}function rv(r,e,t){let n;try{n=Q.readdirSync(r,{withFileTypes:!0})}catch{return}for(let i of n){let o=z.join(r,i.name);if(i.isDirectory()){if(XI.has(i.name))continue;rv(o,e,t)}else eA(i.name)&&t.push(z.relative(e,o).replace(/\\/g,"/"))}}function nv(r,e){let t=[];for(let n of e){let i=z.resolve(r,n.srcPath);rv(i,r,t)}return t.sort()}function tA(r,e){let t=nv(r,e),n={files:t,updatedAt:Date.now()},i=tv(r);try{Q.mkdirSync(z.dirname(i),{recursive:!0}),Q.writeFileSync(i,JSON.stringify(n,null,2),"utf8"),h.info(`[CppCompile] C++ source manifest written, ${t.length} files`)}catch(o){h.warn(`[CppCompile] Failed to write C++ source manifest: ${o}`)}}function rA(r,e){let t=tv(r);if(!Q.existsSync(t))return{required:!0,reason:"C++ source manifest not found, needs initialization"};let n;try{let o=JSON.parse(Q.readFileSync(t,"utf8"));n=Array.isArray(o.files)?o.files:[]}catch{return{required:!0,reason:"C++ source manifest corrupted, needs initialization"}}let i=nv(r,e);return i.length!==n.length||i.some((o,s)=>o!==n[s])?{required:!0,reason:`C++ source file set changed (recorded=${n.length}, actual=${i.length})`}:null}function iv(r){let e=Jn(r);if(!Q.existsSync(e))return{required:!0,reason:"C++ baseline (compile_commands.json) not found, needs initialization"};let t=Q.statSync(e).mtimeMs,n=dn(r);if(n.length===0)return{required:!1,reason:"no C++ modules, skip compileNative"};for(let o of n){let s=z.resolve(r,o.srcPath);if(Xw(z.join(s,"build-profile.json5"),t))return{required:!0,reason:`module '${o.name}': build-profile.json5 newer than baseline`};let a=z.join(s,...YI);if(Xw(a,t))return{required:!0,reason:`module '${o.name}': CMakeLists.txt newer than baseline`}}let i=rA(r,n);return i||{required:!1,reason:`C++ project up-to-date (baseline: ${new Date(t).toISOString()})`}}var sv=["assembleHap","assembleApp","assembleHsp","assembleHar"];function iA(r,e){if(e.product&&r.validateProduct(e.product),e.buildMode){let t=["debug","release"],n=(r.profile.app.buildModeSet?.map(o=>o.name)??[]).filter(o=>!t.includes(o)),i=[...t,...n];if(!i.includes(e.buildMode))throw new Error(`Build mode '${e.buildMode}' not found. Available modes: ${i.join(", ")}`)}if(e.assembleType&&!sv.includes(e.assembleType))throw new Error(`Invalid assemble type '${e.assembleType}'. Valid types: ${sv.join(", ")}`);if(e.signingConfig){if(!/^[\da-zA-Z_-]+$/.test(e.signingConfig))throw new Error(`Invalid signing config name '${e.signingConfig}'. Only letters, digits, hyphens and underscores are allowed.`);let t=r.profile.app.signingConfigs?.map(n=>n.name)??[];if(!t.includes(e.signingConfig)){let n=t.length>0?`Available configs: ${t.join(", ")}.`:"No signing configs found in build-profile.json5.",i=e.signingConfig.endsWith("_release")?"Run `devecocli signature generate --type release` to generate release signing materials.":"Run `devecocli signature generate` to generate signing materials.";throw new Error(`Signing config '${e.signingConfig}' not found in build-profile.json5. ${n} ${i}`)}}}function lv(r,e){let t=r.profile.modules.map(i=>i.name),n=new Set(t);for(let i of e){let o=i.split("@",1)[0];if(!n.has(o))throw new Error(`Module '${o}' not found in project-level build-profile.json5. Available modules: ${t.join(", ")||"none"}`)}}function oA(r,e){let t;if(e.modules&&e.modules.length>0)t=e.modules,lv(r,t);else{let i=r.profile.modules,o=i.filter(s=>r.getModuleType(s.name)==="entry");if(i.length===1)t=[i[0].name];else if(o.length===1)t=[o[0].name];else throw o.length>1?new w(`Multiple entry modules found (${o.map(s=>s.name).join(", ")}). Please specify which module to build with --modules.`,"Multiple entry modules found."):new w(`No entry module found and multiple modules available (${i.map(s=>s.name).join(", ")}). Please specify which module to build with --modules.`,"No entry module found and multiple modules available.")}let n=new Set;for(let i of t){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i,a=o!==-1?i.substring(o+1):"default";n.add(`${s}@${a}`)}return Array.from(n)}function hf(r,e,t){let n=new Set;for(let i of e){let o=i.indexOf("@"),s=o!==-1?i.substring(0,o):i;if(t){let a=r.getModuleType(s),c=a==="shared"?"assembleHsp":a==="har"?"assembleHar":"assembleHap";t!==c&&t!=="assembleApp"&&console.warn(cl(`Warning: --assemble-type ${t} may not be compatible with module '${s}' (type: ${a}, expected: ${c}).`)),n.add(t)}else{let a=r.getModuleType(s);a==="shared"?n.add("assembleHsp"):a==="har"?n.add("assembleHar"):n.add("assembleHap")}}return n}function sl(r,e){let t=e,n=`${r} failed`;console.error(av(n));let i=t.stdout||t.message;throw i&&console.error(i),t.stderr&&console.error(t.stderr),new Error(n,{cause:e})}async function sA(r,e,t,n,i){if(!Qc(i).required)return console.log(`
30
30
  [ohpm install] Skipped (configurations unchanged)`),console.log(`
31
31
  [hvigor sync] Skipped (configurations unchanged)`),"";console.log(`
32
- [ohpm install] Running...`);try{await r.install()}catch(s){Bc("ohpm install",s)}console.log(`
33
- [hvigor sync] Running...`);try{return await e.sync(t,n)}catch(s){Bc("hvigor sync",s)}return""}async function jp(r,e,t,n,i,o){let s=await xx(r,e,t,n,o);console.log(`
34
- [hvigor build] Running...`);let a="";try{i.type==="product"?a=await e.buildProduct(t,n):a=await e.buildModules(t,n,i.modulesToBuild,i.moduleTasks)}catch(c){Bc("hvigor build",c)}return Ax(o),{ohpmMemoryMb:r.peakMemoryMb,syncMemoryMb:s,buildMemoryMb:a}}function Ax(r){try{if(an(r).length===0)return;$p(r),console.log(Wc(`
35
- Merged central compile_commands.json for C++ language server.`))}catch(e){console.warn(Vc(`
36
- Failed to merge compile_commands.json: ${e.message}`))}}async function yw(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=X(o),console.error(fw(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(r,o)}}function Ix(r){let e={event:v.CommandExecuted,args:["build",...r.product?["--product"]:[],...r.modules?["--modules"]:[],...r.buildMode?["--build-mode"]:[],...r.assembleType?["--assemble-type"]:[],...r.signingConfig?["--signing-config"]:[]]};return r.buildMode&&(e.build_mode=r.buildMode),r.modules&&(e.module_count=r.modules.length),r.assembleType&&(e.assemble_type=r.assembleType),r.signingConfig&&(e.signing_config=r.signingConfig),e}function Tx(r){let e={event:v.CommandExecuted,args:["build","clean",...r.mode?["--mode"]:[],...r.modules?["--modules"]:[]]};return r.modules&&(e.module_count=r.modules.length),r.mode&&(e.clean_mode=r.mode),e}async function Ox(r){let e=W.discover(process.cwd());await rt.warnInvalidBundledLinks(e.rootDir),console.warn(Vc("Ensure the project source is trustworthy before proceeding."));let t=await C.new();t.assertJava(),Dx(e,r);let n=r.product||"default",i=r.buildMode||"debug",o=Nx(e,r),s=new zi(t,e.rootDir),a=new gt(t,e.rootDir),c=r.signingConfig?Mx(e.rootDir,n,r.signingConfig):void 0;try{let l=await xr(e.rootDir,async()=>(cr.removeAll(e),jp(s,a,n,i,o,e.rootDir)),()=>console.log("Another build is already running for this project. Waiting for completion..."));return console.log(`
37
- `+Wc("Build completed successfully")),Lx(e,o,n),{bundleName:e.getBundleName(),...l}}finally{c?.()}}function Nx(r,e){if(e.assembleType==="assembleApp"||e.product&&!e.modules&&!e.assembleType)return{type:"product"};let t=Rx(r,e),n=Fp(r,t,e.assembleType);return{type:"modules",modulesToBuild:t,moduleTasks:n}}function Mx(r,e,t){let n=gw.join(r,"build-profile.json5"),i=Ss.readFileSync(n,"utf-8"),o=pw.parse(i),s=o?.app?.products??[],a=s.findIndex(c=>c.name===e);return a>=0?s[a].signingConfig=t:s.push({name:e,signingConfig:t}),m(`[build] temporarily setting product '${e}' signingConfig to '${t}'`),Ss.writeFileSync(n,pw.stringify(o,null,2),"utf-8"),()=>{Ss.writeFileSync(n,i,"utf-8"),m("[build] restored original build-profile.json5")}}function Lx(r,e,t){let n=e.type==="product"?r.resolveModuleSpecsForProduct(t):e.modulesToBuild,i=r.collectBuildArtifacts(e.type==="product",n,t);if(i.length!==0){console.log(Wc("Build artifacts:"));for(let o of i)console.log(` ${o}`)}}async function _x(r){let e=process.cwd(),t=W.discover(e);await rt.warnInvalidBundledLinks(t.rootDir),console.warn(Vc("Ensure the project source is trusted before proceeding."));let n=await C.new();n.assertJava();let i;r.modules&&r.modules.length>0&&(hw(t,r.modules),i=r.modules.map(s=>s.split("@",1)[0]));let o=new gt(n,t.rootDir);return await xr(t.rootDir,async()=>{let s=i&&i.length>0?`mode=${r.mode??Nc}, modules=${i.join(",")}`:`mode=${r.mode??Nc}`;console.log(`
38
- Running hvigor clean (${s})...`);try{await o.clean(r.mode,i)}catch(a){Bc("hvigor clean",a)}},()=>{console.log("Another build is already running for this project. Waiting for it to finish...")}),console.log(`
39
- `+Wc("Clean completed successfully.")),t.getBundleName()}var ww=new kx("build").description("Build HarmonyOS project").option("--product <product>","Product name defined in build-profile.json5 (default: default)").option("--modules <modules...>","Modules to build (format: module or module@target)").option("--build-mode <mode>","Build mode (buildModeSet in build-profile.json5; e.g. debug, release; default: debug)").option("--assemble-type <type>","Assemble task type: assembleHap, assembleApp, assembleHsp, assembleHar (default: auto-detect by module type)").option("--signing-config <name>","Signing config name defined in build-profile.json5 (overrides product default)").action(async r=>{let e=Ix(r);await yw(e,async()=>{let t=await Ox(r);e.bundle_name=t.bundleName,t.ohpmMemoryMb&&(e.ohpm_install_memory=t.ohpmMemoryMb),t.syncMemoryMb&&(e.hvigor_sync_memory=t.syncMemoryMb),t.buildMemoryMb&&(e.hvigor_build_memory=t.buildMemoryMb)})});ww.command("clean").description("Clean HarmonyOS project build outputs").option("--mode <mode>","hvigor --mode value (default: module)").option("--modules <modules...>","Scope clean to specific modules").action(async(r,e)=>{let t=e.parent?.opts()??{},n={mode:r.mode,modules:r.modules??t.modules},i=Tx(n);await yw(i,async()=>{i.bundle_name=await _x(n)})});var vw=ww;import{Command as oT}from"commander";import{green as Ls,red as sT,yellow as bl}from"colorette";import*as _s from"path";import{randomUUID as Kx}from"crypto";import{execa as Rw}from"execa";import{execa as Yx}from"execa";import{execFile as $x,spawn as Fx}from"child_process";import{promisify as jx}from"util";var Hx=jx($x);function bw(r,e,t){let i=r.replace(/\r\n/g,`
32
+ [ohpm install] Running...`);try{await r.install()}catch(s){sl("ohpm install",s)}console.log(`
33
+ [hvigor sync] Running...`);try{return await e.sync(t,n)}catch(s){sl("hvigor sync",s)}return""}async function yf(r,e,t,n,i,o){let s=await sA(r,e,t,n,o);console.log(`
34
+ [hvigor build] Running...`);let a="";try{i.type==="product"?a=await e.buildProduct(t,n):a=await e.buildModules(t,n,i.modulesToBuild,i.moduleTasks)}catch(c){sl("hvigor build",c)}return aA(o),{ohpmMemoryMb:r.peakMemoryMb,syncMemoryMb:s,buildMemoryMb:a}}function aA(r){try{if(dn(r).length===0)return;gf(r),console.log(al(`
35
+ Merged central compile_commands.json for C++ language server.`))}catch(e){console.warn(cl(`
36
+ Failed to merge compile_commands.json: ${e.message}`))}}async function dv(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=Z(o),console.error(av(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(r,o)}}function cA(r){let e={event:v.CommandExecuted,args:["build",...r.product?["--product"]:[],...r.modules?["--modules"]:[],...r.buildMode?["--build-mode"]:[],...r.assembleType?["--assemble-type"]:[],...r.signingConfig?["--signing-config"]:[]]};return r.buildMode&&(e.build_mode=r.buildMode),r.modules&&(e.module_count=r.modules.length),r.assembleType&&(e.assemble_type=r.assembleType),r.signingConfig&&(e.signing_config=r.signingConfig),e}function lA(r){let e={event:v.CommandExecuted,args:["build","clean",...r.mode?["--mode"]:[],...r.modules?["--modules"]:[]]};return r.modules&&(e.module_count=r.modules.length),r.mode&&(e.clean_mode=r.mode),e}async function dA(r){let e=W.discover(process.cwd());await nt.warnInvalidBundledLinks(e.rootDir),console.warn(cl("Ensure the project source is trustworthy before proceeding."));let t=await C.new();t.assertJava(),iA(e,r);let n=r.product||"default",i=r.buildMode||"debug",o=uA(e,r),s=new ro(t,e.rootDir),a=new ht(t,e.rootDir),c=r.signingConfig?pA(e.rootDir,n,r.signingConfig):void 0;try{let l=await Nr(e.rootDir,async()=>(pr.removeAll(e),yf(s,a,n,i,o,e.rootDir)),()=>console.log("Another build is already running for this project. Waiting for completion..."));return console.log(`
37
+ `+al("Build completed successfully")),fA(e,o,n),{bundleName:e.getBundleName(),...l}}finally{c?.()}}function uA(r,e){if(e.assembleType==="assembleApp"||e.product&&!e.modules&&!e.assembleType)return{type:"product"};let t=oA(r,e),n=hf(r,t,e.assembleType);return{type:"modules",modulesToBuild:t,moduleTasks:n}}function pA(r,e,t){let n=cv.join(r,"build-profile.json5"),i=Os.readFileSync(n,"utf-8"),o=ov.parse(i),s=o?.app?.products??[],a=s.findIndex(c=>c.name===e);return a>=0?s[a].signingConfig=t:s.push({name:e,signingConfig:t}),f(`[build] temporarily setting product '${e}' signingConfig to '${t}'`),Os.writeFileSync(n,ov.stringify(o,null,2),"utf-8"),()=>{Os.writeFileSync(n,i,"utf-8"),f("[build] restored original build-profile.json5")}}function fA(r,e,t){let n=e.type==="product"?r.resolveModuleSpecsForProduct(t):e.modulesToBuild,i=r.collectBuildArtifacts(e.type==="product",n,t);if(i.length!==0){console.log(al("Build artifacts:"));for(let o of i)console.log(` ${o}`)}}async function mA(r){let e=process.cwd(),t=W.discover(e);await nt.warnInvalidBundledLinks(t.rootDir),console.warn(cl("Ensure the project source is trusted before proceeding."));let n=await C.new();n.assertJava();let i;r.modules&&r.modules.length>0&&(lv(t,r.modules),i=r.modules.map(s=>s.split("@",1)[0]));let o=new ht(n,t.rootDir);return await Nr(t.rootDir,async()=>{let s=i&&i.length>0?`mode=${r.mode??Xc}, modules=${i.join(",")}`:`mode=${r.mode??Xc}`;console.log(`
38
+ Running hvigor clean (${s})...`);try{await o.clean(r.mode,i)}catch(a){sl("hvigor clean",a)}},()=>{console.log("Another build is already running for this project. Waiting for it to finish...")}),console.log(`
39
+ `+al("Clean completed successfully.")),t.getBundleName()}var uv=new nA("build").description("Build HarmonyOS project").option("--product <product>","Product name defined in build-profile.json5 (default: default)").option("--modules <modules...>","Modules to build (format: module or module@target)").option("--build-mode <mode>","Build mode (buildModeSet in build-profile.json5; e.g. debug, release; default: debug)").option("--assemble-type <type>","Assemble task type: assembleHap, assembleApp, assembleHsp, assembleHar (default: auto-detect by module type)").option("--signing-config <name>","Signing config name defined in build-profile.json5 (overrides product default)").action(async r=>{let e=cA(r);await dv(e,async()=>{let t=await dA(r);e.bundle_name=t.bundleName,t.ohpmMemoryMb&&(e.ohpm_install_memory=t.ohpmMemoryMb),t.syncMemoryMb&&(e.hvigor_sync_memory=t.syncMemoryMb),t.buildMemoryMb&&(e.hvigor_build_memory=t.buildMemoryMb)})});uv.command("clean").description("Clean HarmonyOS project build outputs").option("--mode <mode>","hvigor --mode value (default: module)").option("--modules <modules...>","Scope clean to specific modules").action(async(r,e)=>{let t=e.parent?.opts()??{},n={mode:r.mode,modules:r.modules??t.modules},i=lA(n);await dv(i,async()=>{i.bundle_name=await mA(n)})});var pv=uv;import{Command as FN}from"commander";import{green as zs,red as $N,yellow as $l}from"colorette";import*as Js from"path";import{randomUUID as DA}from"crypto";import{execa as bv}from"execa";import{execa as xA}from"execa";import{execFile as gA,spawn as hA}from"child_process";import{promisify as yA}from"util";var wA=yA(gA);function fv(r,e,t){let i=r.replace(/\r\n/g,`
40
40
  `).split(`
41
- `),o=i.pop()??"",s=i.map(a=>a.endsWith("\r")?a.slice(0,-1):a).filter(a=>a.length>0);return s.length>0&&t.onData(s,e),o}function Sw(r,e,t){let n=r.endsWith("\r")?r.slice(0,-1):r;n.length>0&&t.onData([n],e)}function Ux(r,e){return{stdout:r.stdoutChunks.join(""),stderr:r.stderrChunks.join(""),exitCode:e??-1}}function Bx(){return{stdoutChunks:[],stderrChunks:[],stdoutLineBuffer:"",stderrLineBuffer:"",settled:!1}}function Wx(r,e,t,n,i){r.stdout?.on("data",o=>{let s=o.toString();e.stdoutChunks.push(s),e.stdoutLineBuffer=bw(e.stdoutLineBuffer+s,"stdout",t)}),r.stderr?.on("data",o=>{let s=o.toString();e.stderrChunks.push(s),e.stderrLineBuffer=bw(e.stderrLineBuffer+s,"stderr",t)}),r.on("error",o=>{e.settled||(e.settled=!0,t.onError(o),i(o))}),r.on("close",o=>{if(e.settled)return;e.settled=!0,Sw(e.stdoutLineBuffer,"stdout",t),Sw(e.stderrLineBuffer,"stderr",t),t.onClose(o);let s=Ux(e,o);n(s)})}async function Es(r,e=[],t={}){try{let{stdout:n,stderr:i}=await Hx(r,e,t);return{stdout:typeof n=="string"?n.trim():"",stderr:typeof i=="string"?i.trim():"",exitCode:0}}catch(n){let i=n;return{stdout:i.stdout?.trim()||"",stderr:i.stderr?.trim()??i.message,exitCode:typeof i.code=="number"?i.code:1}}}async function Ew(r,e,t){return await new Promise((n,i)=>{let o=Fx(r,e,{stdio:["inherit","pipe","pipe"]}),s=Bx();Wx(o,s,t,n,i)})}function Pw(r){let e=r.trim(),t=e.indexOf("=");return t!==-1?e.slice(t+1).trim():e}var Vx=[/communication channel is being established/i,/please wait for several seconds and try again/i,/device offline/i,/\[E0+04\]/i,/not connected/i],Gx=[/\[fail\]/i,/\bfail!/i,/not found/i,/permission denied/i,/device unauthorized/i];function Ut(r){return r?Vx.some(e=>e.test(r))?"transient":Gx.some(e=>e.test(r))?"fatal":"ok":"ok"}var qx=/(?:^|\s)(\d{2,})(?:\s|$)/;function Cw(r){let e=r.stdout.trim(),t=r.stderr.trim();return Ut(e)!=="ok"||Ut(t)!=="ok"?"query-failed":r.exitCode===0?e&&qx.test(e)?"alive":"dead":r.exitCode===1&&!e&&!t?"dead":"query-failed"}var Hp=[800,1500,2500];function zx(r){return new Promise(e=>setTimeout(e,r))}async function k(r,e){let t=1+Hp.length,n={stdout:"",stderr:"",exitCode:-1};for(let i=0;i<t;i++){if(n=await Es(r,e),n.exitCode===0||Ut(n.stderr)!=="transient"||i>=t-1)return n;m(`hdc transient failure on \`${e.join(" ")}\`: retrying in ${Hp[i]}ms`),await zx(Hp[i])}return n}var kw=/^[\w.-]+$/;async function Gc(r,e,t){if(!kw.test(t)){m(`Skipping invalid param key: ${JSON.stringify(t)}`);return}let n=["-t",e,"shell","param","get",t];m(`Executing: ${r} ${n.join(" ")}`);let i=await k(r,n);if(i.exitCode!==0)return;let o=i.stdout.trim();if(!(!o||Ut(o)!=="ok"))return Pw(o)}var Up="__DEVECO_PARAM_DELIM__";function Jx(r,e){let t=new Map,n=r.split(Up);for(let i=0;i<e.length;i++){let o=(n[i]??"").trim();if(!o||Ut(o)!=="ok")continue;let s=Pw(o);s&&t.set(e[i],s)}return t}async function Zi(r,e,t){let n=t.filter(a=>kw.test(a)?!0:(m(`Skipping invalid param key: ${JSON.stringify(a)}`),!1));if(n.length===0)return new Map;if(n.length===1){let a=new Map,c=await Gc(r,e,n[0]);return c&&a.set(n[0],c),a}let i=n.map(a=>`param get ${a}`).join(`; echo ${Up}; `)+`; echo ${Up}`,o=await k(r,["-t",e,"shell",i]);if(o.exitCode===0){let a=Jx(o.stdout,n);if(a.size>0)return a}m(`Batched param fetch failed (exit=${o.exitCode}), falling back to individual calls for ${e}`);let s=new Map;for(let a of n){let c=await Gc(r,e,a);c&&s.set(a,c)}return s}function dr(r){return r.startsWith("127.0.0.1:")}var Dw=["ohos.qemu.hvd.name","const.product.name","const.product.model","const.product.brand","const.product.devicetype","const.build.product"],ce=class r{hdcPath;constructor(e){this.hdcPath=e}static from(e){return new r(e.hdcPath)}static withHdcPath(e){return new r(e)}escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}stripBrandPrefix(e,t){let n=e.trim(),i=t?.trim();if(!n||!i)return n;let o=new RegExp(`^${this.escapeRegExp(i)}(\\s+|[-_]+)?`,"i");return n.replace(o,"").trim()||n}async executeHdc(e){return m(`Executing: ${this.hdcPath} ${e.join(" ")}`),Yx(this.hdcPath,e,{stdio:["ignore","pipe","pipe"]})}async listDevices(){let{stdout:e}=await this.executeHdc(["list","targets"]),t=[];for(let n of e.split(`
42
- `)){let i=n.trim();if(!i||i.startsWith("[Empty]"))continue;let o=i.split(/\s+/),s=o[0];if(!s||s.startsWith("[Empty]"))continue;let a=o.length>=2?o[1]:"device";if(a.toLowerCase()==="unauthorized"){m(`[DeviceManager] Skipping unauthorized device: ${s}`);continue}t.push({serial:s,status:a})}return t}extractDisplayName(e){let t=e.get("ohos.qemu.hvd.name");if(t)return t;let n=e.get("const.product.name");if(n&&n!=="emulator")return n;let i=e.get("const.product.model");if(i&&i!=="emulator"){let s=e.get("const.product.brand");return this.stripBrandPrefix(i,s)}let o=e.get("const.build.product");if(o&&o!=="emulator")return o}async getDeviceName(e){let t=await Zi(this.hdcPath,e,[...Dw]);return this.extractDisplayName(t)??e}async getDeviceInfo(e,t){if(e.length===0)return null;if(t){let n=e.find(s=>s.serial===t);if(n)return n;let i=t.toLowerCase(),o=[];for(let s of e){let a=await this.getDeviceName(s.serial);a.toLowerCase()===i&&o.push({device:s,name:a})}if(o.length===1)return o[0].device;throw o.length>1?new w(`Multiple devices match "${t}". Use a serial instead:
41
+ `),o=i.pop()??"",s=i.map(a=>a.endsWith("\r")?a.slice(0,-1):a).filter(a=>a.length>0);return s.length>0&&t.onData(s,e),o}function mv(r,e,t){let n=r.endsWith("\r")?r.slice(0,-1):r;n.length>0&&t.onData([n],e)}function vA(r,e){return{stdout:r.stdoutChunks.join(""),stderr:r.stderrChunks.join(""),exitCode:e??-1}}function bA(){return{stdoutChunks:[],stderrChunks:[],stdoutLineBuffer:"",stderrLineBuffer:"",settled:!1}}function SA(r,e,t,n,i){r.stdout?.on("data",o=>{let s=o.toString();e.stdoutChunks.push(s),e.stdoutLineBuffer=fv(e.stdoutLineBuffer+s,"stdout",t)}),r.stderr?.on("data",o=>{let s=o.toString();e.stderrChunks.push(s),e.stderrLineBuffer=fv(e.stderrLineBuffer+s,"stderr",t)}),r.on("error",o=>{e.settled||(e.settled=!0,t.onError(o),i(o))}),r.on("close",o=>{if(e.settled)return;e.settled=!0,mv(e.stdoutLineBuffer,"stdout",t),mv(e.stderrLineBuffer,"stderr",t),t.onClose(o);let s=vA(e,o);n(s)})}async function _s(r,e=[],t={}){try{let{stdout:n,stderr:i}=await wA(r,e,t);return{stdout:typeof n=="string"?n.trim():"",stderr:typeof i=="string"?i.trim():"",exitCode:0}}catch(n){let i=n;return{stdout:i.stdout?.trim()||"",stderr:i.stderr?.trim()??i.message,exitCode:typeof i.code=="number"?i.code:1}}}async function gv(r,e,t){return await new Promise((n,i)=>{let o=hA(r,e,{stdio:["inherit","pipe","pipe"]}),s=bA();SA(o,s,t,n,i)})}function hv(r){let e=r.trim(),t=e.indexOf("=");return t!==-1?e.slice(t+1).trim():e}var EA=[/communication channel is being established/i,/please wait for several seconds and try again/i,/device offline/i,/\[E0+04\]/i,/not connected/i],PA=[/\[fail\]/i,/\bfail!/i,/not found/i,/permission denied/i,/device unauthorized/i];function Vt(r){return r?EA.some(e=>e.test(r))?"transient":PA.some(e=>e.test(r))?"fatal":"ok":"ok"}var CA=/(?:^|\s)(\d{2,})(?:\s|$)/;function yv(r){let e=r.stdout.trim(),t=r.stderr.trim();return Vt(e)!=="ok"||Vt(t)!=="ok"?"query-failed":r.exitCode===0?e&&CA.test(e)?"alive":"dead":r.exitCode===1&&!e&&!t?"dead":"query-failed"}var wf=[800,1500,2500];function kA(r){return new Promise(e=>setTimeout(e,r))}async function k(r,e){let t=1+wf.length,n={stdout:"",stderr:"",exitCode:-1};for(let i=0;i<t;i++){if(n=await _s(r,e),n.exitCode===0||Vt(n.stderr)!=="transient"||i>=t-1)return n;f(`hdc transient failure on \`${e.join(" ")}\`: retrying in ${wf[i]}ms`),await kA(wf[i])}return n}var wv=/^[\w.-]+$/;async function ll(r,e,t){if(!wv.test(t)){f(`Skipping invalid param key: ${JSON.stringify(t)}`);return}let n=["-t",e,"shell","param","get",t];f(`Executing: ${r} ${n.join(" ")}`);let i=await k(r,n);if(i.exitCode!==0)return;let o=i.stdout.trim();if(!(!o||Vt(o)!=="ok"))return hv(o)}var vf="__DEVECO_PARAM_DELIM__";function RA(r,e){let t=new Map,n=r.split(vf);for(let i=0;i<e.length;i++){let o=(n[i]??"").trim();if(!o||Vt(o)!=="ok")continue;let s=hv(o);s&&t.set(e[i],s)}return t}async function ao(r,e,t){let n=t.filter(a=>wv.test(a)?!0:(f(`Skipping invalid param key: ${JSON.stringify(a)}`),!1));if(n.length===0)return new Map;if(n.length===1){let a=new Map,c=await ll(r,e,n[0]);return c&&a.set(n[0],c),a}let i=n.map(a=>`param get ${a}`).join(`; echo ${vf}; `)+`; echo ${vf}`,o=await k(r,["-t",e,"shell",i]);if(o.exitCode===0){let a=RA(o.stdout,n);if(a.size>0)return a}f(`Batched param fetch failed (exit=${o.exitCode}), falling back to individual calls for ${e}`);let s=new Map;for(let a of n){let c=await ll(r,e,a);c&&s.set(a,c)}return s}function mr(r){return r.startsWith("127.0.0.1:")}var vv=["ohos.qemu.hvd.name","const.product.name","const.product.model","const.product.brand","const.product.devicetype","const.build.product"],le=class r{hdcPath;constructor(e){this.hdcPath=e}static from(e){return new r(e.hdcPath)}static withHdcPath(e){return new r(e)}escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}stripBrandPrefix(e,t){let n=e.trim(),i=t?.trim();if(!n||!i)return n;let o=new RegExp(`^${this.escapeRegExp(i)}(\\s+|[-_]+)?`,"i");return n.replace(o,"").trim()||n}async executeHdc(e){return f(`Executing: ${this.hdcPath} ${e.join(" ")}`),xA(this.hdcPath,e,{stdio:["ignore","pipe","pipe"]})}async listDevices(){let{stdout:e}=await this.executeHdc(["list","targets"]),t=[];for(let n of e.split(`
42
+ `)){let i=n.trim();if(!i||i.startsWith("[Empty]"))continue;let o=i.split(/\s+/),s=o[0];if(!s||s.startsWith("[Empty]"))continue;let a=o.length>=2?o[1]:"device";if(a.toLowerCase()==="unauthorized"){f(`[DeviceManager] Skipping unauthorized device: ${s}`);continue}t.push({serial:s,status:a})}return t}extractDisplayName(e){let t=e.get("ohos.qemu.hvd.name");if(t)return t;let n=e.get("const.product.name");if(n&&n!=="emulator")return n;let i=e.get("const.product.model");if(i&&i!=="emulator"){let s=e.get("const.product.brand");return this.stripBrandPrefix(i,s)}let o=e.get("const.build.product");if(o&&o!=="emulator")return o}async getDeviceName(e){let t=await ao(this.hdcPath,e,[...vv]);return this.extractDisplayName(t)??e}async getDeviceInfo(e,t){if(e.length===0)return null;if(t){let n=e.find(s=>s.serial===t);if(n)return n;let i=t.toLowerCase(),o=[];for(let s of e){let a=await this.getDeviceName(s.serial);a.toLowerCase()===i&&o.push({device:s,name:a})}if(o.length===1)return o[0].device;throw o.length>1?new w(`Multiple devices match "${t}". Use a serial instead:
43
43
  `+o.map(s=>` - ${s.name} (${s.device.serial})`).join(`
44
- `),"Multiple devices match."):new w(`Device "${t}" not found. Use \`devecocli device list\` to see available targets.`,"Device not found.")}return e[0]}async getDeviceDetail(e){let t={serial:e,status:"device"};try{let n=await Zi(this.hdcPath,e,["const.product.devicetype","const.ohos.apiversion","const.ohos.releasetype"]);t.deviceType=n.get("const.product.devicetype");let i=n.get("const.ohos.apiversion"),o=n.get("const.ohos.releasetype");i&&(t.osVersion=o?`API ${i} (${o})`:`API ${i}`)}catch{}return t}async listDevicesWithName(){let e=await this.listDevices();return Promise.all(e.map(async t=>({serial:t.serial,name:await this.getDeviceName(t.serial)})))}async getConnectedEntries(){let e=await this.listDevices();return Promise.all(e.map(t=>this.buildConnectedEntry(t.serial)))}async buildConnectedEntry(e){let t=dr(e),n,i;try{let o=await Zi(this.hdcPath,e,[...Dw]);n=this.extractDisplayName(o),i=o.get("const.product.devicetype")}catch{}return{serial:e,name:n,isEmulator:t,deviceType:i}}};function Xx(r,e,t,n){let i=["-t",r,"shell","bm","install"];return n?.replace&&i.push("-r"),e&&i.push("-p",e),t&&i.push("-s",t),n?.wait!==void 0&&i.push("-w",String(n.wait)),n?.user&&i.push("-u",n.user),i}var le=class{toolProvider;deviceManager;constructor(e){this.toolProvider=e,this.deviceManager=ce.from(e)}async runHdc(e,t=!0){let n=this.toolProvider.hdcPath;m(`Executing: ${n} ${e.join(" ")}`);try{let{stdout:i}=await Rw(n,e,{env:{...process.env}});return i}catch(i){if(t)throw i;return i.stdout||""}}async listTargets(){return(await this.deviceManager.listDevicesWithName()).map(t=>({name:t.name,id:t.serial}))}async uninstallApp(e,t){P.assertBundleNameStrict(t);let n=await this.runHdc(["-t",e,"shell","bm","uninstall","-n",t],!1);if(n.includes("uninstall bundle successfully"))return!0;if(n.includes("uninstall missing installed bundle"))return!1;throw new Error(`Uninstall failed: ${n}`)}async installApp(e,t,n){let i=!!n?.shared?.length;if(t.length===0&&!i)return;let o=Kx(),s=t.length?`/data/local/tmp/${o}`:null,a=i?`/data/local/tmp/${o}-shared`:null;try{s&&await this.runHdc(["-t",e,"shell","mkdir",s]),a&&await this.runHdc(["-t",e,"shell","mkdir",a]),s&&await this.pushFiles(e,t,s),a&&n?.shared&&await this.pushFiles(e,n.shared,a);let c=Xx(e,s,a,n),l=await this.runHdc(c);if(!l.includes("install bundle successfully."))throw new Error(l)}finally{s&&await this.runHdc(["-t",e,"shell","rm","-rf",s],!1),a&&await this.runHdc(["-t",e,"shell","rm","-rf",a],!1)}}async pushFiles(e,t,n){for(let i of t){let o=await this.runHdc(["-t",e,"file","send",i,n+"/"]);if(!o.startsWith("FileTransfer finish"))throw new Error(o)}}async launchApp(e,t,n){P.assertBundleNameStrict(t),P.assertAbilityName(n);let i=["-t",e,"shell","aa","start","-a",n,"-b",t];return await this.runHdc(i)}async pidofBundle(e,t){P.assertBundleNameStrict(t);let n=["-t",e,"shell","pidof",t],i=this.toolProvider.hdcPath;m(`Executing: ${i} ${n.join(" ")}`);let o=await k(i,n),s=Cw(o);if(s==="query-failed"){let a=[o.stdout,o.stderr].map(c=>c.trim()).filter(Boolean).join(" ");throw new Error(`pidof query failed for '${t}': ${a||`exit ${o.exitCode}`}`)}return s==="alive"}async forceStopApp(e,t){P.assertBundleNameStrict(t);let n=["-t",e,"shell","aa","force-stop",t];return await this.runHdc(n,!1)}async transferFile(e,t,n,i){let o=["-t",e,"file",t,n,i],s=await this.runHdc(o,!1);if(!s.includes("FileTransfer finish"))throw new Error(`File ${t} failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}async runSqlite3(e,t,n=[]){let i=["-t",e,"shell","sqlite3",t,...n];await Rw(this.toolProvider.hdcPath,i,{stdio:"inherit",env:{...process.env}})}};import Bp from"fs";import*as Qn from"path";function Ps(r,e){if(!Bp.existsSync(r))throw new Error(`Apply file list not found: ${r}`);let n=Bp.readFileSync(r,"utf-8").split(/\r?\n/).map(a=>a.trim()).filter(a=>a.length>0&&!a.startsWith("#"));if(n.length===0)throw new Error("Apply file list is empty (no valid entries)");let i=Qn.resolve(e),o=new Set,s=[];for(let a of n){let c=Qn.resolve(i,a),l=Qn.isAbsolute(a)?Qn.relative(i,a):a;if(l.startsWith(".."))throw new Error(`File path is outside the project directory: ${a}`);let d=P.isPathContainedWithSymlink(l,i);if(!d.contained){if(!Bp.existsSync(c))throw new Error(`File not found: ${a}`);let g=d.reason?`; ${d.reason}`:"";throw new Error(`File path is outside the project directory: ${a}${g}`)}o.has(c)||(o.add(c),s.push(c))}return s}import Wp from"fs";import Cs from"path";import{execa as Zx}from"execa";async function xw(r,e,t,n){let i=Cs.dirname(r.javaPath),o={...process.env,PATH:`${i}${Cs.delimiter}${process.env.PATH||""}`,DEVECO_SDK_HOME:r.sdkPath},s=[r.hvigorJsPath,"--mode","module","-p",`module=${t.join(",")}@${n}`,"-p",`product=${n}`,"-p","debuggable=true","assembleDevHqf"];m(`[buildSignedHqf] ${r.nodePath} ${s.join(" ")}`);let a=await Zx(r.nodePath,s,{cwd:e,env:o,stdout:"inherit",stderr:"inherit",reject:!1}),c=(a.exitCode??0)|0;if(c===-1)throw new Error("hvigor hot compile produced invalid abc (exit code -1)");if(c!==0)throw new Error(`hvigor assembleDevHqf failed with exit code ${a.exitCode}`);return t.map(l=>eA(e,l,n))}function Aw(r,e,t){let n=jt(r,e);return Cs.join(r,n,"build",t,"outputs")}function Qx(r,e,t){return Cs.join(Aw(r,e,t),`${e}-${t}-signed.hqf`)}function eA(r,e,t){let n=Aw(r,e,t),i=Qx(r,e,t);if(Wp.existsSync(i))return i;let o=Vp(n,"-signed.hqf")??Vp(n,".hqf");if(!o)throw new Error(`Signed hqf not found at ${i} (and no *.hqf under ${n})`);return m(`[buildSignedHqf] signed hqf not at exact path, using fallback: ${o}`),o}function Vp(r,e){if(!Wp.existsSync(r))return null;for(let t of Wp.readdirSync(r,{withFileTypes:!0})){let n=Cs.join(r,t.name);if(t.isDirectory()){let i=Vp(n,e);if(i)return i}else if(t.isFile()&&t.name.endsWith(e))return n}return null}import de from"fs";import*as U from"path";import Gp from"json5";var Iw="default",Qi=class r{static writeChangedFileLists(e,t,n,i){let o=t||Iw,s=r.loadBuildProfile(e);if(!s)return{writtenModules:[],skippedFiles:n};let a=s.modules,c=r.filterRunnableModules(e,a);if(c.length===0)return{writtenModules:[],skippedFiles:n};let l=r.buildReverseDependencyMap(e,a),d=r.createCollectors(c),g=r.collectChanges(n,e,a,l,d);return{writtenModules:r.flushCollectors(e,o,c,d,i),skippedFiles:g}}static initEmptyChangedFileLists(e,t,n){let i=t||Iw,o=r.loadBuildProfile(e);if(!o)return[];let s=o.modules,a=[];for(let c of s){let l=r.getModuleType(e,c.srcPath);if(l!=="entry"&&l!=="shared")continue;let d=!n||c.name===n;r.initEmptyForModule(e,i,c.srcPath,d),a.push(c.name)}return a}static filterRunnableModules(e,t){return t.filter(n=>{let i=r.getModuleType(e,n.srcPath);return i==="entry"||i==="shared"})}static createCollectors(e){let t=new Map;for(let n of e)t.set(n.name,{hotReloadEntries:[],patchEtsFiles:[],patchRawFiles:[],patchResFiles:[],nativeFiles:[]});return t}static collectChanges(e,t,n,i,o){let s=[];for(let a of e){let c=U.normalize(a),l=r.classifyFile(c,t,n);if(l.fileClass==="unknown"){s.push(c);continue}let d=r.findModuleByFilePath(c,t,n);if(!d){s.push(c);continue}let g=r.resolveTargetModules(d,t,n,i);if(g.length===0){s.push(c);continue}r.dispatchToCollectors(g,o,c,l,d.srcPath,t)}return s}static resolveTargetModules(e,t,n,i){let o=r.getModuleType(t,e.srcPath);return o==="entry"||o==="shared"?[e.name]:Array.from(r.findTopLevelConsumers(e.name,i,t,n))}static dispatchToCollectors(e,t,n,i,o,s){for(let a of e){let c=t.get(a);c&&r.addFileToCollector(c,n,i.fileClass,o,s)}}static flushCollectors(e,t,n,i,o){let s=[];for(let a of n){let c=i.get(a.name);if(!c||!r.hasAnyChange(c))continue;(!o||a.name===o)&&c.hotReloadEntries.length>0&&r.writeApplyFile(e,a.srcPath,t,c.hotReloadEntries),r.writePatchFile(e,a.srcPath,t,c.patchEtsFiles,c.patchRawFiles,c.patchResFiles),s.push(a.name)}return s}static hasAnyChange(e){return e.hotReloadEntries.length>0||e.patchEtsFiles.length>0||e.patchRawFiles.length>0||e.patchResFiles.length>0||e.nativeFiles.length>0}static initEmptyForModule(e,t,n,i){let o=U.join(e,n,"build",t,"intermediates","patch","default"),s=U.join(o,"changedFileList.json");if(de.existsSync(s)||(de.mkdirSync(o,{recursive:!0}),de.writeFileSync(s,JSON.stringify({resources:{resFile:[],rawFile:[]},modifiedFiles:[]}),"utf-8")),!i)return;let a=U.join(e,n,"build",t,"intermediates","hotReload"),c=U.join(a,"changedFileList.json");de.existsSync(c)||(de.mkdirSync(a,{recursive:!0}),de.writeFileSync(c,JSON.stringify({modifiedFilesV2:[]},null,2),"utf-8"))}static loadBuildProfile(e){let t=U.join(e,"build-profile.json5");if(!de.existsSync(t))return null;try{let n=de.readFileSync(t,"utf-8");return Gp.parse(n)}catch{return null}}static classifyFile(e,t,n){let i=U.extname(e).toLowerCase();if(i===".ets"||i===".ts")return{fileClass:"ets_ts",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""};if(i===".cpp"||i===".cc"||i===".c"||i===".h"||i===".hpp")return{fileClass:"native",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""};let o=e.replace(/\\/g,"/");return o.includes("/resources/rawfile/")?{fileClass:"raw_file",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""}:o.includes("/resources/resfile/")?{fileClass:"res_file",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""}:{fileClass:"unknown",moduleSrcPath:""}}static findModuleByFilePath(e,t,n){let i=U.normalize(e);for(let o of n){let s=U.normalize(U.join(t,o.srcPath)),a=s+U.sep;if(i.startsWith(a)||i===s)return o}return null}static getModuleType(e,t){let n=U.join(e,t,"src","main","module.json5");if(!de.existsSync(n))return"entry";try{let i=de.readFileSync(n,"utf-8");return Gp.parse(i)?.module?.type||"entry"}catch{return"entry"}}static buildReverseDependencyMap(e,t){let n=new Map;for(let i of t){let o=r.readLocalDependencies(e,i.srcPath);for(let s of o){let a=n.get(s)||[];a.includes(i.name)||a.push(i.name),n.set(s,a)}}return n}static readLocalDependencies(e,t){let n=U.join(e,t,"oh-package.json5");if(!de.existsSync(n))return[];try{let i=de.readFileSync(n,"utf-8"),o=Gp.parse(i);return r.resolveDepModuleNames(e,t,o.dependencies||{})}catch{return[]}}static resolveDepModuleNames(e,t,n){let i=r.loadBuildProfile(e);if(!i)return[];let o=i.modules,s=[];for(let a of Object.values(n)){if(typeof a!="string")continue;let c=r.tryResolveDepModule(e,t,a,o);c&&s.push(c)}return s}static tryResolveDepModule(e,t,n,i){let o=n;if(!(o.startsWith("file:")||o.startsWith(".")||o.startsWith("..")))return null;o.startsWith("file:")&&(o=o.substring(5));let a=U.resolve(e,t,o);return i.find(l=>U.resolve(e,l.srcPath)===a)?.name??null}static findTopLevelConsumers(e,t,n,i){let o=new Set,s=new Set,a=[e];for(;a.length>0;){let c=a.shift();s.has(c)||(s.add(c),r.processDependents(c,t,n,i,o,a))}return o}static processDependents(e,t,n,i,o,s){let a=t.get(e)||[];for(let c of a){let l=i.find(g=>g.name===c);if(!l)continue;let d=r.getModuleType(n,l.srcPath);(d==="entry"||d==="shared")&&o.add(c),d==="har"&&s.push(c)}}static addFileToCollector(e,t,n,i,o){let s=U.join(o,i,"src","main","resources");n==="ets_ts"?(e.hotReloadEntries.push({filePath:t,belongProjectPath:o}),e.patchEtsFiles.push(t)):n==="raw_file"?e.patchRawFiles.push({filePath:t,resourcePath:s}):n==="res_file"?e.patchResFiles.push({filePath:t,resourcePath:s}):n==="native"&&e.nativeFiles.push(t)}static writeApplyFile(e,t,n,i){let o=t.replace(/^\.\//,""),s=U.join(e,o,"build",n,"intermediates","hotReload","changedFileList.json"),a=r.readExistingApply(s),c=r.mergeApplyEntries(a,i),l=U.dirname(s);de.existsSync(l)||de.mkdirSync(l,{recursive:!0}),de.writeFileSync(s,JSON.stringify({modifiedFilesV2:c},null,2),"utf-8"),m(`[ChangedFileListWriter] Written hotReload: ${s} (${c.length} entries)`)}static readExistingApply(e){if(!de.existsSync(e))return[];try{let t=de.readFileSync(e,"utf-8");return JSON.parse(t)?.modifiedFilesV2||[]}catch{return[]}}static writePatchFile(e,t,n,i,o,s){let a=t.replace(/^\.\//,""),c=U.join(e,a,"build",n,"intermediates","patch","default","changedFileList.json"),l=r.readExistingPatch(c),d=U.join(e,a,"src","main","ets"),g=i.map(ut=>r.resolveRelativePathForPatch(ut,d)),y=r.mergeStrings(l.modifiedFiles,g),E=r.mergePatchResources(l.rawFile,o),j=r.mergePatchResources(l.resFile,s),ye=U.dirname(c);de.existsSync(ye)||de.mkdirSync(ye,{recursive:!0}),de.writeFileSync(c,JSON.stringify({resources:{resFile:j,rawFile:E},modifiedFiles:y}),"utf-8"),m(`[ChangedFileListWriter] Written patch: ${c}`)}static readExistingPatch(e){if(!de.existsSync(e))return{modifiedFiles:[],rawFile:[],resFile:[]};try{let t=de.readFileSync(e,"utf-8"),n=JSON.parse(t);return{modifiedFiles:n?.modifiedFiles||[],rawFile:n?.resources?.rawFile||[],resFile:n?.resources?.resFile||[]}}catch{return{modifiedFiles:[],rawFile:[],resFile:[]}}}static resolveRelativePathForPatch(e,t){return U.relative(U.normalize(t),U.normalize(e)).replace(/\\/g,"/")}static mergeApplyEntries(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o.filePath)||(n.add(o.filePath),i.push(o));return i}static mergeStrings(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o)||(n.add(o),i.push(o));return i}static mergePatchResources(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o.filePath)||(n.add(o.filePath),i.push(o));return i}};import tA from"fs";import{randomUUID as rA}from"crypto";import{execa as nA}from"execa";var eo=class{toolProvider;constructor(e){this.toolProvider=e}async install(e,t,n){for(let a of t)if(!tA.existsSync(a)){let c=`Signed hqf file not found: ${a}`;return console.error(`[Apply] ${c}`),{success:!1,message:c}}P.assertBundleName(n);let o=`/data/local/tmp/${rA()}`,s=[];try{for(let a=0;a<t.length;a++){let c=`${o}/${n}_${a}.hqf`;s.push(c),await this.pushHqf(e,t[a],o,c)}return await this.executeQuickfix(e,s)}catch(a){let c=`hqf install error: ${a.message}`;return console.error(`[Apply] ${c}`),{success:!1,message:c}}finally{await this.runHdc(["-t",e,"shell","rm","-rf",o],!1)}}async pushHqf(e,t,n,i){console.log(`[Apply] Pushing hqf to device ${e}: ${t}`),await this.runHdc(["-t",e,"shell","mkdir","-p",n]);let o=await this.runHdc(["-t",e,"file","send",t,i]);if(!o.startsWith("FileTransfer finish"))throw new Error(`Failed to send hqf: ${o}`)}async executeQuickfix(e,t){console.log(`[Apply] Installing ${t.length} hqf patch(es) via quickfix...`);let n=["-t",e,"shell","bm","quickfix","-a","-f",...t,"-d"];await this.getApiVersion(e)>17&&n.push("-o");let o=await this.runHdc(n,!1);if(m(`[InstallHqf] quickfix output: ${o}`),/succe(?:ed|ss)/i.test(o))return console.log("[Apply] hqf installed successfully."),{success:!0,message:"hqf quickfix installed successfully."};let s=`hqf quickfix install failed. Device response: ${o||"(empty)"}. Please try reinstalling the application.`;return console.error(`[Apply] ${s}`),{success:!1,message:s}}async getApiVersion(e){try{let t=await this.runHdc(["-t",e,"shell","param","get","const.ohos.apiversion"],!1),n=parseInt(t.trim(),10);if(!isNaN(n))return console.log(`[InstallHqf] device API version: ${n}`),n}catch{}return 0}async runHdc(e,t=!0){let n=this.toolProvider.hdcPath;m(`[InstallHqf] Executing: ${n} ${e.join(" ")}`);try{let{stdout:i}=await nA(n,e,{env:{...process.env}});return i}catch(i){if(t)throw i;return i.stdout||""}}};var iA="6.1.1",qc=class{constructor(e,t){this.toolProvider=e;this.projectRoot=t}async execute(e){await xr(this.projectRoot,()=>this.executeSteps(e),()=>console.log("[Apply] Waiting for another build to finish..."))}async executeSteps(e){this.toolProvider.assertIdeVersion(iA);let t=Ps(e.applyFile,this.projectRoot);console.log(`[Apply] Parsed ${t.length} changed file(s)`);let n=this.writeChangeFileList(e,t);await this.stopApp(e);let i=await this.buildHqf(e,n);await this.installHqf(e,i),await this.launchApp(e),console.log("[Apply] Apply complete")}writeChangeFileList(e,t){let n=Qi.writeChangedFileLists(this.projectRoot,e.productName,t);if(n.writtenModules.length===0)throw new Error("No changed files belong to a runnable module");return console.log(`[Apply] changeFileList written for: ${n.writtenModules.join(", ")}`),n.writtenModules}async buildHqf(e,t){return m(`[Apply] hvigor assembleDevHqf --no-daemon (modules=${t.join(",")})`),await cr.withBuildConfig(this.projectRoot,t,e.productName,this.toolProvider,()=>xw(this.toolProvider,this.projectRoot,t,e.productName))}async installHqf(e,t){console.log(`[Apply] Installing ${t.length} hqf(s) to ${e.targetDeviceId}`);let i=await new eo(this.toolProvider).install(e.targetDeviceId,t,e.bundleName);if(!i.success)throw new Error(`hqf install failed: ${i.message}`);console.log("[Apply] hqf installed")}async stopApp(e){let t=new le(this.toolProvider);try{await t.forceStopApp(e.targetDeviceId,e.bundleName),console.log("[Apply] app stopped")}catch(n){console.warn(`[Apply] stop app failed: ${n.message}`)}}async launchApp(e){let t=new le(this.toolProvider);try{await t.launchApp(e.targetDeviceId,e.bundleName,e.abilityName),console.log("[Apply] app launched")}catch(n){throw new Error(`[Apply] launch app failed: ${n.message}`,{cause:n})}}};import Tw from"fs";import*as Q from"path";var zc=class r{static generate(e,t,n,i){let o=jt(e,t),s=Q.join(e,o),a=Q.join(s,"build","config"),c=r.buildConfig(e,s,n,i);Tw.mkdirSync(a,{recursive:!0}),Tw.writeFileSync(Q.join(a,"buildConfig.json"),JSON.stringify(c,null,2),"utf-8"),m(`[HotReloadBuildConfigManager] buildConfig.json written to ${a}`)}static buildConfig(e,t,n,i){let o=Q.dirname(i.nodePath)+Q.sep,s=Q.join(t,"build",n),a=Q.join(s,"intermediates"),c=Q.join(a,"loader_out",n),l=Q.join(a,"res",n);return{compileConfig:{deviceType:"default",buildMode:"debug",compilerType:"ark",note:"false",logLevel:"3",hapMode:"false",img2bin:"true",Path:o,projectProfilePath:Q.join(e,"build-profile.json5"),localPropertiesPath:Q.join(e,"local.properties"),appResource:Q.join(l,"ResourceTable.txt"),cachePath:Q.join(s,"cache",n,`${n}@CompileArkTS`,"esmodule","debug"),aceBuildJson:Q.join(a,"loader",n,"loader.json"),aceModuleJsonPath:Q.join(l,"module.json"),aceSoPath:Q.join(c,"nativeDependencies.txt"),aceModuleRoot:Q.join(t,"src","main","ets"),aceModuleBuild:Q.join(c,"ets"),aceProfilePath:Q.join(l,"resources","base","profile"),aceSuperVisualPath:Q.join(t,"src","main","supervisual"),watchMode:"true"},patchConfig:{enableMap:"true",mode:"hotReload",oldMapFilePath:Q.join(c,"ets"),changedFileList:Q.join(a,"hotReload","changedFileList.json"),patchAbcPath:Q.join(a,"hotReload","patchAbcPath","ets"),removeChangedFileListInSdk:"true"}}}};import Ow from"crypto";import Ct from"fs";import kt from"path";import Nw from"os";import{io as oA}from"socket.io-client";var sA=new Int8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]),to=class r{projectRoot;toolProvider;cachedSocket=null;cachedDaemonPort=0;constructor(e,t){this.projectRoot=e,this.toolProvider=t}async sendHotCompile(e){await this.waitForDaemonReady();let t=this.findProjectDaemon();if(!t?.sessionId)throw new Error("No running hvigor daemon with sessionId found. Run `devecocli run --hotreload` first.");return this.sendViaSocket(t,e)}async startWatchSession(e){await this.waitForDaemonReady(),console.log(`[DaemonClient] Compiling, build with: ${JSON.stringify(e)}`);let t=this.findProjectDaemon();if(!t?.sessionId)throw new Error("No running hvigor daemon with sessionId found. Build the hap first.");let n=await this.getOrCreateSocket(t),i=this.watchLogPath;Ct.mkdirSync(kt.dirname(i),{recursive:!0}),Ct.writeFileSync(i,"");let o=this.createWatchLogBuffer(i);n.on("WatchLog",o.onWatchLog),n.on("WatchResult",o.onWatchResult),await this.awaitInitialBuild(n,e)}createWatchLogBuffer(e){let n=[];return{onWatchLog:s=>{let a=r.extractText(s);a.trim()&&(n.push(a.endsWith(`
44
+ `),"Multiple devices match."):new w(`Device "${t}" not found. Use \`devecocli device list\` to see available targets.`,"Device not found.")}return e[0]}async getDeviceDetail(e){let t={serial:e,status:"device"};try{let n=await ao(this.hdcPath,e,["const.product.devicetype","const.ohos.apiversion","const.ohos.releasetype"]);t.deviceType=n.get("const.product.devicetype");let i=n.get("const.ohos.apiversion"),o=n.get("const.ohos.releasetype");i&&(t.osVersion=o?`API ${i} (${o})`:`API ${i}`)}catch{}return t}async listDevicesWithName(){let e=await this.listDevices();return Promise.all(e.map(async t=>({serial:t.serial,name:await this.getDeviceName(t.serial)})))}async getConnectedEntries(){let e=await this.listDevices();return Promise.all(e.map(t=>this.buildConnectedEntry(t.serial)))}async buildConnectedEntry(e){let t=mr(e),n,i;try{let o=await ao(this.hdcPath,e,[...vv]);n=this.extractDisplayName(o),i=o.get("const.product.devicetype")}catch{}return{serial:e,name:n,isEmulator:t,deviceType:i}}};function IA(r,e,t,n){let i=["-t",r,"shell","bm","install"];return n?.replace&&i.push("-r"),e&&i.push("-p",e),t&&i.push("-s",t),n?.wait!==void 0&&i.push("-w",String(n.wait)),n?.user&&i.push("-u",n.user),i}var de=class{toolProvider;deviceManager;constructor(e){this.toolProvider=e,this.deviceManager=le.from(e)}async runHdc(e,t=!0){let n=this.toolProvider.hdcPath;f(`Executing: ${n} ${e.join(" ")}`);try{let{stdout:i}=await bv(n,e,{env:{...process.env}});return i}catch(i){if(t)throw i;return i.stdout||""}}async listTargets(){return(await this.deviceManager.listDevicesWithName()).map(t=>({name:t.name,id:t.serial}))}async uninstallApp(e,t){P.assertBundleNameStrict(t);let n=await this.runHdc(["-t",e,"shell","bm","uninstall","-n",t],!1);if(n.includes("uninstall bundle successfully"))return!0;if(n.includes("uninstall missing installed bundle"))return!1;throw new Error(`Uninstall failed: ${n}`)}async installApp(e,t,n){let i=!!n?.shared?.length;if(t.length===0&&!i)return;let o=DA(),s=t.length?`/data/local/tmp/${o}`:null,a=i?`/data/local/tmp/${o}-shared`:null;try{s&&await this.runHdc(["-t",e,"shell","mkdir",s]),a&&await this.runHdc(["-t",e,"shell","mkdir",a]),s&&await this.pushFiles(e,t,s),a&&n?.shared&&await this.pushFiles(e,n.shared,a);let c=IA(e,s,a,n),l=await this.runHdc(c);if(!l.includes("install bundle successfully."))throw new Error(l)}finally{s&&await this.runHdc(["-t",e,"shell","rm","-rf",s],!1),a&&await this.runHdc(["-t",e,"shell","rm","-rf",a],!1)}}async pushFiles(e,t,n){for(let i of t){let o=await this.runHdc(["-t",e,"file","send",i,n+"/"]);if(!o.startsWith("FileTransfer finish"))throw new Error(o)}}async launchApp(e,t,n){P.assertBundleNameStrict(t),P.assertAbilityName(n);let i=["-t",e,"shell","aa","start","-a",n,"-b",t];return await this.runHdc(i)}async pidofBundle(e,t){P.assertBundleNameStrict(t);let n=["-t",e,"shell","pidof",t],i=this.toolProvider.hdcPath;f(`Executing: ${i} ${n.join(" ")}`);let o=await k(i,n),s=yv(o);if(s==="query-failed"){let a=[o.stdout,o.stderr].map(c=>c.trim()).filter(Boolean).join(" ");throw new Error(`pidof query failed for '${t}': ${a||`exit ${o.exitCode}`}`)}return s==="alive"}async forceStopApp(e,t){P.assertBundleNameStrict(t);let n=["-t",e,"shell","aa","force-stop",t];return await this.runHdc(n,!1)}async transferFile(e,t,n,i){let o=["-t",e,"file",t,n,i],s=await this.runHdc(o,!1);if(!s.includes("FileTransfer finish"))throw new Error(`File ${t} failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}async runSqlite3(e,t,n=[]){let i=["-t",e,"shell","sqlite3",t,...n];await bv(this.toolProvider.hdcPath,i,{stdio:"inherit",env:{...process.env}})}};import bf from"fs";import*as ni from"path";function Ms(r,e){if(!bf.existsSync(r))throw new Error(`Apply file list not found: ${r}`);let n=bf.readFileSync(r,"utf-8").split(/\r?\n/).map(a=>a.trim()).filter(a=>a.length>0&&!a.startsWith("#"));if(n.length===0)throw new Error("Apply file list is empty (no valid entries)");let i=ni.resolve(e),o=new Set,s=[];for(let a of n){let c=ni.resolve(i,a),l=ni.isAbsolute(a)?ni.relative(i,a):a;if(l.startsWith(".."))throw new Error(`File path is outside the project directory: ${a}`);let d=P.isPathContainedWithSymlink(l,i);if(!d.contained){if(!bf.existsSync(c))throw new Error(`File not found: ${a}`);let g=d.reason?`; ${d.reason}`:"";throw new Error(`File path is outside the project directory: ${a}${g}`)}o.has(c)||(o.add(c),s.push(c))}return s}import Sf from"fs";import Ls from"path";import{execa as AA}from"execa";async function Sv(r,e,t,n){let i=Ls.dirname(r.javaPath),o={...process.env,PATH:`${i}${Ls.delimiter}${process.env.PATH||""}`,DEVECO_SDK_HOME:r.sdkPath},s=[r.hvigorJsPath,"--mode","module","-p",`module=${t.join(",")}@${n}`,"-p",`product=${n}`,"-p","debuggable=true","assembleDevHqf"];f(`[buildSignedHqf] ${r.nodePath} ${s.join(" ")}`);let a=await AA(r.nodePath,s,{cwd:e,env:o,stdout:"inherit",stderr:"inherit",reject:!1}),c=(a.exitCode??0)|0;if(c===-1)throw new Error("hvigor hot compile produced invalid abc (exit code -1)");if(c!==0)throw new Error(`hvigor assembleDevHqf failed with exit code ${a.exitCode}`);return t.map(l=>NA(e,l,n))}function Ev(r,e,t){let n=Bt(r,e);return Ls.join(r,n,"build",t,"outputs")}function TA(r,e,t){return Ls.join(Ev(r,e,t),`${e}-${t}-signed.hqf`)}function NA(r,e,t){let n=Ev(r,e,t),i=TA(r,e,t);if(Sf.existsSync(i))return i;let o=Ef(n,"-signed.hqf")??Ef(n,".hqf");if(!o)throw new Error(`Signed hqf not found at ${i} (and no *.hqf under ${n})`);return f(`[buildSignedHqf] signed hqf not at exact path, using fallback: ${o}`),o}function Ef(r,e){if(!Sf.existsSync(r))return null;for(let t of Sf.readdirSync(r,{withFileTypes:!0})){let n=Ls.join(r,t.name);if(t.isDirectory()){let i=Ef(n,e);if(i)return i}else if(t.isFile()&&t.name.endsWith(e))return n}return null}import ue from"fs";import*as U from"path";import Pf from"json5";var Pv="default",co=class r{static writeChangedFileLists(e,t,n,i){let o=t||Pv,s=r.loadBuildProfile(e);if(!s)return{writtenModules:[],skippedFiles:n};let a=s.modules,c=r.filterRunnableModules(e,a);if(c.length===0)return{writtenModules:[],skippedFiles:n};let l=r.buildReverseDependencyMap(e,a),d=r.createCollectors(c),g=r.collectChanges(n,e,a,l,d);return{writtenModules:r.flushCollectors(e,o,c,d,i),skippedFiles:g}}static initEmptyChangedFileLists(e,t,n){let i=t||Pv,o=r.loadBuildProfile(e);if(!o)return[];let s=o.modules,a=[];for(let c of s){let l=r.getModuleType(e,c.srcPath);if(l!=="entry"&&l!=="shared")continue;let d=!n||c.name===n;r.initEmptyForModule(e,i,c.srcPath,d),a.push(c.name)}return a}static filterRunnableModules(e,t){return t.filter(n=>{let i=r.getModuleType(e,n.srcPath);return i==="entry"||i==="shared"})}static createCollectors(e){let t=new Map;for(let n of e)t.set(n.name,{hotReloadEntries:[],patchEtsFiles:[],patchRawFiles:[],patchResFiles:[],nativeFiles:[]});return t}static collectChanges(e,t,n,i,o){let s=[];for(let a of e){let c=U.normalize(a),l=r.classifyFile(c,t,n);if(l.fileClass==="unknown"){s.push(c);continue}let d=r.findModuleByFilePath(c,t,n);if(!d){s.push(c);continue}let g=r.resolveTargetModules(d,t,n,i);if(g.length===0){s.push(c);continue}r.dispatchToCollectors(g,o,c,l,d.srcPath,t)}return s}static resolveTargetModules(e,t,n,i){let o=r.getModuleType(t,e.srcPath);return o==="entry"||o==="shared"?[e.name]:Array.from(r.findTopLevelConsumers(e.name,i,t,n))}static dispatchToCollectors(e,t,n,i,o,s){for(let a of e){let c=t.get(a);c&&r.addFileToCollector(c,n,i.fileClass,o,s)}}static flushCollectors(e,t,n,i,o){let s=[];for(let a of n){let c=i.get(a.name);if(!c||!r.hasAnyChange(c))continue;(!o||a.name===o)&&c.hotReloadEntries.length>0&&r.writeApplyFile(e,a.srcPath,t,c.hotReloadEntries),r.writePatchFile(e,a.srcPath,t,c.patchEtsFiles,c.patchRawFiles,c.patchResFiles),s.push(a.name)}return s}static hasAnyChange(e){return e.hotReloadEntries.length>0||e.patchEtsFiles.length>0||e.patchRawFiles.length>0||e.patchResFiles.length>0||e.nativeFiles.length>0}static initEmptyForModule(e,t,n,i){let o=U.join(e,n,"build",t,"intermediates","patch","default"),s=U.join(o,"changedFileList.json");if(ue.existsSync(s)||(ue.mkdirSync(o,{recursive:!0}),ue.writeFileSync(s,JSON.stringify({resources:{resFile:[],rawFile:[]},modifiedFiles:[]}),"utf-8")),!i)return;let a=U.join(e,n,"build",t,"intermediates","hotReload"),c=U.join(a,"changedFileList.json");ue.existsSync(c)||(ue.mkdirSync(a,{recursive:!0}),ue.writeFileSync(c,JSON.stringify({modifiedFilesV2:[]},null,2),"utf-8"))}static loadBuildProfile(e){let t=U.join(e,"build-profile.json5");if(!ue.existsSync(t))return null;try{let n=ue.readFileSync(t,"utf-8");return Pf.parse(n)}catch{return null}}static classifyFile(e,t,n){let i=U.extname(e).toLowerCase();if(i===".ets"||i===".ts")return{fileClass:"ets_ts",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""};if(i===".cpp"||i===".cc"||i===".c"||i===".h"||i===".hpp")return{fileClass:"native",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""};let o=e.replace(/\\/g,"/");return o.includes("/resources/rawfile/")?{fileClass:"raw_file",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""}:o.includes("/resources/resfile/")?{fileClass:"res_file",moduleSrcPath:r.findModuleByFilePath(e,t,n)?.srcPath??""}:{fileClass:"unknown",moduleSrcPath:""}}static findModuleByFilePath(e,t,n){let i=U.normalize(e);for(let o of n){let s=U.normalize(U.join(t,o.srcPath)),a=s+U.sep;if(i.startsWith(a)||i===s)return o}return null}static getModuleType(e,t){let n=U.join(e,t,"src","main","module.json5");if(!ue.existsSync(n))return"entry";try{let i=ue.readFileSync(n,"utf-8");return Pf.parse(i)?.module?.type||"entry"}catch{return"entry"}}static buildReverseDependencyMap(e,t){let n=new Map;for(let i of t){let o=r.readLocalDependencies(e,i.srcPath);for(let s of o){let a=n.get(s)||[];a.includes(i.name)||a.push(i.name),n.set(s,a)}}return n}static readLocalDependencies(e,t){let n=U.join(e,t,"oh-package.json5");if(!ue.existsSync(n))return[];try{let i=ue.readFileSync(n,"utf-8"),o=Pf.parse(i);return r.resolveDepModuleNames(e,t,o.dependencies||{})}catch{return[]}}static resolveDepModuleNames(e,t,n){let i=r.loadBuildProfile(e);if(!i)return[];let o=i.modules,s=[];for(let a of Object.values(n)){if(typeof a!="string")continue;let c=r.tryResolveDepModule(e,t,a,o);c&&s.push(c)}return s}static tryResolveDepModule(e,t,n,i){let o=n;if(!(o.startsWith("file:")||o.startsWith(".")||o.startsWith("..")))return null;o.startsWith("file:")&&(o=o.substring(5));let a=U.resolve(e,t,o);return i.find(l=>U.resolve(e,l.srcPath)===a)?.name??null}static findTopLevelConsumers(e,t,n,i){let o=new Set,s=new Set,a=[e];for(;a.length>0;){let c=a.shift();s.has(c)||(s.add(c),r.processDependents(c,t,n,i,o,a))}return o}static processDependents(e,t,n,i,o,s){let a=t.get(e)||[];for(let c of a){let l=i.find(g=>g.name===c);if(!l)continue;let d=r.getModuleType(n,l.srcPath);(d==="entry"||d==="shared")&&o.add(c),d==="har"&&s.push(c)}}static addFileToCollector(e,t,n,i,o){let s=U.join(o,i,"src","main","resources");n==="ets_ts"?(e.hotReloadEntries.push({filePath:t,belongProjectPath:o}),e.patchEtsFiles.push(t)):n==="raw_file"?e.patchRawFiles.push({filePath:t,resourcePath:s}):n==="res_file"?e.patchResFiles.push({filePath:t,resourcePath:s}):n==="native"&&e.nativeFiles.push(t)}static writeApplyFile(e,t,n,i){let o=t.replace(/^\.\//,""),s=U.join(e,o,"build",n,"intermediates","hotReload","changedFileList.json"),a=r.readExistingApply(s),c=r.mergeApplyEntries(a,i),l=U.dirname(s);ue.existsSync(l)||ue.mkdirSync(l,{recursive:!0}),ue.writeFileSync(s,JSON.stringify({modifiedFilesV2:c},null,2),"utf-8"),f(`[ChangedFileListWriter] Written hotReload: ${s} (${c.length} entries)`)}static readExistingApply(e){if(!ue.existsSync(e))return[];try{let t=ue.readFileSync(e,"utf-8");return JSON.parse(t)?.modifiedFilesV2||[]}catch{return[]}}static writePatchFile(e,t,n,i,o,s){let a=t.replace(/^\.\//,""),c=U.join(e,a,"build",n,"intermediates","patch","default","changedFileList.json"),l=r.readExistingPatch(c),d=U.join(e,a,"src","main","ets"),g=i.map(pt=>r.resolveRelativePathForPatch(pt,d)),y=r.mergeStrings(l.modifiedFiles,g),E=r.mergePatchResources(l.rawFile,o),K=r.mergePatchResources(l.resFile,s),we=U.dirname(c);ue.existsSync(we)||ue.mkdirSync(we,{recursive:!0}),ue.writeFileSync(c,JSON.stringify({resources:{resFile:K,rawFile:E},modifiedFiles:y}),"utf-8"),f(`[ChangedFileListWriter] Written patch: ${c}`)}static readExistingPatch(e){if(!ue.existsSync(e))return{modifiedFiles:[],rawFile:[],resFile:[]};try{let t=ue.readFileSync(e,"utf-8"),n=JSON.parse(t);return{modifiedFiles:n?.modifiedFiles||[],rawFile:n?.resources?.rawFile||[],resFile:n?.resources?.resFile||[]}}catch{return{modifiedFiles:[],rawFile:[],resFile:[]}}}static resolveRelativePathForPatch(e,t){return U.relative(U.normalize(t),U.normalize(e)).replace(/\\/g,"/")}static mergeApplyEntries(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o.filePath)||(n.add(o.filePath),i.push(o));return i}static mergeStrings(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o)||(n.add(o),i.push(o));return i}static mergePatchResources(e,t){let n=new Set,i=[];for(let o of[...e,...t])n.has(o.filePath)||(n.add(o.filePath),i.push(o));return i}};import OA from"fs";import{randomUUID as _A}from"crypto";import{execa as MA}from"execa";var lo=class{toolProvider;constructor(e){this.toolProvider=e}async install(e,t,n){for(let a of t)if(!OA.existsSync(a)){let c=`Signed hqf file not found: ${a}`;return console.error(`[Apply] ${c}`),{success:!1,message:c}}P.assertBundleName(n);let o=`/data/local/tmp/${_A()}`,s=[];try{for(let a=0;a<t.length;a++){let c=`${o}/${n}_${a}.hqf`;s.push(c),await this.pushHqf(e,t[a],o,c)}return await this.executeQuickfix(e,s)}catch(a){let c=`hqf install error: ${a.message}`;return console.error(`[Apply] ${c}`),{success:!1,message:c}}finally{await this.runHdc(["-t",e,"shell","rm","-rf",o],!1)}}async pushHqf(e,t,n,i){console.log(`[Apply] Pushing hqf to device ${e}: ${t}`),await this.runHdc(["-t",e,"shell","mkdir","-p",n]);let o=await this.runHdc(["-t",e,"file","send",t,i]);if(!o.startsWith("FileTransfer finish"))throw new Error(`Failed to send hqf: ${o}`)}async executeQuickfix(e,t){console.log(`[Apply] Installing ${t.length} hqf patch(es) via quickfix...`);let n=["-t",e,"shell","bm","quickfix","-a","-f",...t,"-d"];await this.getApiVersion(e)>17&&n.push("-o");let o=await this.runHdc(n,!1);if(f(`[InstallHqf] quickfix output: ${o}`),/succe(?:ed|ss)/i.test(o))return console.log("[Apply] hqf installed successfully."),{success:!0,message:"hqf quickfix installed successfully."};let s=`hqf quickfix install failed. Device response: ${o||"(empty)"}. Please try reinstalling the application.`;return console.error(`[Apply] ${s}`),{success:!1,message:s}}async getApiVersion(e){try{let t=await this.runHdc(["-t",e,"shell","param","get","const.ohos.apiversion"],!1),n=parseInt(t.trim(),10);if(!isNaN(n))return console.log(`[InstallHqf] device API version: ${n}`),n}catch{}return 0}async runHdc(e,t=!0){let n=this.toolProvider.hdcPath;f(`[InstallHqf] Executing: ${n} ${e.join(" ")}`);try{let{stdout:i}=await MA(n,e,{env:{...process.env}});return i}catch(i){if(t)throw i;return i.stdout||""}}};var LA="6.1.1",dl=class{constructor(e,t){this.toolProvider=e;this.projectRoot=t}async execute(e){await Nr(this.projectRoot,()=>this.executeSteps(e),()=>console.log("[Apply] Waiting for another build to finish..."))}async executeSteps(e){this.toolProvider.assertIdeVersion(LA);let t=Ms(e.applyFile,this.projectRoot);console.log(`[Apply] Parsed ${t.length} changed file(s)`);let n=this.writeChangeFileList(e,t);await this.stopApp(e);let i=await this.buildHqf(e,n);await this.installHqf(e,i),await this.launchApp(e),console.log("[Apply] Apply complete")}writeChangeFileList(e,t){let n=co.writeChangedFileLists(this.projectRoot,e.productName,t);if(n.writtenModules.length===0)throw new Error("No changed files belong to a runnable module");return console.log(`[Apply] changeFileList written for: ${n.writtenModules.join(", ")}`),n.writtenModules}async buildHqf(e,t){return f(`[Apply] hvigor assembleDevHqf --no-daemon (modules=${t.join(",")})`),await pr.withBuildConfig(this.projectRoot,t,e.productName,this.toolProvider,()=>Sv(this.toolProvider,this.projectRoot,t,e.productName))}async installHqf(e,t){console.log(`[Apply] Installing ${t.length} hqf(s) to ${e.targetDeviceId}`);let i=await new lo(this.toolProvider).install(e.targetDeviceId,t,e.bundleName);if(!i.success)throw new Error(`hqf install failed: ${i.message}`);console.log("[Apply] hqf installed")}async stopApp(e){let t=new de(this.toolProvider);try{await t.forceStopApp(e.targetDeviceId,e.bundleName),console.log("[Apply] app stopped")}catch(n){console.warn(`[Apply] stop app failed: ${n.message}`)}}async launchApp(e){let t=new de(this.toolProvider);try{await t.launchApp(e.targetDeviceId,e.bundleName,e.abilityName),console.log("[Apply] app launched")}catch(n){throw new Error(`[Apply] launch app failed: ${n.message}`,{cause:n})}}};import Cv from"fs";import*as ee from"path";var ul=class r{static generate(e,t,n,i){let o=Bt(e,t),s=ee.join(e,o),a=ee.join(s,"build","config"),c=r.buildConfig(e,s,n,i);Cv.mkdirSync(a,{recursive:!0}),Cv.writeFileSync(ee.join(a,"buildConfig.json"),JSON.stringify(c,null,2),"utf-8"),f(`[HotReloadBuildConfigManager] buildConfig.json written to ${a}`)}static buildConfig(e,t,n,i){let o=ee.dirname(i.nodePath)+ee.sep,s=ee.join(t,"build",n),a=ee.join(s,"intermediates"),c=ee.join(a,"loader_out",n),l=ee.join(a,"res",n);return{compileConfig:{deviceType:"default",buildMode:"debug",compilerType:"ark",note:"false",logLevel:"3",hapMode:"false",img2bin:"true",Path:o,projectProfilePath:ee.join(e,"build-profile.json5"),localPropertiesPath:ee.join(e,"local.properties"),appResource:ee.join(l,"ResourceTable.txt"),cachePath:ee.join(s,"cache",n,`${n}@CompileArkTS`,"esmodule","debug"),aceBuildJson:ee.join(a,"loader",n,"loader.json"),aceModuleJsonPath:ee.join(l,"module.json"),aceSoPath:ee.join(c,"nativeDependencies.txt"),aceModuleRoot:ee.join(t,"src","main","ets"),aceModuleBuild:ee.join(c,"ets"),aceProfilePath:ee.join(l,"resources","base","profile"),aceSuperVisualPath:ee.join(t,"src","main","supervisual"),watchMode:"true"},patchConfig:{enableMap:"true",mode:"hotReload",oldMapFilePath:ee.join(c,"ets"),changedFileList:ee.join(a,"hotReload","changedFileList.json"),patchAbcPath:ee.join(a,"hotReload","patchAbcPath","ets"),removeChangedFileListInSdk:"true"}}}};import kv from"crypto";import kt from"fs";import Rt from"path";import Rv from"os";import{io as FA}from"socket.io-client";var $A=new Int8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]),uo=class r{projectRoot;toolProvider;cachedSocket=null;cachedDaemonPort=0;constructor(e,t){this.projectRoot=e,this.toolProvider=t}async sendHotCompile(e){await this.waitForDaemonReady();let t=this.findProjectDaemon();if(!t?.sessionId)throw new Error("No running hvigor daemon with sessionId found. Run `devecocli run --hotreload` first.");return this.sendViaSocket(t,e)}async startWatchSession(e){await this.waitForDaemonReady(),console.log(`[DaemonClient] Compiling, build with: ${JSON.stringify(e)}`);let t=this.findProjectDaemon();if(!t?.sessionId)throw new Error("No running hvigor daemon with sessionId found. Build the hap first.");let n=await this.getOrCreateSocket(t),i=this.watchLogPath;kt.mkdirSync(Rt.dirname(i),{recursive:!0}),kt.writeFileSync(i,"");let o=this.createWatchLogBuffer(i);n.on("WatchLog",o.onWatchLog),n.on("WatchResult",o.onWatchResult),await this.awaitInitialBuild(n,e)}createWatchLogBuffer(e){let n=[];return{onWatchLog:s=>{let a=r.extractText(s);a.trim()&&(n.push(a.endsWith(`
45
45
  `)?a:a+`
46
- `),n.length>100&&n.shift())},onWatchResult:s=>{let a=r.extractText(s);if(!a.trim())return;let c=`[WatchResult] ${a}`;console.log(c),Ct.writeFileSync(e,[...n,c+`
47
- `].join("")),n.length=0}}}awaitInitialBuild(e,t){return new Promise((n,i)=>{let o=!1,s=this.createOutputHandler(),a=l=>{!l?.status||o||(l.status==="finish"?(o=!0,e.off("disconnect",c),e.off("Output",s),e.off("BuildStatus",a),n()):(l.status==="reject"||l.status==="close")&&(o=!0,e.off("disconnect",c),e.off("Output",s),e.off("BuildStatus",a),this.invalidateSocket(),i(new Error(l.reason||`Watch-session build ${l.status}`))))},c=l=>{o||(o=!0,i(new Error(`Socket disconnected: ${l}`)))};e.on("disconnect",c),e.on("Output",s),e.on("BuildStatus",a),e.emit("CommonBuild",this.buildStartOptions(t)),console.log("[DaemonClient] Compiling, waiting for build to finish...")})}getWatchLogPath(){return this.watchLogPath}get watchLogPath(){return kt.join(this.projectRoot,".hvigor","hotreload-watch.log")}buildStartOptions(e){let t={_:["assembleHap"],daemon:!0,watch:!0,hotReloadBuild:!0,mode:"module",prop:[`module=${e.moduleSpecs.join(",")}`,`product=${e.productName}`,"debuggable=true","hotReload=true","requiredDeviceType=phone"],parallel:!0,incremental:!0,analyze:"normal",env:{DEVECO_SDK_HOME:this.toolProvider.sdkPath}};return console.log("[DaemonClient] buildStartOptions:",JSON.stringify(t,null,2)),t}disconnect(){this.invalidateSocket()}onSocketDisconnect(e){this.cachedSocket&&this.cachedSocket.on("disconnect",e)}async getOrCreateSocket(e){if(this.cachedSocket&&this.cachedDaemonPort===e.port){if(this.cachedSocket.connected)return this.cachedSocket;this.invalidateSocket()}let t=this.decryptSessionId(e.sessionId);console.log(`[DaemonClient] Socket.IO connect: ws://127.0.0.1:${e.port} (${e.state})`);let n=oA(`ws://127.0.0.1:${e.port}`,{transports:["websocket"],path:`/${t}`});return await new Promise((i,o)=>{let s=setTimeout(()=>{o(new Error("Socket connect timeout (10s)"))},1e4);n.once("connect",()=>{clearTimeout(s),i()}),n.once("connect_error",a=>{clearTimeout(s),o(new Error(`Socket connect error: ${a.message}`))})}),this.cachedSocket=n,this.cachedDaemonPort=e.port,n}invalidateSocket(){this.cachedSocket&&(this.cachedSocket.removeAllListeners(),this.cachedSocket.disconnect(),this.cachedSocket=null,this.cachedDaemonPort=0)}async sendViaSocket(e,t){let n=await this.getOrCreateSocket(e);return new Promise((i,o)=>{let s=!1,a=Date.now(),c=this.createHotCompileHandlers(n,()=>s,d=>s=d,o),l=d=>{!d?.status||s||(d.status==="finish"?(s=!0,c.detach(),n.off("BuildStatus",l),console.log(`[Timing] abc compile: ${Date.now()-a}ms`),i(d.exitCode??0)):(d.status==="reject"||d.status==="close")&&(s=!0,c.detach(),n.off("BuildStatus",l),this.invalidateSocket(),o(new Error(`Hot compile ${d.status}: ${d.reason||"see WatchLog/Output above for compile errors"}`))))};n.on("disconnect",c.onDisconnect),n.on("Output",c.onOutput),n.on("BuildStatus",l),n.on("WatchLog",c.onWatchLog),n.on("WatchResult",c.onWatchResult),n.on("WatchCompileResult",c.onWatchCompileResult),n.on("WatchCompileData",c.onWatchCompileData),n.emit("CommonBuild",this.buildCompileOptions(t)),console.log("[DaemonClient] Compiling, waiting for hot compile to finish...")})}static extractText(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;if(typeof t.text=="string")return t.text;if(typeof t.msg=="string")return t.msg;if(typeof t.message=="string")return t.message}return JSON.stringify(e)}createHotCompileHandlers(e,t,n,i){let o=y=>{t()||(n(!0),g(),this.invalidateSocket(),i(new Error(`Socket disconnected: ${y}`)))},s=this.createOutputHandler(),{onWatchLog:a,onWatchResult:c,onWatchCompileResult:l,onWatchCompileData:d}=this.getDataHandler(),g=()=>{e.off("disconnect",o),e.off("Output",s),e.off("WatchLog",a),e.off("WatchResult",c),e.off("WatchCompileResult",l),e.off("WatchCompileData",d)};return{onDisconnect:o,onOutput:s,onWatchLog:a,onWatchResult:c,onWatchCompileResult:l,onWatchCompileData:d,detach:g}}getDataHandler(){let e=r.extractText;return{onWatchLog:s=>{let a=e(s);a.trim()&&process.stdout.write(a+(a.endsWith(`
46
+ `),n.length>100&&n.shift())},onWatchResult:s=>{let a=r.extractText(s);if(!a.trim())return;let c=`[WatchResult] ${a}`;console.log(c),kt.writeFileSync(e,[...n,c+`
47
+ `].join("")),n.length=0}}}awaitInitialBuild(e,t){return new Promise((n,i)=>{let o=!1,s=this.createOutputHandler(),a=l=>{!l?.status||o||(l.status==="finish"?(o=!0,e.off("disconnect",c),e.off("Output",s),e.off("BuildStatus",a),n()):(l.status==="reject"||l.status==="close")&&(o=!0,e.off("disconnect",c),e.off("Output",s),e.off("BuildStatus",a),this.invalidateSocket(),i(new Error(l.reason||`Watch-session build ${l.status}`))))},c=l=>{o||(o=!0,i(new Error(`Socket disconnected: ${l}`)))};e.on("disconnect",c),e.on("Output",s),e.on("BuildStatus",a),e.emit("CommonBuild",this.buildStartOptions(t)),console.log("[DaemonClient] Compiling, waiting for build to finish...")})}getWatchLogPath(){return this.watchLogPath}get watchLogPath(){return Rt.join(this.projectRoot,".hvigor","hotreload-watch.log")}buildStartOptions(e){let t={_:["assembleHap"],daemon:!0,watch:!0,hotReloadBuild:!0,mode:"module",prop:[`module=${e.moduleSpecs.join(",")}`,`product=${e.productName}`,"debuggable=true","hotReload=true","requiredDeviceType=phone"],parallel:!0,incremental:!0,analyze:"normal",env:{DEVECO_SDK_HOME:this.toolProvider.sdkPath}};return console.log("[DaemonClient] buildStartOptions:",JSON.stringify(t,null,2)),t}disconnect(){this.invalidateSocket()}onSocketDisconnect(e){this.cachedSocket&&this.cachedSocket.on("disconnect",e)}async getOrCreateSocket(e){if(this.cachedSocket&&this.cachedDaemonPort===e.port){if(this.cachedSocket.connected)return this.cachedSocket;this.invalidateSocket()}let t=this.decryptSessionId(e.sessionId);console.log(`[DaemonClient] Socket.IO connect: ws://127.0.0.1:${e.port} (${e.state})`);let n=FA(`ws://127.0.0.1:${e.port}`,{transports:["websocket"],path:`/${t}`});return await new Promise((i,o)=>{let s=setTimeout(()=>{o(new Error("Socket connect timeout (10s)"))},1e4);n.once("connect",()=>{clearTimeout(s),i()}),n.once("connect_error",a=>{clearTimeout(s),o(new Error(`Socket connect error: ${a.message}`))})}),this.cachedSocket=n,this.cachedDaemonPort=e.port,n}invalidateSocket(){this.cachedSocket&&(this.cachedSocket.removeAllListeners(),this.cachedSocket.disconnect(),this.cachedSocket=null,this.cachedDaemonPort=0)}async sendViaSocket(e,t){let n=await this.getOrCreateSocket(e);return new Promise((i,o)=>{let s=!1,a=Date.now(),c=this.createHotCompileHandlers(n,()=>s,d=>s=d,o),l=d=>{!d?.status||s||(d.status==="finish"?(s=!0,c.detach(),n.off("BuildStatus",l),console.log(`[Timing] abc compile: ${Date.now()-a}ms`),i(d.exitCode??0)):(d.status==="reject"||d.status==="close")&&(s=!0,c.detach(),n.off("BuildStatus",l),this.invalidateSocket(),o(new Error(`Hot compile ${d.status}: ${d.reason||"see WatchLog/Output above for compile errors"}`))))};n.on("disconnect",c.onDisconnect),n.on("Output",c.onOutput),n.on("BuildStatus",l),n.on("WatchLog",c.onWatchLog),n.on("WatchResult",c.onWatchResult),n.on("WatchCompileResult",c.onWatchCompileResult),n.on("WatchCompileData",c.onWatchCompileData),n.emit("CommonBuild",this.buildCompileOptions(t)),console.log("[DaemonClient] Compiling, waiting for hot compile to finish...")})}static extractText(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;if(typeof t.text=="string")return t.text;if(typeof t.msg=="string")return t.msg;if(typeof t.message=="string")return t.message}return JSON.stringify(e)}createHotCompileHandlers(e,t,n,i){let o=y=>{t()||(n(!0),g(),this.invalidateSocket(),i(new Error(`Socket disconnected: ${y}`)))},s=this.createOutputHandler(),{onWatchLog:a,onWatchResult:c,onWatchCompileResult:l,onWatchCompileData:d}=this.getDataHandler(),g=()=>{e.off("disconnect",o),e.off("Output",s),e.off("WatchLog",a),e.off("WatchResult",c),e.off("WatchCompileResult",l),e.off("WatchCompileData",d)};return{onDisconnect:o,onOutput:s,onWatchLog:a,onWatchResult:c,onWatchCompileResult:l,onWatchCompileData:d,detach:g}}getDataHandler(){let e=r.extractText;return{onWatchLog:s=>{let a=e(s);a.trim()&&process.stdout.write(a+(a.endsWith(`
48
48
  `)?"":`
49
- `))},onWatchResult:s=>{let a=e(s);a.trim()&&console.log(`[WatchResult] ${a}`)},onWatchCompileResult:s=>{let a=e(s);a.trim()&&console.log(`[WatchCompileResult] ${a}`)},onWatchCompileData:s=>{let a=e(s);a.trim()&&console.log(`[WatchCompileData] ${a}`)}}}createOutputHandler(){return e=>{let t=typeof e.text=="string"?e.text:Buffer.from(e.text).toString(e.encoding??"utf-8");t.trim()&&(e.type==="stderr"?process.stderr.write(t):process.stdout.write(t))}}buildCompileOptions(e){let t={_:["assembleDevHqf"],daemon:!0,hotCompile:!0,mode:"module",prop:[`module=${e.moduleSpecs.join(",")}`,`product=${e.productName}`,"debuggable=true","hotReload=true","requiredDeviceType=phone"],parallel:!0,incremental:!0,analyze:"normal",env:{DEVECO_SDK_HOME:this.toolProvider.sdkPath}};return console.log("[DaemonClient] buildCompileOptions:",JSON.stringify(t,null,2)),t}async waitForDaemonReady(){let n=Date.now();for(;Date.now()-n<3e4;){let i=this.findProjectDaemon();if(i&&(i.state==="half_busy"||i.state==="idle"))return;await new Promise(o=>setTimeout(o,1e3))}throw new Error("No running hvigor daemon found. Run `devecocli run --hotreload` first.")}findProjectDaemon(){let e=this.getRegistryPath();if(!Ct.existsSync(e))return null;try{let t=Ct.readFileSync(e,"utf-8"),n=JSON.parse(t),i=Object.values(n).filter(o=>o.cwdPath===this.projectRoot&&(o.state==="idle"||o.state==="half_busy"||o.state==="busy")&&this.isProcessAlive(o.pid));return i.length>0?i[i.length-1]:null}catch{return null}}decryptSessionId(e){let t=this.getMetaDir(),n=kt.join(t,"fd"),i=kt.join(t,"ac"),o=kt.join(t,"ce"),s=this.readComponents(n),a=this.xorBuffers([s[0],s[1],s[2],Buffer.from(sA)]),c=this.readSingleFile(i),l=Ow.pbkdf2Sync(Buffer.from(a).toString(),c,1e4,16,"sha256"),d=this.readSingleFile(o),g=this.aesGcmDecrypt(l,d),y=Buffer.from(e,"hex");return this.aesGcmDecrypt(g,y).toString("utf-8")}aesGcmDecrypt(e,t){let n=0,i=t.readUInt32BE(n);n+=4;let o=t.subarray(n,n+12);n+=12;let s=i-16,a=t.subarray(n,n+s);n+=s;let c=t.subarray(n,n+16),l=Ow.createDecipheriv("aes-128-gcm",e,o);return l.setAuthTag(c),Buffer.concat([l.update(a),l.final()])}readComponents(e){let t=Ct.readdirSync(e).map(n=>kt.join(e,n)).filter(n=>Ct.statSync(n).isDirectory()).sort();if(t.length<3)throw new Error(`Expected 3 subdirectories in ${e}, found ${t.length}`);return t.slice(0,3).map(n=>{let i=Ct.readdirSync(n);if(i.length===0)throw new Error(`No file in ${n}`);return Ct.readFileSync(kt.join(n,i[0]))})}readSingleFile(e){let t=Ct.readdirSync(e).map(n=>kt.join(e,n)).filter(n=>Ct.statSync(n).isFile());if(t.length===0)throw new Error(`No file in ${e}`);return Ct.readFileSync(t[0])}xorBuffers(e){let t=Buffer.alloc(e[0].length);t.set(e[0]);for(let n=1;n<e.length;n++){let i=Buffer.isBuffer(e[n])?e[n]:Buffer.from(e[n]);for(let o=0;o<t.length;o++)t[o]^=i[o]}return t}getRegistryPath(){let e=process.env.HVIGOR_USER_HOME||kt.join(Nw.homedir(),".hvigor");return kt.join(e,"daemon","cache","daemon-sec.json")}getMetaDir(){let e=process.env.HVIGOR_USER_HOME||kt.join(Nw.homedir(),".hvigor");return kt.join(e,"meta")}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}};import _w from"fs";import*as Tr from"path";import{green as Xc,yellow as qp}from"colorette";import ei from"fs";import*as ti from"path";import aA from"json5";var cA=2e6,lA=1e6,dA="hotreload",Jc=class r{static generateOrUpdate(e,t,n){let i=r.readAppConfig(e),o=ti.resolve(e,t),s=ti.join(o,"patch.json"),a;return ei.existsSync(s)?(m(`[PatchManager] patch.json found at ${s}, incrementing patchVersionCode`),a=r.readExistingPatch(s),a.app.patchVersionCode+=1):(m(`[PatchManager] patch.json not found, generating new one at ${s}`),a={app:{bundleName:i.bundleName,patchVersionCode:cA,versionCode:i.versionCode},module:{name:n,type:dA}}),r.writePatchJson(s,a),a}static readAppConfig(e){let t=ti.join(e,"AppScope","app.json5");if(!ei.existsSync(t))throw new Error(`AppScope/app.json5 not found at ${t}. Unable to read bundleName and versionCode.`);let n=ei.readFileSync(t,"utf-8"),i=aA.parse(n),o=i?.app?.bundleName;if(!o)throw new Error("bundleName is missing in AppScope/app.json5");let s=i?.app?.versionCode??lA;return{bundleName:o,versionCode:s}}static readExistingPatch(e){let t=ei.readFileSync(e,"utf-8"),n=JSON.parse(t);if(!n?.app?.patchVersionCode)throw new Error(`Invalid patch.json at ${e}: missing app.patchVersionCode`);return n}static writePatchJson(e,t){let n=ti.dirname(e);ei.existsSync(n)||ei.mkdirSync(n,{recursive:!0});let i=JSON.stringify(t,null,2);ei.writeFileSync(e,i,"utf-8"),m(`[PatchManager] patch.json written to ${e}`),m(`[PatchManager] Content: ${i}`)}};import Ae from"fs";import*as ee from"path";import Mw from"crypto";import uA from"json5";import{execa as Lw}from"execa";var Yc=class r{static COMPONENT=new Int8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]);static DIRS=["fd","ac","ce"];static decryptPwd(e,t,n){if(t.length<32||t.length%2!==0)throw new Error(`Invalid encrypted password for ${n}`);m(`[DecipherUtil] Decrypting ${n}, encrypted length: ${t.length}`);let i=ee.resolve(e,"material"),o=r.getKey(i,n),s=new Int8Array(Buffer.from(t,"hex"));return m(`[DecipherUtil] Data length: ${s.length}, key length: ${o.length}`),r.decrypt(o,s).toString("utf-8")}static getKey(e,t){let n=ee.resolve(e,r.DIRS[0]),i=r.readFd(n,t),o=r.readDirBytes(ee.resolve(e,r.DIRS[1]),t),s=r.getRootKey(i,o,t),a=r.readDirBytes(ee.resolve(e,r.DIRS[2]),t);return new Int8Array(r.decrypt(s,a))}static getRootKey(e,t,n){if(!e.every(a=>a.length===16))throw new Error(`Signing material data error for ${n}`);let i=[...e,r.COMPONENT],o=r.xor(i[0],i[1],n);for(let a=2;a<i.length;a++)o=r.xor(o,i[a],n);let s=Mw.pbkdf2Sync(Buffer.from(o).toString(),Buffer.from(t),1e4,16,"sha256");return new Int8Array(s)}static xor(e,t,n){if(e.byteLength!==t.byteLength)throw new Error(`Signing material data error for ${n}`);let i=new Int8Array(e.byteLength);for(let o=0;o<e.byteLength;o++)i[o]=e[o]^t[o];return i}static decrypt(e,t){let n=(255&t[0])<<24|(255&t[1])<<16|(255&t[2])<<8|255&t[3],i=t.length-4-n,o=t.slice(4,4+i),s=t.slice(t.length-16),a=Mw.createDecipheriv("aes-128-gcm",Buffer.from(e),Buffer.from(o));a.setAuthTag(Buffer.from(s));let c=a.update(Buffer.from(t.subarray(4+i,t.length-16))),l=a.final();return Buffer.concat([c,l])}static readFd(e,t){let n=Ae.readdirSync(e).filter(o=>o!==".DS_Store");if(n.length!==3)throw new Error(`fd directory must have 3 entries for ${t}`);let i=[];for(let o of n){let s=ee.join(e,o);i.push(r.readDirBytes(s,t))}return i}static readDirBytes(e,t){if(Ae.statSync(e).isDirectory()){let i=Ae.readdirSync(e).filter(o=>o!==".DS_Store");if(i.length!==1)throw new Error(`Expected exactly 1 file in ${e} for ${t}`);return new Int8Array(Ae.readFileSync(ee.join(e,i[0])))}return new Int8Array(Ae.readFileSync(e))}},Kc=class{toolProvider;projectRoot;env;constructor(e,t){this.toolProvider=e,this.projectRoot=t;let i=`${ee.dirname(e.javaPath)}${ee.delimiter}${process.env.PATH||""}`;this.env={...process.env,PATH:i,DEVECO_SDK_HOME:e.sdkPath}}async generateAndSign(e,t,n,i,o=!1){let s=this.checkAbcExists(t);if(!s.exists)return{signedHqfPaths:[],message:s.message};let a=this.resolveHqfPaths(e,i);return await this.generateHqf(n,s.abcPath,a.unsignedHqfPath)?o?{success:!0,signedHqfPaths:[a.unsignedHqfPath],unsignedHqfPath:a.unsignedHqfPath,message:"Unsigned hqf generated (signing skipped for emulator)."}:this.signHqfDirect(a.unsignedHqfPath,a.signedHqfPath):{signedHqfPaths:[],unsignedHqfPath:a.unsignedHqfPath,message:"Failed to generate unsigned hqf."}}checkAbcExists(e){let t=ee.join(e,"ets","modules.abc");if(Ae.existsSync(t))return{exists:!0,abcPath:t,message:"abc file exists."};let n=this.findFirstAbc(e);return n?{exists:!0,abcPath:n,message:"abc file exists."}:{exists:!1,abcPath:"",message:`abc file not found in ${e}.`}}findFirstAbc(e){if(!Ae.existsSync(e))return null;let t=Ae.readdirSync(e,{withFileTypes:!0});for(let n of t){let i=ee.join(e,n.name);if(n.isDirectory()){let o=this.findFirstAbc(i);if(o)return o}else if(n.isFile()&&n.name.endsWith(".abc"))return i}return null}resolveHqfPaths(e,t){let n=jt(this.projectRoot,e),i=ee.join(this.projectRoot,n,"build",t,"outputs","default");return Ae.existsSync(i)||Ae.mkdirSync(i,{recursive:!0}),{unsignedHqfPath:ee.join(i,`${e}-default-unsigned.hqf`),signedHqfPath:ee.join(i,`${e}-default-signed.hqf`)}}async generateHqf(e,t,n){let i=this.resolvePackingTool();if(!i)return console.error("[HotReload] app_packing_tool.jar not found in SDK."),!1;let o=ee.dirname(t),s=this.toolProvider.javaPath,a=["-jar",i,"--mode","hqf","--json-path",e,"--ets-path",o,"--out-path",n,"--force","true"];m(`[GenSignHqf] Packing: ${s} ${a.join(" ")}`);try{let c=Date.now(),l=await Lw(s,a,{cwd:this.projectRoot,stdout:"pipe",stderr:"pipe",reject:!1});return console.log(`[Timing] pack (JVM#1): ${Date.now()-c}ms`),l.stdout&&console.log(l.stdout),l.stderr&&console.error(l.stderr),l.exitCode!==0?(console.error(`[HotReload] app_packing_tool failed with exit code ${l.exitCode}`),!1):Ae.existsSync(n)?(console.log(`[HotReload] Unsigned hqf generated: ${n}`),!0):(console.error(`[HotReload] hqf not generated at ${n}`),!1)}catch(c){return console.error(`[HotReload] Packing hqf failed: ${c.message}`),!1}}async signHqfDirect(e,t){let n=this.resolveSignConfig();if(!n)return this.signFailResult(e,"Signing prerequisites not met.");let i=this.buildSignArgs(n,e,t),o=this.toolProvider.javaPath,s=i.map((a,c)=>c>0&&["-keyPwd","-keystorePwd"].includes(i[c-1])?"******":a);m(`[GenSignHqf] Signing: ${o} ${s.join(" ")}`);try{let a=Date.now(),c=await Lw(o,i,{cwd:this.projectRoot,stdout:"pipe",stderr:"pipe",reject:!1});return console.log(`[Timing] sign (JVM#2): ${Date.now()-a}ms`),c.stdout&&console.log(c.stdout),c.stderr&&console.error(c.stderr),c.exitCode!==0?this.signFailResult(e,`hqf signing failed with exit code ${c.exitCode}`):Ae.existsSync(t)?(console.log(`[HotReload] Signed hqf generated: ${t}`),{success:!0,signedHqfPaths:[t],unsignedHqfPath:e,message:"hqf generated and signed successfully."}):this.signFailResult(e,`Signed hqf not generated at ${t}`)}catch(a){return this.signFailResult(e,`hqf signing failed: ${a.message}`)}}resolveSignConfig(){let e=this.resolveSignTool();if(!e)return null;let t=this.readSigningConfig("default");if(!t?.storeFile||!t?.certpath||!t?.profile)return null;let n=this.resolveMaterialDir();if(!n)return null;try{let i=Yc.decryptPwd(n,t.storePassword,"storePassword"),o=Yc.decryptPwd(n,t.keyPassword,"keyPassword");return{signToolPath:e,storePwd:i,keyPwd:o,signingConfig:t}}catch{return null}}buildSignArgs(e,t,n){return["-jar",e.signToolPath,"sign-app","-mode","localSign","-keyAlias",e.signingConfig.keyAlias||"debugKey","-keyPwd",e.keyPwd,"-keystoreFile",e.signingConfig.storeFile,"-keystorePwd",e.storePwd,"-appCertFile",e.signingConfig.certpath,"-profileFile",e.signingConfig.profile,"-inFile",t,"-outFile",n,"-signAlg",e.signingConfig.signAlg||"SHA256withECDSA"]}resolveMaterialDir(){let e=this.readSigningConfig("default");if(!e?.storeFile)return null;let t=ee.resolve(e.storeFile,".."),n=ee.join(t,"material");return Ae.existsSync(n)?t:null}readSigningConfig(e){let t=ee.join(this.projectRoot,"build-profile.json5");if(!Ae.existsSync(t))return null;try{let n=Ae.readFileSync(t,"utf-8"),i=uA.parse(n),s=i.app?.products?.find(a=>a.name===e)?.signingConfig;return s?i.app?.signingConfigs?.find(a=>a.name===s)?.material??null:null}catch{return null}}resolveSignTool(){let e=this.toolProvider.sdkPath,t=[ee.join(e,"default","openharmony","toolchains","lib","hap-sign-tool.jar"),ee.join(e,"toolchains","lib","hap-sign-tool.jar")];for(let n of t)if(Ae.existsSync(n))return n;return null}signFailResult(e,t){return console.error(`[HotReload] ${t}`),{success:!1,signedHqfPaths:[],unsignedHqfPath:e,message:t}}resolvePackingTool(){let e=this.toolProvider.sdkPath,t=[ee.join(e,"default","openharmony","toolchains","lib","app_packing_tool.jar"),ee.join(e,"toolchains","lib","app_packing_tool.jar")];for(let n of t)if(Ae.existsSync(n))return n;return null}};async function $w(r){let e=Date.now(),t=jt(r.projectPath,r.moduleName),n=pA(r);console.log(qp("[HotReload] Ensure the project source is trusted before proceeding."));let i=mA(r),o=Ps(n,r.projectPath);console.log(`[HotReload] Parsed ${o.length} changed file(s) from ${r.applyFileName}`),fA(r,o),gA(r,t),await hA(r,i);let s=Tr.join(r.projectPath,t,"patch.json"),a=await wA(r,t,s);return await vA(r,a),console.log(Xc("[HotReload] hot reload applied successfully (app not restarted).")),console.log(`[Timing] TOTAL executeHotReloadApply: ${Date.now()-e}ms`),{success:!0,message:"Hot reload applied successfully."}}function pA(r){if(Tr.basename(r.applyFileName)!==r.applyFileName)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${r.applyFileName}`);return Tr.join(r.projectPath,".hvigor",r.applyFileName)}function mA(r){let{projectPath:e,toolProvider:t}=r,n=new to(e,t);if(!n.findProjectDaemon())throw new Error("No running hvigor daemon found. Run `devecocli run --hotreload` first to start the daemon.");return n}function fA(r,e){let t=Qi.writeChangedFileLists(r.projectPath,r.productName,e,r.moduleName);if(t.writtenModules.length===0)throw new Error("No changed files belong to a runnable module");console.log(Xc(`[HotReload] changedFileList written for: ${t.writtenModules.join(", ")}`)),t.skippedFiles.length>0&&console.warn(qp(`[HotReload] skipped ${t.skippedFiles.length} file(s)`))}function gA(r,e){let t=Jc.generateOrUpdate(r.projectPath,e,r.moduleName);console.log(Xc(`[HotReload] patch.json ready (patchVersionCode=${t.app.patchVersionCode})`))}async function hA(r,e){let t=Date.now(),n=e.getWatchLogPath();try{console.log("[HotReload] Daemon hot compile (socket short connection)...");let i=await e.sendHotCompile({moduleSpecs:r.moduleSpecs,productName:r.productName});if(i!==0){let o=yA(n);throw new Error(`Daemon hot compile exited with code ${i}`+(o?`
49
+ `))},onWatchResult:s=>{let a=e(s);a.trim()&&console.log(`[WatchResult] ${a}`)},onWatchCompileResult:s=>{let a=e(s);a.trim()&&console.log(`[WatchCompileResult] ${a}`)},onWatchCompileData:s=>{let a=e(s);a.trim()&&console.log(`[WatchCompileData] ${a}`)}}}createOutputHandler(){return e=>{let t=typeof e.text=="string"?e.text:Buffer.from(e.text).toString(e.encoding??"utf-8");t.trim()&&(e.type==="stderr"?process.stderr.write(t):process.stdout.write(t))}}buildCompileOptions(e){let t={_:["assembleDevHqf"],daemon:!0,hotCompile:!0,mode:"module",prop:[`module=${e.moduleSpecs.join(",")}`,`product=${e.productName}`,"debuggable=true","hotReload=true","requiredDeviceType=phone"],parallel:!0,incremental:!0,analyze:"normal",env:{DEVECO_SDK_HOME:this.toolProvider.sdkPath}};return console.log("[DaemonClient] buildCompileOptions:",JSON.stringify(t,null,2)),t}async waitForDaemonReady(){let n=Date.now();for(;Date.now()-n<3e4;){let i=this.findProjectDaemon();if(i&&(i.state==="half_busy"||i.state==="idle"))return;await new Promise(o=>setTimeout(o,1e3))}throw new Error("No running hvigor daemon found. Run `devecocli run --hotreload` first.")}findProjectDaemon(){let e=this.getRegistryPath();if(!kt.existsSync(e))return null;try{let t=kt.readFileSync(e,"utf-8"),n=JSON.parse(t),i=Object.values(n).filter(o=>o.cwdPath===this.projectRoot&&(o.state==="idle"||o.state==="half_busy"||o.state==="busy")&&this.isProcessAlive(o.pid));return i.length>0?i[i.length-1]:null}catch{return null}}decryptSessionId(e){let t=this.getMetaDir(),n=Rt.join(t,"fd"),i=Rt.join(t,"ac"),o=Rt.join(t,"ce"),s=this.readComponents(n),a=this.xorBuffers([s[0],s[1],s[2],Buffer.from($A)]),c=this.readSingleFile(i),l=kv.pbkdf2Sync(Buffer.from(a).toString(),c,1e4,16,"sha256"),d=this.readSingleFile(o),g=this.aesGcmDecrypt(l,d),y=Buffer.from(e,"hex");return this.aesGcmDecrypt(g,y).toString("utf-8")}aesGcmDecrypt(e,t){let n=0,i=t.readUInt32BE(n);n+=4;let o=t.subarray(n,n+12);n+=12;let s=i-16,a=t.subarray(n,n+s);n+=s;let c=t.subarray(n,n+16),l=kv.createDecipheriv("aes-128-gcm",e,o);return l.setAuthTag(c),Buffer.concat([l.update(a),l.final()])}readComponents(e){let t=kt.readdirSync(e).map(n=>Rt.join(e,n)).filter(n=>kt.statSync(n).isDirectory()).sort();if(t.length<3)throw new Error(`Expected 3 subdirectories in ${e}, found ${t.length}`);return t.slice(0,3).map(n=>{let i=kt.readdirSync(n);if(i.length===0)throw new Error(`No file in ${n}`);return kt.readFileSync(Rt.join(n,i[0]))})}readSingleFile(e){let t=kt.readdirSync(e).map(n=>Rt.join(e,n)).filter(n=>kt.statSync(n).isFile());if(t.length===0)throw new Error(`No file in ${e}`);return kt.readFileSync(t[0])}xorBuffers(e){let t=Buffer.alloc(e[0].length);t.set(e[0]);for(let n=1;n<e.length;n++){let i=Buffer.isBuffer(e[n])?e[n]:Buffer.from(e[n]);for(let o=0;o<t.length;o++)t[o]^=i[o]}return t}getRegistryPath(){let e=process.env.HVIGOR_USER_HOME||Rt.join(Rv.homedir(),".hvigor");return Rt.join(e,"daemon","cache","daemon-sec.json")}getMetaDir(){let e=process.env.HVIGOR_USER_HOME||Rt.join(Rv.homedir(),".hvigor");return Rt.join(e,"meta")}isProcessAlive(e){try{return process.kill(e,0),!0}catch{return!1}}};import Iv from"fs";import*as Mr from"path";import{green as gl,yellow as Cf}from"colorette";import ii from"fs";import*as oi from"path";import jA from"json5";var HA=2e6,UA=1e6,BA="hotreload",pl=class r{static generateOrUpdate(e,t,n){let i=r.readAppConfig(e),o=oi.resolve(e,t),s=oi.join(o,"patch.json"),a;return ii.existsSync(s)?(f(`[PatchManager] patch.json found at ${s}, incrementing patchVersionCode`),a=r.readExistingPatch(s),a.app.patchVersionCode+=1):(f(`[PatchManager] patch.json not found, generating new one at ${s}`),a={app:{bundleName:i.bundleName,patchVersionCode:HA,versionCode:i.versionCode},module:{name:n,type:BA}}),r.writePatchJson(s,a),a}static readAppConfig(e){let t=oi.join(e,"AppScope","app.json5");if(!ii.existsSync(t))throw new Error(`AppScope/app.json5 not found at ${t}. Unable to read bundleName and versionCode.`);let n=ii.readFileSync(t,"utf-8"),i=jA.parse(n),o=i?.app?.bundleName;if(!o)throw new Error("bundleName is missing in AppScope/app.json5");let s=i?.app?.versionCode??UA;return{bundleName:o,versionCode:s}}static readExistingPatch(e){let t=ii.readFileSync(e,"utf-8"),n=JSON.parse(t);if(!n?.app?.patchVersionCode)throw new Error(`Invalid patch.json at ${e}: missing app.patchVersionCode`);return n}static writePatchJson(e,t){let n=oi.dirname(e);ii.existsSync(n)||ii.mkdirSync(n,{recursive:!0});let i=JSON.stringify(t,null,2);ii.writeFileSync(e,i,"utf-8"),f(`[PatchManager] patch.json written to ${e}`),f(`[PatchManager] Content: ${i}`)}};import Ae from"fs";import*as te from"path";import xv from"crypto";import WA from"json5";import{execa as Dv}from"execa";var fl=class r{static COMPONENT=new Int8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]);static DIRS=["fd","ac","ce"];static decryptPwd(e,t,n){if(t.length<32||t.length%2!==0)throw new Error(`Invalid encrypted password for ${n}`);f(`[DecipherUtil] Decrypting ${n}, encrypted length: ${t.length}`);let i=te.resolve(e,"material"),o=r.getKey(i,n),s=new Int8Array(Buffer.from(t,"hex"));return f(`[DecipherUtil] Data length: ${s.length}, key length: ${o.length}`),r.decrypt(o,s).toString("utf-8")}static getKey(e,t){let n=te.resolve(e,r.DIRS[0]),i=r.readFd(n,t),o=r.readDirBytes(te.resolve(e,r.DIRS[1]),t),s=r.getRootKey(i,o,t),a=r.readDirBytes(te.resolve(e,r.DIRS[2]),t);return new Int8Array(r.decrypt(s,a))}static getRootKey(e,t,n){if(!e.every(a=>a.length===16))throw new Error(`Signing material data error for ${n}`);let i=[...e,r.COMPONENT],o=r.xor(i[0],i[1],n);for(let a=2;a<i.length;a++)o=r.xor(o,i[a],n);let s=xv.pbkdf2Sync(Buffer.from(o).toString(),Buffer.from(t),1e4,16,"sha256");return new Int8Array(s)}static xor(e,t,n){if(e.byteLength!==t.byteLength)throw new Error(`Signing material data error for ${n}`);let i=new Int8Array(e.byteLength);for(let o=0;o<e.byteLength;o++)i[o]=e[o]^t[o];return i}static decrypt(e,t){let n=(255&t[0])<<24|(255&t[1])<<16|(255&t[2])<<8|255&t[3],i=t.length-4-n,o=t.slice(4,4+i),s=t.slice(t.length-16),a=xv.createDecipheriv("aes-128-gcm",Buffer.from(e),Buffer.from(o));a.setAuthTag(Buffer.from(s));let c=a.update(Buffer.from(t.subarray(4+i,t.length-16))),l=a.final();return Buffer.concat([c,l])}static readFd(e,t){let n=Ae.readdirSync(e).filter(o=>o!==".DS_Store");if(n.length!==3)throw new Error(`fd directory must have 3 entries for ${t}`);let i=[];for(let o of n){let s=te.join(e,o);i.push(r.readDirBytes(s,t))}return i}static readDirBytes(e,t){if(Ae.statSync(e).isDirectory()){let i=Ae.readdirSync(e).filter(o=>o!==".DS_Store");if(i.length!==1)throw new Error(`Expected exactly 1 file in ${e} for ${t}`);return new Int8Array(Ae.readFileSync(te.join(e,i[0])))}return new Int8Array(Ae.readFileSync(e))}},ml=class{toolProvider;projectRoot;env;constructor(e,t){this.toolProvider=e,this.projectRoot=t;let i=`${te.dirname(e.javaPath)}${te.delimiter}${process.env.PATH||""}`;this.env={...process.env,PATH:i,DEVECO_SDK_HOME:e.sdkPath}}async generateAndSign(e,t,n,i,o=!1){let s=this.checkAbcExists(t);if(!s.exists)return{signedHqfPaths:[],message:s.message};let a=this.resolveHqfPaths(e,i);return await this.generateHqf(n,s.abcPath,a.unsignedHqfPath)?o?{success:!0,signedHqfPaths:[a.unsignedHqfPath],unsignedHqfPath:a.unsignedHqfPath,message:"Unsigned hqf generated (signing skipped for emulator)."}:this.signHqfDirect(a.unsignedHqfPath,a.signedHqfPath):{signedHqfPaths:[],unsignedHqfPath:a.unsignedHqfPath,message:"Failed to generate unsigned hqf."}}checkAbcExists(e){let t=te.join(e,"ets","modules.abc");if(Ae.existsSync(t))return{exists:!0,abcPath:t,message:"abc file exists."};let n=this.findFirstAbc(e);return n?{exists:!0,abcPath:n,message:"abc file exists."}:{exists:!1,abcPath:"",message:`abc file not found in ${e}.`}}findFirstAbc(e){if(!Ae.existsSync(e))return null;let t=Ae.readdirSync(e,{withFileTypes:!0});for(let n of t){let i=te.join(e,n.name);if(n.isDirectory()){let o=this.findFirstAbc(i);if(o)return o}else if(n.isFile()&&n.name.endsWith(".abc"))return i}return null}resolveHqfPaths(e,t){let n=Bt(this.projectRoot,e),i=te.join(this.projectRoot,n,"build",t,"outputs","default");return Ae.existsSync(i)||Ae.mkdirSync(i,{recursive:!0}),{unsignedHqfPath:te.join(i,`${e}-default-unsigned.hqf`),signedHqfPath:te.join(i,`${e}-default-signed.hqf`)}}async generateHqf(e,t,n){let i=this.resolvePackingTool();if(!i)return console.error("[HotReload] app_packing_tool.jar not found in SDK."),!1;let o=te.dirname(t),s=this.toolProvider.javaPath,a=["-jar",i,"--mode","hqf","--json-path",e,"--ets-path",o,"--out-path",n,"--force","true"];f(`[GenSignHqf] Packing: ${s} ${a.join(" ")}`);try{let c=Date.now(),l=await Dv(s,a,{cwd:this.projectRoot,stdout:"pipe",stderr:"pipe",reject:!1});return console.log(`[Timing] pack (JVM#1): ${Date.now()-c}ms`),l.stdout&&console.log(l.stdout),l.stderr&&console.error(l.stderr),l.exitCode!==0?(console.error(`[HotReload] app_packing_tool failed with exit code ${l.exitCode}`),!1):Ae.existsSync(n)?(console.log(`[HotReload] Unsigned hqf generated: ${n}`),!0):(console.error(`[HotReload] hqf not generated at ${n}`),!1)}catch(c){return console.error(`[HotReload] Packing hqf failed: ${c.message}`),!1}}async signHqfDirect(e,t){let n=this.resolveSignConfig();if(!n)return this.signFailResult(e,"Signing prerequisites not met.");let i=this.buildSignArgs(n,e,t),o=this.toolProvider.javaPath,s=i.map((a,c)=>c>0&&["-keyPwd","-keystorePwd"].includes(i[c-1])?"******":a);f(`[GenSignHqf] Signing: ${o} ${s.join(" ")}`);try{let a=Date.now(),c=await Dv(o,i,{cwd:this.projectRoot,stdout:"pipe",stderr:"pipe",reject:!1});return console.log(`[Timing] sign (JVM#2): ${Date.now()-a}ms`),c.stdout&&console.log(c.stdout),c.stderr&&console.error(c.stderr),c.exitCode!==0?this.signFailResult(e,`hqf signing failed with exit code ${c.exitCode}`):Ae.existsSync(t)?(console.log(`[HotReload] Signed hqf generated: ${t}`),{success:!0,signedHqfPaths:[t],unsignedHqfPath:e,message:"hqf generated and signed successfully."}):this.signFailResult(e,`Signed hqf not generated at ${t}`)}catch(a){return this.signFailResult(e,`hqf signing failed: ${a.message}`)}}resolveSignConfig(){let e=this.resolveSignTool();if(!e)return null;let t=this.readSigningConfig("default");if(!t?.storeFile||!t?.certpath||!t?.profile)return null;let n=this.resolveMaterialDir();if(!n)return null;try{let i=fl.decryptPwd(n,t.storePassword,"storePassword"),o=fl.decryptPwd(n,t.keyPassword,"keyPassword");return{signToolPath:e,storePwd:i,keyPwd:o,signingConfig:t}}catch{return null}}buildSignArgs(e,t,n){return["-jar",e.signToolPath,"sign-app","-mode","localSign","-keyAlias",e.signingConfig.keyAlias||"debugKey","-keyPwd",e.keyPwd,"-keystoreFile",e.signingConfig.storeFile,"-keystorePwd",e.storePwd,"-appCertFile",e.signingConfig.certpath,"-profileFile",e.signingConfig.profile,"-inFile",t,"-outFile",n,"-signAlg",e.signingConfig.signAlg||"SHA256withECDSA"]}resolveMaterialDir(){let e=this.readSigningConfig("default");if(!e?.storeFile)return null;let t=te.resolve(e.storeFile,".."),n=te.join(t,"material");return Ae.existsSync(n)?t:null}readSigningConfig(e){let t=te.join(this.projectRoot,"build-profile.json5");if(!Ae.existsSync(t))return null;try{let n=Ae.readFileSync(t,"utf-8"),i=WA.parse(n),s=i.app?.products?.find(a=>a.name===e)?.signingConfig;return s?i.app?.signingConfigs?.find(a=>a.name===s)?.material??null:null}catch{return null}}resolveSignTool(){let e=this.toolProvider.sdkPath,t=[te.join(e,"default","openharmony","toolchains","lib","hap-sign-tool.jar"),te.join(e,"toolchains","lib","hap-sign-tool.jar")];for(let n of t)if(Ae.existsSync(n))return n;return null}signFailResult(e,t){return console.error(`[HotReload] ${t}`),{success:!1,signedHqfPaths:[],unsignedHqfPath:e,message:t}}resolvePackingTool(){let e=this.toolProvider.sdkPath,t=[te.join(e,"default","openharmony","toolchains","lib","app_packing_tool.jar"),te.join(e,"toolchains","lib","app_packing_tool.jar")];for(let n of t)if(Ae.existsSync(n))return n;return null}};async function Av(r){let e=Date.now(),t=Bt(r.projectPath,r.moduleName),n=VA(r);console.log(Cf("[HotReload] Ensure the project source is trusted before proceeding."));let i=GA(r),o=Ms(n,r.projectPath);console.log(`[HotReload] Parsed ${o.length} changed file(s) from ${r.applyFileName}`),qA(r,o),zA(r,t),await JA(r,i);let s=Mr.join(r.projectPath,t,"patch.json"),a=await YA(r,t,s);return await XA(r,a),console.log(gl("[HotReload] hot reload applied successfully (app not restarted).")),console.log(`[Timing] TOTAL executeHotReloadApply: ${Date.now()-e}ms`),{success:!0,message:"Hot reload applied successfully."}}function VA(r){if(Mr.basename(r.applyFileName)!==r.applyFileName)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${r.applyFileName}`);return Mr.join(r.projectPath,".hvigor",r.applyFileName)}function GA(r){let{projectPath:e,toolProvider:t}=r,n=new uo(e,t);if(!n.findProjectDaemon())throw new Error("No running hvigor daemon found. Run `devecocli run --hotreload` first to start the daemon.");return n}function qA(r,e){let t=co.writeChangedFileLists(r.projectPath,r.productName,e,r.moduleName);if(t.writtenModules.length===0)throw new Error("No changed files belong to a runnable module");console.log(gl(`[HotReload] changedFileList written for: ${t.writtenModules.join(", ")}`)),t.skippedFiles.length>0&&console.warn(Cf(`[HotReload] skipped ${t.skippedFiles.length} file(s)`))}function zA(r,e){let t=pl.generateOrUpdate(r.projectPath,e,r.moduleName);console.log(gl(`[HotReload] patch.json ready (patchVersionCode=${t.app.patchVersionCode})`))}async function JA(r,e){let t=Date.now(),n=e.getWatchLogPath();try{console.log("[HotReload] Daemon hot compile (socket short connection)...");let i=await e.sendHotCompile({moduleSpecs:r.moduleSpecs,productName:r.productName});if(i!==0){let o=KA(n);throw new Error(`Daemon hot compile exited with code ${i}`+(o?`
50
50
  --- compile output (from watch session) ---
51
- ${o}`:""))}}finally{e.disconnect()}console.log(`[Timing] daemon hot compile: ${Date.now()-t}ms`)}function yA(r){try{return _w.existsSync(r)?_w.readFileSync(r,"utf8").split(/\r?\n/).filter(t=>t.trim()).slice(-40).join(`
52
- `):""}catch{return""}}async function wA(r,e,t){let n=Tr.join(r.projectPath,e,"build",r.productName,"intermediates"),i=[Tr.join(n,"hotReload","patchAbcPath"),Tr.join(n,"patch","default")],o=Date.now(),s=new Kc(r.toolProvider,r.projectPath),a=r.targetDeviceId.includes("127.0.0.1")||r.targetDeviceId.includes("localhost"),c=null;for(let l of i){let d=await s.generateAndSign(r.moduleName,l,t,r.productName,a);if(d.success&&d.signedHqfPaths.length>0){c=d;break}c=d}if(console.log(`[Timing] gen+sign hqf: ${Date.now()-o}ms`),!c?.success||c.signedHqfPaths.length===0)throw new Error(`hqf generation/signing failed (no abc found in any candidate). Last: ${c?.message??"unknown"}`);return c.signedHqfPaths}async function vA(r,e){let t=Date.now(),i=await new eo(r.toolProvider).install(r.targetDeviceId,e,r.bundleName);if(console.log(`[Timing] quickfix install: ${Date.now()-t}ms`),!i.success)throw new Error(`hqf install failed: ${i.message}`)}function zp(r,e){if(!r||r.length===0)throw new Error(`Hot reload requires --module <name> (a single target module; har deps are fine). Got: '${e??""}' (no --module passed).`)}function Fw(r,e,t){let n=Tr.join(r.rootDir,".hvigor",t),i;try{i=Ps(n,r.rootDir)}catch{return}let o=new Set;for(let s of i){let a=r.findOwningModule(s);if(!a||a===e)continue;let c=r.getModuleType(a);(c==="feature"||c==="shared")&&o.add(`${a} (${c})`)}o.size>0&&console.warn(qp(`[HotReload] Changed files belong to feature/hsp dependency module(s): ${[...o].join(", ")}. These are NOT hot-reloadable \u2014 run \`devecocli run\` (full redeploy) for them. Only the target module (+ har deps) will be hot-reloaded this time.`))}function jw(r,e,t,n,i){let o=new Set,s=r.collectNonHarDependentModuleList(e);for(let a of s)o.add(r.findArtifactPath(a,t,n,i));return o.add(r.findArtifactPath(e,t,n,i)),[...o]}async function Hw(r,e){let t=new gt(r,e.rootDir);try{await t.stopDaemon()}finally{await xr(e.rootDir,async()=>{cr.removeAll(e)},()=>console.log("Another build is already running for this project. Waiting for completion..."))}console.log(Xc("Hvigor daemon stopped."))}var Zc=class{formatPass(e){return e.evidence.processCheckSkipped?"Smoke: PASS (process check unavailable, smoke skipped)":e.evidence.phashBlank===null?"Smoke: PASS (screenshot unavailable, blank check skipped)":"Smoke: PASS"}formatFailure(e,t){let{status:n,reason:i,evidence:o}=e,s=[`Smoke: ${n}`,`${i} (bundle=${t.bundleName}, device=${t.targetDeviceId}).`];return n==="FAIL_CRASH"&&o.crashLogPath&&s.push(`crash_log: ${o.crashLogPath}`),n==="FAIL_BLANK"&&o.screenshotPath&&s.push(`screenshot: ${o.screenshotPath}`),s.join(`
53
- `)}toTraceError(e,t){return new w(this.formatFailure(e,t),e.status)}};import hl from"fs";import nT from"path";import{yellow as Ms}from"colorette";import{cyan as Qc}from"colorette";function ri(r,e){if(r.exitCode===0)return null;let t=r.stderr||r.stdout,n=Ut(t);return n==="transient"?new Error(`${e}: Device communication channel unavailable. Retry in a few seconds.`):n==="fatal"?new Error(`${e}: ${t.trim()}`):null}var Jp=[800,1500,2500];function SA(r){return new Promise(e=>setTimeout(e,r))}var cn=class{toolProvider;deviceManager;constructor(e){this.toolProvider=e,this.deviceManager=ce.from(e)}createFollowLineHandler(){return(e,t)=>{if(t==="stderr"){for(let n of e)console.error(n);return}for(let n of e)console.log(n)}}findDeviceByArg(e,t){return e.find(n=>n.serial===t||n.name===t)}formatConnectedDeviceList(e){return e.map(t=>` - ${t.name} (${t.serial})`).join(`
54
- `)}async loadConnectedDevicesByName(){return this.getConnectedDevices()}async selectDevice(e){let t=await this.getConnectedDeviceSerials();if(!e&&t.length===1){let i=t[0];return m(Qc(`Using device serial: ${i}`)),i}if(e&&t.includes(e))return m(Qc(`Using device serial: ${e}`)),e;let n=await this.loadConnectedDevicesByName();if(e){let i=this.findDeviceByArg(n,e);if(i)return m(Qc(`Using device: ${i.name} (${i.serial})`)),i.serial;let o=this.formatConnectedDeviceList(n);throw new w(`Device '${e}' not found.
51
+ ${o}`:""))}}finally{e.disconnect()}console.log(`[Timing] daemon hot compile: ${Date.now()-t}ms`)}function KA(r){try{return Iv.existsSync(r)?Iv.readFileSync(r,"utf8").split(/\r?\n/).filter(t=>t.trim()).slice(-40).join(`
52
+ `):""}catch{return""}}async function YA(r,e,t){let n=Mr.join(r.projectPath,e,"build",r.productName,"intermediates"),i=[Mr.join(n,"hotReload","patchAbcPath"),Mr.join(n,"patch","default")],o=Date.now(),s=new ml(r.toolProvider,r.projectPath),a=r.targetDeviceId.includes("127.0.0.1")||r.targetDeviceId.includes("localhost"),c=null;for(let l of i){let d=await s.generateAndSign(r.moduleName,l,t,r.productName,a);if(d.success&&d.signedHqfPaths.length>0){c=d;break}c=d}if(console.log(`[Timing] gen+sign hqf: ${Date.now()-o}ms`),!c?.success||c.signedHqfPaths.length===0)throw new Error(`hqf generation/signing failed (no abc found in any candidate). Last: ${c?.message??"unknown"}`);return c.signedHqfPaths}async function XA(r,e){let t=Date.now(),i=await new lo(r.toolProvider).install(r.targetDeviceId,e,r.bundleName);if(console.log(`[Timing] quickfix install: ${Date.now()-t}ms`),!i.success)throw new Error(`hqf install failed: ${i.message}`)}function kf(r,e){if(!r||r.length===0)throw new Error(`Hot reload requires --module <name> (a single target module; har deps are fine). Got: '${e??""}' (no --module passed).`)}function Tv(r,e,t){let n=Mr.join(r.rootDir,".hvigor",t),i;try{i=Ms(n,r.rootDir)}catch{return}let o=new Set;for(let s of i){let a=r.findOwningModule(s);if(!a||a===e)continue;let c=r.getModuleType(a);(c==="feature"||c==="shared")&&o.add(`${a} (${c})`)}o.size>0&&console.warn(Cf(`[HotReload] Changed files belong to feature/hsp dependency module(s): ${[...o].join(", ")}. These are NOT hot-reloadable \u2014 run \`devecocli run\` (full redeploy) for them. Only the target module (+ har deps) will be hot-reloaded this time.`))}function Nv(r,e,t,n,i){let o=new Set,s=r.collectNonHarDependentModuleList(e);for(let a of s)o.add(r.findArtifactPath(a,t,n,i));return o.add(r.findArtifactPath(e,t,n,i)),[...o]}async function Ov(r,e){let t=new ht(r,e.rootDir);try{await t.stopDaemon()}finally{await Nr(e.rootDir,async()=>{pr.removeAll(e)},()=>console.log("Another build is already running for this project. Waiting for completion..."))}console.log(gl("Hvigor daemon stopped."))}var hl=class{formatPass(e){return e.evidence.processCheckSkipped?"Smoke: PASS (process check unavailable, smoke skipped)":e.evidence.phashBlank===null?"Smoke: PASS (screenshot unavailable, blank check skipped)":"Smoke: PASS"}formatFailure(e,t){let{status:n,reason:i,evidence:o}=e,s=[`Smoke: ${n}`,`${i} (bundle=${t.bundleName}, device=${t.targetDeviceId}).`];return n==="FAIL_CRASH"&&o.crashLogPath&&s.push(`crash_log: ${o.crashLogPath}`),n==="FAIL_BLANK"&&o.screenshotPath&&s.push(`screenshot: ${o.screenshotPath}`),s.join(`
53
+ `)}toTraceError(e,t){return new w(this.formatFailure(e,t),e.status)}};import _l from"fs";import MN from"path";import{yellow as qs}from"colorette";import{cyan as yl}from"colorette";function si(r,e){if(r.exitCode===0)return null;let t=r.stderr||r.stdout,n=Vt(t);return n==="transient"?new Error(`${e}: Device communication channel unavailable. Retry in a few seconds.`):n==="fatal"?new Error(`${e}: ${t.trim()}`):null}var Rf=[800,1500,2500];function QA(r){return new Promise(e=>setTimeout(e,r))}var un=class{toolProvider;deviceManager;constructor(e){this.toolProvider=e,this.deviceManager=le.from(e)}createFollowLineHandler(){return(e,t)=>{if(t==="stderr"){for(let n of e)console.error(n);return}for(let n of e)console.log(n)}}findDeviceByArg(e,t){return e.find(n=>n.serial===t||n.name===t)}formatConnectedDeviceList(e){return e.map(t=>` - ${t.name} (${t.serial})`).join(`
54
+ `)}async loadConnectedDevicesByName(){return this.getConnectedDevices()}async selectDevice(e){let t=await this.getConnectedDeviceSerials();if(!e&&t.length===1){let i=t[0];return f(yl(`Using device serial: ${i}`)),i}if(e&&t.includes(e))return f(yl(`Using device serial: ${e}`)),e;let n=await this.loadConnectedDevicesByName();if(e){let i=this.findDeviceByArg(n,e);if(i)return f(yl(`Using device: ${i.name} (${i.serial})`)),i.serial;let o=this.formatConnectedDeviceList(n);throw new w(`Device '${e}' not found.
55
55
  Available devices:
56
- ${o}`,"Device not found.")}if(n.length===1){let i=n[0];return m(Qc(`Using device: ${i.name} (${i.serial})`)),i.serial}throw new w("Multiple devices found. Specify a target device using `--device <name>` or `--device <serial>`.\nAvailable devices:\n"+this.formatConnectedDeviceList(n),"Multiple devices found.")}async getConnectedDeviceSerials(){let e=await this.deviceManager.listDevices();if(e.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");return e.map(t=>t.serial)}async getConnectedDevices(){let e=await this.deviceManager.listDevicesWithName();if(e.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");return e}async getPidForBundle(e,t,n){m(`Retrieving PID for bundle ${n}`),P.assertBundleNameStrict(n);let i=await k(e,["-t",t,"shell","pidof",n]),o=ri(i,"Failed to look up PID");if(o)throw o;if(i.exitCode===0&&i.stdout.trim()){let s=i.stdout.trim(),a=s.split(/\s+/)[0]||s;return m(`Found PID for ${n}: ${a}`),a}return m(`No PID found for bundle: ${n}`),null}async resizeHilogBuffer(e,t,n){if(m(`Setting hilog buffer size to: ${n}`),!/^\d+[KMG]?$/.test(n))throw new Error(`Invalid hilog buffer size: ${JSON.stringify(n)}. Expected format: <number>[K|M|G], e.g. "4M", "16M"`);let i=await k(e,["-t",t,"shell","hilog","-G",n]),o=ri(i,"Failed to resize hilog buffer");if(o)throw o;i.exitCode!==0&&console.error(`Failed to resize hilog buffer: ${i.stderr||i.stdout}`)}buildHilogCommand(e,t,n,i){let o=this.buildHilogShellCommand(n,i);return[e,["-t",t,"shell",o]]}buildHilogShellCommand(e,t){let n=["hilog"];return e.isFollow||n.push("-x"),e.tag&&(P.assertHilogToken(e.tag,"tag"),n.push("-T",e.tag)),e.level&&(P.assertHilogLevel(e.level),n.push("-L",e.level)),e.domain&&(P.assertHilogToken(e.domain,"domain"),n.push("-D",e.domain)),t&&n.push("-P",t),e.keyword&&(P.assertHilogKeyword(e.keyword),n.push("-e",P.quotePosixShellArg(e.keyword))),n.join(" ")}async followHilog(e,t,n,i,o){let a=await Ew(e,t,{onData:n,onError:i,onClose:o});return{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode}}async runHilogWithSpawnRetry(e,t,n,i,o){let s=1+Jp.length,a={stdout:"",stderr:"",exitCode:-1};for(let c=0;c<s;c++){if(a=await this.followHilog(e,t,n,i,o),a.exitCode===0||Ut(a.stderr)!=="transient"||c>=s-1)return a;m(`hdc transient failure on \`${t.join(" ")}\`: retrying in ${Jp[c]}ms`),await SA(Jp[c])}return a}async runHilogStreamingCollect(e,t,n){return this.runHilogWithSpawnRetry(e,t,()=>{},i=>{m(`Callback triggered when an error occurs during ${n}: ${i.message}`)},()=>{})}async printTailSnapshotIfNeeded(e,t,n,i){if(!n.tail&&!n.fromSeconds&&!n.toSeconds)return;let o={...n,isFollow:!1},[s,a]=this.buildHilogCommand(e,t,o,i);m(`Ready to run hilog snapshot command: ${s} ${a.join(" ")}`);let c=await this.runHilogStreamingCollect(s,a,"a hilog snapshot streaming read"),l=ri(c,"Failed to get hilog");if(l)throw l;if(c.exitCode!==0&&c.stderr)throw new Error(`Failed to get hilog: ${c.stderr}`);let d=P.filterLogsByRelativeWindow(c.stdout||c.stderr,n.fromSeconds,n.toSeconds);d=P.getLastLines(d,n.tail),d.trim()&&console.log(d)}async getHilogOnce(e,t,n,i){let[o,s]=this.buildHilogCommand(e,t,n,i);m(`Ready to run hilog command: ${o} ${s.join(" ")}`);let a=await this.runHilogStreamingCollect(o,s,"a single hilog streaming read"),c=ri(a,"Failed to get hilog");if(c)throw c;if(a.exitCode!==0&&a.stderr)throw new Error(`Failed to get hilog: ${a.stderr}`);let l=a.stdout||a.stderr,d=P.filterLogsByRelativeWindow(l,n.fromSeconds,n.toSeconds);return d=P.getLastLines(d,n.tail),d}async runHilogFollow(e,t,n,i){try{await this.printTailSnapshotIfNeeded(e,t,n,i)}catch(l){console.error(`Warning: Failed to fetch log snapshot, continuing with live stream: ${l.message}`)}let[o,s]=this.buildHilogCommand(e,t,n,i);m(`Ready to run hilog command which contain \`follow\` and \`tail\`: ${o} ${s.join(" ")}`);let a=await this.runHilogWithSpawnRetry(o,s,this.createFollowLineHandler(),l=>{m(`Spawn error during hilog follow: ${l.message}`)},()=>{}),c=ri(a,"Failed to follow hilog");if(c)throw c;if(a.exitCode!==0&&a.stderr)throw new Error(`Failed to follow hilog: ${a.stderr}`);return""}async getHilog(e,t){let n=this.toolProvider.hdcPath,i=t.bundleName?await this.getPidForBundle(n,e,t.bundleName):void 0;if(t.bundleName&&!i)throw new w(`No running process found for bundle '${t.bundleName}'. Ensure the app is launched on the device before fetching logs.`,"No running process found for bundle.");return t.logSize&&await this.resizeHilogBuffer(n,e,t.logSize),t.isFollow?await this.runHilogFollow(n,e,t,i||""):await this.getHilogOnce(n,e,t,i||"")}async getLatestCrashLog(e,t){m(`Fetching crash logs from device: ${e}`);let n=this.toolProvider.hdcPath,i=await this.listCrashLogs(n,e,t);if(i.length===0)return;let s=[...i].sort((c,l)=>{let d=c.split("-").pop()||"";return(l.split("-").pop()||"").localeCompare(d)})[0],a=await this.fetchCrashLogContent(n,e,s);return`--- Latest Crash Log File: ${s} ---${a}`}async getCrashLog(e,t){let n=await this.getLatestCrashLog(e,t);return n!==void 0?n:t?`No crash logs found for bundle '${t}'.`:"No crash logs found."}async listCrashLogs(e,t,n){let i=["-t",t,"shell","hidumper","-s","1201","-a","-p Faultlogger"];m(`Running command: ${e} ${i.join(" ")}`);let o=await this.runHilogStreamingCollect(e,i,"a crash log list streaming read"),s=ri(o,"Failed to list crash logs");if(s)throw s;if(o.exitCode!==0)throw new Error(`Failed to list crash logs: ${o.stderr||o.stdout}`);return m(`Crash logs list output:
56
+ ${o}`,"Device not found.")}if(n.length===1){let i=n[0];return f(yl(`Using device: ${i.name} (${i.serial})`)),i.serial}throw new w("Multiple devices found. Specify a target device using `--device <name>` or `--device <serial>`.\nAvailable devices:\n"+this.formatConnectedDeviceList(n),"Multiple devices found.")}async getConnectedDeviceSerials(){let e=await this.deviceManager.listDevices();if(e.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");return e.map(t=>t.serial)}async getConnectedDevices(){let e=await this.deviceManager.listDevicesWithName();if(e.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");return e}async getPidForBundle(e,t,n){f(`Retrieving PID for bundle ${n}`),P.assertBundleNameStrict(n);let i=await k(e,["-t",t,"shell","pidof",n]),o=si(i,"Failed to look up PID");if(o)throw o;if(i.exitCode===0&&i.stdout.trim()){let s=i.stdout.trim(),a=s.split(/\s+/)[0]||s;return f(`Found PID for ${n}: ${a}`),a}return f(`No PID found for bundle: ${n}`),null}async resizeHilogBuffer(e,t,n){if(f(`Setting hilog buffer size to: ${n}`),!/^\d+[KMG]?$/.test(n))throw new Error(`Invalid hilog buffer size: ${JSON.stringify(n)}. Expected format: <number>[K|M|G], e.g. "4M", "16M"`);let i=await k(e,["-t",t,"shell","hilog","-G",n]),o=si(i,"Failed to resize hilog buffer");if(o)throw o;i.exitCode!==0&&console.error(`Failed to resize hilog buffer: ${i.stderr||i.stdout}`)}buildHilogCommand(e,t,n,i){let o=this.buildHilogShellCommand(n,i);return[e,["-t",t,"shell",o]]}buildHilogShellCommand(e,t){let n=["hilog"];return e.isFollow||n.push("-x"),e.tag&&(P.assertHilogToken(e.tag,"tag"),n.push("-T",e.tag)),e.level&&(P.assertHilogLevel(e.level),n.push("-L",e.level)),e.domain&&(P.assertHilogToken(e.domain,"domain"),n.push("-D",e.domain)),t&&n.push("-P",t),e.keyword&&(P.assertHilogKeyword(e.keyword),n.push("-e",P.quotePosixShellArg(e.keyword))),n.join(" ")}async followHilog(e,t,n,i,o){let a=await gv(e,t,{onData:n,onError:i,onClose:o});return{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode}}async runHilogWithSpawnRetry(e,t,n,i,o){let s=1+Rf.length,a={stdout:"",stderr:"",exitCode:-1};for(let c=0;c<s;c++){if(a=await this.followHilog(e,t,n,i,o),a.exitCode===0||Vt(a.stderr)!=="transient"||c>=s-1)return a;f(`hdc transient failure on \`${t.join(" ")}\`: retrying in ${Rf[c]}ms`),await QA(Rf[c])}return a}async runHilogStreamingCollect(e,t,n){return this.runHilogWithSpawnRetry(e,t,()=>{},i=>{f(`Callback triggered when an error occurs during ${n}: ${i.message}`)},()=>{})}async printTailSnapshotIfNeeded(e,t,n,i){if(!n.tail&&!n.fromSeconds&&!n.toSeconds)return;let o={...n,isFollow:!1},[s,a]=this.buildHilogCommand(e,t,o,i);f(`Ready to run hilog snapshot command: ${s} ${a.join(" ")}`);let c=await this.runHilogStreamingCollect(s,a,"a hilog snapshot streaming read"),l=si(c,"Failed to get hilog");if(l)throw l;if(c.exitCode!==0&&c.stderr)throw new Error(`Failed to get hilog: ${c.stderr}`);let d=P.filterLogsByRelativeWindow(c.stdout||c.stderr,n.fromSeconds,n.toSeconds);d=P.getLastLines(d,n.tail),d.trim()&&console.log(d)}async getHilogOnce(e,t,n,i){let[o,s]=this.buildHilogCommand(e,t,n,i);f(`Ready to run hilog command: ${o} ${s.join(" ")}`);let a=await this.runHilogStreamingCollect(o,s,"a single hilog streaming read"),c=si(a,"Failed to get hilog");if(c)throw c;if(a.exitCode!==0&&a.stderr)throw new Error(`Failed to get hilog: ${a.stderr}`);let l=a.stdout||a.stderr,d=P.filterLogsByRelativeWindow(l,n.fromSeconds,n.toSeconds);return d=P.getLastLines(d,n.tail),d}async runHilogFollow(e,t,n,i){try{await this.printTailSnapshotIfNeeded(e,t,n,i)}catch(l){console.error(`Warning: Failed to fetch log snapshot, continuing with live stream: ${l.message}`)}let[o,s]=this.buildHilogCommand(e,t,n,i);f(`Ready to run hilog command which contain \`follow\` and \`tail\`: ${o} ${s.join(" ")}`);let a=await this.runHilogWithSpawnRetry(o,s,this.createFollowLineHandler(),l=>{f(`Spawn error during hilog follow: ${l.message}`)},()=>{}),c=si(a,"Failed to follow hilog");if(c)throw c;if(a.exitCode!==0&&a.stderr)throw new Error(`Failed to follow hilog: ${a.stderr}`);return""}async getHilog(e,t){let n=this.toolProvider.hdcPath,i=t.bundleName?await this.getPidForBundle(n,e,t.bundleName):void 0;if(t.bundleName&&!i)throw new w(`No running process found for bundle '${t.bundleName}'. Ensure the app is launched on the device before fetching logs.`,"No running process found for bundle.");return t.logSize&&await this.resizeHilogBuffer(n,e,t.logSize),t.isFollow?await this.runHilogFollow(n,e,t,i||""):await this.getHilogOnce(n,e,t,i||"")}async getLatestCrashLog(e,t){f(`Fetching crash logs from device: ${e}`);let n=this.toolProvider.hdcPath,i=await this.listCrashLogs(n,e,t);if(i.length===0)return;let s=[...i].sort((c,l)=>{let d=c.split("-").pop()||"";return(l.split("-").pop()||"").localeCompare(d)})[0],a=await this.fetchCrashLogContent(n,e,s);return`--- Latest Crash Log File: ${s} ---${a}`}async getCrashLog(e,t){let n=await this.getLatestCrashLog(e,t);return n!==void 0?n:t?`No crash logs found for bundle '${t}'.`:"No crash logs found."}async listCrashLogs(e,t,n){let i=["-t",t,"shell","hidumper","-s","1201","-a","-p Faultlogger"];f(`Running command: ${e} ${i.join(" ")}`);let o=await this.runHilogStreamingCollect(e,i,"a crash log list streaming read"),s=si(o,"Failed to list crash logs");if(s)throw s;if(o.exitCode!==0)throw new Error(`Failed to list crash logs: ${o.stderr||o.stdout}`);return f(`Crash logs list output:
57
57
  ${o.stdout}`),this.parseCrashLogFilenames(o.stdout,n)}parseCrashLogFilenames(e,t){return e.split(`
58
- `).map(n=>n.trim()).filter(n=>n.length>0).filter(n=>{try{return P.assertCrashFilename(n),!0}catch{return!1}}).filter(n=>t?n.toLowerCase().includes(t.toLowerCase()):!0)}async fetchCrashLogContent(e,t,n){m(`Fetching latest crash log file: ${n}`);let i=["-t",t,"shell","hidumper","-s","1201","-a",`-p Faultlogger -f ${n}`];m(`Executing command: ${e} ${i.join(" ")}`);let o=await this.runHilogStreamingCollect(e,i,"a crash log streaming read"),s=ri(o,"Failed to fetch crash log content");if(s)throw s;return o.exitCode!==0&&o.stderr&&console.error(`Warning: Failed to fetch crash logs: ${o.stderr}`),o.stdout+o.stderr}};import{readFileSync as PA,unlinkSync as CA}from"fs";import{tmpdir as kA}from"os";import{join as DA}from"path";var Or=class{constructor(e,t){this.hdcPath=e;this.serial=t}async listWindows(e){let t=await this.fetchDump(),n=EA(t);return e?.all||(n=n.filter(i=>i.type===1)),n}async fetchDump(){let e=["-t",this.serial,"shell","hidumper","-s","WindowManagerService","-a","-a"];m(`Executing: ${this.hdcPath} ${e.join(" ")}`);let t=await k(this.hdcPath,e);if(t.exitCode!==0)throw new Error(`Failed to query windows: ${(t.stderr||t.stdout).trim()}`);return t.stdout}};function EA(r){let e=r.split(`
59
- `),t=e.findIndex(s=>s.trimStart().startsWith("WindowName"));if(t===-1)return[];let n=[];for(let s=t+1;s<e.length;s++){let a=e[s].trim();if(!a||/^-+$/.test(a)||a.startsWith("Focus window")||a.startsWith("total window"))break;let c=a.split(/\s+/);if(c.length<5)continue;let l=c[0],d=Number(c[1]),g=Number(c[2]),y=Number(c[3]),E=Number(c[4]);Number.isFinite(y)&&Number.isFinite(d)&&Number.isFinite(g)&&n.push({id:y,name:l,pid:g,displayId:d,type:E})}let i=e.find(s=>s.trim().startsWith("Focus window")),o=i?Number(i.replace(/.*:\s*/,"").trim()):NaN;return n.map(s=>({...s,focused:s.id===o}))}function Uw(r){if(!(!r||r==="HitTestMode.Default"))return r.startsWith("HitTestMode.")?r.slice(12):r}function ks(r){if(!(r==null||r==="")){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1}}function el(r){if(typeof r!="string")return;let e=r.match(/-?\d+/g);if(!(!e||e.length<4))return[Number(e[0]),Number(e[1]),Number(e[2]),Number(e[3])]}function Bw(r){return r.originalText||void 0}function ro(r,e){let t=[],n=[...r].reverse();for(;n.length>0;){let i=n.pop();i.id===e&&t.push(i);for(let o=i.children.length-1;o>=0;o--)n.push(i.children[o])}return t}function Ww(r,e){let t=[],n=[{current:r,parent:null,depth:0}];for(;n.length>0;){let{current:i,parent:o,depth:s}=n.pop(),a=o===null,c=!i.id&&!i.text&&!i.clickable&&!i.longClickable&&!i.scrollable&&!i.checkable,l=a||!c,d=o;if(l){let y={...i,children:[]};if(a?t.push(y):o.children.push(y),d=y,e>0&&s+1>=e)continue}if(process.env.DEVECO_CLI_DEBUG){let y=i.type?i.id?`${i.type}#${i.id}`:i.type:"#";m(`collapse ${y} depth=${s} -> ${a?"root":c?"collapsed":"emitted"}`)}let g=l?s+1:s;for(let y=i.children.length-1;y>=0;y--)n.push({current:i.children[y],parent:d,depth:g})}return t}function RA(r){let e=PA(r,"utf-8").trim();if(!e)throw new Error("Empty dumpLayout response from device");return JSON.parse(e)}function xA(r){return r.attributes??{}}function tl(r,e,t){let n=xA(r),i={id:n.id||void 0,type:n.type||void 0,text:Bw(n),bounds:el(n.bounds),clickable:ks(n.clickable)||void 0,longClickable:ks(n.longClickable)||void 0,scrollable:ks(n.scrollable)||void 0,checkable:ks(n.checkable)||void 0,hitTestBehavior:Uw(n.hitTestBehavior),children:[]};return e>0&&t+1>=e||r.children&&(i.children=r.children.map(o=>tl(o,e,t+1))),i}function AA(r,e){if(e){let n=r.find(i=>String(i.id)===e);if(!n){let i=r.map(o=>`${o.id} (${o.name})`).join(", ");throw new w(`Window '${e}' not found. Available windows: ${i||"none"}`,"Window not found.")}return n}let t=r.find(n=>n.focused);if(t)return t;throw new Error("No window id specified and could not detect focused window")}var Nr=class{hdcPath;constructor(e){this.hdcPath=e}buildRemoteDumpPath(){return`/data/local/tmp/deveco_cli_dump_${Date.now()}_${process.pid}.json`}async fetchRawDump(e,t,n){let i=this.buildRemoteDumpPath(),o=["-t",e,"shell","uitest","dumpLayout","-p",i];n!==void 0&&o.push("-d",String(n)),t&&o.push("-w",t),m(`Executing: ${this.hdcPath} ${o.join(" ")}`);let s=await k(this.hdcPath,o);if(s.exitCode!==0)throw new Error(`Failed to dump layout: ${(s.stderr||s.stdout).trim()}`);return this.recvAndParseDump(e,i)}async recvAndParseDump(e,t){let n=DA(kA(),`deveco_cli_dump_${Date.now()}_${process.pid}.json`);try{return await this.recvDumpFile(e,t,n),RA(n)}finally{await this.cleanupDumpArtifacts(e,n,t)}}async recvDumpFile(e,t,n){let i=["-t",e,"file","recv",t,n];m(`Executing: ${this.hdcPath} ${i.join(" ")}`);let o=await k(this.hdcPath,i);if(o.exitCode!==0)throw new Error(`Failed to recv dump file: ${(o.stderr||o.stdout).trim()}`)}async cleanupDumpArtifacts(e,t,n){try{m(`Removing local dump file: ${t}`),CA(t)}catch(o){m(`Failed to clean local dump file ${t}: ${o.message}`)}let i=["-t",e,"shell","rm","-f",n];m(`Executing: ${this.hdcPath} ${i.join(" ")}`),await k(this.hdcPath,i).catch(o=>{m(`Failed to clean remote dump file ${n}: ${o.message}`)})}async dumpRawNodes(e,t,n){let o=await new Or(this.hdcPath,e).listWindows({all:!0});if(n){let a=[...new Set(o.map(l=>l.displayId))],c=[];for(let l of a)c.push(await this.fetchRawDump(e,void 0,l));return c}let s=AA(o,t);return[await this.fetchRawDump(e,String(s.id),s.displayId)]}async dumpFullTree(e,t,n,i){return(await this.dumpRawNodes(e,n,i)).map(s=>tl(s,t,0))}async dumpFullTreeByDisplays(e,t,n){let i=[];for(let o of n){let s=await this.fetchRawDump(e,void 0,o);i.push({displayId:o,tree:tl(s,t,0)})}return i}async dumpCollapsedTree(e,t,n,i){return(await this.dumpRawNodes(e,n,i)).flatMap(s=>Ww(tl(s,0,0),t))}async dumpRawTree(e,t){return(await this.dumpRawNodes(e,t,!1))[0]}};var We=class extends Error{position;input;constructor(e,t,n){super(`Selector parse error at ${t}: ${e}`),this.name="SelectorParseError",this.position=t,this.input=n}},IA=["*=","^=","$=","/="],TA=/[A-Za-z_]/,OA=/[A-Za-z0-9_]/,Kp=/\s/,NA=/^(.*)\/([gimsuy]+)$/,Xp=class{input;pos=0;constructor(e){this.input=e}eof(){return this.pos>=this.input.length}peek(e=0){let t=this.pos+e;return t>=0&&t<this.input.length?this.input[t]:""}next(){return this.pos<this.input.length?this.input[this.pos++]:""}startsWith(e){return this.input.slice(this.pos,this.pos+e.length)===e}};function Mr(r){for(;!r.eof()&&Kp.test(r.peek());)r.next()}function MA(r){let e=r.pos;if(!TA.test(r.peek()))throw new We("expected attribute key",r.pos,r.input);for(;!r.eof()&&OA.test(r.peek());)r.next();return r.input.slice(e,r.pos)}function LA(r,e){for(let t of IA)if(r.startsWith(t))return r.pos+=t.length,t;if(r.peek()==="=")return r.next(),"=";throw new We(`expected operator (=, *=, ^=, $=, /=) after key "${e}"`,r.pos,r.input)}function Vw(r){let e=r.match(NA);return e?{value:e[1],flags:e[2]}:{value:r}}function _A(r,e){r.next();let t="";for(;!r.eof();){let n=r.next();if(n==="\\"){if(r.eof())throw new We("dangling escape in quoted value",r.pos,r.input);t+=r.next();continue}if(n===e)return t;t+=n}throw new We("unterminated quoted value",r.pos,r.input)}function Yp(r){return r==='"'||r==="'"}function $A(r,e){let t=r.peek();if(Yp(t)){let i=_A(r,t);return e==="/="?Vw(i):{value:i}}let n="";for(;!r.eof();){let i=r.peek();if(i===","||i==="["||Yp(i))break;if(Kp.test(i)){let o=r.pos+1;for(;o<r.input.length&&Kp.test(r.input[o]);)o++;let s=o<r.input.length?r.input[o]:"";if(s===""||s===","||s==="["||Yp(s))break;n+=r.next();continue}if(i==="\\"){if(r.next(),r.eof())throw new We("dangling escape in value",r.pos,r.input);n+=r.next();continue}n+=r.next()}return e==="/="?Vw(n):{value:n}}function Gw(r){Mr(r);let e=MA(r);Mr(r);let t=LA(r,e);if(Mr(r),r.eof()||r.peek()===","||r.peek()==="[")throw new We(`missing value for key "${e}"`,r.pos,r.input);let{value:n,flags:i}=$A(r,t);if(t==="/=")try{new RegExp(n,i)}catch(s){throw new We(`invalid regex "${n}"${i?` with flags "${i}"`:""}: ${s.message}`,r.pos,r.input)}let o={key:e,op:t,value:n};return i!==void 0&&(o.flags=i),o}function FA(r){let e="";for(;!r.eof()&&r.peek()!=="]";)e+=r.next();if(e=e.trim(),e==="last")return-1;if(/^-?\d+$/.test(e))return parseInt(e,10);throw new We(`invalid index "${e}" (expected N, -N, or "last")`,r.pos,r.input)}function Ds(r){if(typeof r!="string")throw new We("input must be a string",0,String(r));let e=new Xp(r),t=[];if(Mr(e),e.eof())throw new We("empty selector",e.pos,r);for(t.push(Gw(e));Mr(e),e.peek()===",";){if(e.next(),Mr(e),e.eof()||e.peek()===",")throw new We("expected clause after comma",e.pos,r);t.push(Gw(e))}let n;if(Mr(e),e.peek()==="["){if(e.next(),n=FA(e),Mr(e),e.peek()!=="]")throw new We("expected ']' after index",e.pos,r);e.next(),Mr(e)}if(!e.eof())throw new We(`unexpected trailing input "${e.input.slice(e.pos)}"`,e.pos,r);return{clauses:t,index:n,raw:r}}function jA(r,e){if(r==null)return;if(e==="text"){let n=r.originalText??r.text;return n==null?void 0:String(n)}if(e==="desc"||e==="description"){let n=r.description;return n==null?void 0:String(n)}let t=r[e];return t==null?void 0:String(t)}function HA(r,e){let t=jA(r,e.key);if(t===void 0)return!1;switch(e.op){case"=":return t===e.value;case"*=":return t.includes(e.value);case"^=":return t.startsWith(e.value);case"$=":return t.endsWith(e.value);case"/=":try{return(e.flags?new RegExp(e.value,e.flags):new RegExp(e.value)).test(t)}catch{return!1}default:return!1}}function rl(r,e){let t=[],n=[r];for(;n.length>0;){let i=n.pop(),o=i.attributes??null;e.clauses.every(a=>HA(o,a))&&t.push(i);let s=i.children;if(s)for(let a=s.length-1;a>=0;a--)n.push(s[a])}return t}function no(r,e){return e===void 0?r[0]:e>=0?r[e]:r[r.length+e]}import{DOMParser as UA}from"@xmldom/xmldom";import{select as BA}from"xpath";var WA=["id","key","originalText","description","enabled","focused","checked","selected","visible","clickable","longClickable","scrollable","checkable","accessibilityLevel","hitTestBehavior","bounds"];function VA(r){if(!r)return"node";let e=r.replace(/[^A-Za-z0-9_-]/g,"_");return/^[0-9]/.test(e)&&(e="_"+e),e||"node"}var GA=/&/g,qA=/</g,zA=/>/g,JA=/"/g,YA=/'/g;function nl(r){return r.replace(GA,"&amp;").replace(qA,"&lt;").replace(zA,"&gt;").replace(JA,"&quot;").replace(YA,"&apos;")}function KA(r){let e=[],t=typeof r.type=="string"?r.type:"";t&&e.push(` type="${nl(t)}"`);let n=r.originalText??r.text;n!=null&&n!==""&&e.push(` text="${nl(String(n))}"`);for(let o of WA){let s=r[o];s==null||s===""||e.push(` ${o}="${nl(String(s))}"`)}let i=r.description;return i!=null&&i!==""&&e.push(` desc="${nl(String(i))}"`),e.join("")}function qw(r){let e=r.attributes??{},t=VA(typeof e.type=="string"?e.type:void 0),n=KA(e),i=r.children??[];return i.length===0?`<${t}${n}/>`:`<${t}${n}>${i.map(qw).join("")}</${t}>`}function XA(r){return`<?xml version="1.0" encoding="UTF-8"?>${qw(r)}`}function ZA(r){if(!r)return;let e=r.match(/-?\d+/g);if(!e||e.length<4)return;let[t,n,i,o]=e.map(Number);return[t,n,i,o]}function QA(r){return typeof r!="object"||r===null?!1:r.nodeType===1}function eI(r){let e=i=>{let o=r.getAttribute(i);return o===""||o===null?void 0:o},t={},n=r.attributes;if(n)for(let i=0;i<n.length;i++){let o=n[i];o&&(t[o.name]=o.value)}return{type:e("type")??r.tagName,id:e("id"),key:e("key"),text:e("text"),originalText:e("originalText"),description:e("description")??e("desc"),enabled:e("enabled"),focused:e("focused"),checked:e("checked"),selected:e("selected"),visible:e("visible"),clickable:e("clickable"),longClickable:e("longClickable"),scrollable:e("scrollable"),checkable:e("checkable"),accessibilityLevel:e("accessibilityLevel"),hitTestBehavior:e("hitTestBehavior"),bounds:ZA(e("bounds")),attributes:t}}function Zp(r,e){if(typeof e!="string"||e.trim()==="")throw new Error("xpath expression must be a non-empty string");let t=XA(r),n=new UA().parseFromString(t,"text/xml"),i=BA(e,n);if(!Array.isArray(i))throw new Error(`xpath "${e}" did not return a node-set; use a path expression like //Button[@text='\u767B\u5F55']`);let o=[];for(let s of i)QA(s)&&o.push(eI(s));return o}function il(r){return typeof r=="string"&&r.trimStart().startsWith("xpath=")}function ol(r){return r.trimStart().slice(6)}function sl(r){return new Promise(e=>setTimeout(e,r))}function Qp(r,e){let t=r.attributes??{};return{index:e,id:t.id||void 0,key:t.key||void 0,type:t.type||void 0,text:t.originalText||t.text||void 0,description:t.description||void 0,enabled:t.enabled||void 0,focused:t.focused||void 0,checked:t.checked||void 0,selected:t.selected||void 0,visible:t.visible||void 0,clickable:t.clickable||void 0,longClickable:t.longClickable||void 0,scrollable:t.scrollable||void 0,checkable:t.checkable||void 0,bounds:el(t.bounds),attributes:t}}function zw(r,e){return{index:e,id:r.id,key:r.key,type:r.type,text:r.text,description:r.description,enabled:r.enabled,focused:r.focused,checked:r.checked,selected:r.selected,visible:r.visible,clickable:r.clickable,longClickable:r.longClickable,scrollable:r.scrollable,checkable:r.checkable,bounds:r.bounds,attributes:r.attributes}}function al(r){return r.startsWith("base64=")?Buffer.from(r.slice(7).trim(),"base64").toString("utf8"):r}var tI=new Set(["text","desc","description"]),Rs=[];function Yw(r,e){if(r.attributes)for(let t of Object.keys(r.attributes))e.add(t);if(r.children)for(let t of r.children)Yw(t,e)}function Kw(r,e){let t=new Set;Yw(r,t);let n=[];for(let i of e)tI.has(i.key)||t.has(i.key)||n.push(i.key);return n}function Jw(r,e){let t=Kw(r,e);for(let n of t)Rs.push(`WARNING: attribute "${n}" not found in any node of the layout tree. No matches will be returned for this key.`)}function em(){return Rs.splice(0)}var io=class{dumper;constructor(e){this.dumper=new Nr(e)}async find(e,t,n){Rs.splice(0);let i=al(t);if(il(i))return this.runXpathFind(e,ol(i),n);let o=Ds(i);return this.runFind(e,o,n)}async runFind(e,t,n){let i=n?.timeoutMs??3e3,o=300,s=Date.now(),a=[],c=!1,l=!1;for(;!c;){let g=await this.dumper.dumpRawTree(e,n?.window);if(l||(Jw(g,t.clauses),l=!0),a=rl(g,t),c=n?.all?a.length>0:no(a,t.index)!==void 0,c)break;if(Date.now()-s>=i)throw new Error(`Timed out (${i}ms) waiting for selector: ${t.raw}`);await sl(o)}if(n?.all)return a.map((g,y)=>Qp(g,y));let d=no(a,t.index);if(!d){let g=a.length,y=t.index===void 0?0:t.index;throw new Error(`Index ${y} out of range (matched ${g} element(s)) for selector: ${t.raw}`)}return[Qp(d,t.index??0)]}async runXpathFind(e,t,n){let i=n?.timeoutMs??3e3,o=300,s=Date.now(),a=[],c=!1;for(;!c;){let l=await this.dumper.dumpRawTree(e,n?.window);if(a=Zp(l,t),c=a.length>0,c)break;if(Date.now()-s>=i)throw new Error(`Timed out (${i}ms) waiting for xpath: ${t}`);await sl(o)}return n?.all?a.map((l,d)=>zw(l,d)):[zw(a[0],0)]}async waitForAppearance(e,t,n,i){Rs.splice(0);let o=al(t);if(il(o))return(await this.runXpathFind(e,ol(o),{timeoutMs:n,window:i}))[0];let s=Ds(o);return await this.runWaitFor(e,s,n,i,!0)}async waitForDisappear(e,t,n,i){Rs.splice(0);let o=al(t);if(il(o))return this.runXpathWaitFor(e,ol(o),n,i,!1);let s=Ds(o);await this.runWaitFor(e,s,n,i,!1)}async runWaitFor(e,t,n,i,o){let a=Date.now(),c=!1;for(;;){let l=await this.dumper.dumpRawTree(e,i);c||(Jw(l,t.clauses),c=!0);let d=rl(l,t),g=no(d,t.index)!==void 0;if(o&&g){let y=no(d,t.index);return Qp(y,t.index??0)}if(!o&&!g)return;if(Date.now()-a>=n)throw new Error(`Timed out (${n}ms) waiting for selector to ${o?"appear":"disappear"}: ${t.raw}`);await sl(300)}}async runXpathWaitFor(e,t,n,i,o){let a=Date.now();for(;;){let c=await this.dumper.dumpRawTree(e,i),d=Zp(c,t).length>0;if(o&&d||!o&&!d)return;if(Date.now()-a>=n)throw new Error(`Timed out (${n}ms) waiting for xpath to ${o?"appear":"disappear"}: ${t}`);await sl(300)}}};import ot from"fs";import $e from"path";import{randomUUID as rI}from"crypto";function Xw(r,e){let t=["-t",r.serial,"shell","snapshot_display"];return r.display!==void 0&&t.push("-i",r.display),t.push("-f",r.remotePath),e&&t.push("-t",e),t}function Zw(r,e){return[r,e].filter(Boolean).join(`
60
- `).trim()}function Qw(r){return r.replace(/(Tips:\s*supported\s+displayIds)\s*:?[ \t]*(?:\r?\n[ \t]*)?(\d+(?:(?:[ \t]*,[ \t]*|[ \t]+|\r?\n[ \t]*)\d+)*)/gi,(e,t,n)=>`${t}: ${n.match(/\d+/g)?.join(", ")??n}`)}function ev(r){let e=String.raw`invalid|not found|not exist|does not exist|out of range|unsupported`;return new RegExp(String.raw`display(?:\s*id)?.*(?:${e})`,"is").test(r)||new RegExp(String.raw`(?:${e}).*display(?:\s*id)?`,"is").test(r)}function tv(r){let e=r.trim();if(!e||/No such file|not found|cannot access/i.test(e))return;let t=e.split(/\s+/),n=Number(t[4]);return Number.isFinite(n)?n:void 0}function nI(){return String(Date.now())}function tm(r){let e;try{e=ot.statSync(r)}catch(t){let n=t.code;throw n==="ENOENT"?new Error(`Screenshot directory does not exist: ${r}`,{cause:t}):n==="EACCES"||n==="EPERM"?new Error(`Screenshot directory is not writable: ${r}`,{cause:t}):new Error(`Invalid screenshot path: ${t.message}${n?` (${n})`:""}`,{cause:t})}if(!e.isDirectory())throw new Error(`Screenshot parent path is not a directory: ${r}`);try{ot.accessSync(r,ot.constants.W_OK|ot.constants.X_OK)}catch(t){throw new Error(`Screenshot directory is not writable: ${r}`,{cause:t})}}function rm(r,e){try{throw ot.lstatSync(r),new Error(`Screenshot file already exists: ${r}`)}catch(t){let n=t.code;if(n==="ENOENT")return;throw n==="EACCES"||n==="EPERM"?new Error(`Screenshot directory is not writable: ${e}`,{cause:t}):t instanceof Error&&!n?t:new Error(`Invalid screenshot path: ${t.message}${n?` (${n})`:""}`,{cause:t})}}function rv(r){if(!ot.existsSync(r))throw new Error(`Screenshot file was not created: ${r}`);let e=ot.statSync(r);if(!e.isFile()||e.size===0)throw new Error(`Screenshot file is empty: ${r}`);let t=ot.readFileSync(r).subarray(0,8),n=Buffer.from([137,80,78,71,13,10,26,10]);if(!t.equals(n))throw new Error(`Screenshot file is not a valid PNG: ${r}`)}function nv(r){try{return rv(r),!0}catch{return!1}}function iv(r){let e=[];for(let t of ot.readdirSync(r,{withFileTypes:!0})){let n=$e.join(r,t.name);if(t.isDirectory()){e.push(...iv(n));continue}t.isFile()&&nv(n)&&e.push(n)}return e}function iI(r,e){let t=$e.join(r,$e.basename(e));if(nv(t))return t;let n=iv(r);if(n.length===1)return n[0];if(n.length>1)throw new Error(`Multiple screenshot files were received in ${r}.`)}function oI(r,e){try{ot.copyFileSync(r,e,ot.constants.COPYFILE_EXCL)}catch(t){throw t.code==="EEXIST"?new Error(`Screenshot file already exists: ${e}`,{cause:t}):t}rv(e)}var ni=class{constructor(e){this.toolProvider=e}resolveDestinationPath(e){if(!e?.trim())throw new Error("--path is required.");let t=e.trim(),n=$e.resolve(t);try{if(ot.statSync(n).isDirectory()){tm(n);let o=$e.join(n,`screenshot-${nI()}.png`);return rm(o,n),o}}catch(o){if(o.code!=="ENOENT")throw o}if($e.extname(n).toLowerCase()!==".png")throw new Error(`Screenshot path must be an existing directory or a PNG file: ${n}`);let i=$e.dirname(n);return tm(i),rm(n,i),n}async captureToPath(e,t,n){let i=$e.dirname($e.resolve(t));tm(i),rm($e.resolve(t),i);let o=`/data/local/tmp/devecocli-${rI()}.png`;await this.capture({hdcPath:this.toolProvider.hdcPath,serial:e,localPath:$e.resolve(t),remotePath:o,display:n})}async capture(e){try{await this.createRemoteScreenshot(e),await this.receiveScreenshotFile(e)}finally{await this.removeRemoteScreenshot(e)}}async getRemoteScreenshotSize(e){let t=["-t",e.serial,"shell","ls","-l",e.remotePath];m(`Executing: ${e.hdcPath} ${t.join(" ")}`);let n=await k(e.hdcPath,t);return n.exitCode===0?tv(n.stdout):void 0}async tryCreateRemoteScreenshot(e,t){let n=Xw(e,t);m(`Executing: ${e.hdcPath} ${n.join(" ")}`);let i=await k(e.hdcPath,n),o=await this.getRemoteScreenshotSize(e);return{created:o!==void 0&&o>0,output:Qw(Zw(i.stdout,i.stderr))}}async createRemoteScreenshot(e){let t="";for(let n of[void 0,"png"]){let i=await this.tryCreateRemoteScreenshot(e,n);if(i.created)return;if(e.display!==void 0&&ev(i.output))throw new Error(`Screenshot was not created on device: ${e.remotePath}.
58
+ `).map(n=>n.trim()).filter(n=>n.length>0).filter(n=>{try{return P.assertCrashFilename(n),!0}catch{return!1}}).filter(n=>t?n.toLowerCase().includes(t.toLowerCase()):!0)}async fetchCrashLogContent(e,t,n){f(`Fetching latest crash log file: ${n}`);let i=["-t",t,"shell","hidumper","-s","1201","-a",`-p Faultlogger -f ${n}`];f(`Executing command: ${e} ${i.join(" ")}`);let o=await this.runHilogStreamingCollect(e,i,"a crash log streaming read"),s=si(o,"Failed to fetch crash log content");if(s)throw s;return o.exitCode!==0&&o.stderr&&console.error(`Warning: Failed to fetch crash logs: ${o.stderr}`),o.stdout+o.stderr}};import{readFileSync as tT,unlinkSync as rT}from"fs";import{tmpdir as nT}from"os";import{join as iT}from"path";var Lr=class{constructor(e,t){this.hdcPath=e;this.serial=t}async listWindows(e){let t=await this.fetchDump(),n=eT(t);return e?.all||(n=n.filter(i=>i.type===1)),n}async fetchDump(){let e=["-t",this.serial,"shell","hidumper","-s","WindowManagerService","-a","-a"];f(`Executing: ${this.hdcPath} ${e.join(" ")}`);let t=await k(this.hdcPath,e);if(t.exitCode!==0)throw new Error(`Failed to query windows: ${(t.stderr||t.stdout).trim()}`);return t.stdout}};function eT(r){let e=r.split(`
59
+ `),t=e.findIndex(s=>s.trimStart().startsWith("WindowName"));if(t===-1)return[];let n=[];for(let s=t+1;s<e.length;s++){let a=e[s].trim();if(!a||/^-+$/.test(a)||a.startsWith("Focus window")||a.startsWith("total window"))break;let c=a.split(/\s+/);if(c.length<5)continue;let l=c[0],d=Number(c[1]),g=Number(c[2]),y=Number(c[3]),E=Number(c[4]);Number.isFinite(y)&&Number.isFinite(d)&&Number.isFinite(g)&&n.push({id:y,name:l,pid:g,displayId:d,type:E})}let i=e.find(s=>s.trim().startsWith("Focus window")),o=i?Number(i.replace(/.*:\s*/,"").trim()):NaN;return n.map(s=>({...s,focused:s.id===o}))}function _v(r){if(!(!r||r==="HitTestMode.Default"))return r.startsWith("HitTestMode.")?r.slice(12):r}function Fs(r){if(!(r==null||r==="")){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1}}function wl(r){if(typeof r!="string")return;let e=r.match(/-?\d+/g);if(!(!e||e.length<4))return[Number(e[0]),Number(e[1]),Number(e[2]),Number(e[3])]}function Mv(r){return r.originalText||void 0}function po(r,e){let t=[],n=[...r].reverse();for(;n.length>0;){let i=n.pop();i.id===e&&t.push(i);for(let o=i.children.length-1;o>=0;o--)n.push(i.children[o])}return t}function Lv(r,e){let t=[],n=[{current:r,parent:null,depth:0}];for(;n.length>0;){let{current:i,parent:o,depth:s}=n.pop(),a=o===null,c=!i.id&&!i.text&&!i.clickable&&!i.longClickable&&!i.scrollable&&!i.checkable,l=a||!c,d=o;if(l){let y={...i,children:[]};if(a?t.push(y):o.children.push(y),d=y,e>0&&s+1>=e)continue}if(process.env.DEVECO_CLI_DEBUG){let y=i.type?i.id?`${i.type}#${i.id}`:i.type:"#";f(`collapse ${y} depth=${s} -> ${a?"root":c?"collapsed":"emitted"}`)}let g=l?s+1:s;for(let y=i.children.length-1;y>=0;y--)n.push({current:i.children[y],parent:d,depth:g})}return t}function oT(r){let e=tT(r,"utf-8").trim();if(!e)throw new Error("Empty dumpLayout response from device");return JSON.parse(e)}function sT(r){return r.attributes??{}}function vl(r,e,t){let n=sT(r),i={id:n.id||void 0,type:n.type||void 0,text:Mv(n),bounds:wl(n.bounds),clickable:Fs(n.clickable)||void 0,longClickable:Fs(n.longClickable)||void 0,scrollable:Fs(n.scrollable)||void 0,checkable:Fs(n.checkable)||void 0,hitTestBehavior:_v(n.hitTestBehavior),children:[]};return e>0&&t+1>=e||r.children&&(i.children=r.children.map(o=>vl(o,e,t+1))),i}function aT(r,e){if(e){let n=r.find(i=>String(i.id)===e);if(!n){let i=r.map(o=>`${o.id} (${o.name})`).join(", ");throw new w(`Window '${e}' not found. Available windows: ${i||"none"}`,"Window not found.")}return n}let t=r.find(n=>n.focused);if(t)return t;throw new Error("No window id specified and could not detect focused window")}var Fr=class{hdcPath;constructor(e){this.hdcPath=e}buildRemoteDumpPath(){return`/data/local/tmp/deveco_cli_dump_${Date.now()}_${process.pid}.json`}async fetchRawDump(e,t,n){let i=this.buildRemoteDumpPath(),o=["-t",e,"shell","uitest","dumpLayout","-p",i];n!==void 0&&o.push("-d",String(n)),t&&o.push("-w",t),f(`Executing: ${this.hdcPath} ${o.join(" ")}`);let s=await k(this.hdcPath,o);if(s.exitCode!==0)throw new Error(`Failed to dump layout: ${(s.stderr||s.stdout).trim()}`);return this.recvAndParseDump(e,i)}async recvAndParseDump(e,t){let n=iT(nT(),`deveco_cli_dump_${Date.now()}_${process.pid}.json`);try{return await this.recvDumpFile(e,t,n),oT(n)}finally{await this.cleanupDumpArtifacts(e,n,t)}}async recvDumpFile(e,t,n){let i=["-t",e,"file","recv",t,n];f(`Executing: ${this.hdcPath} ${i.join(" ")}`);let o=await k(this.hdcPath,i);if(o.exitCode!==0)throw new Error(`Failed to recv dump file: ${(o.stderr||o.stdout).trim()}`)}async cleanupDumpArtifacts(e,t,n){try{f(`Removing local dump file: ${t}`),rT(t)}catch(o){f(`Failed to clean local dump file ${t}: ${o.message}`)}let i=["-t",e,"shell","rm","-f",n];f(`Executing: ${this.hdcPath} ${i.join(" ")}`),await k(this.hdcPath,i).catch(o=>{f(`Failed to clean remote dump file ${n}: ${o.message}`)})}async dumpRawNodes(e,t,n){let o=await new Lr(this.hdcPath,e).listWindows({all:!0});if(n){let a=[...new Set(o.map(l=>l.displayId))],c=[];for(let l of a)c.push(await this.fetchRawDump(e,void 0,l));return c}let s=aT(o,t);return[await this.fetchRawDump(e,String(s.id),s.displayId)]}async dumpFullTree(e,t,n,i){return(await this.dumpRawNodes(e,n,i)).map(s=>vl(s,t,0))}async dumpFullTreeByDisplays(e,t,n){let i=[];for(let o of n){let s=await this.fetchRawDump(e,void 0,o);i.push({displayId:o,tree:vl(s,t,0)})}return i}async dumpCollapsedTree(e,t,n,i){return(await this.dumpRawNodes(e,n,i)).flatMap(s=>Lv(vl(s,0,0),t))}async dumpRawTree(e,t){return(await this.dumpRawNodes(e,t,!1))[0]}};var Ve=class extends Error{position;input;constructor(e,t,n){super(`Selector parse error at ${t}: ${e}`),this.name="SelectorParseError",this.position=t,this.input=n}},cT=["*=","^=","$=","/="],lT=/[A-Za-z_]/,dT=/[A-Za-z0-9_]/,Df=/\s/,uT=/^(.*)\/([gimsuy]+)$/,If=class{input;pos=0;constructor(e){this.input=e}eof(){return this.pos>=this.input.length}peek(e=0){let t=this.pos+e;return t>=0&&t<this.input.length?this.input[t]:""}next(){return this.pos<this.input.length?this.input[this.pos++]:""}startsWith(e){return this.input.slice(this.pos,this.pos+e.length)===e}};function $r(r){for(;!r.eof()&&Df.test(r.peek());)r.next()}function pT(r){let e=r.pos;if(!lT.test(r.peek()))throw new Ve("expected attribute key",r.pos,r.input);for(;!r.eof()&&dT.test(r.peek());)r.next();return r.input.slice(e,r.pos)}function fT(r,e){for(let t of cT)if(r.startsWith(t))return r.pos+=t.length,t;if(r.peek()==="=")return r.next(),"=";throw new Ve(`expected operator (=, *=, ^=, $=, /=) after key "${e}"`,r.pos,r.input)}function Fv(r){let e=r.match(uT);return e?{value:e[1],flags:e[2]}:{value:r}}function mT(r,e){r.next();let t="";for(;!r.eof();){let n=r.next();if(n==="\\"){if(r.eof())throw new Ve("dangling escape in quoted value",r.pos,r.input);t+=r.next();continue}if(n===e)return t;t+=n}throw new Ve("unterminated quoted value",r.pos,r.input)}function xf(r){return r==='"'||r==="'"}function gT(r,e){let t=r.peek();if(xf(t)){let i=mT(r,t);return e==="/="?Fv(i):{value:i}}let n="";for(;!r.eof();){let i=r.peek();if(i===","||i==="["||xf(i))break;if(Df.test(i)){let o=r.pos+1;for(;o<r.input.length&&Df.test(r.input[o]);)o++;let s=o<r.input.length?r.input[o]:"";if(s===""||s===","||s==="["||xf(s))break;n+=r.next();continue}if(i==="\\"){if(r.next(),r.eof())throw new Ve("dangling escape in value",r.pos,r.input);n+=r.next();continue}n+=r.next()}return e==="/="?Fv(n):{value:n}}function $v(r){$r(r);let e=pT(r);$r(r);let t=fT(r,e);if($r(r),r.eof()||r.peek()===","||r.peek()==="[")throw new Ve(`missing value for key "${e}"`,r.pos,r.input);let{value:n,flags:i}=gT(r,t);if(t==="/=")try{new RegExp(n,i)}catch(s){throw new Ve(`invalid regex "${n}"${i?` with flags "${i}"`:""}: ${s.message}`,r.pos,r.input)}let o={key:e,op:t,value:n};return i!==void 0&&(o.flags=i),o}function hT(r){let e="";for(;!r.eof()&&r.peek()!=="]";)e+=r.next();if(e=e.trim(),e==="last")return-1;if(/^-?\d+$/.test(e))return parseInt(e,10);throw new Ve(`invalid index "${e}" (expected N, -N, or "last")`,r.pos,r.input)}function $s(r){if(typeof r!="string")throw new Ve("input must be a string",0,String(r));let e=new If(r),t=[];if($r(e),e.eof())throw new Ve("empty selector",e.pos,r);for(t.push($v(e));$r(e),e.peek()===",";){if(e.next(),$r(e),e.eof()||e.peek()===",")throw new Ve("expected clause after comma",e.pos,r);t.push($v(e))}let n;if($r(e),e.peek()==="["){if(e.next(),n=hT(e),$r(e),e.peek()!=="]")throw new Ve("expected ']' after index",e.pos,r);e.next(),$r(e)}if(!e.eof())throw new Ve(`unexpected trailing input "${e.input.slice(e.pos)}"`,e.pos,r);return{clauses:t,index:n,raw:r}}function yT(r,e){if(r==null)return;if(e==="text"){let n=r.originalText??r.text;return n==null?void 0:String(n)}if(e==="desc"||e==="description"){let n=r.description;return n==null?void 0:String(n)}let t=r[e];return t==null?void 0:String(t)}function wT(r,e){let t=yT(r,e.key);if(t===void 0)return!1;switch(e.op){case"=":return t===e.value;case"*=":return t.includes(e.value);case"^=":return t.startsWith(e.value);case"$=":return t.endsWith(e.value);case"/=":try{return(e.flags?new RegExp(e.value,e.flags):new RegExp(e.value)).test(t)}catch{return!1}default:return!1}}function bl(r,e){let t=[],n=[r];for(;n.length>0;){let i=n.pop(),o=i.attributes??null;e.clauses.every(a=>wT(o,a))&&t.push(i);let s=i.children;if(s)for(let a=s.length-1;a>=0;a--)n.push(s[a])}return t}function fo(r,e){return e===void 0?r[0]:e>=0?r[e]:r[r.length+e]}import{DOMParser as vT}from"@xmldom/xmldom";import{select as bT}from"xpath";var ST=["id","key","originalText","description","enabled","focused","checked","selected","visible","clickable","longClickable","scrollable","checkable","accessibilityLevel","hitTestBehavior","bounds"];function ET(r){if(!r)return"node";let e=r.replace(/[^A-Za-z0-9_-]/g,"_");return/^[0-9]/.test(e)&&(e="_"+e),e||"node"}var PT=/&/g,CT=/</g,kT=/>/g,RT=/"/g,xT=/'/g;function Sl(r){return r.replace(PT,"&amp;").replace(CT,"&lt;").replace(kT,"&gt;").replace(RT,"&quot;").replace(xT,"&apos;")}function DT(r){let e=[],t=typeof r.type=="string"?r.type:"";t&&e.push(` type="${Sl(t)}"`);let n=r.originalText??r.text;n!=null&&n!==""&&e.push(` text="${Sl(String(n))}"`);for(let o of ST){let s=r[o];s==null||s===""||e.push(` ${o}="${Sl(String(s))}"`)}let i=r.description;return i!=null&&i!==""&&e.push(` desc="${Sl(String(i))}"`),e.join("")}function jv(r){let e=r.attributes??{},t=ET(typeof e.type=="string"?e.type:void 0),n=DT(e),i=r.children??[];return i.length===0?`<${t}${n}/>`:`<${t}${n}>${i.map(jv).join("")}</${t}>`}function IT(r){return`<?xml version="1.0" encoding="UTF-8"?>${jv(r)}`}function AT(r){if(!r)return;let e=r.match(/-?\d+/g);if(!e||e.length<4)return;let[t,n,i,o]=e.map(Number);return[t,n,i,o]}function TT(r){return typeof r!="object"||r===null?!1:r.nodeType===1}function NT(r){let e=i=>{let o=r.getAttribute(i);return o===""||o===null?void 0:o},t={},n=r.attributes;if(n)for(let i=0;i<n.length;i++){let o=n[i];o&&(t[o.name]=o.value)}return{type:e("type")??r.tagName,id:e("id"),key:e("key"),text:e("text"),originalText:e("originalText"),description:e("description")??e("desc"),enabled:e("enabled"),focused:e("focused"),checked:e("checked"),selected:e("selected"),visible:e("visible"),clickable:e("clickable"),longClickable:e("longClickable"),scrollable:e("scrollable"),checkable:e("checkable"),accessibilityLevel:e("accessibilityLevel"),hitTestBehavior:e("hitTestBehavior"),bounds:AT(e("bounds")),attributes:t}}function Af(r,e){if(typeof e!="string"||e.trim()==="")throw new Error("xpath expression must be a non-empty string");let t=IT(r),n=new vT().parseFromString(t,"text/xml"),i=bT(e,n);if(!Array.isArray(i))throw new Error(`xpath "${e}" did not return a node-set; use a path expression like //Button[@text='\u767B\u5F55']`);let o=[];for(let s of i)TT(s)&&o.push(NT(s));return o}function El(r){return typeof r=="string"&&r.trimStart().startsWith("xpath=")}function Pl(r){return r.trimStart().slice(6)}function Cl(r){return new Promise(e=>setTimeout(e,r))}function Tf(r,e){let t=r.attributes??{};return{index:e,id:t.id||void 0,key:t.key||void 0,type:t.type||void 0,text:t.originalText||t.text||void 0,description:t.description||void 0,enabled:t.enabled||void 0,focused:t.focused||void 0,checked:t.checked||void 0,selected:t.selected||void 0,visible:t.visible||void 0,clickable:t.clickable||void 0,longClickable:t.longClickable||void 0,scrollable:t.scrollable||void 0,checkable:t.checkable||void 0,bounds:wl(t.bounds),attributes:t}}function Hv(r,e){return{index:e,id:r.id,key:r.key,type:r.type,text:r.text,description:r.description,enabled:r.enabled,focused:r.focused,checked:r.checked,selected:r.selected,visible:r.visible,clickable:r.clickable,longClickable:r.longClickable,scrollable:r.scrollable,checkable:r.checkable,bounds:r.bounds,attributes:r.attributes}}function kl(r){return r.startsWith("base64=")?Buffer.from(r.slice(7).trim(),"base64").toString("utf8"):r}var OT=new Set(["text","desc","description"]),js=[];function Bv(r,e){if(r.attributes)for(let t of Object.keys(r.attributes))e.add(t);if(r.children)for(let t of r.children)Bv(t,e)}function Wv(r,e){let t=new Set;Bv(r,t);let n=[];for(let i of e)OT.has(i.key)||t.has(i.key)||n.push(i.key);return n}function Uv(r,e){let t=Wv(r,e);for(let n of t)js.push(`WARNING: attribute "${n}" not found in any node of the layout tree. No matches will be returned for this key.`)}function Nf(){return js.splice(0)}var mo=class{dumper;constructor(e){this.dumper=new Fr(e)}async find(e,t,n){js.splice(0);let i=kl(t);if(El(i))return this.runXpathFind(e,Pl(i),n);let o=$s(i);return this.runFind(e,o,n)}async runFind(e,t,n){let i=n?.timeoutMs??3e3,o=300,s=Date.now(),a=[],c=!1,l=!1;for(;!c;){let g=await this.dumper.dumpRawTree(e,n?.window);if(l||(Uv(g,t.clauses),l=!0),a=bl(g,t),c=n?.all?a.length>0:fo(a,t.index)!==void 0,c)break;if(Date.now()-s>=i)throw new Error(`Timed out (${i}ms) waiting for selector: ${t.raw}`);await Cl(o)}if(n?.all)return a.map((g,y)=>Tf(g,y));let d=fo(a,t.index);if(!d){let g=a.length,y=t.index===void 0?0:t.index;throw new Error(`Index ${y} out of range (matched ${g} element(s)) for selector: ${t.raw}`)}return[Tf(d,t.index??0)]}async runXpathFind(e,t,n){let i=n?.timeoutMs??3e3,o=300,s=Date.now(),a=[],c=!1;for(;!c;){let l=await this.dumper.dumpRawTree(e,n?.window);if(a=Af(l,t),c=a.length>0,c)break;if(Date.now()-s>=i)throw new Error(`Timed out (${i}ms) waiting for xpath: ${t}`);await Cl(o)}return n?.all?a.map((l,d)=>Hv(l,d)):[Hv(a[0],0)]}async waitForAppearance(e,t,n,i){js.splice(0);let o=kl(t);if(El(o))return(await this.runXpathFind(e,Pl(o),{timeoutMs:n,window:i}))[0];let s=$s(o);return await this.runWaitFor(e,s,n,i,!0)}async waitForDisappear(e,t,n,i){js.splice(0);let o=kl(t);if(El(o))return this.runXpathWaitFor(e,Pl(o),n,i,!1);let s=$s(o);await this.runWaitFor(e,s,n,i,!1)}async runWaitFor(e,t,n,i,o){let a=Date.now(),c=!1;for(;;){let l=await this.dumper.dumpRawTree(e,i);c||(Uv(l,t.clauses),c=!0);let d=bl(l,t),g=fo(d,t.index)!==void 0;if(o&&g){let y=fo(d,t.index);return Tf(y,t.index??0)}if(!o&&!g)return;if(Date.now()-a>=n)throw new Error(`Timed out (${n}ms) waiting for selector to ${o?"appear":"disappear"}: ${t.raw}`);await Cl(300)}}async runXpathWaitFor(e,t,n,i,o){let a=Date.now();for(;;){let c=await this.dumper.dumpRawTree(e,i),d=Af(c,t).length>0;if(o&&d||!o&&!d)return;if(Date.now()-a>=n)throw new Error(`Timed out (${n}ms) waiting for xpath to ${o?"appear":"disappear"}: ${t}`);await Cl(300)}}};import st from"fs";import $e from"path";import{randomUUID as _T}from"crypto";function Vv(r,e){let t=["-t",r.serial,"shell","snapshot_display"];return r.display!==void 0&&t.push("-i",r.display),t.push("-f",r.remotePath),e&&t.push("-t",e),t}function Gv(r,e){return[r,e].filter(Boolean).join(`
60
+ `).trim()}function qv(r){return r.replace(/(Tips:\s*supported\s+displayIds)\s*:?[ \t]*(?:\r?\n[ \t]*)?(\d+(?:(?:[ \t]*,[ \t]*|[ \t]+|\r?\n[ \t]*)\d+)*)/gi,(e,t,n)=>`${t}: ${n.match(/\d+/g)?.join(", ")??n}`)}function zv(r){let e=String.raw`invalid|not found|not exist|does not exist|out of range|unsupported`;return new RegExp(String.raw`display(?:\s*id)?.*(?:${e})`,"is").test(r)||new RegExp(String.raw`(?:${e}).*display(?:\s*id)?`,"is").test(r)}function Jv(r){let e=r.trim();if(!e||/No such file|not found|cannot access/i.test(e))return;let t=e.split(/\s+/),n=Number(t[4]);return Number.isFinite(n)?n:void 0}function MT(){return String(Date.now())}function Of(r){let e;try{e=st.statSync(r)}catch(t){let n=t.code;throw n==="ENOENT"?new Error(`Screenshot directory does not exist: ${r}`,{cause:t}):n==="EACCES"||n==="EPERM"?new Error(`Screenshot directory is not writable: ${r}`,{cause:t}):new Error(`Invalid screenshot path: ${t.message}${n?` (${n})`:""}`,{cause:t})}if(!e.isDirectory())throw new Error(`Screenshot parent path is not a directory: ${r}`);try{st.accessSync(r,st.constants.W_OK|st.constants.X_OK)}catch(t){throw new Error(`Screenshot directory is not writable: ${r}`,{cause:t})}}function _f(r,e){try{throw st.lstatSync(r),new Error(`Screenshot file already exists: ${r}`)}catch(t){let n=t.code;if(n==="ENOENT")return;throw n==="EACCES"||n==="EPERM"?new Error(`Screenshot directory is not writable: ${e}`,{cause:t}):t instanceof Error&&!n?t:new Error(`Invalid screenshot path: ${t.message}${n?` (${n})`:""}`,{cause:t})}}function Kv(r){if(!st.existsSync(r))throw new Error(`Screenshot file was not created: ${r}`);let e=st.statSync(r);if(!e.isFile()||e.size===0)throw new Error(`Screenshot file is empty: ${r}`);let t=st.readFileSync(r).subarray(0,8),n=Buffer.from([137,80,78,71,13,10,26,10]);if(!t.equals(n))throw new Error(`Screenshot file is not a valid PNG: ${r}`)}function Yv(r){try{return Kv(r),!0}catch{return!1}}function Xv(r){let e=[];for(let t of st.readdirSync(r,{withFileTypes:!0})){let n=$e.join(r,t.name);if(t.isDirectory()){e.push(...Xv(n));continue}t.isFile()&&Yv(n)&&e.push(n)}return e}function LT(r,e){let t=$e.join(r,$e.basename(e));if(Yv(t))return t;let n=Xv(r);if(n.length===1)return n[0];if(n.length>1)throw new Error(`Multiple screenshot files were received in ${r}.`)}function FT(r,e){try{st.copyFileSync(r,e,st.constants.COPYFILE_EXCL)}catch(t){throw t.code==="EEXIST"?new Error(`Screenshot file already exists: ${e}`,{cause:t}):t}Kv(e)}var ai=class{constructor(e){this.toolProvider=e}resolveDestinationPath(e){if(!e?.trim())throw new Error("--path is required.");let t=e.trim(),n=$e.resolve(t);try{if(st.statSync(n).isDirectory()){Of(n);let o=$e.join(n,`screenshot-${MT()}.png`);return _f(o,n),o}}catch(o){if(o.code!=="ENOENT")throw o}if($e.extname(n).toLowerCase()!==".png")throw new Error(`Screenshot path must be an existing directory or a PNG file: ${n}`);let i=$e.dirname(n);return Of(i),_f(n,i),n}async captureToPath(e,t,n){let i=$e.dirname($e.resolve(t));Of(i),_f($e.resolve(t),i);let o=`/data/local/tmp/devecocli-${_T()}.png`;await this.capture({hdcPath:this.toolProvider.hdcPath,serial:e,localPath:$e.resolve(t),remotePath:o,display:n})}async capture(e){try{await this.createRemoteScreenshot(e),await this.receiveScreenshotFile(e)}finally{await this.removeRemoteScreenshot(e)}}async getRemoteScreenshotSize(e){let t=["-t",e.serial,"shell","ls","-l",e.remotePath];f(`Executing: ${e.hdcPath} ${t.join(" ")}`);let n=await k(e.hdcPath,t);return n.exitCode===0?Jv(n.stdout):void 0}async tryCreateRemoteScreenshot(e,t){let n=Vv(e,t);f(`Executing: ${e.hdcPath} ${n.join(" ")}`);let i=await k(e.hdcPath,n),o=await this.getRemoteScreenshotSize(e);return{created:o!==void 0&&o>0,output:qv(Gv(i.stdout,i.stderr))}}async createRemoteScreenshot(e){let t="";for(let n of[void 0,"png"]){let i=await this.tryCreateRemoteScreenshot(e,n);if(i.created)return;if(e.display!==void 0&&zv(i.output))throw new Error(`Screenshot was not created on device: ${e.remotePath}.
61
61
  snapshot_display output:
62
62
  ${i.output}`);i.output&&(t=i.output)}throw new Error(t?`Screenshot was not created on device: ${e.remotePath}.
63
63
  snapshot_display output:
64
- ${t}`:`Screenshot was not created on device: ${e.remotePath}.`)}async tryReceiveScreenshot(e,t,n){let i=["-t",e.serial,"file","recv",e.remotePath,n];m(`Executing: ${e.hdcPath} ${i.join(" ")}`);let o=await k(e.hdcPath,i);return o.exitCode!==0&&m(`hdc file recv failed: ${o.stderr||o.stdout||`exit code ${o.exitCode}`}`),iI(t,e.remotePath)}async receiveScreenshotFile(e){let t=ot.mkdtempSync($e.join($e.dirname(e.localPath),".devecocli-screenshot-"));try{let n=await this.tryReceiveScreenshot(e,t,$e.join(t,$e.basename(e.remotePath)))??await this.tryReceiveScreenshot(e,t,t)??await this.tryReceiveScreenshot(e,t,$e.join(t,"screenshot.png"));if(!n)throw new Error(`Screenshot file was not created in ${t}.`);oI(n,e.localPath)}finally{ot.rmSync(t,{recursive:!0,force:!0})}}async removeRemoteScreenshot(e){let t=["-t",e.serial,"shell","rm","-f",e.remotePath];m(`Executing: ${e.hdcPath} ${t.join(" ")}`),await k(e.hdcPath,t)}};import _v from"path";import{randomBytes as FI}from"crypto";async function T(r,e){let n=await new cn(r).selectDevice(e);if(!n)throw new Error("No device selected. Use `devecocli device list` to see targets.");return n}var xs="com.huawei.hmos.screenrecorder",ii="com.huawei.hmos.screenrecorder.ServiceExtAbility",ov="/data/local/tmp",S=class extends Error{constructor(t,n=t,i){super(n,i);this.code=t;this.name="ScreenRecordError"}};var nm=/^\s*uri \[([^\]]*)\]\s*$/,sI=/^\s*uri \[/,aI=/AbilityRecord ID\s*[:#]\s*(\d+)/,cI=/start time \[(\d+)\]/,lI=/bundle name \[([^\]]*)\]/,dI=/main name \[([^\]]*)\]/,uI=/\[(?:Fail|E\d{5,})\]|^\s*(?:error|Error)(?::|\s)/m,pI=ii.slice(ii.lastIndexOf(".")+1);function mI(r){let e=[],t;for(let n of r.split(/\r?\n/))nm.test(n)?(t=[n],e.push(t)):t&&t.push(n);return e}function fI(r){let e={};for(let t of r){let n=nm.exec(t);if(n){e.uri=n[1].trim();continue}let i=aI.exec(t);if(i&&(e.id=Number(i[1]),!Number.isSafeInteger(e.id)))throw new S("DUMP_PARSE_FAILED",`Unparseable AbilityRecord ID in aa dump output: ${i[1]}`);let o=cI.exec(t);if(o){e.startedAtMs=Number(o[1]);continue}let s=lI.exec(t);if(s){e.bundleName=s[1].trim();continue}let a=dI.exec(t);a&&(e.mainName=a[1].trim())}return e}function sv(r){let e=r.mainName;if((!r.bundleName||!e)&&r.uri){let t=r.uri.split("/").filter(Boolean);t.length>=3&&(r.bundleName??=t[0],e??=t[t.length-1])}return{bundleName:r.bundleName,abilityName:e}}function gI(r){let{bundleName:e,abilityName:t}=sv(r);return e!==xs||!t?!1:t===ii||t===pI}function hI(r){if(uI.test(r))throw new S("DUMP_PARSE_FAILED",`Unexpected aa dump output: ${r.trim().split(/\r?\n/)[0]??""}`);if(!r.includes("ExtensionRecords")&&!r.includes("AbilityRecord ID"))throw new S("DUMP_PARSE_FAILED","aa dump output has no recognizable extension-record structure");for(let t of r.split(/\r?\n/))if(sI.test(t)&&!nm.test(t))throw new S("DUMP_PARSE_FAILED","aa dump output has an unterminated uri line; output may be truncated");let e=mI(r);if(e.length===0&&r.replace(/ExtensionRecords:\s*/,"").trim()!=="")throw new S("DUMP_PARSE_FAILED","aa dump output has no complete ability records; output may be truncated");return e}function av(r){if(!r.trim())throw new S("DUMP_PARSE_FAILED","aa dump output is empty; the device state is unknown");let e=new Map;for(let t of hI(r)){let n=fI(t);if(!gI(n))continue;if(n.id===void 0)throw new S("DUMP_PARSE_FAILED","Recorder ability block is missing its AbilityRecord ID");let{bundleName:i,abilityName:o}=sv(n);e.set(n.id,{abilityRecordId:n.id,bundleName:i??xs,abilityName:o??ii,startedAtMs:n.startedAtMs})}return[...e.values()]}function im(r,e){if(r.length>1)throw new S("AMBIGUOUS_DEVICE_STATE",`Multiple screen recorder ability records: ${r.map(n=>n.abilityRecordId).join(", ")}`);let t=r[0];return t?{status:e?.abilityRecordId===t.abilityRecordId?"recording":"busy",activeId:t.abilityRecordId,session:e}:{status:"idle",session:e}}function oi(r,e){return!r||!e?r===e:r.fileName===e.fileName&&r.abilityRecordId===e.abilityRecordId&&r.startTime===e.startTime&&r.localPath===e.localPath}function cv(r){return r.status==="recording"?{plan:"error",error:new S("CLI_RECORDING_ACTIVE","A CLI recording session is already running; run stop first")}:r.status==="busy"?{plan:"error",error:new S("EXTERNAL_RECORDING","A recording not started by this CLI is in progress; run stop --force first")}:r.session?{plan:"discard-first",session:r.session}:{plan:"start-new"}}function lv(r){return r.status==="idle"&&!r.session?{plan:"start-new"}:{plan:"error",error:new S("STATE_CHANGED","Device state changed while discarding the interrupted registration; not starting")}}function dv(r,e){return r.status==="busy"?e?{plan:"force-stop-external",activeId:r.activeId}:{plan:"error",error:new S("EXTERNAL_RECORDING","Recording was not started by this CLI. Stop it on the device or run stop --force.")}:r.session?{plan:"finalize-session",session:r.session}:{plan:"error",error:new S("NO_CLI_SESSION","No CLI recording session on this device")}}function uv(r,e,t){return oi(r,e)?{plan:"proceed"}:t==="interactive"?{plan:"completed-elsewhere"}:{plan:"error",error:new S("SESSION_CHANGED","The recording session changed; leaving the current one untouched")}}function pv(r){return r.status==="busy"?{plan:"error",error:new S("EXTERNAL_RECORDING","A recording not started by this CLI is in progress; not toggling")}:r.status==="recording"?{plan:"stop-recording"}:{plan:"retrieve"}}function mv(r,e){if(r.length===0)return{outcome:"gone"};if(r.length>1)return{outcome:"error",error:new S("STATE_CHANGED","Multiple recorder records while confirming stop; not toggling again")};let t=r[0].abilityRecordId;return t!==e?{outcome:"error",error:new S("STATE_CHANGED",`A different recording (ID ${t}) appeared while stopping; leaving it alone`)}:{outcome:"still-recording",activeId:t}}function fv(r){return r.length===1?{outcome:"confirmed",record:r[0]}:r.length>1?{outcome:"error",error:new S("AMBIGUOUS_DEVICE_STATE","Multiple recorder records after start; refusing to pick one")}:{outcome:"pending"}}function gv(r,e){if(r.length===0)return{plan:"already-stopped"};if(r.length>1)return{plan:"error",error:new S("AMBIGUOUS_DEVICE_STATE","Multiple recorder records; refusing to force-stop")};let t=r[0];return e!==void 0&&t.abilityRecordId!==e?{plan:"error",error:new S("STATE_CHANGED","The recording changed while stopping; leaving it alone")}:{plan:"stop",currentId:t.abilityRecordId,startedAtMs:t.startedAtMs}}function hv(r){return r.status==="idle"&&r.session?{status:"idle",note:"interrupted session found; retrievable via ui screenrecord stop"}:{status:r.status}}function yv(r,e){return!oi(r.session,e)||r.status!=="recording"}function om(r,e){return r.startTime+e}function wv(r,e,t){return t+Math.max(0,e-r)}import ln from"fs";import Cv from"path";import{randomBytes as bI}from"crypto";import{lock as SI}from"proper-lockfile";import As from"path";var yI=/^[A-Za-z0-9][A-Za-z0-9.-]*\.mp4$/;function oo(r){return Buffer.from(r,"utf8").toString("hex")}function si(r,e){return String(r).padStart(e,"0")}function vv(r){return`${si(r.getFullYear(),4)}${si(r.getMonth()+1,2)}${si(r.getDate(),2)}-${si(r.getHours(),2)}${si(r.getMinutes(),2)}${si(r.getSeconds(),2)}${si(r.getMilliseconds(),3)}`}function wI(r){return r.replace(/[<>:"/\\|?*\u0000-\u001f]/g,"-").replace(/\s+/g," ").trim().replace(/[. ]+$/,"").replace(/^[. ]+/,"")||"device"}function bv(r,e){if(!/^[a-z0-9]{4}$/.test(e))throw new S("INVALID_RECORDING_PATH",`Internal: bad random suffix ${JSON.stringify(e)}`);return`devecocli-${vv(r)}-${e}.mp4`}function Sv(r,e,t){return`${wI(r)}-${vv(e)}-${t}.mp4`}function Ev(r,e){if(!yI.test(r))throw new S("INVALID_RECORDING_PATH",`Unsafe device file name: ${JSON.stringify(r)}`);return`${ov}/devecocli-${e}-${r}`}var vI=20;function Pv(r){let e=As.dirname(r),t=As.extname(r),n=As.basename(r,t),i=[r];i.push(As.join(e,`${n}-recovered${t}`));for(let o=2;o<vI;o++)i.push(As.join(e,`${n}-recovered-${o}${t}`));return i}var EI=5*6e4,PI=5*6e4,CI=1e4,kI=6e4,sm=200;function DI(r){if(!Number.isInteger(r)||r<=0)return"unknown";try{return process.kill(r,0),"alive"}catch(e){let t=e.code;return t==="ESRCH"?"dead":t==="EPERM"?"alive":"unknown"}}function kv(r){return new Promise(e=>setTimeout(e,r))}function RI(){return bI(8).toString("hex")}async function Dv(r){let e;try{e=await ln.promises.readFile(r,"utf8")}catch{return}try{let t=JSON.parse(e);return typeof t.token=="string"?t.token:void 0}catch{return}}var cl=class{constructor(e,t={}){this.recordDir=e;this.releaseGuardWaitMs=t.releaseGuardWaitMs??CI}releaseGuardWaitMs;lockPath(e){return Cv.join(this.recordDir,`${oo(e)}.lock`)}guardPath(e){return Cv.join(this.recordDir,`${oo(e)}.guard`)}async withDeviceLock(e,t,n=kI){let i=await this.acquire(e,n),o;try{o=await t(i)}catch(s){try{await this.releaseOwned(e,i)}catch(a){m(`lock release failed after action error: ${a.message}`)}throw s}return await this.releaseOwned(e,i),o}async withGuard(e,t,n=0){let i=Date.now()+n;for(;;){let o;try{o=await SI(this.guardPath(e),{realpath:!1,stale:EI,update:1e3,retries:0})}catch(s){if(s.code!=="ELOCKED"||Date.now()>=i)throw s;await kv(Math.min(sm,i-Date.now()));continue}try{return await t()}finally{await o()}}}async acquire(e,t){await ln.promises.mkdir(this.recordDir,{recursive:!0});let n=RI(),i=this.lockPath(e),o=Date.now()+t;for(;;){let s=!1;try{await this.withGuard(e,async()=>{s=await this.tryCreateOrReclaim(i,n)})}catch(a){if(a.code!=="ELOCKED")throw a}if(s)return this.buildLease(i,n);if(Date.now()+sm>o)throw new S("LOCK_BUSY",`Timed out waiting ${t}ms for the device lock (${e})`);await kv(sm)}}async tryCreateOrReclaim(e,t){let n;try{n=await ln.promises.open(e,"wx")}catch(i){if(i.code!=="EEXIST")throw i;return await this.reclaimIfDead(e),!1}try{let i={pid:process.pid,createdAt:Date.now(),token:t};await n.writeFile(JSON.stringify(i)),await n.sync()}finally{await n.close()}return!0}async reclaimIfDead(e){let t,n;try{t=await ln.promises.readFile(e,"utf8"),n=await ln.promises.stat(e)}catch(o){if(o.code==="ENOENT")return;throw o}let i;try{let o=JSON.parse(t);typeof o.pid=="number"&&typeof o.createdAt=="number"&&typeof o.token=="string"&&(i=o)}catch{}if(i){DI(i.pid)==="dead"&&await ln.promises.unlink(e);return}Date.now()-n.mtimeMs>PI&&await ln.promises.unlink(e)}buildLease(e,t){let n=new AbortController;return{token:t,signal:n.signal,assertOwned:async()=>{if(await Dv(e)!==t)throw n.abort(),new S("LOCK_LOST","Lost the device lock; aborting this operation")}}}async releaseOwned(e,t){let n=this.lockPath(e);try{await this.withGuard(e,async()=>{await Dv(n)===t.token&&await ln.promises.unlink(n)},this.releaseGuardWaitMs)}catch(i){throw new S("LOCK_RELEASE_FAILED",`Could not release the device lock (${e}): ${i.message}. The lock stays in place; it is reclaimed by the dead-PID or corrupt-age rule once this process exits.`,{cause:i})}}};import{execa as xI}from"execa";var am=15e3,Rv=10*6e4,AI=3,xv=400;function II(r){return new Promise(e=>setTimeout(e,r))}function TI(r){return async(e,t)=>{m(`Executing: ${r} ${e.join(" ")}`);let n=await xI(r,e,{reject:!1,timeout:t.timeoutMs??am,cancelSignal:t.signal,stdout:"pipe",stderr:"pipe"});return{stdout:typeof n.stdout=="string"?n.stdout:"",stderr:typeof n.stderr=="string"?n.stderr:"",exitCode:n.exitCode??-1}}}var ll=class r{runner;constructor(e){this.runner=TI(e)}async runReadOnly(e,t){let n={stdout:"",stderr:"",exitCode:-1},i=t!==void 0?Date.now()+t:void 0;for(let o=0;o<AI;o++){let s=i!==void 0?i-Date.now():void 0;n=await this.runner(e,s===void 0?{}:{timeoutMs:Math.max(1,s)});let a=`${n.stdout}
65
- ${n.stderr}`;if(n.exitCode===0||Ut(a)!=="transient")return n;if(i!==void 0&&Date.now()+xv>i)break;await II(xv)}return n}static assertUsable(e,t){let n=`${e.stdout}
66
- ${e.stderr}`.trim();if(e.exitCode!==0||Ut(n)!=="ok")throw new S(t,`hdc command failed (exit ${e.exitCode}): ${n.split(`
67
- `)[0]??""}`)}async observeOnce(e,t){let n=await this.runReadOnly(["-t",e,"shell","aa","dump","-e"],t);return r.assertUsable(n,"DUMP_PARSE_FAILED"),av(n.stdout)}async readUptimeMs(e,t){let n=await this.runReadOnly(["-t",e,"shell","cat","/proc/uptime"],t);r.assertUsable(n,"DUMP_PARSE_FAILED");let i=Number(/^([\d.]+)/.exec(n.stdout.trim())?.[1]);if(!Number.isFinite(i)||i<=0)throw new S("DUMP_PARSE_FAILED",`Unparseable /proc/uptime output: ${n.stdout.trim().split(`
68
- `)[0]??""}`);return Math.round(i*1e3)}async toggleOnce(e,t,n,i){await n.assertOwned();let o=["-t",e,"shell","aa","start","-b",xs,"-a",ii];t!==void 0&&o.push("--ps","CustomizedFileName",t);try{let s=await this.runner(o,{timeoutMs:i??am,signal:n.signal});return s.exitCode!==0?(m(`aa start exited ${s.exitCode}: ${s.stderr||s.stdout}`),{transport:"uncertain",stdout:s.stdout,stderr:s.stderr}):{transport:"returned",stdout:s.stdout,stderr:s.stderr}}catch(s){return m(`aa start transport failure: ${s.message}`),{transport:"uncertain",stderr:s.message}}}async queryMediaUri(e,t,n){let i=await this.runReadOnly(["-t",e,"shell","mediatool","query",t,"-u"],n);r.assertUsable(i,"MEDIA_QUERY_FAILED");let o=/find\s+(\d+)\s+result/i.exec(i.stdout);if(!o)throw new S("MEDIA_QUERY_FAILED",`Unparseable mediatool query output: ${i.stdout.trim().split(`
69
- `)[0]??""}`);let s=[...i.stdout.matchAll(/"(file:\/\/[^"]+)"/g)].map(c=>c[1]),a=Number(o[1]);if(a!==0){if(a>1||s.length>1)throw new S("MEDIA_AMBIGUOUS",`mediatool returned ${a} entries for ${t}`);if(s.length!==1)throw new S("MEDIA_QUERY_FAILED",`mediatool reported 1 entry but no URI for ${t}`);return s[0]}}async exportToStaging(e,t,n){let i=await this.runner(["-t",e,"shell","mediatool","recv",t,n],{timeoutMs:Rv});if(r.assertUsable(i,"SAVE_FAILED"),!i.stdout.includes(n))throw new S("SAVE_FAILED",`mediatool recv did not confirm ${n}: ${i.stdout.trim().split(`
70
- `)[0]??""}`)}async receiveFile(e,t,n,i){let o=await this.runner(["-t",e,"file","recv",t,n],{timeoutMs:Rv,signal:i});if(o.exitCode!==0)throw new S("SAVE_FAILED",`hdc file recv failed (exit ${o.exitCode}): ${(o.stderr||o.stdout).split(`
71
- `)[0]??""}`)}async removeStaging(e,t){return(await this.runReadOnly(["-t",e,"shell","rm","-f",t],am)).exitCode===0}};import Lr from"fs";import ur from"path";import{createFile as OI}from"mp4box";var Iv=".devecocli-record-";function so(r,e){return new S("INVALID_RECORDING_PATH",e instanceof Error?`${r}: ${e.message}`:r,e instanceof Error?{cause:e}:void 0)}async function cm(r){try{return{stat:await Lr.promises.stat(r)}}catch(e){let t=e.code;return t==="ENOENT"?null:{code:t??"UNKNOWN"}}}async function Av(r){let e=await cm(r);if(!e)throw so(`Directory does not exist: ${r}`);if("code"in e)throw so(`Directory is not accessible: ${r}`);if(!e.stat.isDirectory())throw so(`Path is not a directory: ${r}`);try{await Lr.promises.access(r,Lr.constants.W_OK)}catch(t){throw so(`Directory is not writable: ${r}`,t)}}async function lm(r){if(await cm(r))throw new S("DESTINATION_EXISTS",`Destination already exists: ${r}`)}async function dm(r,e,t,n){if(!r?.trim())throw so("--path is required.");let i=ur.resolve(r.trim()),o=await cm(i);if(o&&"stat"in o&&o.stat.isDirectory()){await Av(i);let a=ur.join(i,Sv(e,t,n));return await lm(a),a}if(o)throw new S("DESTINATION_EXISTS",`Destination already exists: ${i}`);if(ur.extname(i).toLowerCase()!==".mp4")throw so(`Destination must be an existing directory or a new .mp4 file: ${i}`);let s=ur.dirname(i);return await Av(s),i}async function Tv(r){return Lr.promises.mkdtemp(ur.join(ur.dirname(r),Iv))}var NI=4*1024*1024;async function MI(r){let e=await Lr.promises.open(r,"r");try{let{size:t}=await e.stat(),n=OI(),i=0;for(let s=0;s<t;){let a=Math.min(NI,t-s),c=Buffer.alloc(a),{bytesRead:l}=await e.read(c,0,a,s);if(l<=0)break;let d=c.buffer.slice(c.byteOffset,c.byteOffset+l);d.fileStart=s,i=n.appendBuffer(d,s+l>=t),s+=l}n.flush();let o=n.getBox("moov");return{size:t,complete:i===t,hasMovieHeader:o?.mvhd!==void 0,videoTrackCount:o?.mvhd!==void 0?n.getInfo().videoTracks.length:0}}finally{await e.close()}}async function Ov(r){let e;try{e=await MI(r)}catch(t){throw new S("SAVE_FAILED",`Cannot inspect received file: ${t.message}`,{cause:t})}if(e.size===0)throw new S("MEDIA_NOT_READY","Received file is empty");if(!e.complete||!e.hasMovieHeader)throw new S("MEDIA_NOT_READY","Received file is not a complete MP4");if(e.videoTrackCount<1)throw new S("MEDIA_NOT_READY","Received file has no video track");return e.size}async function LI(r){let e=await Lr.promises.open(r,"r+");try{await e.sync()}finally{await e.close()}}async function _I(r){try{let e=await Lr.promises.open(ur.dirname(r),"r");try{await e.sync()}finally{await e.close()}}catch{}}async function Nv(r,e){await LI(r);for(let t of Pv(e))try{return await Lr.promises.link(r,t),await _I(t),t}catch(n){if(n.code==="EEXIST")continue;throw new S("SAVE_FAILED",`Cannot publish recording to ${t}: ${n.message}`,{cause:n})}throw new S("DESTINATION_UNAVAILABLE",`All recovery names are taken near ${e}`)}async function Mv(r,e){let t=ur.dirname(e),n=ur.basename(r);ur.dirname(r)!==t||!n.startsWith(Iv)||await Lr.promises.rm(r,{recursive:!0,force:!0}).catch(()=>{})}import _r from"fs";import dl from"path";import{randomBytes as $I}from"crypto";function Lv(r,e){let t=r,n=i=>new S("SESSION_CORRUPT",`Invalid recording session ${i} in ${e}`);if(!t||typeof t!="object")throw n("object");if(typeof t.fileName!="string"||t.fileName.length===0||t.fileName!==dl.basename(t.fileName)||t.fileName.includes(".."))throw n("fileName");if(typeof t.abilityRecordId!="number"||!Number.isSafeInteger(t.abilityRecordId)||t.abilityRecordId<=0)throw n("abilityRecordId");if(typeof t.startTime!="number"||!Number.isFinite(t.startTime))throw n("startTime");if(typeof t.localPath!="string"||t.localPath.length===0||!dl.isAbsolute(t.localPath))throw n("localPath");return{fileName:t.fileName,abilityRecordId:t.abilityRecordId,startTime:t.startTime,localPath:t.localPath}}var ul=class{constructor(e){this.recordDir=e}sessionPath(e){return dl.join(this.recordDir,`${oo(e)}.json`)}async read(e){let t=this.sessionPath(e),n;try{n=await _r.promises.readFile(t,"utf8")}catch(o){if(o.code==="ENOENT")return;throw new S("SESSION_CORRUPT",`Cannot read recording session: ${o.message}`,{cause:o})}let i;try{i=JSON.parse(n)}catch(o){throw new S("SESSION_CORRUPT",`Recording session file is not valid JSON: ${t}`,{cause:o})}return Lv(i,t)}async createAtomic(e,t,n){await _r.promises.mkdir(this.recordDir,{recursive:!0});let i=this.sessionPath(e),o=dl.join(this.recordDir,`${oo(e)}.${$I(6).toString("hex")}.tmp`),s=JSON.stringify(Lv(t,"input")),a;try{a=await _r.promises.open(o,"wx")}catch(c){throw new S("SESSION_PUBLISH_FAILED",`Cannot create session temp file: ${c.message}`,{cause:c})}try{await a.writeFile(s),await a.sync()}catch(c){throw await a.close().catch(()=>{}),await _r.promises.unlink(o).catch(()=>{}),new S("SESSION_PUBLISH_FAILED",`Cannot write session temp file: ${c.message}`,{cause:c})}await a.close();try{if(await n.assertOwned(),await this.exists(i))throw new S("SESSION_CHANGED",`A recording session was created concurrently for ${e}`);await _r.promises.link(o,i),await this.syncDir()}finally{await _r.promises.unlink(o).catch(()=>{})}}async deleteIfSame(e,t,n){await n.assertOwned();let i=await this.read(e);if(i){if(!oi(i,t))throw new S("SESSION_CHANGED","The recording session changed hands; leaving the new record untouched");await _r.promises.unlink(this.sessionPath(e)),await this.syncDir()}}async exists(e){try{return await _r.promises.lstat(e),!0}catch{return!1}}async syncDir(){try{let e=await _r.promises.open(this.recordDir,"r");try{await e.sync()}finally{await e.close()}}catch{}}};var jI={startConfirmMs:1e4,stopConfirmMs:15e3,stopReadyMs:3e3,observeIntervalMs:250,foregroundPollMs:1e3,mediaReadyMs:3e4,mediaBackoffMs:[250,500,1e3,2e3],mediaRecvAttempts:3,lockWaitMs:6e4,interactiveLockWaitMs:10*6e4,foregroundFailureBudget:3},$v=4e3;function Is(r){return new Promise(e=>setTimeout(e,r))}function pl(){return FI(2).toString("hex")}var Fv=["SIGINT","SIGTERM","SIGHUP"];function HI(r,e){let t=()=>{r.requested||(r.requested=!0,e?.(),r.wake())};for(let n of Fv)process.on(n,t);return()=>{for(let n of Fv)process.off(n,t)}}var dn=class{constructor(e,t={}){this.toolProvider=e;let n=_v.join($(),"record");this.deps={store:t.store??new ul(n),lock:t.lock??new cl(n),device:t.device??new ll(e.hdcPath),timing:{...jI,...t.timing}}}deps;async startDetached(e,t){let n=await this.resolveTarget(e),i=await dm(t,n.name,new Date,pl());return this.startSession(n,i)}async recordInteractively(e,t,n){let i=new Set,o={requested:!1,wake:()=>{for(let a of i)a()}},s=HI(o,n.onStopRequested);try{let a=await this.resolveTarget(e),c=await dm(t,a.name,new Date,pl()),l=await this.startSession(a,c);return n.onStarted(),await this.waitForInteractiveCompletion(l,o,i)}finally{s()}}async waitForInteractiveCompletion(e,t,n){let i,o=()=>(i??=this.deps.lock.withDeviceLock(e.serial,a=>this.finalizeLocked(e.serial,e.session,"interactive",a),this.deps.timing.interactiveLockWaitMs),i),s=0;for(;;){if(t.requested)return await o();let a;try{a=await this.readSnapshot(e.serial),s=0}catch(c){if(s+=1,s>=this.deps.timing.foregroundFailureBudget)throw c;await this.waitPoll(t,n);continue}if(yv(a,e.session))return await o();await this.waitPoll(t,n)}}async stopRecording(e,t){let n=await this.resolveTarget(e);return this.deps.lock.withDeviceLock(n.serial,async i=>{let o=await this.readSnapshot(n.serial),s=dv(o,t);if(s.plan==="force-stop-external")return await this.stopExternal(n.serial,s.activeId,i),{kind:"external-stopped"};if(s.plan==="error")throw s.error;return this.finalizeLocked(n.serial,s.session,"stop-or-recover",i)},this.deps.timing.lockWaitMs)}async getRecordingStatus(e){let t=await this.resolveTarget(e);for(let n=0;n<3;n++){let i=await this.deps.store.read(t.serial),o=await this.deps.device.observeOnce(t.serial),s=await this.deps.store.read(t.serial);if(!oi(i,s))continue;let a=im(o,s);return hv(a)}throw new S("STATE_CHANGING","The recording session keeps changing; try again")}async resolveTarget(e){let t=await ce.from(this.toolProvider).getConnectedEntries();if(t.length===0)throw new S("NO_ACTIVE_DEVICES","No active devices found. Connect a physical device; screen recording does not support emulators.");let n=await T(this.toolProvider,e),i=t.find(o=>o.serial===n);if(i?.isEmulator)throw new S("EMULATOR_NOT_SUPPORTED","Screen recording is only supported on physical devices");return{serial:n,name:i?.name??n}}async readSnapshot(e){let t=await this.deps.store.read(e),n=await this.deps.device.observeOnce(e);return im(n,t)}async startSession(e,t){return this.deps.lock.withDeviceLock(e.serial,n=>this.startSessionLocked(e,t,n),this.deps.timing.lockWaitMs)}async startSessionLocked(e,t,n){let i=await this.readSnapshot(e.serial),o=cv(i);if(o.plan==="error")throw o.error;if(o.plan==="discard-first"){await this.deps.store.deleteIfSame(e.serial,o.session,n);let s=await this.readSnapshot(e.serial),a=lv(s);if(a.plan==="error")throw a.error}return this.toggleAndRegister(e,t,n)}async toggleAndRegister(e,t,n){await lm(t);let i=bv(new Date,pl()),o=Date.now(),s=Date.now()+this.deps.timing.startConfirmMs;await n.assertOwned(),await this.deps.device.toggleOnce(e.serial,i,n,Math.max(1,s-Date.now()));let a=await this.waitForStarted(e.serial,s),c={fileName:i,abilityRecordId:a.abilityRecordId,startTime:o,localPath:t};return await this.registerSession(e.serial,c,n),{serial:e.serial,session:c}}async registerSession(e,t,n){try{await this.deps.store.createAtomic(e,t,n)}catch(i){throw await this.abortUnregistered(e,t,n),new S(i.code??"SESSION_PUBLISH_FAILED",`Recording started on device (file ${t.fileName}) but could not be registered: ${i.message}. Check the device gallery.`,{cause:i})}}async withinDeadline(e,t,n){try{return await n(Math.max(1,e-Date.now()))}catch(i){throw Date.now()>=e?t:i}}async waitForStarted(e,t){for(;;){let n=t-Date.now();if(n<=0)throw new S("START_CONFIRM_TIMEOUT","Device screen may be locked");let i=await this.withinDeadline(t,new S("START_CONFIRM_TIMEOUT","Device screen may be locked"),s=>this.deps.device.observeOnce(e,s)),o=fv(i);if(o.outcome==="error")throw o.error;if(o.outcome==="confirmed"){if(Date.now()>t)throw new S("START_CONFIRM_TIMEOUT","Device screen may be locked");return o.record}await Is(Math.min(this.deps.timing.observeIntervalMs,n))}}async observeActiveId(e,t,n){let i=await this.deps.device.observeOnce(e,n),o=mv(i,t);if(o.outcome==="error")throw o.error;return o.outcome==="gone"?void 0:o.activeId}async waitForStopped(e,t,n){for(;;){let i=n-Date.now();if(i<=0)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");if(await this.withinDeadline(n,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),s=>this.observeActiveId(e,t,s))===void 0)return;await Is(Math.min(this.deps.timing.observeIntervalMs,i))}}async awaitStopReady(e,t,n,i){for(;;){let o=i-Date.now();if(o<=0)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");if(await this.withinDeadline(i,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),a=>this.observeActiveId(e,t,a))===void 0)return"vanished";if(Date.now()>=n){if(Date.now()>i)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");return"ready"}await Is(Math.min(this.deps.timing.observeIntervalMs,n-Date.now(),o))}}async abortUnregistered(e,t,n){try{let i=Date.now()+this.deps.timing.stopConfirmMs,o=om(t,this.deps.timing.stopReadyMs);await this.awaitStopReady(e,t.abilityRecordId,o,i)==="ready"&&await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,i-Date.now()))}catch(i){m(`abortUnregistered: best-effort stop failed: ${i.message}`)}}async finalizeLocked(e,t,n,i){let o=await this.deps.store.read(e),s=uv(o,t,n);if(s.plan==="completed-elsewhere")return{kind:"completed-elsewhere"};if(s.plan==="error")throw s.error;let a=await this.readSnapshot(e),c=pv(a);if(c.plan==="error")throw c.error;if(c.plan==="stop-recording"){let l=Date.now()+this.deps.timing.stopConfirmMs;return this.stopLiveRecording(e,t,i,l)}return this.retrieveAndPublish(e,t,i)}async stopLiveRecording(e,t,n,i){let o=om(t,this.deps.timing.stopReadyMs);return await this.awaitStopReady(e,t.abilityRecordId,o,i)==="vanished"?this.retrieveAndPublish(e,t,n):(await n.assertOwned(),await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,i-Date.now())),await this.waitForStopped(e,t.abilityRecordId,i),this.retrieveAndPublish(e,t,n))}async stopExternal(e,t,n){let i=await this.deps.device.observeOnce(e),o=gv(i,t);if(o.plan==="already-stopped")return;if(o.plan==="error")throw o.error;let s=Date.now()+this.deps.timing.stopConfirmMs;o.startedAtMs!==void 0&&!await this.awaitForeignStopReady(e,o.currentId,o.startedAtMs,s)||(await n.assertOwned(),await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,s-Date.now())),await this.waitForStopped(e,o.currentId,s))}async awaitForeignStopReady(e,t,n,i){let o=await this.withinDeadline(i,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),c=>this.deps.device.readUptimeMs(e,c)),s=wv(o-n,this.deps.timing.stopReadyMs,Date.now());return await this.awaitStopReady(e,t,s,i)==="ready"}async retrieveAndPublish(e,t,n){let i=[],o=await this.waitForMediaUri(e,t.fileName),s=await Tv(t.localPath);try{let a=await this.receiveUntilValid(e,o,t,s,n,i);await n.assertOwned();let c=await Nv(a,t.localPath);return await this.deleteSessionAfterSave(e,t,n,c),{kind:"saved",localPath:c,warnings:i}}finally{await Mv(s,t.localPath)}}async waitForMediaUri(e,t){let n=Date.now()+this.deps.timing.mediaReadyMs,i=0;for(;;){let o=n-Date.now();if(o<=0)throw new S("MEDIA_NOT_READY",`Timed out waiting for ${t} in the media library; session kept for a later stop`);let s=await this.withinDeadline(n,new S("MEDIA_NOT_READY",`Timed out waiting for ${t} in the media library; session kept for a later stop`),c=>this.deps.device.queryMediaUri(e,t,c));if(s&&Date.now()<=n)return s;let a=Math.min(this.deps.timing.mediaBackoffMs[Math.min(i,this.deps.timing.mediaBackoffMs.length-1)]??$v,$v,o);i+=1,await Is(a)}}async receiveUntilValid(e,t,n,i,o,s){for(let a=0;a<this.deps.timing.mediaRecvAttempts;a++){await o.assertOwned();let c=Ev(n.fileName,pl()),l=await this.receiveOnce(e,t,c,i,n.fileName,o,s);try{return await Ov(l),l}catch(d){if(d.code!=="MEDIA_NOT_READY")throw d;m(`Received file incomplete (attempt ${a+1}); retrying export`),await Is(this.deps.timing.mediaBackoffMs[0]??250)}}throw new S("MEDIA_NOT_READY",`Received file for ${n.fileName} is incomplete after ${this.deps.timing.mediaRecvAttempts} attempts; session kept`)}async receiveOnce(e,t,n,i,o,s,a){let c=_v.join(i,o);try{await this.deps.device.exportToStaging(e,t,n),await this.deps.device.receiveFile(e,n,c,s.signal)}finally{await this.deps.device.removeStaging(e,n)||a.push(`Failed to remove device staging file: ${n}`)}return c}async deleteSessionAfterSave(e,t,n,i){try{await this.deps.store.deleteIfSame(e,t,n)}catch(o){throw new S(o.code??"SESSION_DELETE_FAILED",`Recording saved to ${i}, but the session record could not be removed: ${o.message}. A later stop may create a recovered copy.`,{cause:o})}}async waitPoll(e,t){await new Promise(n=>{let i=setTimeout(()=>{t.delete(o),n()},this.deps.timing.foregroundPollMs),o=()=>{t.delete(o),clearTimeout(i),n()};t.add(o)})}};var ml={left:"0",right:"1",up:"2",down:"3"};function Ve(r,e){let t=Number(r);if(!Number.isInteger(t)||t<=0)throw new Error(`${e} must be a positive integer`)}function um(r,e){r!==void 0&&Ve(r,e)}function jv(r,e){if(r===void 0!=(e===void 0))throw new Error("x and y must be provided together")}function fl(r,e){if(r!==void 0&&r.length===0)throw new Error(`${e} must not be empty`)}function Ts(r){if(r===void 0)return;let e=Number(r);if(!Number.isInteger(e)||e<200||e>4e4)throw new Error("--speed must be an integer between 200 and 40000");return r}function Hv(r){if(r!==void 0&&!/^[a-zA-Z0-9_-]+$/.test(r))throw new Error("--window must consist of letters, digits, - or _")}function Uv(r,e,t,n=!0){if(t&&!e)throw new Error("--window must be used with --id");if(r&&e)throw new Error("Coordinates and --id are mutually exclusive");if(n&&!r&&!e)throw new Error("Either provide x y coordinates or use --id")}function ao(r,e,t,n,i=!0){jv(r,e),fl(t,"--id"),um(r,"x"),um(e,"y"),Hv(n),Uv(r!==void 0,!!t,!!n,i)}async function pr(r){let e=await C.new(),t=await T(e,r);return{hdcPath:e.hdcPath,deviceId:t}}async function co(r,e,t,n,i,o){if(t!==void 0&&n!==void 0)return{x:t,y:n};if(i===void 0)throw new Error("Either provide x y coordinates or use --id");let a=await new Or(r,e).listWindows({all:!0}),c=new Nr(r);return UI(c,e,a,i,o)}async function UI(r,e,t,n,i){if(i!==void 0){let o=t.find(a=>String(a.id)===i);if(o&&o.displayId!==0)throw new w(`Window "${i}" is on display ${o.displayId}. The current command only supports operations on the primary display.`,"The current command only supports operations on the primary display.");let s=await r.dumpFullTree(e,0,i,!1);return WI(s,n)}return BI(r,e,t,n)}async function BI(r,e,t,n){let i=[...new Set(t.map(a=>a.displayId))],o=await r.dumpFullTreeByDisplays(e,0,i),s=[];for(let{displayId:a,tree:c}of o)for(let l of ro([c],n))s.push({node:l,displayId:a});if(s.length===0)throw new w(`Node "${n}" not found.`,"Node not found.");if(s.length>1)throw new w(`Multiple nodes found with id "${n}".`,"Multiple nodes found");if(s[0].displayId!==0)throw new w(`Node "${n}" is on display ${s[0].displayId}. The current command only supports operations on the primary display.`,"The current command only supports operations on the primary display.");return Bv(s[0].node,n)}function WI(r,e){let t=ro(r,e);if(t.length===0)throw new w(`Node "${e}" not found.`,"Node not found.");if(t.length>1)throw new w(`Multiple nodes found with id "${e}".`,"Multiple nodes found");return Bv(t[0],e)}function Bv(r,e){let t=r.bounds;if(!t)throw new w(`Node "${e}" has no bounds.`,"Node has no bounds.");let[n,i,o,s]=t;return{x:Math.ceil((n+o)/2),y:Math.ceil((i+s)/2)}}async function Dt(r,e,t){let n=["-t",e,"shell",...t];m(`Executing: ${r} ${n.join(" ")}`);let i=await k(r,n);if(i.exitCode!==0)throw new Error(i.stderr||i.stdout||`uitest exited with code ${i.exitCode}`);let o=i.stdout.toLowerCase();if(["illegal","fail","error","incorrect","please confirm that the coordinate values are correct"].some(a=>o.includes(a))&&!o.includes("no error"))throw new Error(i.stdout.trim()||"uitest command failed")}import{deflateSync as VI,inflateSync as GI}from"zlib";import qI from"fs";var Wv=8,Vv=32,zI=.06,JI=.04,pm=10,gl=class r{whiteBits=null;blackBits=null;analyzeRgb(e,t,n){if(e<8||t<8||n.length<e*t*3)return null;let i=this.cropChrome(e,t,n),o=this.hashBits(i.width,i.height,i.rgb),s=Math.min(this.hammingDistance(o,this.solidRefBits(255)),this.hammingDistance(o,this.solidRefBits(0)));return{phash:this.bitsToHex(o),hamming:s,isBlank:s<=pm}}analyzeFile(e){let t;try{t=qI.readFileSync(e)}catch{return null}let n=this.decodePngRgb(t);return n?this.analyzeRgb(n.width,n.height,n.rgb):null}static encodePngRgb(e,t,n){let i=r.pngCrcTable(),o=[Buffer.from(`\x89PNG\r
64
+ ${t}`:`Screenshot was not created on device: ${e.remotePath}.`)}async tryReceiveScreenshot(e,t,n){let i=["-t",e.serial,"file","recv",e.remotePath,n];f(`Executing: ${e.hdcPath} ${i.join(" ")}`);let o=await k(e.hdcPath,i);return o.exitCode!==0&&f(`hdc file recv failed: ${o.stderr||o.stdout||`exit code ${o.exitCode}`}`),LT(t,e.remotePath)}async receiveScreenshotFile(e){let t=st.mkdtempSync($e.join($e.dirname(e.localPath),".devecocli-screenshot-"));try{let n=await this.tryReceiveScreenshot(e,t,$e.join(t,$e.basename(e.remotePath)))??await this.tryReceiveScreenshot(e,t,t)??await this.tryReceiveScreenshot(e,t,$e.join(t,"screenshot.png"));if(!n)throw new Error(`Screenshot file was not created in ${t}.`);FT(n,e.localPath)}finally{st.rmSync(t,{recursive:!0,force:!0})}}async removeRemoteScreenshot(e){let t=["-t",e.serial,"shell","rm","-f",e.remotePath];f(`Executing: ${e.hdcPath} ${t.join(" ")}`),await k(e.hdcPath,t)}};import Ib from"path";import{randomBytes as hN}from"crypto";async function T(r,e){let n=await new un(r).selectDevice(e);if(!n)throw new Error("No device selected. Use `devecocli device list` to see targets.");return n}var Hs="com.huawei.hmos.screenrecorder",ci="com.huawei.hmos.screenrecorder.ServiceExtAbility",Zv="/data/local/tmp",S=class extends Error{constructor(t,n=t,i){super(n,i);this.code=t;this.name="ScreenRecordError"}};var Mf=/^\s*uri \[([^\]]*)\]\s*$/,$T=/^\s*uri \[/,jT=/AbilityRecord ID\s*[:#]\s*(\d+)/,HT=/start time \[(\d+)\]/,UT=/bundle name \[([^\]]*)\]/,BT=/main name \[([^\]]*)\]/,WT=/\[(?:Fail|E\d{5,})\]|^\s*(?:error|Error)(?::|\s)/m,VT=ci.slice(ci.lastIndexOf(".")+1);function GT(r){let e=[],t;for(let n of r.split(/\r?\n/))Mf.test(n)?(t=[n],e.push(t)):t&&t.push(n);return e}function qT(r){let e={};for(let t of r){let n=Mf.exec(t);if(n){e.uri=n[1].trim();continue}let i=jT.exec(t);if(i&&(e.id=Number(i[1]),!Number.isSafeInteger(e.id)))throw new S("DUMP_PARSE_FAILED",`Unparseable AbilityRecord ID in aa dump output: ${i[1]}`);let o=HT.exec(t);if(o){e.startedAtMs=Number(o[1]);continue}let s=UT.exec(t);if(s){e.bundleName=s[1].trim();continue}let a=BT.exec(t);a&&(e.mainName=a[1].trim())}return e}function Qv(r){let e=r.mainName;if((!r.bundleName||!e)&&r.uri){let t=r.uri.split("/").filter(Boolean);t.length>=3&&(r.bundleName??=t[0],e??=t[t.length-1])}return{bundleName:r.bundleName,abilityName:e}}function zT(r){let{bundleName:e,abilityName:t}=Qv(r);return e!==Hs||!t?!1:t===ci||t===VT}function JT(r){if(WT.test(r))throw new S("DUMP_PARSE_FAILED",`Unexpected aa dump output: ${r.trim().split(/\r?\n/)[0]??""}`);if(!r.includes("ExtensionRecords")&&!r.includes("AbilityRecord ID"))throw new S("DUMP_PARSE_FAILED","aa dump output has no recognizable extension-record structure");for(let t of r.split(/\r?\n/))if($T.test(t)&&!Mf.test(t))throw new S("DUMP_PARSE_FAILED","aa dump output has an unterminated uri line; output may be truncated");let e=GT(r);if(e.length===0&&r.replace(/ExtensionRecords:\s*/,"").trim()!=="")throw new S("DUMP_PARSE_FAILED","aa dump output has no complete ability records; output may be truncated");return e}function eb(r){if(!r.trim())throw new S("DUMP_PARSE_FAILED","aa dump output is empty; the device state is unknown");let e=new Map;for(let t of JT(r)){let n=qT(t);if(!zT(n))continue;if(n.id===void 0)throw new S("DUMP_PARSE_FAILED","Recorder ability block is missing its AbilityRecord ID");let{bundleName:i,abilityName:o}=Qv(n);e.set(n.id,{abilityRecordId:n.id,bundleName:i??Hs,abilityName:o??ci,startedAtMs:n.startedAtMs})}return[...e.values()]}function Lf(r,e){if(r.length>1)throw new S("AMBIGUOUS_DEVICE_STATE",`Multiple screen recorder ability records: ${r.map(n=>n.abilityRecordId).join(", ")}`);let t=r[0];return t?{status:e?.abilityRecordId===t.abilityRecordId?"recording":"busy",activeId:t.abilityRecordId,session:e}:{status:"idle",session:e}}function li(r,e){return!r||!e?r===e:r.fileName===e.fileName&&r.abilityRecordId===e.abilityRecordId&&r.startTime===e.startTime&&r.localPath===e.localPath}function tb(r){return r.status==="recording"?{plan:"error",error:new S("CLI_RECORDING_ACTIVE","A CLI recording session is already running; run stop first")}:r.status==="busy"?{plan:"error",error:new S("EXTERNAL_RECORDING","A recording not started by this CLI is in progress; run stop --force first")}:r.session?{plan:"discard-first",session:r.session}:{plan:"start-new"}}function rb(r){return r.status==="idle"&&!r.session?{plan:"start-new"}:{plan:"error",error:new S("STATE_CHANGED","Device state changed while discarding the interrupted registration; not starting")}}function nb(r,e){return r.status==="busy"?e?{plan:"force-stop-external",activeId:r.activeId}:{plan:"error",error:new S("EXTERNAL_RECORDING","Recording was not started by this CLI. Stop it on the device or run stop --force.")}:r.session?{plan:"finalize-session",session:r.session}:{plan:"error",error:new S("NO_CLI_SESSION","No CLI recording session on this device")}}function ib(r,e,t){return li(r,e)?{plan:"proceed"}:t==="interactive"?{plan:"completed-elsewhere"}:{plan:"error",error:new S("SESSION_CHANGED","The recording session changed; leaving the current one untouched")}}function ob(r){return r.status==="busy"?{plan:"error",error:new S("EXTERNAL_RECORDING","A recording not started by this CLI is in progress; not toggling")}:r.status==="recording"?{plan:"stop-recording"}:{plan:"retrieve"}}function sb(r,e){if(r.length===0)return{outcome:"gone"};if(r.length>1)return{outcome:"error",error:new S("STATE_CHANGED","Multiple recorder records while confirming stop; not toggling again")};let t=r[0].abilityRecordId;return t!==e?{outcome:"error",error:new S("STATE_CHANGED",`A different recording (ID ${t}) appeared while stopping; leaving it alone`)}:{outcome:"still-recording",activeId:t}}function ab(r){return r.length===1?{outcome:"confirmed",record:r[0]}:r.length>1?{outcome:"error",error:new S("AMBIGUOUS_DEVICE_STATE","Multiple recorder records after start; refusing to pick one")}:{outcome:"pending"}}function cb(r,e){if(r.length===0)return{plan:"already-stopped"};if(r.length>1)return{plan:"error",error:new S("AMBIGUOUS_DEVICE_STATE","Multiple recorder records; refusing to force-stop")};let t=r[0];return e!==void 0&&t.abilityRecordId!==e?{plan:"error",error:new S("STATE_CHANGED","The recording changed while stopping; leaving it alone")}:{plan:"stop",currentId:t.abilityRecordId,startedAtMs:t.startedAtMs}}function lb(r){return r.status==="idle"&&r.session?{status:"idle",note:"interrupted session found; retrievable via ui screenrecord stop"}:{status:r.status}}function db(r,e){return!li(r.session,e)||r.status!=="recording"}function Ff(r,e){return r.startTime+e}function ub(r,e,t){return t+Math.max(0,e-r)}import pn from"fs";import yb from"path";import{randomBytes as ZT}from"crypto";import{lock as QT}from"proper-lockfile";import Us from"path";var KT=/^[A-Za-z0-9][A-Za-z0-9.-]*\.mp4$/;function go(r){return Buffer.from(r,"utf8").toString("hex")}function di(r,e){return String(r).padStart(e,"0")}function pb(r){return`${di(r.getFullYear(),4)}${di(r.getMonth()+1,2)}${di(r.getDate(),2)}-${di(r.getHours(),2)}${di(r.getMinutes(),2)}${di(r.getSeconds(),2)}${di(r.getMilliseconds(),3)}`}function YT(r){return r.replace(/[<>:"/\\|?*\u0000-\u001f]/g,"-").replace(/\s+/g," ").trim().replace(/[. ]+$/,"").replace(/^[. ]+/,"")||"device"}function fb(r,e){if(!/^[a-z0-9]{4}$/.test(e))throw new S("INVALID_RECORDING_PATH",`Internal: bad random suffix ${JSON.stringify(e)}`);return`devecocli-${pb(r)}-${e}.mp4`}function mb(r,e,t){return`${YT(r)}-${pb(e)}-${t}.mp4`}function gb(r,e){if(!KT.test(r))throw new S("INVALID_RECORDING_PATH",`Unsafe device file name: ${JSON.stringify(r)}`);return`${Zv}/devecocli-${e}-${r}`}var XT=20;function hb(r){let e=Us.dirname(r),t=Us.extname(r),n=Us.basename(r,t),i=[r];i.push(Us.join(e,`${n}-recovered${t}`));for(let o=2;o<XT;o++)i.push(Us.join(e,`${n}-recovered-${o}${t}`));return i}var eN=5*6e4,tN=5*6e4,rN=1e4,nN=6e4,$f=200;function iN(r){if(!Number.isInteger(r)||r<=0)return"unknown";try{return process.kill(r,0),"alive"}catch(e){let t=e.code;return t==="ESRCH"?"dead":t==="EPERM"?"alive":"unknown"}}function wb(r){return new Promise(e=>setTimeout(e,r))}function oN(){return ZT(8).toString("hex")}async function vb(r){let e;try{e=await pn.promises.readFile(r,"utf8")}catch{return}try{let t=JSON.parse(e);return typeof t.token=="string"?t.token:void 0}catch{return}}var Rl=class{constructor(e,t={}){this.recordDir=e;this.releaseGuardWaitMs=t.releaseGuardWaitMs??rN}releaseGuardWaitMs;lockPath(e){return yb.join(this.recordDir,`${go(e)}.lock`)}guardPath(e){return yb.join(this.recordDir,`${go(e)}.guard`)}async withDeviceLock(e,t,n=nN){let i=await this.acquire(e,n),o;try{o=await t(i)}catch(s){try{await this.releaseOwned(e,i)}catch(a){f(`lock release failed after action error: ${a.message}`)}throw s}return await this.releaseOwned(e,i),o}async withGuard(e,t,n=0){let i=Date.now()+n;for(;;){let o;try{o=await QT(this.guardPath(e),{realpath:!1,stale:eN,update:1e3,retries:0})}catch(s){if(s.code!=="ELOCKED"||Date.now()>=i)throw s;await wb(Math.min($f,i-Date.now()));continue}try{return await t()}finally{await o()}}}async acquire(e,t){await pn.promises.mkdir(this.recordDir,{recursive:!0});let n=oN(),i=this.lockPath(e),o=Date.now()+t;for(;;){let s=!1;try{await this.withGuard(e,async()=>{s=await this.tryCreateOrReclaim(i,n)})}catch(a){if(a.code!=="ELOCKED")throw a}if(s)return this.buildLease(i,n);if(Date.now()+$f>o)throw new S("LOCK_BUSY",`Timed out waiting ${t}ms for the device lock (${e})`);await wb($f)}}async tryCreateOrReclaim(e,t){let n;try{n=await pn.promises.open(e,"wx")}catch(i){if(i.code!=="EEXIST")throw i;return await this.reclaimIfDead(e),!1}try{let i={pid:process.pid,createdAt:Date.now(),token:t};await n.writeFile(JSON.stringify(i)),await n.sync()}finally{await n.close()}return!0}async reclaimIfDead(e){let t,n;try{t=await pn.promises.readFile(e,"utf8"),n=await pn.promises.stat(e)}catch(o){if(o.code==="ENOENT")return;throw o}let i;try{let o=JSON.parse(t);typeof o.pid=="number"&&typeof o.createdAt=="number"&&typeof o.token=="string"&&(i=o)}catch{}if(i){iN(i.pid)==="dead"&&await pn.promises.unlink(e);return}Date.now()-n.mtimeMs>tN&&await pn.promises.unlink(e)}buildLease(e,t){let n=new AbortController;return{token:t,signal:n.signal,assertOwned:async()=>{if(await vb(e)!==t)throw n.abort(),new S("LOCK_LOST","Lost the device lock; aborting this operation")}}}async releaseOwned(e,t){let n=this.lockPath(e);try{await this.withGuard(e,async()=>{await vb(n)===t.token&&await pn.promises.unlink(n)},this.releaseGuardWaitMs)}catch(i){throw new S("LOCK_RELEASE_FAILED",`Could not release the device lock (${e}): ${i.message}. The lock stays in place; it is reclaimed by the dead-PID or corrupt-age rule once this process exits.`,{cause:i})}}};import{execa as sN}from"execa";var jf=15e3,bb=10*6e4,aN=3,Sb=400;function cN(r){return new Promise(e=>setTimeout(e,r))}function lN(r){return async(e,t)=>{f(`Executing: ${r} ${e.join(" ")}`);let n=await sN(r,e,{reject:!1,timeout:t.timeoutMs??jf,cancelSignal:t.signal,stdout:"pipe",stderr:"pipe"});return{stdout:typeof n.stdout=="string"?n.stdout:"",stderr:typeof n.stderr=="string"?n.stderr:"",exitCode:n.exitCode??-1}}}var xl=class r{runner;constructor(e){this.runner=lN(e)}async runReadOnly(e,t){let n={stdout:"",stderr:"",exitCode:-1},i=t!==void 0?Date.now()+t:void 0;for(let o=0;o<aN;o++){let s=i!==void 0?i-Date.now():void 0;n=await this.runner(e,s===void 0?{}:{timeoutMs:Math.max(1,s)});let a=`${n.stdout}
65
+ ${n.stderr}`;if(n.exitCode===0||Vt(a)!=="transient")return n;if(i!==void 0&&Date.now()+Sb>i)break;await cN(Sb)}return n}static assertUsable(e,t){let n=`${e.stdout}
66
+ ${e.stderr}`.trim();if(e.exitCode!==0||Vt(n)!=="ok")throw new S(t,`hdc command failed (exit ${e.exitCode}): ${n.split(`
67
+ `)[0]??""}`)}async observeOnce(e,t){let n=await this.runReadOnly(["-t",e,"shell","aa","dump","-e"],t);return r.assertUsable(n,"DUMP_PARSE_FAILED"),eb(n.stdout)}async readUptimeMs(e,t){let n=await this.runReadOnly(["-t",e,"shell","cat","/proc/uptime"],t);r.assertUsable(n,"DUMP_PARSE_FAILED");let i=Number(/^([\d.]+)/.exec(n.stdout.trim())?.[1]);if(!Number.isFinite(i)||i<=0)throw new S("DUMP_PARSE_FAILED",`Unparseable /proc/uptime output: ${n.stdout.trim().split(`
68
+ `)[0]??""}`);return Math.round(i*1e3)}async toggleOnce(e,t,n,i){await n.assertOwned();let o=["-t",e,"shell","aa","start","-b",Hs,"-a",ci];t!==void 0&&o.push("--ps","CustomizedFileName",t);try{let s=await this.runner(o,{timeoutMs:i??jf,signal:n.signal});return s.exitCode!==0?(f(`aa start exited ${s.exitCode}: ${s.stderr||s.stdout}`),{transport:"uncertain",stdout:s.stdout,stderr:s.stderr}):{transport:"returned",stdout:s.stdout,stderr:s.stderr}}catch(s){return f(`aa start transport failure: ${s.message}`),{transport:"uncertain",stderr:s.message}}}async queryMediaUri(e,t,n){let i=await this.runReadOnly(["-t",e,"shell","mediatool","query",t,"-u"],n);r.assertUsable(i,"MEDIA_QUERY_FAILED");let o=/find\s+(\d+)\s+result/i.exec(i.stdout);if(!o)throw new S("MEDIA_QUERY_FAILED",`Unparseable mediatool query output: ${i.stdout.trim().split(`
69
+ `)[0]??""}`);let s=[...i.stdout.matchAll(/"(file:\/\/[^"]+)"/g)].map(c=>c[1]),a=Number(o[1]);if(a!==0){if(a>1||s.length>1)throw new S("MEDIA_AMBIGUOUS",`mediatool returned ${a} entries for ${t}`);if(s.length!==1)throw new S("MEDIA_QUERY_FAILED",`mediatool reported 1 entry but no URI for ${t}`);return s[0]}}async exportToStaging(e,t,n){let i=await this.runner(["-t",e,"shell","mediatool","recv",t,n],{timeoutMs:bb});if(r.assertUsable(i,"SAVE_FAILED"),!i.stdout.includes(n))throw new S("SAVE_FAILED",`mediatool recv did not confirm ${n}: ${i.stdout.trim().split(`
70
+ `)[0]??""}`)}async receiveFile(e,t,n,i){let o=await this.runner(["-t",e,"file","recv",t,n],{timeoutMs:bb,signal:i});if(o.exitCode!==0)throw new S("SAVE_FAILED",`hdc file recv failed (exit ${o.exitCode}): ${(o.stderr||o.stdout).split(`
71
+ `)[0]??""}`)}async removeStaging(e,t){return(await this.runReadOnly(["-t",e,"shell","rm","-f",t],jf)).exitCode===0}};import jr from"fs";import gr from"path";import{createFile as dN}from"mp4box";var Pb=".devecocli-record-";function ho(r,e){return new S("INVALID_RECORDING_PATH",e instanceof Error?`${r}: ${e.message}`:r,e instanceof Error?{cause:e}:void 0)}async function Hf(r){try{return{stat:await jr.promises.stat(r)}}catch(e){let t=e.code;return t==="ENOENT"?null:{code:t??"UNKNOWN"}}}async function Eb(r){let e=await Hf(r);if(!e)throw ho(`Directory does not exist: ${r}`);if("code"in e)throw ho(`Directory is not accessible: ${r}`);if(!e.stat.isDirectory())throw ho(`Path is not a directory: ${r}`);try{await jr.promises.access(r,jr.constants.W_OK)}catch(t){throw ho(`Directory is not writable: ${r}`,t)}}async function Uf(r){if(await Hf(r))throw new S("DESTINATION_EXISTS",`Destination already exists: ${r}`)}async function Bf(r,e,t,n){if(!r?.trim())throw ho("--path is required.");let i=gr.resolve(r.trim()),o=await Hf(i);if(o&&"stat"in o&&o.stat.isDirectory()){await Eb(i);let a=gr.join(i,mb(e,t,n));return await Uf(a),a}if(o)throw new S("DESTINATION_EXISTS",`Destination already exists: ${i}`);if(gr.extname(i).toLowerCase()!==".mp4")throw ho(`Destination must be an existing directory or a new .mp4 file: ${i}`);let s=gr.dirname(i);return await Eb(s),i}async function Cb(r){return jr.promises.mkdtemp(gr.join(gr.dirname(r),Pb))}var uN=4*1024*1024;async function pN(r){let e=await jr.promises.open(r,"r");try{let{size:t}=await e.stat(),n=dN(),i=0;for(let s=0;s<t;){let a=Math.min(uN,t-s),c=Buffer.alloc(a),{bytesRead:l}=await e.read(c,0,a,s);if(l<=0)break;let d=c.buffer.slice(c.byteOffset,c.byteOffset+l);d.fileStart=s,i=n.appendBuffer(d,s+l>=t),s+=l}n.flush();let o=n.getBox("moov");return{size:t,complete:i===t,hasMovieHeader:o?.mvhd!==void 0,videoTrackCount:o?.mvhd!==void 0?n.getInfo().videoTracks.length:0}}finally{await e.close()}}async function kb(r){let e;try{e=await pN(r)}catch(t){throw new S("SAVE_FAILED",`Cannot inspect received file: ${t.message}`,{cause:t})}if(e.size===0)throw new S("MEDIA_NOT_READY","Received file is empty");if(!e.complete||!e.hasMovieHeader)throw new S("MEDIA_NOT_READY","Received file is not a complete MP4");if(e.videoTrackCount<1)throw new S("MEDIA_NOT_READY","Received file has no video track");return e.size}async function fN(r){let e=await jr.promises.open(r,"r+");try{await e.sync()}finally{await e.close()}}async function mN(r){try{let e=await jr.promises.open(gr.dirname(r),"r");try{await e.sync()}finally{await e.close()}}catch{}}async function Rb(r,e){await fN(r);for(let t of hb(e))try{return await jr.promises.link(r,t),await mN(t),t}catch(n){if(n.code==="EEXIST")continue;throw new S("SAVE_FAILED",`Cannot publish recording to ${t}: ${n.message}`,{cause:n})}throw new S("DESTINATION_UNAVAILABLE",`All recovery names are taken near ${e}`)}async function xb(r,e){let t=gr.dirname(e),n=gr.basename(r);gr.dirname(r)!==t||!n.startsWith(Pb)||await jr.promises.rm(r,{recursive:!0,force:!0}).catch(()=>{})}import Hr from"fs";import Dl from"path";import{randomBytes as gN}from"crypto";function Db(r,e){let t=r,n=i=>new S("SESSION_CORRUPT",`Invalid recording session ${i} in ${e}`);if(!t||typeof t!="object")throw n("object");if(typeof t.fileName!="string"||t.fileName.length===0||t.fileName!==Dl.basename(t.fileName)||t.fileName.includes(".."))throw n("fileName");if(typeof t.abilityRecordId!="number"||!Number.isSafeInteger(t.abilityRecordId)||t.abilityRecordId<=0)throw n("abilityRecordId");if(typeof t.startTime!="number"||!Number.isFinite(t.startTime))throw n("startTime");if(typeof t.localPath!="string"||t.localPath.length===0||!Dl.isAbsolute(t.localPath))throw n("localPath");return{fileName:t.fileName,abilityRecordId:t.abilityRecordId,startTime:t.startTime,localPath:t.localPath}}var Il=class{constructor(e){this.recordDir=e}sessionPath(e){return Dl.join(this.recordDir,`${go(e)}.json`)}async read(e){let t=this.sessionPath(e),n;try{n=await Hr.promises.readFile(t,"utf8")}catch(o){if(o.code==="ENOENT")return;throw new S("SESSION_CORRUPT",`Cannot read recording session: ${o.message}`,{cause:o})}let i;try{i=JSON.parse(n)}catch(o){throw new S("SESSION_CORRUPT",`Recording session file is not valid JSON: ${t}`,{cause:o})}return Db(i,t)}async createAtomic(e,t,n){await Hr.promises.mkdir(this.recordDir,{recursive:!0});let i=this.sessionPath(e),o=Dl.join(this.recordDir,`${go(e)}.${gN(6).toString("hex")}.tmp`),s=JSON.stringify(Db(t,"input")),a;try{a=await Hr.promises.open(o,"wx")}catch(c){throw new S("SESSION_PUBLISH_FAILED",`Cannot create session temp file: ${c.message}`,{cause:c})}try{await a.writeFile(s),await a.sync()}catch(c){throw await a.close().catch(()=>{}),await Hr.promises.unlink(o).catch(()=>{}),new S("SESSION_PUBLISH_FAILED",`Cannot write session temp file: ${c.message}`,{cause:c})}await a.close();try{if(await n.assertOwned(),await this.exists(i))throw new S("SESSION_CHANGED",`A recording session was created concurrently for ${e}`);await Hr.promises.link(o,i),await this.syncDir()}finally{await Hr.promises.unlink(o).catch(()=>{})}}async deleteIfSame(e,t,n){await n.assertOwned();let i=await this.read(e);if(i){if(!li(i,t))throw new S("SESSION_CHANGED","The recording session changed hands; leaving the new record untouched");await Hr.promises.unlink(this.sessionPath(e)),await this.syncDir()}}async exists(e){try{return await Hr.promises.lstat(e),!0}catch{return!1}}async syncDir(){try{let e=await Hr.promises.open(this.recordDir,"r");try{await e.sync()}finally{await e.close()}}catch{}}};var yN={startConfirmMs:1e4,stopConfirmMs:15e3,stopReadyMs:3e3,observeIntervalMs:250,foregroundPollMs:1e3,mediaReadyMs:3e4,mediaBackoffMs:[250,500,1e3,2e3],mediaRecvAttempts:3,lockWaitMs:6e4,interactiveLockWaitMs:10*6e4,foregroundFailureBudget:3},Ab=4e3;function Bs(r){return new Promise(e=>setTimeout(e,r))}function Al(){return hN(2).toString("hex")}var Tb=["SIGINT","SIGTERM","SIGHUP"];function wN(r,e){let t=()=>{r.requested||(r.requested=!0,e?.(),r.wake())};for(let n of Tb)process.on(n,t);return()=>{for(let n of Tb)process.off(n,t)}}var fn=class{constructor(e,t={}){this.toolProvider=e;let n=Ib.join($(),"record");this.deps={store:t.store??new Il(n),lock:t.lock??new Rl(n),device:t.device??new xl(e.hdcPath),timing:{...yN,...t.timing}}}deps;async startDetached(e,t){let n=await this.resolveTarget(e),i=await Bf(t,n.name,new Date,Al());return this.startSession(n,i)}async recordInteractively(e,t,n){let i=new Set,o={requested:!1,wake:()=>{for(let a of i)a()}},s=wN(o,n.onStopRequested);try{let a=await this.resolveTarget(e),c=await Bf(t,a.name,new Date,Al()),l=await this.startSession(a,c);return n.onStarted(),await this.waitForInteractiveCompletion(l,o,i)}finally{s()}}async waitForInteractiveCompletion(e,t,n){let i,o=()=>(i??=this.deps.lock.withDeviceLock(e.serial,a=>this.finalizeLocked(e.serial,e.session,"interactive",a),this.deps.timing.interactiveLockWaitMs),i),s=0;for(;;){if(t.requested)return await o();let a;try{a=await this.readSnapshot(e.serial),s=0}catch(c){if(s+=1,s>=this.deps.timing.foregroundFailureBudget)throw c;await this.waitPoll(t,n);continue}if(db(a,e.session))return await o();await this.waitPoll(t,n)}}async stopRecording(e,t){let n=await this.resolveTarget(e);return this.deps.lock.withDeviceLock(n.serial,async i=>{let o=await this.readSnapshot(n.serial),s=nb(o,t);if(s.plan==="force-stop-external")return await this.stopExternal(n.serial,s.activeId,i),{kind:"external-stopped"};if(s.plan==="error")throw s.error;return this.finalizeLocked(n.serial,s.session,"stop-or-recover",i)},this.deps.timing.lockWaitMs)}async getRecordingStatus(e){let t=await this.resolveTarget(e);for(let n=0;n<3;n++){let i=await this.deps.store.read(t.serial),o=await this.deps.device.observeOnce(t.serial),s=await this.deps.store.read(t.serial);if(!li(i,s))continue;let a=Lf(o,s);return lb(a)}throw new S("STATE_CHANGING","The recording session keeps changing; try again")}async resolveTarget(e){let t=await le.from(this.toolProvider).getConnectedEntries();if(t.length===0)throw new S("NO_ACTIVE_DEVICES","No active devices found. Connect a physical device; screen recording does not support emulators.");let n=await T(this.toolProvider,e),i=t.find(o=>o.serial===n);if(i?.isEmulator)throw new S("EMULATOR_NOT_SUPPORTED","Screen recording is only supported on physical devices");return{serial:n,name:i?.name??n}}async readSnapshot(e){let t=await this.deps.store.read(e),n=await this.deps.device.observeOnce(e);return Lf(n,t)}async startSession(e,t){return this.deps.lock.withDeviceLock(e.serial,n=>this.startSessionLocked(e,t,n),this.deps.timing.lockWaitMs)}async startSessionLocked(e,t,n){let i=await this.readSnapshot(e.serial),o=tb(i);if(o.plan==="error")throw o.error;if(o.plan==="discard-first"){await this.deps.store.deleteIfSame(e.serial,o.session,n);let s=await this.readSnapshot(e.serial),a=rb(s);if(a.plan==="error")throw a.error}return this.toggleAndRegister(e,t,n)}async toggleAndRegister(e,t,n){await Uf(t);let i=fb(new Date,Al()),o=Date.now(),s=Date.now()+this.deps.timing.startConfirmMs;await n.assertOwned(),await this.deps.device.toggleOnce(e.serial,i,n,Math.max(1,s-Date.now()));let a=await this.waitForStarted(e.serial,s),c={fileName:i,abilityRecordId:a.abilityRecordId,startTime:o,localPath:t};return await this.registerSession(e.serial,c,n),{serial:e.serial,session:c}}async registerSession(e,t,n){try{await this.deps.store.createAtomic(e,t,n)}catch(i){throw await this.abortUnregistered(e,t,n),new S(i.code??"SESSION_PUBLISH_FAILED",`Recording started on device (file ${t.fileName}) but could not be registered: ${i.message}. Check the device gallery.`,{cause:i})}}async withinDeadline(e,t,n){try{return await n(Math.max(1,e-Date.now()))}catch(i){throw Date.now()>=e?t:i}}async waitForStarted(e,t){for(;;){let n=t-Date.now();if(n<=0)throw new S("START_CONFIRM_TIMEOUT","Device screen may be locked");let i=await this.withinDeadline(t,new S("START_CONFIRM_TIMEOUT","Device screen may be locked"),s=>this.deps.device.observeOnce(e,s)),o=ab(i);if(o.outcome==="error")throw o.error;if(o.outcome==="confirmed"){if(Date.now()>t)throw new S("START_CONFIRM_TIMEOUT","Device screen may be locked");return o.record}await Bs(Math.min(this.deps.timing.observeIntervalMs,n))}}async observeActiveId(e,t,n){let i=await this.deps.device.observeOnce(e,n),o=sb(i,t);if(o.outcome==="error")throw o.error;return o.outcome==="gone"?void 0:o.activeId}async waitForStopped(e,t,n){for(;;){let i=n-Date.now();if(i<=0)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");if(await this.withinDeadline(n,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),s=>this.observeActiveId(e,t,s))===void 0)return;await Bs(Math.min(this.deps.timing.observeIntervalMs,i))}}async awaitStopReady(e,t,n,i){for(;;){let o=i-Date.now();if(o<=0)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");if(await this.withinDeadline(i,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),a=>this.observeActiveId(e,t,a))===void 0)return"vanished";if(Date.now()>=n){if(Date.now()>i)throw new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent");return"ready"}await Bs(Math.min(this.deps.timing.observeIntervalMs,n-Date.now(),o))}}async abortUnregistered(e,t,n){try{let i=Date.now()+this.deps.timing.stopConfirmMs,o=Ff(t,this.deps.timing.stopReadyMs);await this.awaitStopReady(e,t.abilityRecordId,o,i)==="ready"&&await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,i-Date.now()))}catch(i){f(`abortUnregistered: best-effort stop failed: ${i.message}`)}}async finalizeLocked(e,t,n,i){let o=await this.deps.store.read(e),s=ib(o,t,n);if(s.plan==="completed-elsewhere")return{kind:"completed-elsewhere"};if(s.plan==="error")throw s.error;let a=await this.readSnapshot(e),c=ob(a);if(c.plan==="error")throw c.error;if(c.plan==="stop-recording"){let l=Date.now()+this.deps.timing.stopConfirmMs;return this.stopLiveRecording(e,t,i,l)}return this.retrieveAndPublish(e,t,i)}async stopLiveRecording(e,t,n,i){let o=Ff(t,this.deps.timing.stopReadyMs);return await this.awaitStopReady(e,t.abilityRecordId,o,i)==="vanished"?this.retrieveAndPublish(e,t,n):(await n.assertOwned(),await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,i-Date.now())),await this.waitForStopped(e,t.abilityRecordId,i),this.retrieveAndPublish(e,t,n))}async stopExternal(e,t,n){let i=await this.deps.device.observeOnce(e),o=cb(i,t);if(o.plan==="already-stopped")return;if(o.plan==="error")throw o.error;let s=Date.now()+this.deps.timing.stopConfirmMs;o.startedAtMs!==void 0&&!await this.awaitForeignStopReady(e,o.currentId,o.startedAtMs,s)||(await n.assertOwned(),await this.deps.device.toggleOnce(e,void 0,n,Math.max(1,s-Date.now())),await this.waitForStopped(e,o.currentId,s))}async awaitForeignStopReady(e,t,n,i){let o=await this.withinDeadline(i,new S("STOP_CONFIRM_TIMEOUT","The recording did not stop in time; session kept, no re-toggle sent"),c=>this.deps.device.readUptimeMs(e,c)),s=ub(o-n,this.deps.timing.stopReadyMs,Date.now());return await this.awaitStopReady(e,t,s,i)==="ready"}async retrieveAndPublish(e,t,n){let i=[],o=await this.waitForMediaUri(e,t.fileName),s=await Cb(t.localPath);try{let a=await this.receiveUntilValid(e,o,t,s,n,i);await n.assertOwned();let c=await Rb(a,t.localPath);return await this.deleteSessionAfterSave(e,t,n,c),{kind:"saved",localPath:c,warnings:i}}finally{await xb(s,t.localPath)}}async waitForMediaUri(e,t){let n=Date.now()+this.deps.timing.mediaReadyMs,i=0;for(;;){let o=n-Date.now();if(o<=0)throw new S("MEDIA_NOT_READY",`Timed out waiting for ${t} in the media library; session kept for a later stop`);let s=await this.withinDeadline(n,new S("MEDIA_NOT_READY",`Timed out waiting for ${t} in the media library; session kept for a later stop`),c=>this.deps.device.queryMediaUri(e,t,c));if(s&&Date.now()<=n)return s;let a=Math.min(this.deps.timing.mediaBackoffMs[Math.min(i,this.deps.timing.mediaBackoffMs.length-1)]??Ab,Ab,o);i+=1,await Bs(a)}}async receiveUntilValid(e,t,n,i,o,s){for(let a=0;a<this.deps.timing.mediaRecvAttempts;a++){await o.assertOwned();let c=gb(n.fileName,Al()),l=await this.receiveOnce(e,t,c,i,n.fileName,o,s);try{return await kb(l),l}catch(d){if(d.code!=="MEDIA_NOT_READY")throw d;f(`Received file incomplete (attempt ${a+1}); retrying export`),await Bs(this.deps.timing.mediaBackoffMs[0]??250)}}throw new S("MEDIA_NOT_READY",`Received file for ${n.fileName} is incomplete after ${this.deps.timing.mediaRecvAttempts} attempts; session kept`)}async receiveOnce(e,t,n,i,o,s,a){let c=Ib.join(i,o);try{await this.deps.device.exportToStaging(e,t,n),await this.deps.device.receiveFile(e,n,c,s.signal)}finally{await this.deps.device.removeStaging(e,n)||a.push(`Failed to remove device staging file: ${n}`)}return c}async deleteSessionAfterSave(e,t,n,i){try{await this.deps.store.deleteIfSame(e,t,n)}catch(o){throw new S(o.code??"SESSION_DELETE_FAILED",`Recording saved to ${i}, but the session record could not be removed: ${o.message}. A later stop may create a recovered copy.`,{cause:o})}}async waitPoll(e,t){await new Promise(n=>{let i=setTimeout(()=>{t.delete(o),n()},this.deps.timing.foregroundPollMs),o=()=>{t.delete(o),clearTimeout(i),n()};t.add(o)})}};var Tl={left:"0",right:"1",up:"2",down:"3"};function Ge(r,e){let t=Number(r);if(!Number.isInteger(t)||t<=0)throw new Error(`${e} must be a positive integer`)}function Wf(r,e){r!==void 0&&Ge(r,e)}function Nb(r,e){if(r===void 0!=(e===void 0))throw new Error("x and y must be provided together")}function Nl(r,e){if(r!==void 0&&r.length===0)throw new Error(`${e} must not be empty`)}function Ws(r){if(r===void 0)return;let e=Number(r);if(!Number.isInteger(e)||e<200||e>4e4)throw new Error("--speed must be an integer between 200 and 40000");return r}function Ob(r){if(r!==void 0&&!/^[a-zA-Z0-9_-]+$/.test(r))throw new Error("--window must consist of letters, digits, - or _")}function _b(r,e,t,n=!0){if(t&&!e)throw new Error("--window must be used with --id");if(r&&e)throw new Error("Coordinates and --id are mutually exclusive");if(n&&!r&&!e)throw new Error("Either provide x y coordinates or use --id")}function yo(r,e,t,n,i=!0){Nb(r,e),Nl(t,"--id"),Wf(r,"x"),Wf(e,"y"),Ob(n),_b(r!==void 0,!!t,!!n,i)}async function hr(r){let e=await C.new(),t=await T(e,r);return{hdcPath:e.hdcPath,deviceId:t}}async function wo(r,e,t,n,i,o){if(t!==void 0&&n!==void 0)return{x:t,y:n};if(i===void 0)throw new Error("Either provide x y coordinates or use --id");let a=await new Lr(r,e).listWindows({all:!0}),c=new Fr(r);return vN(c,e,a,i,o)}async function vN(r,e,t,n,i){if(i!==void 0){let o=t.find(a=>String(a.id)===i);if(o&&o.displayId!==0)throw new w(`Window "${i}" is on display ${o.displayId}. The current command only supports operations on the primary display.`,"The current command only supports operations on the primary display.");let s=await r.dumpFullTree(e,0,i,!1);return SN(s,n)}return bN(r,e,t,n)}async function bN(r,e,t,n){let i=[...new Set(t.map(a=>a.displayId))],o=await r.dumpFullTreeByDisplays(e,0,i),s=[];for(let{displayId:a,tree:c}of o)for(let l of po([c],n))s.push({node:l,displayId:a});if(s.length===0)throw new w(`Node "${n}" not found.`,"Node not found.");if(s.length>1)throw new w(`Multiple nodes found with id "${n}".`,"Multiple nodes found");if(s[0].displayId!==0)throw new w(`Node "${n}" is on display ${s[0].displayId}. The current command only supports operations on the primary display.`,"The current command only supports operations on the primary display.");return Mb(s[0].node,n)}function SN(r,e){let t=po(r,e);if(t.length===0)throw new w(`Node "${e}" not found.`,"Node not found.");if(t.length>1)throw new w(`Multiple nodes found with id "${e}".`,"Multiple nodes found");return Mb(t[0],e)}function Mb(r,e){let t=r.bounds;if(!t)throw new w(`Node "${e}" has no bounds.`,"Node has no bounds.");let[n,i,o,s]=t;return{x:Math.ceil((n+o)/2),y:Math.ceil((i+s)/2)}}async function xt(r,e,t){let n=["-t",e,"shell",...t];f(`Executing: ${r} ${n.join(" ")}`);let i=await k(r,n);if(i.exitCode!==0)throw new Error(i.stderr||i.stdout||`uitest exited with code ${i.exitCode}`);let o=i.stdout.toLowerCase();if(["illegal","fail","error","incorrect","please confirm that the coordinate values are correct"].some(a=>o.includes(a))&&!o.includes("no error"))throw new Error(i.stdout.trim()||"uitest command failed")}import{deflateSync as EN,inflateSync as PN}from"zlib";import CN from"fs";var Lb=8,Fb=32,kN=.06,RN=.04,Vf=10,Ol=class r{whiteBits=null;blackBits=null;analyzeRgb(e,t,n){if(e<8||t<8||n.length<e*t*3)return null;let i=this.cropChrome(e,t,n),o=this.hashBits(i.width,i.height,i.rgb),s=Math.min(this.hammingDistance(o,this.solidRefBits(255)),this.hammingDistance(o,this.solidRefBits(0)));return{phash:this.bitsToHex(o),hamming:s,isBlank:s<=Vf}}analyzeFile(e){let t;try{t=CN.readFileSync(e)}catch{return null}let n=this.decodePngRgb(t);return n?this.analyzeRgb(n.width,n.height,n.rgb):null}static encodePngRgb(e,t,n){let i=r.pngCrcTable(),o=[Buffer.from(`\x89PNG\r
72
72
  
73
- `,"binary")],s=Buffer.alloc(13);s.writeUInt32BE(e,0),s.writeUInt32BE(t,4),s[8]=8,s[9]=2,o.push(r.pngChunk("IHDR",s,i));let a=Buffer.alloc((e*3+1)*t);for(let c=0;c<t;c++)a[c*(e*3+1)]=0,Buffer.from(n.buffer,n.byteOffset+c*e*3,e*3).copy(a,c*(e*3+1)+1);return o.push(r.pngChunk("IDAT",VI(a),i)),o.push(r.pngChunk("IEND",Buffer.alloc(0),i)),Buffer.concat(o)}cropChrome(e,t,n){let i=Math.floor(t*zI),o=Math.floor(t*(1-JI));if(o<=i+8)return{width:e,height:t,rgb:n};let s=o-i,a=new Uint8Array(e*s*3);for(let c=0;c<s;c++){let l=(i+c)*e*3;a.set(n.subarray(l,l+e*3),c*e*3)}return{width:e,height:s,rgb:a}}hashBits(e,t,n){let i=this.toGray(e,t,n),o=this.resizeGray(i,Vv,Vv),s=this.dct2(o),a=[];for(let d=0;d<Wv;d++)a.push(s[d].slice(0,Wv));let c=this.stabilizeDct(a),l=this.median(c);return c.map(d=>d>l)}solidRefBits(e){return e===255?this.whiteBits??=this.solidBits(255,255,255):this.blackBits??=this.solidBits(0,0,0)}solidBits(e,t,n){let o=new Uint8Array(12288);for(let s=0;s<4096;s++)o[s*3]=e,o[s*3+1]=t,o[s*3+2]=n;return this.hashBits(64,64,o)}hammingDistance(e,t){let n=Math.min(e.length,t.length),i=Math.abs(e.length-t.length);for(let o=0;o<n;o++)e[o]!==t[o]&&i++;return i}bitsToHex(e){let t=0n;for(let i of e)t=t<<1n|(i?1n:0n);let n=Math.max(1,Math.ceil(e.length/4));return t.toString(16).padStart(n,"0")}toGray(e,t,n){let i=[];for(let o=0;o<t;o++){let s=[];for(let a=0;a<e;a++){let c=(o*e+a)*3;s.push(.299*n[c]+.587*n[c+1]+.114*n[c+2])}i.push(s)}return i}resizeGray(e,t,n){let i=e.length,o=e[0]?.length??0;if(o===t&&i===n)return e;let s=[];for(let a=0;a<n;a++){let c=(a+.5)*i/n-.5,l=Math.max(0,Math.min(i-1,Math.floor(c))),d=Math.max(0,Math.min(i-1,l+1)),g=c-l,y=[];for(let E=0;E<t;E++){let j=(E+.5)*o/t-.5,ye=Math.max(0,Math.min(o-1,Math.floor(j))),ut=Math.max(0,Math.min(o-1,ye+1)),er=j-ye,Un=e[l][ye],Bn=e[l][ut],Wn=e[d][ye],uh=e[d][ut];y.push(Un*(1-er)*(1-g)+Bn*er*(1-g)+Wn*(1-er)*g+uh*er*g)}s.push(y)}return s}stabilizeDct(e){let t=e.flat(),n=Math.abs(t[0]??0),i=Math.max(.001,n*1e-8);return t.map(o=>Math.abs(o)<i?0:o)}median(e){if(e.length===0)return 0;let t=[...e].sort((i,o)=>i-o),n=Math.floor(t.length/2);return t.length%2?t[n]:.5*(t[n-1]+t[n])}dct2(e){let t=e.length,n=a=>{let c=new Array(t).fill(0);for(let l=0;l<t;l++){let d=0;for(let g=0;g<t;g++)d+=a[g]*Math.cos(Math.PI*(g+.5)*l/t);c[l]=d}return c},i=e.map(n),o=[];for(let a=0;a<t;a++)o.push(n(i.map(c=>c[a])));let s=[];for(let a=0;a<t;a++){let c=[];for(let l=0;l<t;l++)c.push(o[l][a]);s.push(c)}return s}decodePngRgb(e){let t=this.parsePngChunks(e);if(!t)return null;let n;try{n=GI(Buffer.concat(t.idat))}catch{return null}let i=this.pngScanlinesToRgb(n,t.width,t.height,t.colorType);return{width:t.width,height:t.height,rgb:i}}parsePngChunks(e){if(e.length<8||e.subarray(0,8).toString("binary")!==`\x89PNG\r
73
+ `,"binary")],s=Buffer.alloc(13);s.writeUInt32BE(e,0),s.writeUInt32BE(t,4),s[8]=8,s[9]=2,o.push(r.pngChunk("IHDR",s,i));let a=Buffer.alloc((e*3+1)*t);for(let c=0;c<t;c++)a[c*(e*3+1)]=0,Buffer.from(n.buffer,n.byteOffset+c*e*3,e*3).copy(a,c*(e*3+1)+1);return o.push(r.pngChunk("IDAT",EN(a),i)),o.push(r.pngChunk("IEND",Buffer.alloc(0),i)),Buffer.concat(o)}cropChrome(e,t,n){let i=Math.floor(t*kN),o=Math.floor(t*(1-RN));if(o<=i+8)return{width:e,height:t,rgb:n};let s=o-i,a=new Uint8Array(e*s*3);for(let c=0;c<s;c++){let l=(i+c)*e*3;a.set(n.subarray(l,l+e*3),c*e*3)}return{width:e,height:s,rgb:a}}hashBits(e,t,n){let i=this.toGray(e,t,n),o=this.resizeGray(i,Fb,Fb),s=this.dct2(o),a=[];for(let d=0;d<Lb;d++)a.push(s[d].slice(0,Lb));let c=this.stabilizeDct(a),l=this.median(c);return c.map(d=>d>l)}solidRefBits(e){return e===255?this.whiteBits??=this.solidBits(255,255,255):this.blackBits??=this.solidBits(0,0,0)}solidBits(e,t,n){let o=new Uint8Array(12288);for(let s=0;s<4096;s++)o[s*3]=e,o[s*3+1]=t,o[s*3+2]=n;return this.hashBits(64,64,o)}hammingDistance(e,t){let n=Math.min(e.length,t.length),i=Math.abs(e.length-t.length);for(let o=0;o<n;o++)e[o]!==t[o]&&i++;return i}bitsToHex(e){let t=0n;for(let i of e)t=t<<1n|(i?1n:0n);let n=Math.max(1,Math.ceil(e.length/4));return t.toString(16).padStart(n,"0")}toGray(e,t,n){let i=[];for(let o=0;o<t;o++){let s=[];for(let a=0;a<e;a++){let c=(o*e+a)*3;s.push(.299*n[c]+.587*n[c+1]+.114*n[c+2])}i.push(s)}return i}resizeGray(e,t,n){let i=e.length,o=e[0]?.length??0;if(o===t&&i===n)return e;let s=[];for(let a=0;a<n;a++){let c=(a+.5)*i/n-.5,l=Math.max(0,Math.min(i-1,Math.floor(c))),d=Math.max(0,Math.min(i-1,l+1)),g=c-l,y=[];for(let E=0;E<t;E++){let K=(E+.5)*o/t-.5,we=Math.max(0,Math.min(o-1,Math.floor(K))),pt=Math.max(0,Math.min(o-1,we+1)),ir=K-we,Vn=e[l][we],Gn=e[l][pt],qn=e[d][we],iy=e[d][pt];y.push(Vn*(1-ir)*(1-g)+Gn*ir*(1-g)+qn*(1-ir)*g+iy*ir*g)}s.push(y)}return s}stabilizeDct(e){let t=e.flat(),n=Math.abs(t[0]??0),i=Math.max(.001,n*1e-8);return t.map(o=>Math.abs(o)<i?0:o)}median(e){if(e.length===0)return 0;let t=[...e].sort((i,o)=>i-o),n=Math.floor(t.length/2);return t.length%2?t[n]:.5*(t[n-1]+t[n])}dct2(e){let t=e.length,n=a=>{let c=new Array(t).fill(0);for(let l=0;l<t;l++){let d=0;for(let g=0;g<t;g++)d+=a[g]*Math.cos(Math.PI*(g+.5)*l/t);c[l]=d}return c},i=e.map(n),o=[];for(let a=0;a<t;a++)o.push(n(i.map(c=>c[a])));let s=[];for(let a=0;a<t;a++){let c=[];for(let l=0;l<t;l++)c.push(o[l][a]);s.push(c)}return s}decodePngRgb(e){let t=this.parsePngChunks(e);if(!t)return null;let n;try{n=PN(Buffer.concat(t.idat))}catch{return null}let i=this.pngScanlinesToRgb(n,t.width,t.height,t.colorType);return{width:t.width,height:t.height,rgb:i}}parsePngChunks(e){if(e.length<8||e.subarray(0,8).toString("binary")!==`\x89PNG\r
74
74
  
75
- `)return null;let t=8,n=0,i=0,o=0,s=0,a=[];for(;t+8<=e.length;){let c=e.readUInt32BE(t),l=e.subarray(t+4,t+8).toString("ascii"),d=e.subarray(t+8,t+8+c);if(t+=12+c,l==="IHDR")n=d.readUInt32BE(0),i=d.readUInt32BE(4),o=d[8],s=d[9];else if(l==="IDAT")a.push(d);else if(l==="IEND")break}return!n||!i||o!==8||s!==2&&s!==6?null:{width:n,height:i,colorType:s,idat:a}}pngScanlinesToRgb(e,t,n,i){let o=i===6?4:3,s=t*o,a=new Uint8Array(t*n*3),c=0,l=new Uint8Array(s),d=new Uint8Array(s);for(let g=0;g<n;g++){let y=e[c++];d.set(e.subarray(c,c+s)),c+=s,this.applyPngFilter(y,d,l,o);for(let E=0;E<t;E++){let j=(g*t+E)*3,ye=E*o;a[j]=d[ye],a[j+1]=d[ye+1],a[j+2]=d[ye+2]}l.set(d)}return a}applyPngFilter(e,t,n,i){for(let o=0;o<t.length;o++){let s=o>=i?t[o-i]:0,a=n[o],c=o>=i?n[o-i]:0;e===1?t[o]=t[o]+s&255:e===2?t[o]=t[o]+a&255:e===3?t[o]=t[o]+Math.floor((s+a)/2)&255:e===4&&(t[o]=t[o]+this.paeth(s,a,c)&255)}}paeth(e,t,n){let i=e+t-n,o=Math.abs(i-e),s=Math.abs(i-t),a=Math.abs(i-n);return o<=s&&o<=a?e:s<=a?t:n}static pngChunk(e,t,n){let i=Buffer.concat([Buffer.from(e,"ascii"),t]),o=Buffer.alloc(12+t.length);return o.writeUInt32BE(t.length,0),i.copy(o,4),o.writeUInt32BE(r.pngCrc(i,n),8+t.length),o}static pngCrcTable(){let e=new Uint32Array(256);for(let t=0;t<256;t++){let n=t;for(let i=0;i<8;i++)n=n&1?3988292384^n>>>1:n>>>1;e[t]=n>>>0}return e}static pngCrc(e,t){let n=4294967295;for(let i=0;i<e.length;i++)n=t[(n^e[i])&255]^n>>>8;return(n^4294967295)>>>0}};import $r from"fs";import Bt from"path";import{randomUUID as eT}from"crypto";var YI=/^smoke-screenshot-\d+\.png$/,KI=/^smoke-crash-\d+\.log$/,XI=/^run-\d+-\d+-[0-9a-f]{4}$/;function Gv(r){return`smoke-screenshot-${r}.png`}function qv(r){return`smoke-crash-${r}.log`}function zv(r){return YI.test(r)||KI.test(r)}var Os="RUNNING",mm="ENDED",ZI=1440*60*1e3,QI=1440*60*1e3;function Jv(r,e,t){return`run-${r}-${e}-${t}`}function Yv(r){return XI.test(r)}function Kv(r){try{let e=JSON.parse(r);if(typeof e.pid!="number"||typeof e.startedAt!="number"||!Number.isFinite(e.pid)||!Number.isFinite(e.startedAt))return null;let t={pid:e.pid,startedAt:e.startedAt};return typeof e.endedAt=="number"&&Number.isFinite(e.endedAt)&&(t.endedAt=e.endedAt),t}catch{}return null}function Xv(r,e,t){return r===null?!0:r==="ended"?e?.endedAt===void 0?!0:t.now-e.endedAt>=ZI:!e||!Number.isInteger(e.pid)||e.pid<=0||t.now-e.startedAt>=QI?!0:!t.isPidAlive(e.pid)}var tT="smoke";function rT(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}var Ns=class{constructor(e,t=rT){this.baseDir=e;this.isPidAlive=t;this.runsRoot=Bt.join(e,tT)}runsRoot;static resolveBaseDir(e,t){return t??Bt.join(e,".hvigor")}createRun(){let e=Bt.join(this.runsRoot,Jv(Date.now(),process.pid,eT().slice(0,4)));$r.mkdirSync(e,{recursive:!0});let t={pid:process.pid,startedAt:Date.now()};return $r.writeFileSync(Bt.join(e,Os),JSON.stringify(t),"utf8"),e}prune(e,t=Date.now()){this.pruneLegacyFlatArtifacts(),this.pruneEndedRuns(e,t)}finalize(e){try{let t=this.readMarker(e,Os),n={pid:t?.pid??process.pid,startedAt:t?.startedAt??Date.now(),endedAt:Date.now()};$r.writeFileSync(Bt.join(e,mm),JSON.stringify(n),"utf8"),$r.rmSync(Bt.join(e,Os),{force:!0})}catch(t){m(`Smoke: finalize run failed (${e}): ${t.message}`)}}discard(e){try{$r.rmSync(e,{recursive:!0,force:!0})}catch(t){m(`Smoke: discard run failed (${e}): ${t.message}`)}}pruneLegacyFlatArtifacts(){let e;try{e=$r.readdirSync(this.baseDir,{withFileTypes:!0})}catch{return}for(let t of e)!t.isFile()||!zv(t.name)||this.removeQuietly(Bt.join(this.baseDir,t.name))}pruneEndedRuns(e,t){let n;try{n=$r.readdirSync(this.runsRoot,{withFileTypes:!0})}catch{return}for(let i of n){if(!i.isDirectory()||!Yv(i.name))continue;let o=Bt.join(this.runsRoot,i.name);if(Bt.resolve(o)===Bt.resolve(e))continue;let s=this.readMarkerState(o);Xv(s.kind,s.marker,{now:t,isPidAlive:this.isPidAlive})&&this.removeQuietly(o)}}readMarkerState(e){let t=this.readMarker(e,mm);if(t!==void 0)return{kind:"ended",marker:t};let n=this.readMarker(e,Os);return n!==void 0?{kind:"running",marker:n}:{kind:null,marker:null}}readMarker(e,t){try{return Kv($r.readFileSync(Bt.join(e,t),"utf8"))}catch(n){return n.code==="ENOENT"?void 0:null}}removeQuietly(e){try{$r.rmSync(e,{recursive:!0,force:!0})}catch(t){m(`Smoke: prune artifact failed (${e}): ${t.message}`)}}};var Zv=3e3;function iT(){let r=process.env.DEVECO_CLI_SMOKE_WAIT_MS;if(r===void 0||r==="")return Zv;let e=Number(r);return Number.isFinite(e)&&e>=0?Math.floor(e):Zv}var yl=class{constructor(e,t,n){this.hdc=t;this.projectRoot=n;this.hilog=new cn(e),this.screenshots=new ni(e)}phash=new gl;hilog;screenshots;runDir;runStore;async collect(e){this.openRun(e);let t=iT();t>0&&await new Promise(i=>setTimeout(i,t));let n;try{n=await this.hdc.pidofBundle(e.targetDeviceId,e.bundleName)}catch(i){return console.warn(Ms(`Smoke: process check failed (${i.message}); smoke skipped.`)),{processAlive:!0,phashBlank:null,processCheckSkipped:!0}}return n?this.collectScreenshotEvidence(e):{processAlive:!1,phashBlank:null,crashLogPath:await this.writeCrashLogFile(e)}}openRun(e){let t=new Ns(Ns.resolveBaseDir(this.projectRoot,e.screenshotDir)),n=t.createRun();t.prune(n),this.runStore=t,this.runDir=n}artifactPath(e){return nT.join(this.runDir??"",e)}discardEvidence(e){for(let t of[e.screenshotPath,e.crashLogPath])if(t)try{hl.rmSync(t,{force:!0})}catch(n){m(`Smoke: discard artifact failed (${t}): ${n.message}`)}this.runStore&&this.runDir&&this.runStore.discard(this.runDir)}finalizeRun(){this.runStore&&this.runDir&&this.runStore.finalize(this.runDir)}async collectScreenshotEvidence(e){let t=this.artifactPath(Gv(Date.now()));try{await this.screenshots.captureToPath(e.targetDeviceId,t)}catch(i){return this.skipBlank(`screenshot failed (${i.message})`)}if(!hl.existsSync(t)||hl.statSync(t).size<=32)return this.skipBlank("screenshot file missing or empty");let n=this.phash.analyzeFile(t);return n?{processAlive:!0,phashBlank:n.isBlank,phash:n.phash,phashHamming:n.hamming,screenshotPath:t}:this.skipBlank("failed to analyze screenshot",t)}skipBlank(e,t){return console.warn(Ms(`Smoke: ${e}; blank check skipped.`)),{processAlive:!0,phashBlank:null,screenshotPath:t,screenshotSkipped:!0}}async writeCrashLogFile(e){let t;try{t=await this.hilog.getLatestCrashLog(e.targetDeviceId,e.bundleName)}catch(n){console.warn(Ms(`Smoke: crash log query failed (${n.message}).`));return}if(!t?.trim()){console.warn(Ms("Smoke: no crash log found on device."));return}try{let n=this.artifactPath(qv(Date.now()));return hl.writeFileSync(n,t,"utf8"),n}catch(n){console.warn(Ms(`Smoke: failed to save crash log (${n.message}).`));return}}};var wl=class{judge(e){if(!e.processAlive)return this.verdict("FAIL_CRASH","Application process died after launch (possible crash).",e);if(e.phashBlank===!0)return this.verdict("FAIL_BLANK",`Blank/solid screen after launch (hamming ${e.phashHamming} \u2264 ${pm}, hash=${e.phash||"-"}).`,e);let t=e.phashBlank===null?"Process alive; screenshot unavailable, blank check skipped.":"Process alive; screenshot is not a solid blank screen.";return this.verdict("PASS",t,e)}verdict(e,t,n){return{status:e,reason:t,evidence:n,passed:e==="PASS"}}};var vl=class{inspector;judge=new wl;formatter=new Zc;constructor(e,t,n){let i=n??new le(e);this.inspector=new yl(e,i,t)}async execute(e){let t=await this.inspector.collect(e),n=this.judge.judge(t);if(n.passed){this.inspector.discardEvidence(t),console.log(this.formatter.formatPass(n));return}throw this.inspector.finalizeRun(),this.formatter.toTraceError(n,e)}};async function fm(r){await new vl(r.toolProvider,r.projectRoot,r.hdcAdapter).execute(r)}function gm(r){let e=r.indexOf("@"),t=e!==-1?r.substring(0,e):r,n=e!==-1?r.substring(e+1):"default";return{moduleName:t,targetName:n}}async function Sl(r,e){let t=await r.listDevices();if(t.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");if(!e&&t.length>1){let i=await r.listDevicesWithName();throw new w("Multiple devices found. Specify a target device using `--device <Name>` or `--device <ID>`.\nAvailable devices:\n"+i.map(o=>` - ${o.name} (${o.serial})`).join(`
76
- `),"Multiple devices found.")}let n=await r.getDeviceInfo(t,e);if(!n)throw new Error("No active devices found.");if(!e){let i=await r.getDeviceName(n.serial);console.log(`Auto-selected device: ${i} (${n.serial})`)}return n.serial}function hm(r,e){if(e&&e.length>0)return e;let t=r.profile.modules.filter(n=>{let i=r.getModuleType(n.name);return i==="entry"||i==="feature"||i==="shared"});if(t.length===1){let n=t[0].name;return console.log(`Auto-selected module: ${n}`),[n]}throw new w(`Specify module(s) using --module <name> [<name>...].
75
+ `)return null;let t=8,n=0,i=0,o=0,s=0,a=[];for(;t+8<=e.length;){let c=e.readUInt32BE(t),l=e.subarray(t+4,t+8).toString("ascii"),d=e.subarray(t+8,t+8+c);if(t+=12+c,l==="IHDR")n=d.readUInt32BE(0),i=d.readUInt32BE(4),o=d[8],s=d[9];else if(l==="IDAT")a.push(d);else if(l==="IEND")break}return!n||!i||o!==8||s!==2&&s!==6?null:{width:n,height:i,colorType:s,idat:a}}pngScanlinesToRgb(e,t,n,i){let o=i===6?4:3,s=t*o,a=new Uint8Array(t*n*3),c=0,l=new Uint8Array(s),d=new Uint8Array(s);for(let g=0;g<n;g++){let y=e[c++];d.set(e.subarray(c,c+s)),c+=s,this.applyPngFilter(y,d,l,o);for(let E=0;E<t;E++){let K=(g*t+E)*3,we=E*o;a[K]=d[we],a[K+1]=d[we+1],a[K+2]=d[we+2]}l.set(d)}return a}applyPngFilter(e,t,n,i){for(let o=0;o<t.length;o++){let s=o>=i?t[o-i]:0,a=n[o],c=o>=i?n[o-i]:0;e===1?t[o]=t[o]+s&255:e===2?t[o]=t[o]+a&255:e===3?t[o]=t[o]+Math.floor((s+a)/2)&255:e===4&&(t[o]=t[o]+this.paeth(s,a,c)&255)}}paeth(e,t,n){let i=e+t-n,o=Math.abs(i-e),s=Math.abs(i-t),a=Math.abs(i-n);return o<=s&&o<=a?e:s<=a?t:n}static pngChunk(e,t,n){let i=Buffer.concat([Buffer.from(e,"ascii"),t]),o=Buffer.alloc(12+t.length);return o.writeUInt32BE(t.length,0),i.copy(o,4),o.writeUInt32BE(r.pngCrc(i,n),8+t.length),o}static pngCrcTable(){let e=new Uint32Array(256);for(let t=0;t<256;t++){let n=t;for(let i=0;i<8;i++)n=n&1?3988292384^n>>>1:n>>>1;e[t]=n>>>0}return e}static pngCrc(e,t){let n=4294967295;for(let i=0;i<e.length;i++)n=t[(n^e[i])&255]^n>>>8;return(n^4294967295)>>>0}};import Ur from"fs";import Gt from"path";import{randomUUID as NN}from"crypto";var xN=/^smoke-screenshot-\d+\.png$/,DN=/^smoke-crash-\d+\.log$/,IN=/^run-\d+-\d+-[0-9a-f]{4}$/;function $b(r){return`smoke-screenshot-${r}.png`}function jb(r){return`smoke-crash-${r}.log`}function Hb(r){return xN.test(r)||DN.test(r)}var Vs="RUNNING",Gf="ENDED",AN=1440*60*1e3,TN=1440*60*1e3;function Ub(r,e,t){return`run-${r}-${e}-${t}`}function Bb(r){return IN.test(r)}function Wb(r){try{let e=JSON.parse(r);if(typeof e.pid!="number"||typeof e.startedAt!="number"||!Number.isFinite(e.pid)||!Number.isFinite(e.startedAt))return null;let t={pid:e.pid,startedAt:e.startedAt};return typeof e.endedAt=="number"&&Number.isFinite(e.endedAt)&&(t.endedAt=e.endedAt),t}catch{}return null}function Vb(r,e,t){return r===null?!0:r==="ended"?e?.endedAt===void 0?!0:t.now-e.endedAt>=AN:!e||!Number.isInteger(e.pid)||e.pid<=0||t.now-e.startedAt>=TN?!0:!t.isPidAlive(e.pid)}var ON="smoke";function _N(r){try{return process.kill(r,0),!0}catch(e){return e.code==="EPERM"}}var Gs=class{constructor(e,t=_N){this.baseDir=e;this.isPidAlive=t;this.runsRoot=Gt.join(e,ON)}runsRoot;static resolveBaseDir(e,t){return t??Gt.join(e,".hvigor")}createRun(){let e=Gt.join(this.runsRoot,Ub(Date.now(),process.pid,NN().slice(0,4)));Ur.mkdirSync(e,{recursive:!0});let t={pid:process.pid,startedAt:Date.now()};return Ur.writeFileSync(Gt.join(e,Vs),JSON.stringify(t),"utf8"),e}prune(e,t=Date.now()){this.pruneLegacyFlatArtifacts(),this.pruneEndedRuns(e,t)}finalize(e){try{let t=this.readMarker(e,Vs),n={pid:t?.pid??process.pid,startedAt:t?.startedAt??Date.now(),endedAt:Date.now()};Ur.writeFileSync(Gt.join(e,Gf),JSON.stringify(n),"utf8"),Ur.rmSync(Gt.join(e,Vs),{force:!0})}catch(t){f(`Smoke: finalize run failed (${e}): ${t.message}`)}}discard(e){try{Ur.rmSync(e,{recursive:!0,force:!0})}catch(t){f(`Smoke: discard run failed (${e}): ${t.message}`)}}pruneLegacyFlatArtifacts(){let e;try{e=Ur.readdirSync(this.baseDir,{withFileTypes:!0})}catch{return}for(let t of e)!t.isFile()||!Hb(t.name)||this.removeQuietly(Gt.join(this.baseDir,t.name))}pruneEndedRuns(e,t){let n;try{n=Ur.readdirSync(this.runsRoot,{withFileTypes:!0})}catch{return}for(let i of n){if(!i.isDirectory()||!Bb(i.name))continue;let o=Gt.join(this.runsRoot,i.name);if(Gt.resolve(o)===Gt.resolve(e))continue;let s=this.readMarkerState(o);Vb(s.kind,s.marker,{now:t,isPidAlive:this.isPidAlive})&&this.removeQuietly(o)}}readMarkerState(e){let t=this.readMarker(e,Gf);if(t!==void 0)return{kind:"ended",marker:t};let n=this.readMarker(e,Vs);return n!==void 0?{kind:"running",marker:n}:{kind:null,marker:null}}readMarker(e,t){try{return Wb(Ur.readFileSync(Gt.join(e,t),"utf8"))}catch(n){return n.code==="ENOENT"?void 0:null}}removeQuietly(e){try{Ur.rmSync(e,{recursive:!0,force:!0})}catch(t){f(`Smoke: prune artifact failed (${e}): ${t.message}`)}}};var Gb=3e3;function LN(){let r=process.env.DEVECO_CLI_SMOKE_WAIT_MS;if(r===void 0||r==="")return Gb;let e=Number(r);return Number.isFinite(e)&&e>=0?Math.floor(e):Gb}var Ml=class{constructor(e,t,n){this.hdc=t;this.projectRoot=n;this.hilog=new un(e),this.screenshots=new ai(e)}phash=new Ol;hilog;screenshots;runDir;runStore;async collect(e){this.openRun(e);let t=LN();t>0&&await new Promise(i=>setTimeout(i,t));let n;try{n=await this.hdc.pidofBundle(e.targetDeviceId,e.bundleName)}catch(i){return console.warn(qs(`Smoke: process check failed (${i.message}); smoke skipped.`)),{processAlive:!0,phashBlank:null,processCheckSkipped:!0}}return n?this.collectScreenshotEvidence(e):{processAlive:!1,phashBlank:null,crashLogPath:await this.writeCrashLogFile(e)}}openRun(e){let t=new Gs(Gs.resolveBaseDir(this.projectRoot,e.screenshotDir)),n=t.createRun();t.prune(n),this.runStore=t,this.runDir=n}artifactPath(e){return MN.join(this.runDir??"",e)}discardEvidence(e){for(let t of[e.screenshotPath,e.crashLogPath])if(t)try{_l.rmSync(t,{force:!0})}catch(n){f(`Smoke: discard artifact failed (${t}): ${n.message}`)}this.runStore&&this.runDir&&this.runStore.discard(this.runDir)}finalizeRun(){this.runStore&&this.runDir&&this.runStore.finalize(this.runDir)}async collectScreenshotEvidence(e){let t=this.artifactPath($b(Date.now()));try{await this.screenshots.captureToPath(e.targetDeviceId,t)}catch(i){return this.skipBlank(`screenshot failed (${i.message})`)}if(!_l.existsSync(t)||_l.statSync(t).size<=32)return this.skipBlank("screenshot file missing or empty");let n=this.phash.analyzeFile(t);return n?{processAlive:!0,phashBlank:n.isBlank,phash:n.phash,phashHamming:n.hamming,screenshotPath:t}:this.skipBlank("failed to analyze screenshot",t)}skipBlank(e,t){return console.warn(qs(`Smoke: ${e}; blank check skipped.`)),{processAlive:!0,phashBlank:null,screenshotPath:t,screenshotSkipped:!0}}async writeCrashLogFile(e){let t;try{t=await this.hilog.getLatestCrashLog(e.targetDeviceId,e.bundleName)}catch(n){console.warn(qs(`Smoke: crash log query failed (${n.message}).`));return}if(!t?.trim()){console.warn(qs("Smoke: no crash log found on device."));return}try{let n=this.artifactPath(jb(Date.now()));return _l.writeFileSync(n,t,"utf8"),n}catch(n){console.warn(qs(`Smoke: failed to save crash log (${n.message}).`));return}}};var Ll=class{judge(e){if(!e.processAlive)return this.verdict("FAIL_CRASH","Application process died after launch (possible crash).",e);if(e.phashBlank===!0)return this.verdict("FAIL_BLANK",`Blank/solid screen after launch (hamming ${e.phashHamming} \u2264 ${Vf}, hash=${e.phash||"-"}).`,e);let t=e.phashBlank===null?"Process alive; screenshot unavailable, blank check skipped.":"Process alive; screenshot is not a solid blank screen.";return this.verdict("PASS",t,e)}verdict(e,t,n){return{status:e,reason:t,evidence:n,passed:e==="PASS"}}};var Fl=class{inspector;judge=new Ll;formatter=new hl;constructor(e,t,n){let i=n??new de(e);this.inspector=new Ml(e,i,t)}async execute(e){let t=await this.inspector.collect(e),n=this.judge.judge(t);if(n.passed){this.inspector.discardEvidence(t),console.log(this.formatter.formatPass(n));return}throw this.inspector.finalizeRun(),this.formatter.toTraceError(n,e)}};async function qf(r){await new Fl(r.toolProvider,r.projectRoot,r.hdcAdapter).execute(r)}function zf(r){let e=r.indexOf("@"),t=e!==-1?r.substring(0,e):r,n=e!==-1?r.substring(e+1):"default";return{moduleName:t,targetName:n}}async function jl(r,e){let t=await r.listDevices();if(t.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");if(!e&&t.length>1){let i=await r.listDevicesWithName();throw new w("Multiple devices found. Specify a target device using `--device <Name>` or `--device <ID>`.\nAvailable devices:\n"+i.map(o=>` - ${o.name} (${o.serial})`).join(`
76
+ `),"Multiple devices found.")}let n=await r.getDeviceInfo(t,e);if(!n)throw new Error("No active devices found.");if(!e){let i=await r.getDeviceName(n.serial);console.log(`Auto-selected device: ${i} (${n.serial})`)}return n.serial}function Jf(r,e){if(e&&e.length>0)return e;let t=r.profile.modules.filter(n=>{let i=r.getModuleType(n.name);return i==="entry"||i==="feature"||i==="shared"});if(t.length===1){let n=t[0].name;return console.log(`Auto-selected module: ${n}`),[n]}throw new w(`Specify module(s) using --module <name> [<name>...].
77
77
  Available runnable modules:
78
78
  `+t.map(n=>` - ${n.name}`).join(`
79
- `),"Specify module error.")}function Qv(r,e,t){if(t)return t;let n=e.find(({moduleName:o})=>r.getModuleType(o)==="entry");if(n)return r.getMainAbility(n.moduleName);let i=e.find(({moduleName:o})=>r.getModuleType(o)==="feature");if(i)return r.getMainAbility(i.moduleName)}async function eb(r,e,t,n,i,o){if(o&&(console.log(`Uninstalling ${t}...`),await r.uninstallApp(e,t)||console.log(`App ${t} not installed; skipping uninstallation.`)),console.log(`
80
- Installing artifacts to device ${e}...`),await r.installApp(e,n),i){console.log(`Launching ${t}/${i}...`);let s=await r.launchApp(e,t,i);console.log(Ls(`
79
+ `),"Specify module error.")}function qb(r,e,t){if(t)return t;let n=e.find(({moduleName:o})=>r.getModuleType(o)==="entry");if(n)return r.getMainAbility(n.moduleName);let i=e.find(({moduleName:o})=>r.getModuleType(o)==="feature");if(i)return r.getMainAbility(i.moduleName)}async function zb(r,e,t,n,i,o){if(o&&(console.log(`Uninstalling ${t}...`),await r.uninstallApp(e,t)||console.log(`App ${t} not installed; skipping uninstallation.`)),console.log(`
80
+ Installing artifacts to device ${e}...`),await r.installApp(e,n),i){console.log(`Launching ${t}/${i}...`);let s=await r.launchApp(e,t,i);console.log(zs(`
81
81
  Application '${t}': ${s}`))}else console.log(`
82
- Application '${t}' installed successfully (no ability to launch).`)}function aT(r){let e={event:v.CommandExecuted,args:["run",...r.module?["--module"]:[],...r.device?["--device"]:[],...r.product?["--product"]:[],...r.buildMode?["--build-mode"]:[],...r.ability?["--ability"]:[],...r.uninstall?["--uninstall"]:[],...r.skipBuild?["--skip-build"]:[],...r.apply?["--apply"]:[],...r.hotreload?["--hotreload"]:[],...r.hotreloadApply?["--hotreload-apply"]:[]]};return r.buildMode&&(e.build_mode=r.buildMode),r.module&&(e.module_count=r.module.length),e}var cT=new oT("run").description("Build and run the project on a connected device").option("--module <modules...>","Module(s) to run (format: module or module@target)").option("--device <device>","Target device name or serial").option("--product <product>","Product name (default: default)").option("--build-mode <mode>","Build mode (options: debug, release; default: debug)").option("--ability <ability>","Ability name to launch").option("--uninstall","Uninstall existing app before installation").option("--skip-build","Skip build step and deploy existing artifacts").option("--apply <fileName>","Quick-apply changed files via quickfix (incremental hqf) and restart. <fileName> under project .hvigor/").option("--hotreload [action]",'Start hot-reload mode (build+deploy with daemon, then exit). Use "stop" to shut down the hvigor daemon.').option("--hotreload-apply <fileName>","Hot-reload changed files (.hvigor/<fileName> list) via daemon hot compile + signed hqf + quickfix, without restarting the app.").action(async r=>{let e=aT(r),t=Date.now(),n=!0,i=null;try{let o=await dT(r,e);o&&(o.ohpmMemoryMb&&(e.ohpm_install_memory=o.ohpmMemoryMb),o.syncMemoryMb&&(e.hvigor_sync_memory=o.syncMemoryMb),o.buildMemoryMb&&(e.hvigor_build_memory=o.buildMemoryMb))}catch(o){n=!1,i=X(o),console.error(sT(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(e,o)}});async function lT(r,e,t,n,i){let o=new zi(e,r.rootDir),s=new gt(e,r.rootDir),a=new Set;for(let{moduleName:y,targetName:E}of t)for(let j of r.collectNonHarDependentModuleList(y))a.add(`${j}@${E}`);let c=[...a],l=Fp(r,c),d={type:"modules",modulesToBuild:c,moduleTasks:l},g=await xr(r.rootDir,()=>(cr.removeAll(r),jp(o,s,n,i,d,r.rootDir)),()=>console.log("Another build is already running for this project. Waiting for completion..."));return console.log(`
83
- `+Ls("Build completed successfully.")),g}async function dT(r,e){let t=W.discover(process.cwd());await rt.warnInvalidBundledLinks(t.rootDir),console.warn(bl("Ensure the project source is trusted before proceeding."));let n=await C.new();if(r.skipBuild||n.assertJava(),e.bundle_name=t.getBundleName(),r.hotreloadApply){await mT(r,t,n);return}if(r.hotreload){await pT(r,t,n);return}if(r.apply){await gT(r,t,n);return}return tb(r,t,n)}async function uT(r,e,t){r.onSocketDisconnect(()=>{console.log("Daemon disconnected (likely via --hotreload stop). Exiting watch session."),process.exit(0)});let n=new gt(e,t.rootDir),i=setInterval(async()=>{await n.isDaemonAlive()||(clearInterval(i),console.log("Daemon stopped (via --hotreload stop). Exiting watch session."),process.exit(0))},3e3);await new Promise(()=>{})}async function pT(r,e,t){if(r.hotreload==="stop"){await Hw(t,e);return}let i=hm(e,r.module).map(gm),{moduleName:o,targetName:s}=i[0];zp(r.module,o);let a=new le(t),c=ce.from(t),l=await Sl(c,r.device),d=l.includes("127.0.0.1")||l.includes("localhost"),g=r.product||"default";e.validateProduct(g);let y=e.getBundleName(g),E=Qv(e,i,r.ability);zc.generate(e.rootDir,o,g,t);let j=new gt(t,e.rootDir);console.log(Ls("Ensuring hvigor daemon is running (via --sync --daemon, no hap build)...")),await j.ensureDaemonRunning();let ye=[`${o}@${g}`];for(let Un of e.collectNonHarDependentModuleList(o))ye.includes(`${Un}@${g}`)||ye.push(`${Un}@${g}`);console.log(Ls("Building hap + starting watch session (socket -> CommonBuild assembleHap --hot-reload-build --watch, kept open)..."));let ut=new to(e.rootDir,t);await ut.startWatchSession({moduleSpecs:ye,productName:g});let er=jw(e,o,s,d,g);await eb(a,l,y,er,E,!!r.uninstall),console.log(Ls("Hot-reload watch session active (socket persistent). Edit code, write .hvigor/<file>, then `devecocli run --hotreload-apply <file>` in another terminal. Ctrl+C here to stop.")),await uT(ut,t,e)}async function mT(r,e,t){let n=r.hotreloadApply;if(!n)throw new Error("hotreload-apply requires --hotreload-apply <fileName> (under .hvigor/)");if(_s.basename(n)!==n)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${n}`);let i=hm(e,r.module),{moduleName:o}=gm(i[0]);zp(r.module,o);let s=ce.from(t),a=await Sl(s,r.device),c=r.product||"default";e.validateProduct(c);let l=e.getBundleName(c);Fw(e,o,n);let d=[`${o}@${c}`],g=await $w({applyFileName:n,projectPath:e.rootDir,moduleName:o,productName:c,bundleName:l,toolProvider:t,targetDeviceId:a,moduleSpecs:d});if(!g.success)throw new Error(g.message)}function fT(r,e,t,n){let i=new Set;for(let{moduleName:o,targetName:s}of e)for(let a of r.collectNonHarDependentModuleList(o)){i.add(r.findArtifactPath(a,s,t,n));for(let c of r.findRemoteHspPaths(a,s,n))i.add(c)}return[...i]}async function tb(r,e,t){let i=hm(e,r.module).map(gm);for(let{moduleName:ye}of i){let ut=e.getModuleType(ye);if(ut!=="entry"&&ut!=="feature"&&ut!=="shared")throw new w(`Module '${ye}' '${ut}' is not runnable. Specify an entry or feature module.`,"Module is not runnable.")}let o=new le(t),s=ce.from(t),a=await Sl(s,r.device),c=a.includes("127.0.0.1")||a.includes("localhost"),l=r.product||"default";e.validateProduct(l);let d=r.buildMode||"debug",g;r.skipBuild||(g=await lT(e,t,i,l,d));let y=fT(e,i,c,l),E=e.getBundleName(l),j=Qv(e,i,r.ability);return await eb(o,a,E,y,j,!!r.uninstall),j&&await fm({toolProvider:t,projectRoot:e.rootDir,hdcAdapter:o,targetDeviceId:a,bundleName:E}),g}async function gT(r,e,t){let n=r.apply;if(!n)throw new Error("apply requires --apply <fileName> (under .hvigor/)");if(_s.basename(n)!==n)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${n}`);let i=_s.join(e.rootDir,".hvigor",n),o=ce.from(t),s=await Sl(o,r.device),a=r.product||"default";e.validateProduct(a);let c=e.getBundleName(a),l=e.profile.modules.find(y=>e.getModuleType(y.name)==="entry")?.name,d=l?e.getMainAbility(l,r.ability):r.ability||"EntryAbility",g=new qc(t,e.rootDir);try{await g.execute({applyFile:i,productName:a,targetDeviceId:s,bundleName:c,abilityName:d})}catch(y){console.warn(bl(`[Apply] failed: ${y.message}`)),console.warn(bl('[Apply] Falling back to full "devecocli run"...')),await tb(r,e,t);return}console.log(bl('[Apply] Done. If changes did not take effect, run "devecocli run" for a full build.')),await fm({toolProvider:t,projectRoot:e.rootDir,targetDeviceId:s,bundleName:c})}var rb=cT;import{Command as RT}from"commander";import*as bm from"path";import{red as ob,cyan as kl,yellow as wm}from"colorette";import{execa as Dl}from"execa";import{execa as hT}from"execa";function ai(r){return Array.isArray(r)?r[0]:r}async function lo(r){let e=rn();m(`Executing: npm view ${Dr}@${e} --json`);let{stdout:t}=await hT("npm",["view",`${Dr}@${e}`,"--json"]),n=ai(JSON.parse(t)),i=typeof n.version=="string"?n.version.trim():n["dist-tags"]?.[e]?.trim();if(!i)throw new Error(`Could not resolve version for ${Dr}@${e}`);let o=n.versions?.[i],s=n.dist??o?.dist;if(!s)throw new Error(`Could not resolve dist for ${Dr}@${e}`);let a=n.apiVersion??o?.apiVersion??0,c={version:i,apiVersion:a,dist:s};return c.apiVersion<=r?{latest:c,compatible:c}:{latest:c,compatible:null}}import{execa as ib}from"execa";import*as Wt from"path";import*as he from"fs/promises";import*as nb from"crypto";function El(r,e){let t=e.indexOf("-");if(t<0)return!1;let n=e.slice(0,t),i=e.slice(t+1);if(n!=="sha512")return!1;let o=Buffer.from(i,"base64");return nb.createHash(n).update(r).digest().equals(o)}async function yT(r,e){let t=`${r}.tmp.${process.pid}`;await he.writeFile(t,JSON.stringify(e,null,2),"utf-8"),await he.rename(t,r)}async function wT(r,e,t){m(`Executing: npm pack ${Dr}@${r}`);let{stdout:n}=await ib("npm",["pack",`${Dr}@${r}`],{cwd:t}),i=n.trim().split(`
84
- `).pop(),o=Wt.join(t,i),s=await he.readFile(o);if(!El(s,e))throw await he.unlink(o).catch(()=>{}),new Error("Documentation package integrity verification failed");return o}async function vT(r,e,t){let n=Wt.join(t,e),i=Wt.join(t,`.tmp-${e}-${process.pid}`);return await he.rm(n,{recursive:!0,force:!0}),await he.rm(i,{recursive:!0,force:!0}),await he.mkdir(i,{recursive:!0}),m(`Executing: tar -xzf ${Wt.basename(r)} -C ${i}`),await ib("tar",["-xzf",r,"-C",i]),await he.rename(Wt.join(i,"package"),n),await he.rm(i,{recursive:!0,force:!0}),await he.unlink(r).catch(()=>{}),await he.access(Wt.join(n,"dist","engine","index.js")),await he.access(Wt.join(n,"docs.zip")),await he.access(Wt.join(n,"index.zip")),n}async function Pl(r,e,t){await he.mkdir(e,{recursive:!0});let n=await wT(r.version,r.dist.integrity,e);return await vT(n,r.version,e),await yT(Wt.join(e,"current.json"),{version:r.version,apiVersion:r.apiVersion,installedAt:Date.now(),installedBy:t}),{version:r.version,apiVersion:r.apiVersion}}import*as Cl from"fs";import*as uo from"path";import{execa as bT}from"execa";import{yellow as ST}from"colorette";function ET(r){return r?r.endsWith(".ts"):!0}function PT(r,e){let t=uo.join(r,"package.json");try{return JSON.parse(Cl.readFileSync(t,"utf8")).name===e}catch{return!1}}function CT(r,e){let t;try{t=uo.dirname(Cl.realpathSync(r))}catch{return null}for(let n=0;n<20&&t&&t!==uo.dirname(t);n++){if(PT(t,e))return t;t=uo.dirname(t)}return null}async function kT(){try{m("Executing: npm root -g");let{stdout:r}=await bT("npm",["root","-g"]);return r.trim()||null}catch(r){return m(`[install-check] npm root -g failed: ${r instanceof Error?r.message:String(r)}`),null}}function DT(r,e){return op(r,e)}async function ym(r){if(process.env.DEVECO_CLI_SKIP_INSTALL_CHECK)return;let e=process.argv[1];if(ET(e))return;let t=await kT();if(!t)return;let n=CT(e,r);if(!n){m("[install-check] running package root not found, skipping");return}DT(n,t)||(console.log(),console.log(ST(`Warning: devecocli is running from
82
+ Application '${t}' installed successfully (no ability to launch).`)}function jN(r){let e={event:v.CommandExecuted,args:["run",...r.module?["--module"]:[],...r.device?["--device"]:[],...r.product?["--product"]:[],...r.buildMode?["--build-mode"]:[],...r.ability?["--ability"]:[],...r.uninstall?["--uninstall"]:[],...r.skipBuild?["--skip-build"]:[],...r.apply?["--apply"]:[],...r.hotreload?["--hotreload"]:[],...r.hotreloadApply?["--hotreload-apply"]:[]]};return r.buildMode&&(e.build_mode=r.buildMode),r.module&&(e.module_count=r.module.length),e}var HN=new FN("run").description("Build and run the project on a connected device").option("--module <modules...>","Module(s) to run (format: module or module@target)").option("--device <device>","Target device name or serial").option("--product <product>","Product name (default: default)").option("--build-mode <mode>","Build mode (options: debug, release; default: debug)").option("--ability <ability>","Ability name to launch").option("--uninstall","Uninstall existing app before installation").option("--skip-build","Skip build step and deploy existing artifacts").option("--apply <fileName>","Quick-apply changed files via quickfix (incremental hqf) and restart. <fileName> under project .hvigor/").option("--hotreload [action]",'Start hot-reload mode (build+deploy with daemon, then exit). Use "stop" to shut down the hvigor daemon.').option("--hotreload-apply <fileName>","Hot-reload changed files (.hvigor/<fileName> list) via daemon hot compile + signed hqf + quickfix, without restarting the app.").action(async r=>{let e=jN(r),t=Date.now(),n=!0,i=null;try{let o=await BN(r,e);o&&(o.ohpmMemoryMb&&(e.ohpm_install_memory=o.ohpmMemoryMb),o.syncMemoryMb&&(e.hvigor_sync_memory=o.syncMemoryMb),o.buildMemoryMb&&(e.hvigor_build_memory=o.buildMemoryMb))}catch(o){n=!1,i=Z(o),console.error($N(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(e,o)}});async function UN(r,e,t,n,i){let o=new ro(e,r.rootDir),s=new ht(e,r.rootDir),a=new Set;for(let{moduleName:y,targetName:E}of t)for(let K of r.collectNonHarDependentModuleList(y))a.add(`${K}@${E}`);let c=[...a],l=hf(r,c),d={type:"modules",modulesToBuild:c,moduleTasks:l},g=await Nr(r.rootDir,()=>(pr.removeAll(r),yf(o,s,n,i,d,r.rootDir)),()=>console.log("Another build is already running for this project. Waiting for completion..."));return console.log(`
83
+ `+zs("Build completed successfully.")),g}async function BN(r,e){let t=W.discover(process.cwd());await nt.warnInvalidBundledLinks(t.rootDir),console.warn($l("Ensure the project source is trusted before proceeding."));let n=await C.new();if(r.skipBuild||n.assertJava(),e.bundle_name=t.getBundleName(),r.hotreloadApply){await GN(r,t,n);return}if(r.hotreload){await VN(r,t,n);return}if(r.apply){await zN(r,t,n);return}return Jb(r,t,n)}async function WN(r,e,t){r.onSocketDisconnect(()=>{console.log("Daemon disconnected (likely via --hotreload stop). Exiting watch session."),process.exit(0)});let n=new ht(e,t.rootDir),i=setInterval(async()=>{await n.isDaemonAlive()||(clearInterval(i),console.log("Daemon stopped (via --hotreload stop). Exiting watch session."),process.exit(0))},3e3);await new Promise(()=>{})}async function VN(r,e,t){if(r.hotreload==="stop"){await Ov(t,e);return}let i=Jf(e,r.module).map(zf),{moduleName:o,targetName:s}=i[0];kf(r.module,o);let a=new de(t),c=le.from(t),l=await jl(c,r.device),d=l.includes("127.0.0.1")||l.includes("localhost"),g=r.product||"default";e.validateProduct(g);let y=e.getBundleName(g),E=qb(e,i,r.ability);ul.generate(e.rootDir,o,g,t);let K=new ht(t,e.rootDir);console.log(zs("Ensuring hvigor daemon is running (via --sync --daemon, no hap build)...")),await K.ensureDaemonRunning();let we=[`${o}@${g}`];for(let Vn of e.collectNonHarDependentModuleList(o))we.includes(`${Vn}@${g}`)||we.push(`${Vn}@${g}`);console.log(zs("Building hap + starting watch session (socket -> CommonBuild assembleHap --hot-reload-build --watch, kept open)..."));let pt=new uo(e.rootDir,t);await pt.startWatchSession({moduleSpecs:we,productName:g});let ir=Nv(e,o,s,d,g);await zb(a,l,y,ir,E,!!r.uninstall),console.log(zs("Hot-reload watch session active (socket persistent). Edit code, write .hvigor/<file>, then `devecocli run --hotreload-apply <file>` in another terminal. Ctrl+C here to stop.")),await WN(pt,t,e)}async function GN(r,e,t){let n=r.hotreloadApply;if(!n)throw new Error("hotreload-apply requires --hotreload-apply <fileName> (under .hvigor/)");if(Js.basename(n)!==n)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${n}`);let i=Jf(e,r.module),{moduleName:o}=zf(i[0]);kf(r.module,o);let s=le.from(t),a=await jl(s,r.device),c=r.product||"default";e.validateProduct(c);let l=e.getBundleName(c);Tv(e,o,n);let d=[`${o}@${c}`],g=await Av({applyFileName:n,projectPath:e.rootDir,moduleName:o,productName:c,bundleName:l,toolProvider:t,targetDeviceId:a,moduleSpecs:d});if(!g.success)throw new Error(g.message)}function qN(r,e,t,n){let i=new Set;for(let{moduleName:o,targetName:s}of e)for(let a of r.collectNonHarDependentModuleList(o)){i.add(r.findArtifactPath(a,s,t,n));for(let c of r.findRemoteHspPaths(a,s,n))i.add(c)}return[...i]}async function Jb(r,e,t){let i=Jf(e,r.module).map(zf);for(let{moduleName:we}of i){let pt=e.getModuleType(we);if(pt!=="entry"&&pt!=="feature"&&pt!=="shared")throw new w(`Module '${we}' '${pt}' is not runnable. Specify an entry or feature module.`,"Module is not runnable.")}let o=new de(t),s=le.from(t),a=await jl(s,r.device),c=a.includes("127.0.0.1")||a.includes("localhost"),l=r.product||"default";e.validateProduct(l);let d=r.buildMode||"debug",g;r.skipBuild||(g=await UN(e,t,i,l,d));let y=qN(e,i,c,l),E=e.getBundleName(l),K=qb(e,i,r.ability);return await zb(o,a,E,y,K,!!r.uninstall),K&&await qf({toolProvider:t,projectRoot:e.rootDir,hdcAdapter:o,targetDeviceId:a,bundleName:E}),g}async function zN(r,e,t){let n=r.apply;if(!n)throw new Error("apply requires --apply <fileName> (under .hvigor/)");if(Js.basename(n)!==n)throw new Error(`apply file must be a plain file name (under .hvigor/), got: ${n}`);let i=Js.join(e.rootDir,".hvigor",n),o=le.from(t),s=await jl(o,r.device),a=r.product||"default";e.validateProduct(a);let c=e.getBundleName(a),l=e.profile.modules.find(y=>e.getModuleType(y.name)==="entry")?.name,d=l?e.getMainAbility(l,r.ability):r.ability||"EntryAbility",g=new dl(t,e.rootDir);try{await g.execute({applyFile:i,productName:a,targetDeviceId:s,bundleName:c,abilityName:d})}catch(y){console.warn($l(`[Apply] failed: ${y.message}`)),console.warn($l('[Apply] Falling back to full "devecocli run"...')),await Jb(r,e,t);return}console.log($l('[Apply] Done. If changes did not take effect, run "devecocli run" for a full build.')),await qf({toolProvider:t,projectRoot:e.rootDir,targetDeviceId:s,bundleName:c})}var Kb=HN;import{Command as oO}from"commander";import*as Zf from"path";import{red as Zb,cyan as Wl,yellow as Yf}from"colorette";import{execa as Vl}from"execa";import{execa as JN}from"execa";function ui(r){return Array.isArray(r)?r[0]:r}async function vo(r){let e=sn();f(`Executing: npm view ${Ut}@${e} --json`);let{stdout:t}=await JN("npm",["view",`${Ut}@${e}`,"--json"]),n=ui(JSON.parse(t)),i=typeof n.version=="string"?n.version.trim():n["dist-tags"]?.[e]?.trim();if(!i)throw new Error(`Could not resolve version for ${Ut}@${e}`);let o=n.versions?.[i],s=n.dist??o?.dist;if(!s)throw new Error(`Could not resolve dist for ${Ut}@${e}`);let a=n.apiVersion??o?.apiVersion??0,c={version:i,apiVersion:a,dist:s};return c.apiVersion<=r?{latest:c,compatible:c}:{latest:c,compatible:null}}import{execa as Xb}from"execa";import*as qt from"path";import*as ye from"fs/promises";import*as Yb from"crypto";function Hl(r,e){let t=e.indexOf("-");if(t<0)return!1;let n=e.slice(0,t),i=e.slice(t+1);if(n!=="sha512")return!1;let o=Buffer.from(i,"base64");return Yb.createHash(n).update(r).digest().equals(o)}async function KN(r,e){let t=`${r}.tmp.${process.pid}`;await ye.writeFile(t,JSON.stringify(e,null,2),"utf-8"),await ye.rename(t,r)}async function YN(r,e,t){f(`Executing: npm pack ${Ut}@${r}`);let{stdout:n}=await Xb("npm",["pack",`${Ut}@${r}`],{cwd:t}),i=n.trim().split(`
84
+ `).pop(),o=qt.join(t,i),s=await ye.readFile(o);if(!Hl(s,e))throw await ye.unlink(o).catch(()=>{}),new Error("Documentation package integrity verification failed");return o}async function XN(r,e,t){let n=qt.join(t,e),i=qt.join(t,`.tmp-${e}-${process.pid}`);return await ye.rm(n,{recursive:!0,force:!0}),await ye.rm(i,{recursive:!0,force:!0}),await ye.mkdir(i,{recursive:!0}),f(`Executing: tar -xzf ${qt.basename(r)} -C ${i}`),await Xb("tar",["-xzf",r,"-C",i]),await ye.rename(qt.join(i,"package"),n),await ye.rm(i,{recursive:!0,force:!0}),await ye.unlink(r).catch(()=>{}),await ye.access(qt.join(n,"dist","engine","index.js")),await ye.access(qt.join(n,"docs.zip")),await ye.access(qt.join(n,"index.zip")),n}async function Ul(r,e,t){await ye.mkdir(e,{recursive:!0});let n=await YN(r.version,r.dist.integrity,e);return await XN(n,r.version,e),await KN(qt.join(e,"current.json"),{version:r.version,apiVersion:r.apiVersion,installedAt:Date.now(),installedBy:t}),{version:r.version,apiVersion:r.apiVersion}}import*as Bl from"fs";import*as bo from"path";import{execa as ZN}from"execa";import{yellow as QN}from"colorette";function eO(r){return r?r.endsWith(".ts"):!0}function tO(r,e){let t=bo.join(r,"package.json");try{return JSON.parse(Bl.readFileSync(t,"utf8")).name===e}catch{return!1}}function rO(r,e){let t;try{t=bo.dirname(Bl.realpathSync(r))}catch{return null}for(let n=0;n<20&&t&&t!==bo.dirname(t);n++){if(tO(t,e))return t;t=bo.dirname(t)}return null}async function nO(){try{f("Executing: npm root -g");let{stdout:r}=await ZN("npm",["root","-g"]);return r.trim()||null}catch(r){return f(`[install-check] npm root -g failed: ${r instanceof Error?r.message:String(r)}`),null}}function iO(r,e){return Lp(r,e)}async function Kf(r){if(process.env.DEVECO_CLI_SKIP_INSTALL_CHECK)return;let e=process.argv[1];if(eO(e))return;let t=await nO();if(!t)return;let n=rO(e,r);if(!n){f("[install-check] running package root not found, skipping");return}iO(n,t)||(console.log(),console.log(QN(`Warning: devecocli is running from
85
85
  ${n}
86
86
  but \`npm\` in PATH installs global packages to
87
87
  ${t}
88
88
  The devecocli binary in PATH does not match the npm that \`devecocli update\` uses.
89
89
  The update would land in the wrong place and would not reach the binary you are running.
90
90
  Continuing with update \u2014 abort if this is unexpected.
91
- Fix: run \`which -a devecocli\` (Windows: \`where devecocli\`) to list all shims, remove the stale one, or reinstall with the matching npm: \`npm install -g ${r}@latest\`.`)))}var Sm=new RT("update").description("Update deveco-cli to latest");Sm.command("_check",{hidden:!0}).action(async()=>{let r=Date.now(),e=new nn(bm.join($(),"update"));try{let t=rn(),n=Fi();m(`Executing: npm view ${n}@${t} --json`);let{stdout:i}=await Dl("npm",["view",`${n}@${t}`,"--json"]),{latestVersion:o,blockedVersions:s}=AT(i,t),a=await xT().catch(c=>{m(`Docs version check failed: ${c instanceof Error?c.message:String(c)}`)});await e.writeSuccess(o,s,ar(),t,a),await sb(r,!0,null)}catch(t){await e.writeError(t instanceof Error?t.message:String(t));let n=t,i=n.code??n.name??"UnknownError";await sb(r,!1,i)}});async function xT(){let r=Ft(),{latest:e,compatible:t}=await lo(r);return{latestDocsVersion:e.version,latestDocsApiVersion:e.apiVersion,latestCompatibleDocsVersion:t?.version??null,checkedAgainstDocsApi:r}}function AT(r,e){let t=ai(JSON.parse(r)),n=null;typeof t.version=="string"?n=t.version.trim():t["dist-tags"]?.[e]&&(n=t["dist-tags"][e].trim());let i=[];return Array.isArray(t.blockedVersions)?i=t.blockedVersions:n&&t.versions?.[n]?.blockedVersions&&(i=t.versions[n].blockedVersions),{latestVersion:n,blockedVersions:i}}var IT={event:v.CommandExecuted,args:["update"]},TT={event:v.CommandExecuted,args:["update","_check"]};async function vm(r,e,t){let n={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(IT,n).catch(()=>{})}async function sb(r,e,t){let n={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(TT,n).catch(()=>{})}async function OT(r,e,t){let n=t,i=n.code??n.name??"UnknownError";console.error(ob(`Failed to update ${r}`)),n.message&&console.error(ob(n.message)),await vm(e,!1,i),process.exit(1)}Sm.action(async()=>{if(ji()==="all")throw new Error("devecocli update is disabled (DEVECO_CLI_DISABLE_UPDATE=all).");await ym(Fi());let r=Date.now(),e=ar(),t=rn(),n=Fi();console.log(kl("Checking for updates..."));try{let{stdout:i}=await Dl("npm",["view",n,`dist-tags.${t}`]),o=i.trim();if(!o||o===e){console.log(wm(`
92
- ${n} is already up to date (v${e}, tag: ${t})`)),await vm(r,!0,null);return}console.log(kl(`
93
- New version found: ${o} (current: ${e})`)),console.log(kl(`Updating ${n}...`)),await Dl("npm",["install","-g",`${n}@${t}`],{stdio:"inherit"}),console.log(wm(`
94
- CLI successfully updated to ${o}`)),await NT(o).catch(s=>{m(`Docs auto-sync failed: ${s instanceof Error?s.message:String(s)}`)}),await vm(r,!0,null)}catch(i){await OT(n,r,i)}});async function NT(r){let e=Fi();m(`Executing: npm view ${e}@${r} --json`);let{stdout:t}=await Dl("npm",["view",`${e}@${r}`,"--json"]),n=ai(JSON.parse(t)),i=typeof n.supportedDocsApi=="number"?n.supportedDocsApi:Ft(),{compatible:o}=await lo(i);if(!o){m("Docs auto-sync: no compatible docs version found, skipping");return}let s=bm.join($(),"doc-data"),a=await Ui();(!a||Pt(o.version,a)>0)&&await Pl({version:o.version,apiVersion:o.apiVersion,dist:o.dist},s,"cli-update"),console.log(wm(`Docs has been automatically synced to the compatible version ${o.version}`));let c=await lo(i).catch(()=>null);c?.compatible&&Pt(c.compatible.version,o.version)>0&&console.log(kl(`New docs version ${c.compatible.version} available, run \`devecocli docs update\` to upgrade`))}var ab=Sm;import{Command as mM,Option as Yb}from"commander";import{execa as Rl}from"execa";function Fe(r){return r.normalize("NFKC").replace(/\s+/g," ").trim()}function cb(r){let e=r.normalize("NFKC").match(/\((\d+)(?:\.\d+)*\)/)?.[1];return e!==void 0&&Number(e)>=26}import{spawn as MT}from"child_process";var LT=2500;function _T(r,e,t,n,i,o){r.once("exit",s=>{if(o())return;clearTimeout(e);let a=t();s===0||s===null?n():i(a||`Emulator process exited with code ${s}`)})}function $T(r,e,t,n){let i=!1,o=()=>i,s=()=>Buffer.concat(e).toString("utf8").trim(),a=()=>{i||(i=!0,clearTimeout(l),r.removeAllListeners(),r.stderr?.removeAllListeners(),r.stderr?.destroy(),r.unref(),t())},c=d=>{if(!i){i=!0,clearTimeout(l),r.removeAllListeners(),r.stderr?.removeAllListeners();try{r.kill()}catch{}n(new Error(d))}},l=setTimeout(a,LT);r.once("error",d=>c(d.message)),_T(r,l,s,a,c,o)}function lb(r,e,t){m(`Spawning emulator: ${r} ${t.join(" ")}`);let n=[],i=MT(r,t,{detached:!0,stdio:["ignore","ignore","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},windowsHide:!0});i.stderr?.on("data",a=>n.push(a));let o=i.pid!==void 0&&!Qe()?qi(i.pid,500,!0):void 0,s=new Promise((a,c)=>{$T(i,n,a,c)});return{pid:i.pid,started:s,tracker:o}}import*as po from"path";function FT(r){let e=new Set,t=[];for(let n of r){let i=JSON.stringify(n);e.has(i)||(e.add(i),t.push(n))}return t}function jT(r){let e=r.instancePath?.trim();if(e)return po.dirname(po.normalize(e)).replace(/\\/g,"/");let t=r.path?.trim();return t?po.dirname(po.normalize(t)).replace(/\\/g,"/"):""}function HT(r){let e=[];return r&&e.push(["-imageRoot",r]),e.push([]),e}function db(r,e,t){let n=[...r],i=t?.bootMode??e;return i&&n.push("-bootmode",i),t?.hdcPort!==void 0&&n.push("-hdcport",String(t.hdcPort)),t?.noWindow&&n.push("-noWindow"),n}function UT(r,e,t,n){let i=[db(["-start",r],t,n)],o=jT(e);if(o)for(let s of HT(e.imageRoot))i.push(db(["-hvd",r,"-path",o,...s],t,n));return FT(i)}async function ub(r,e,t,n,i){let o=new Error("No start strategy ran"),s=UT(r,e,n,i);for(let a of s){let c;try{return c=t(a),await c.started,{ok:!0,args:a,tracker:c.tracker}}catch(l){if(c?.tracker)try{await c.tracker.stop()}catch{}o=l}}return{ok:!1,lastError:o}}function BT(r){let e=r.normalize("NFKC").match(/^\s*chargingStatus\s*:\s*(\d+)\s*$/im);if(!e)return;let t=Number(e[1]);if(t===1||t===3)return!0;if(t===0||t===2)return!1}async function Em(r){return(await ce.withHdcPath(r).listDevices()).map(t=>t.serial).filter(dr)}async function Pm(r){let e=await Em(r);return e.length===0?[]:(await Promise.all(e.map(n=>Gc(r,n,"ohos.qemu.hvd.name")))).filter(n=>!!n)}async function pb(r,e){return(await Pm(r)).includes(e)}async function mb(r,e){let t=await ce.withHdcPath(r).listDevicesWithName(),n=e.normalize("NFKC").replace(/\s+/g," ").trim(),i=t.find(a=>a.name.normalize("NFKC").replace(/\s+/g," ").trim()===n);if(!i||!dr(i.serial))throw new Error(`Cannot resolve the running emulator serial for "${e}".`);let o=["-t",i.serial,"shell","hidumper","-s","3302","-a","-i"];m(`Executing: ${r} ${o.join(" ")}`);let s=await k(r,o);if(s.exitCode===0){let a=BT(s.stdout);if(a!==void 0)return a}throw new Error(`Cannot determine the battery charging state for emulator "${e}".`)}import*as fo from"path";import{existsSync as WT,statSync as VT}from"fs";function mo(r,e){for(let t of e){let n=r[t];if(typeof n=="string"&&n.trim())return n.trim()}return""}function GT(r){let e=mo(r,["instancePath","instance_path","InstancePath","instancepath","instanceDir","instance_dir","InstanceDir","deployPath","deploy_path","deployedPath","deployed_path","workPath","work_path","dataPath","data_path"]);if(e)return e;for(let[t,n]of Object.entries(r)){if(typeof n!="string"||!n.trim())continue;let i=t.toLowerCase();if(i.includes("instance")&&(i.includes("path")||i.includes("dir"))||i==="deployedpath")return n.trim()}return""}function qT(r){return mo(r,["uuid","UUID","Uuid","instanceUuid","instance_uuid","InstanceUuid"])}function zT(r,e){for(let t of e){let n=r[t];if(!(n==null||n===""))return n===!0||String(n).toLowerCase()==="true"}}function JT(r){let e=r.find(n=>n.instancePath?.trim());if(!e?.instancePath?.trim())return;let t=fo.dirname(fo.normalize(e.instancePath));for(let n of r){if(n.instancePath?.trim())continue;let i=P.ensurePathWithinRoot(t,fo.join(t,n.name));WT(i)&&VT(i).isDirectory()&&(n.instancePath=i.replace(/\\/g,"/"))}}function YT(r){try{let e=JSON.parse(r);return Array.isArray(e)?e.map(t=>{let n=qT(t),i=mo(t,["deviceType","DeviceType","devicetype"]),o=mo(t,["os.osVersion","osVersion","OsVersion","OSVersion"]);return{name:t.name||t.Name||"",isRunning:t.isRunning===!0||String(t.isRunning).toLowerCase()==="true",instancePath:GT(t),path:mo(t,["path","Path","hvdPath","hvd_path"]),imageRoot:mo(t,["imageRoot","image_root","ImageRoot"]),uuid:n||void 0,deviceType:i||void 0,osVersion:o||void 0,hotBoot:zT(t,["isHotBoot","ishotboot","hotBoot"])}}).filter(t=>t.name):null}catch{return null}}function KT(r){let e=[],t=/^(name|isrunning|ishotboot|instancepath|path|imageroot|devicetype|os\.osversion)\s*:\s*(.+)/gim,n=null,i;for(;(i=t.exec(r))!==null;){let[,o,s]=i;if(o.toLowerCase()==="name")n&&e.push(n),n={name:s.trim()};else if(n){let a=o.toLowerCase();a==="isrunning"?n.isRunning=s.trim().toLowerCase()==="true":a==="ishotboot"?n.hotBoot=s.trim().toLowerCase()==="true":a==="instancepath"?n.instancePath=s.trim():a==="path"?n.path=s.trim():a==="imageroot"?n.imageRoot=s.trim():a==="devicetype"?n.deviceType=s.trim():a==="os.osversion"&&(n.osVersion=s.trim())}}return n&&e.push(n),e}function fb(r){let t=YT(r)??KT(r);return JT(t),t}function Cm(r,e){for(let t of e){let n=r[t];if(typeof n=="string"&&n.trim())return n.trim()}return""}function XT(r){let e=r.downloaded??r.Downloaded;return e===!0||String(e).toLowerCase()==="true"}function ZT(r){let e=Cm(r,["osVersion","OsVersion","OSVersion"]),t=Cm(r,["SoftWareVersion","SoftwareVersion","softwareVersion"]),n=Cm(r,["deviceType","DeviceType"]);return!e&&!t?null:{osVersion:e,softwareVersion:t,deviceType:n}}function gb(r,e=()=>!0){let t=r.trim();if(!t)return[];try{let n=JSON.parse(t);if(!Array.isArray(n))return[];let i=[];for(let o of n){if(!o||typeof o!="object")continue;let s=o;if(!e(s))continue;let a=ZT(s);a&&i.push(a)}return i}catch{return[]}}function hb(r){return gb(r)}function yb(r){return gb(r,XT)}var wb=/no images are available/i,QT=/Scenario simulation failed\s*[::]/i,eO="7.0.0";function Fr(r){return r.normalize("NFKC").trim().toLowerCase()}function tO(r){let e=r.message||"";return wb.test(e)}function rO(r){return r.normalize("NFKC").match(/(\d+(?:\.\d+){1,3})/)?.[1]}function $s(r,e){return`${r} ${e.join(" ")}`.trim()}function nO(r){switch(r.type){case"gps":return`${r.type}:${r.key}=${r.value}`;case"sensor":return`${r.type}:${r.key}=${r.value}`;case"rotation":case"volume":return`${r.type}:${r.direction}`;case"folded-state":return`${r.type}:${r.state}`;case"battery":return`${r.type}:${r.level}`;case"battery-status":return`${r.type}:${r.status}`;default:return r.type}}var go=class r{static supportedControlPaths=new Set;emulatorPath;sdkPath;hdcPath;constructor(e,t,n){this.emulatorPath=e,this.sdkPath=t,this.hdcPath=n}static from(e){return new r(e.emulatorPath,e.sdkPath,e.hdcPath)}async executeEmulator(e){return m(`Executing: ${$s(this.emulatorPath,e)}`),Rl(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath}})}executeEmulatorDetached(e){return lb(this.emulatorPath,this.sdkPath,e)}async listEmulators(e){let t=["-list","-details"];e!==void 0&&t.push("-instancePath",e);let{stdout:n}=await this.executeEmulator(t);return fb(n)}async listEmulatorDetails(){let{stdout:e}=await this.executeEmulator(["-list","-details"]);return e}async getDeviceTypeByName(){let e=new Map;try{let t=await this.listEmulators();for(let n of t)n.name&&n.deviceType&&e.set(Fe(n.name),n.deviceType)}catch{}return e}async startEmulator(e,t){let n=await this.listEmulators(),i=Fe(e),o=n.find(c=>Fe(c.name)===i);if(!o)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let s=o.name;if(await this.isAlreadyRunning(s,o))return{status:"already-running"};let a=await ub(s,o,c=>this.executeEmulatorDetached(c),o.hotBoot===!1?"coldboot":"snapshot",t);if(a.ok)return{status:"started",args:a.args,tracker:a.tracker};if(await this.isAlreadyRunning(s))return{status:"already-running"};throw new w(`Unable to start emulator "${e}". All methods failed.
91
+ Fix: run \`which -a devecocli\` (Windows: \`where devecocli\`) to list all shims, remove the stale one, or reinstall with the matching npm: \`npm install -g ${r}@latest\`.`)))}var Qf=new oO("update").description("Update deveco-cli to latest");Qf.command("_check",{hidden:!0}).action(async()=>{let r=Date.now(),e=new an(Zf.join($(),"update"));try{let t=sn(),n=zi();f(`Executing: npm view ${n}@${t} --json`);let{stdout:i}=await Vl("npm",["view",`${n}@${t}`,"--json"]),{latestVersion:o,blockedVersions:s}=aO(i,t),a=await sO().catch(c=>{f(`Docs version check failed: ${c instanceof Error?c.message:String(c)}`)});await e.writeSuccess(o,s,ur(),t,a),await Qb(r,!0,null)}catch(t){await e.writeError(t instanceof Error?t.message:String(t));let n=t,i=n.code??n.name??"UnknownError";await Qb(r,!1,i)}});async function sO(){let r=Ht(),{latest:e,compatible:t}=await vo(r);return{latestDocsVersion:e.version,latestDocsApiVersion:e.apiVersion,latestCompatibleDocsVersion:t?.version??null,checkedAgainstDocsApi:r}}function aO(r,e){let t=ui(JSON.parse(r)),n=null;typeof t.version=="string"?n=t.version.trim():t["dist-tags"]?.[e]&&(n=t["dist-tags"][e].trim());let i=[];return Array.isArray(t.blockedVersions)?i=t.blockedVersions:n&&t.versions?.[n]?.blockedVersions&&(i=t.versions[n].blockedVersions),{latestVersion:n,blockedVersions:i}}var cO={event:v.CommandExecuted,args:["update"]},lO={event:v.CommandExecuted,args:["update","_check"]};async function Xf(r,e,t){let n={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(cO,n).catch(()=>{})}async function Qb(r,e,t){let n={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(lO,n).catch(()=>{})}async function dO(r,e,t){let n=t,i=n.code??n.name??"UnknownError";console.error(Zb(`Failed to update ${r}`)),n.message&&console.error(Zb(n.message)),await Xf(e,!1,i),process.exit(1)}Qf.action(async()=>{if(Ji()==="all")throw new Error("devecocli update is disabled (DEVECO_CLI_DISABLE_UPDATE=all).");await Kf(zi());let r=Date.now(),e=ur(),t=sn(),n=zi();console.log(Wl("Checking for updates..."));try{let{stdout:i}=await Vl("npm",["view",n,`dist-tags.${t}`]),o=i.trim();if(!o||o===e){console.log(Yf(`
92
+ ${n} is already up to date (v${e}, tag: ${t})`)),await Xf(r,!0,null);return}console.log(Wl(`
93
+ New version found: ${o} (current: ${e})`)),console.log(Wl(`Updating ${n}...`)),await Vl("npm",["install","-g",`${n}@${t}`],{stdio:"inherit"}),console.log(Yf(`
94
+ CLI successfully updated to ${o}`)),await uO(o).catch(s=>{f(`Docs auto-sync failed: ${s instanceof Error?s.message:String(s)}`)}),await Xf(r,!0,null)}catch(i){await dO(n,r,i)}});async function uO(r){let e=zi();f(`Executing: npm view ${e}@${r} --json`);let{stdout:t}=await Vl("npm",["view",`${e}@${r}`,"--json"]),n=ui(JSON.parse(t)),i=typeof n.supportedDocsApi=="number"?n.supportedDocsApi:Ht(),{compatible:o}=await vo(i);if(!o){f("Docs auto-sync: no compatible docs version found, skipping");return}let s=Zf.join($(),"doc-data"),a=await Yi();(!a||Ct(o.version,a)>0)&&await Ul({version:o.version,apiVersion:o.apiVersion,dist:o.dist},s,"cli-update"),console.log(Yf(`Docs has been automatically synced to the compatible version ${o.version}`));let c=await vo(i).catch(()=>null);c?.compatible&&Ct(c.compatible.version,o.version)>0&&console.log(Wl(`New docs version ${c.compatible.version} available, run \`devecocli docs update\` to upgrade`))}var eS=Qf;import{Command as GM,Option as BS}from"commander";import{execa as Gl}from"execa";function je(r){return r.normalize("NFKC").replace(/\s+/g," ").trim()}function tS(r){let e=r.normalize("NFKC").match(/\((\d+)(?:\.\d+)*\)/)?.[1];return e!==void 0&&Number(e)>=26}import{spawn as pO}from"child_process";var fO=2500;function mO(r,e,t,n,i,o){r.once("exit",s=>{if(o())return;clearTimeout(e);let a=t();s===0||s===null?n():i(a||`Emulator process exited with code ${s}`)})}function gO(r,e,t,n){let i=!1,o=()=>i,s=()=>Buffer.concat(e).toString("utf8").trim(),a=()=>{i||(i=!0,clearTimeout(l),r.removeAllListeners(),r.stderr?.removeAllListeners(),r.stderr?.destroy(),r.unref(),t())},c=d=>{if(!i){i=!0,clearTimeout(l),r.removeAllListeners(),r.stderr?.removeAllListeners();try{r.kill()}catch{}n(new Error(d))}},l=setTimeout(a,fO);r.once("error",d=>c(d.message)),mO(r,l,s,a,c,o)}function rS(r,e,t){f(`Spawning emulator: ${r} ${t.join(" ")}`);let n=[],i=pO(r,t,{detached:!0,stdio:["ignore","ignore","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},windowsHide:!0});i.stderr?.on("data",a=>n.push(a));let o=i.pid!==void 0&&!et()?to(i.pid,500,!0):void 0,s=new Promise((a,c)=>{gO(i,n,a,c)});return{pid:i.pid,started:s,tracker:o}}import*as So from"path";function hO(r){let e=new Set,t=[];for(let n of r){let i=JSON.stringify(n);e.has(i)||(e.add(i),t.push(n))}return t}function yO(r){let e=r.instancePath?.trim();if(e)return So.dirname(So.normalize(e)).replace(/\\/g,"/");let t=r.path?.trim();return t?So.dirname(So.normalize(t)).replace(/\\/g,"/"):""}function wO(r){let e=[];return r&&e.push(["-imageRoot",r]),e.push([]),e}function nS(r,e,t){let n=[...r],i=t?.bootMode??e;return i&&n.push("-bootmode",i),t?.hdcPort!==void 0&&n.push("-hdcport",String(t.hdcPort)),t?.noWindow&&n.push("-noWindow"),n}function vO(r,e,t,n){let i=[nS(["-start",r],t,n)],o=yO(e);if(o)for(let s of wO(e.imageRoot))i.push(nS(["-hvd",r,"-path",o,...s],t,n));return hO(i)}async function iS(r,e,t,n,i){let o=new Error("No start strategy ran"),s=vO(r,e,n,i);for(let a of s){let c;try{return c=t(a),await c.started,{ok:!0,args:a,tracker:c.tracker}}catch(l){if(c?.tracker)try{await c.tracker.stop()}catch{}o=l}}return{ok:!1,lastError:o}}function bO(r){let e=r.normalize("NFKC").match(/^\s*chargingStatus\s*:\s*(\d+)\s*$/im);if(!e)return;let t=Number(e[1]);if(t===1||t===3)return!0;if(t===0||t===2)return!1}async function em(r){return(await le.withHdcPath(r).listDevices()).map(t=>t.serial).filter(mr)}async function tm(r){let e=await em(r);return e.length===0?[]:(await Promise.all(e.map(n=>ll(r,n,"ohos.qemu.hvd.name")))).filter(n=>!!n)}async function oS(r,e){return(await tm(r)).includes(e)}async function sS(r,e){let t=await le.withHdcPath(r).listDevicesWithName(),n=e.normalize("NFKC").replace(/\s+/g," ").trim(),i=t.find(a=>a.name.normalize("NFKC").replace(/\s+/g," ").trim()===n);if(!i||!mr(i.serial))throw new Error(`Cannot resolve the running emulator serial for "${e}".`);let o=["-t",i.serial,"shell","hidumper","-s","3302","-a","-i"];f(`Executing: ${r} ${o.join(" ")}`);let s=await k(r,o);if(s.exitCode===0){let a=bO(s.stdout);if(a!==void 0)return a}throw new Error(`Cannot determine the battery charging state for emulator "${e}".`)}import*as Po from"path";import{existsSync as SO,statSync as EO}from"fs";function Eo(r,e){for(let t of e){let n=r[t];if(typeof n=="string"&&n.trim())return n.trim()}return""}function PO(r){let e=Eo(r,["instancePath","instance_path","InstancePath","instancepath","instanceDir","instance_dir","InstanceDir","deployPath","deploy_path","deployedPath","deployed_path","workPath","work_path","dataPath","data_path"]);if(e)return e;for(let[t,n]of Object.entries(r)){if(typeof n!="string"||!n.trim())continue;let i=t.toLowerCase();if(i.includes("instance")&&(i.includes("path")||i.includes("dir"))||i==="deployedpath")return n.trim()}return""}function CO(r){return Eo(r,["uuid","UUID","Uuid","instanceUuid","instance_uuid","InstanceUuid"])}function kO(r,e){for(let t of e){let n=r[t];if(!(n==null||n===""))return n===!0||String(n).toLowerCase()==="true"}}function RO(r){let e=r.find(n=>n.instancePath?.trim());if(!e?.instancePath?.trim())return;let t=Po.dirname(Po.normalize(e.instancePath));for(let n of r){if(n.instancePath?.trim())continue;let i=P.ensurePathWithinRoot(t,Po.join(t,n.name));SO(i)&&EO(i).isDirectory()&&(n.instancePath=i.replace(/\\/g,"/"))}}function xO(r){try{let e=JSON.parse(r);return Array.isArray(e)?e.map(t=>{let n=CO(t),i=Eo(t,["deviceType","DeviceType","devicetype"]),o=Eo(t,["os.osVersion","osVersion","OsVersion","OSVersion"]);return{name:t.name||t.Name||"",isRunning:t.isRunning===!0||String(t.isRunning).toLowerCase()==="true",instancePath:PO(t),path:Eo(t,["path","Path","hvdPath","hvd_path"]),imageRoot:Eo(t,["imageRoot","image_root","ImageRoot"]),uuid:n||void 0,deviceType:i||void 0,osVersion:o||void 0,hotBoot:kO(t,["isHotBoot","ishotboot","hotBoot"])}}).filter(t=>t.name):null}catch{return null}}function DO(r){let e=[],t=/^(name|isrunning|ishotboot|instancepath|path|imageroot|devicetype|os\.osversion)\s*:\s*(.+)/gim,n=null,i;for(;(i=t.exec(r))!==null;){let[,o,s]=i;if(o.toLowerCase()==="name")n&&e.push(n),n={name:s.trim()};else if(n){let a=o.toLowerCase();a==="isrunning"?n.isRunning=s.trim().toLowerCase()==="true":a==="ishotboot"?n.hotBoot=s.trim().toLowerCase()==="true":a==="instancepath"?n.instancePath=s.trim():a==="path"?n.path=s.trim():a==="imageroot"?n.imageRoot=s.trim():a==="devicetype"?n.deviceType=s.trim():a==="os.osversion"&&(n.osVersion=s.trim())}}return n&&e.push(n),e}function aS(r){let t=xO(r)??DO(r);return RO(t),t}function rm(r,e){for(let t of e){let n=r[t];if(typeof n=="string"&&n.trim())return n.trim()}return""}function IO(r){let e=r.downloaded??r.Downloaded;return e===!0||String(e).toLowerCase()==="true"}function AO(r){let e=rm(r,["osVersion","OsVersion","OSVersion"]),t=rm(r,["SoftWareVersion","SoftwareVersion","softwareVersion"]),n=rm(r,["deviceType","DeviceType"]);return!e&&!t?null:{osVersion:e,softwareVersion:t,deviceType:n}}function cS(r,e=()=>!0){let t=r.trim();if(!t)return[];try{let n=JSON.parse(t);if(!Array.isArray(n))return[];let i=[];for(let o of n){if(!o||typeof o!="object")continue;let s=o;if(!e(s))continue;let a=AO(s);a&&i.push(a)}return i}catch{return[]}}function lS(r){return cS(r)}function dS(r){return cS(r,IO)}var uS=/no images are available/i,TO=/Scenario simulation failed\s*[::]/i,NO="7.0.0";function Br(r){return r.normalize("NFKC").trim().toLowerCase()}function OO(r){let e=r.message||"";return uS.test(e)}function _O(r){return r.normalize("NFKC").match(/(\d+(?:\.\d+){1,3})/)?.[1]}function Ks(r,e){return`${r} ${e.join(" ")}`.trim()}function MO(r){switch(r.type){case"gps":return`${r.type}:${r.key}=${r.value}`;case"sensor":return`${r.type}:${r.key}=${r.value}`;case"rotation":case"volume":return`${r.type}:${r.direction}`;case"folded-state":return`${r.type}:${r.state}`;case"battery":return`${r.type}:${r.level}`;case"battery-status":return`${r.type}:${r.status}`;default:return r.type}}var Co=class r{static supportedControlPaths=new Set;emulatorPath;sdkPath;hdcPath;constructor(e,t,n){this.emulatorPath=e,this.sdkPath=t,this.hdcPath=n}static from(e){return new r(e.emulatorPath,e.sdkPath,e.hdcPath)}async executeEmulator(e){return f(`Executing: ${Ks(this.emulatorPath,e)}`),Gl(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath}})}executeEmulatorDetached(e){return rS(this.emulatorPath,this.sdkPath,e)}async listEmulators(e){let t=["-list","-details"];e!==void 0&&t.push("-instancePath",e);let{stdout:n}=await this.executeEmulator(t);return aS(n)}async listEmulatorDetails(){let{stdout:e}=await this.executeEmulator(["-list","-details"]);return e}async getDeviceTypeByName(){let e=new Map;try{let t=await this.listEmulators();for(let n of t)n.name&&n.deviceType&&e.set(je(n.name),n.deviceType)}catch{}return e}async startEmulator(e,t){let n=await this.listEmulators(),i=je(e),o=n.find(c=>je(c.name)===i);if(!o)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let s=o.name;if(await this.isAlreadyRunning(s,o))return{status:"already-running"};let a=await iS(s,o,c=>this.executeEmulatorDetached(c),o.hotBoot===!1?"coldboot":"snapshot",t);if(a.ok)return{status:"started",args:a.args,tracker:a.tracker};if(await this.isAlreadyRunning(s))return{status:"already-running"};throw new w(`Unable to start emulator "${e}". All methods failed.
95
95
  Last error: ${a.lastError.message||"unknown"}`,`Unable to start emulator. All methods failed.
96
- Last error: ${a.lastError.message||"unknown"}`)}async isAlreadyRunning(e,t){return t?.isRunning===!0||t===void 0&&(await this.listEmulators()).find(i=>i.name===e)?.isRunning===!0?!0:pb(this.hdcPath,e)}async stopEmulator(e){let t=await this.listEmulators(),n=Fe(e),i=t.find(a=>Fe(a.name)===n);if(!i)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let o=i.name;return await this.isAlreadyRunning(o,i)?(await this.executeEmulator(["-stop",o]),"stopped"):"already-stopped"}async controlEmulator(e,t){await this.assertControlCommandSupported();let i=(await this.listEmulators()).find(s=>s.name===e);if(!i)throw new w(`Emulator "${e}" not found.`,"Emulator instance not found.");if(!await this.isAlreadyRunning(i.name,i))throw new w(`Emulator "${e}" is not running.`,"Emulator instance is not running.");if(t.type==="battery"&&!(t.assumedCharging?!0:await mb(this.hdcPath,i.name))&&t.level===0)throw new Error("Battery level must be an integer in [1, 100] while the emulator is not charging.");let o=this.buildControlArgs(i.name,t);m(`[EmulatorManager] control ${nO(t)} -> ${$s(this.emulatorPath,o)}`),await this.runEmulatorChecked(o,{extraReject:t.type==="folded-state"?[QT]:void 0,printOutputOnSuccess:!1})}async assertControlCommandSupported(){let e=this.emulatorPath;if(r.supportedControlPaths.has(e))return;let t=["-version"];m(`Executing: ${$s(this.emulatorPath,t)}`);let{stdout:n,stderr:i,exitCode:o}=await Rl(this.emulatorPath,t,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1,maxBuffer:1024*1024}),s=[n,i].filter(Boolean).join(`
97
- `).trim(),a=rO(s);if(o!==0||!a)throw new Error("Emulator scene control commands require Emulator 7.0 or later. Unable to determine the current Emulator version.");if(C.compareVersion(a,eO)<0)throw new Error(`Emulator scene control commands require Emulator 7.0 or later. Current Emulator version is ${a}. Please upgrade DevEco Studio or the Emulator SDK.`);r.supportedControlPaths.add(e)}buildControlArgs(e,t){let n=["-instance",e];switch(t.type){case"shake":return[...n,"-shake"];case"power":return[...n,"-power"];case"rotation":return[...n,"-rotation",t.direction];case"volume":return[...n,"-volume",t.direction];case"folded-state":return[...n,"-foldedState",t.state];case"battery":return[...n,"-battery",String(t.level)];case"battery-status":return[...n,"-batteryStatus",String(t.status)];case"gps":return[...n,"-gps",`-${t.key}`,t.value];case"outdoor-running":return[...n,"-outdoorRunning"];case"outdoor-cycling":return[...n,"-outdoorCycling"];case"driving-navigation":return[...n,"-drivingNavigation"];case"sensor":return[...n,"-sensor",`-${t.key}`,String(t.value)];default:throw new Error(`Unknown emulator control action type: ${t.type}`)}}async executeEmulatorInherit(e){m(`Executing: ${$s(this.emulatorPath,e)}`);let{exitCode:t}=await Rl(this.emulatorPath,e,{stdio:"inherit",env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1});if(t!==0)throw new Error(`Emulator exited with code ${t===null?"null":t}.`)}async installEmulatorImage(e){let t=["-install","-deviceType",e.deviceType,"-osVersion",e.osVersion];e.force&&t.push("-force"),await this.executeEmulatorInherit(t)}async hasAvailableEmulatorImage(e){let t=await this.listEmulatorImages({deviceType:e.deviceType}),n=Fr(e.deviceType),i=Fr(e.osVersion);return hb(t).some(o=>Fr(o.deviceType)===n&&Fr(o.osVersion)===i)}async uninstallEmulatorImage(e){let t=await this.resolveSoftwareVersionsForUninstall(e);if(t.length===0)throw new Error(`No downloaded image matches --os-version "${e.osVersion}" for --device-type "${e.deviceType}".`);let n;try{await this.runUninstallImageChecked(e.deviceType,e.osVersion)}catch(o){if(!tO(o))throw o;n=o}(n!==void 0||await this.hasMatchingDownloadedImage(e))&&await this.runSoftwareVersionFallback(e,t,n)}async listEmulatorImages(e){let t=["-imageList"];e.deviceType&&t.push("-deviceType",e.deviceType),e.downloaded!==void 0&&t.push("-downloaded",e.downloaded?"true":"false");let{stdout:n}=await this.executeEmulator(t);return n}async hasMatchingDownloadedImage(e){return(await this.findMatchingDownloadedImages(e)).length>0}async runSoftwareVersionFallback(e,t,n){try{for(let i of t)await this.runUninstallImageChecked(e.deviceType,i)}catch(i){let o=n!==void 0?`Primary uninstall failed: ${n.message}
98
- `:"";throw new Error(`${o}Fallback uninstall failed: ${i.message}`,{cause:i})}if(await this.hasMatchingDownloadedImage(e))throw new Error(`Image for --device-type "${e.deviceType}" and --os-version "${e.osVersion}" remains listed as downloaded after uninstallation.`)}async resolveSoftwareVersionsForUninstall(e){let t=await this.findMatchingDownloadedImages(e);return[...new Set(t.map(n=>n.softwareVersion).filter(Boolean))]}async findMatchingDownloadedImages(e){let t=await this.listEmulatorImages({deviceType:e.deviceType,downloaded:!0}),n=yb(t),i=Fr(e.deviceType),o=Fr(e.osVersion);return n.filter(s=>Fr(s.deviceType)===i&&(Fr(s.osVersion)===o||Fr(s.softwareVersion)===o))}async runUninstallImageChecked(e,t){await this.runEmulatorChecked(["-uninstall","-deviceType",e,"-osVersion",t,"-force"],{printOutputOnSuccess:!0,extraReject:[wb]})}async runEmulatorChecked(e,t){m(`Executing: ${$s(this.emulatorPath,e)}`);let{stdout:n,stderr:i,exitCode:o}=await Rl(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1,maxBuffer:20*1024*1024}),s=[n,i].filter(Boolean).join(`
99
- `).trim(),a=/Invalid command|无效命令|鏃犳晥鍛戒护/i.test(s)||/please attach the correct parameter/i.test(s),c=(t?.extraReject??[]).some(d=>d.test(s));if(o!==0||a||c)throw new Error(s||`emulator exited with code ${o===null?"null":o}`);if(t?.printOutputOnSuccess!==!1&&s){let d=(t?.transformOutput?t.transformOutput(s):s).trim();d&&console.log(d)}}async checkExistingVirtualDevice(e){let t=await this.listEmulators(e.instancePath),n=Fe(e.name),i=t.find(o=>Fe(o.name)===n);if(i)if(e.force)await this.deleteVirtualDevice(i.name,e.instancePath);else throw new w(`Emulator "${e.name}" already exists. Use \`--force\` to overwrite.`,"Emulator already exists.");return n}buildCreateVirtualDeviceArgs(e){let t=["-create",e.name,"-deviceType",e.deviceType,"-osVersion",e.osVersion];e.instancePath!==void 0&&t.push("-instancePath",e.instancePath),e.imageRoot!==void 0&&t.push("-imageRoot",e.imageRoot),e.screenProfile!==void 0&&t.push("-screenProfile",e.screenProfile),e.screen?.length&&t.push("-screen",...e.screen),e.storage!==void 0&&t.push("-storage",String(e.storage)),e.memory!==void 0&&t.push("-memory",String(e.memory));let n=e.hotBoot??(cb(e.osVersion)?!0:void 0);return n!==void 0&&t.push("-hotBoot",String(n)),t}async createVirtualDevice(e){let t=await this.checkExistingVirtualDevice(e),n=this.buildCreateVirtualDeviceArgs(e);if(await this.runEmulatorChecked(n,{extraReject:[/Device create fail/i,/already exists/i,/Invalid OS version/i,/cannot be empty/i],printOutputOnSuccess:!0,transformOutput:o=>o.split(/\r?\n/).map(s=>s.trim().startsWith("Device create success.")?"Device create success.":s).join(`
100
- `)}),!await this.waitForEmulatorPresenceByList(t,e.instancePath))throw new w(`Emulator "${e.name}" was reported as created, but it did not appear in the emulator list within the waiting period. Open the device manager list in DevEco Studio, then run this command again.`,"Emulator was reported as created, but it did not appear in the emulator list within the waiting period.")}async waitForEmulatorPresenceByList(e,t,n=1e4,i=500){let o=Date.now()+n;for(;Date.now()<o;){if((await this.listEmulators(t)).some(c=>Fe(c.name)===e))return!0;await new Promise(c=>setTimeout(c,i))}return!1}async deleteVirtualDevice(e,t){let n=await this.listEmulators(t),i=Fe(e),o=n.find(c=>Fe(c.name)===i);if(!o)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let s=o.name;if(o.isRunning===!0||await this.isAlreadyRunning(s,o))throw new w(`Failed to delete device: ${s}
101
- The device may be running.`,"Failed to delete device, The device may be running.");let a=["-delete",s];return t!==void 0&&a.push("-instancePath",t),a.push("-force"),await this.runEmulatorChecked(a,{printOutputOnSuccess:!1}),s}};import{yellow as fM,gray as gM}from"colorette";import hM from"ora";import{green as iO}from"colorette";var oO=[[4352,4447],[9001,9002],[11904,42191],[43360,43388],[44032,55203],[63744,64255],[65040,65049],[65072,65135],[65281,65376],[65504,65510],[127744,129535],[131072,173791],[173824,177983],[177984,178207],[178208,183983],[183984,191456]],sO=[[0,31],[127,159],[768,879],[6832,6911],[7616,7679],[8203,8207],[8400,8447],[65024,65039],[65056,65071],[8205,8205]],aO=new RegExp("\x1B\\[([0-9;]*)[a-zA-Z]","g");function vb(r,e){for(let[t,n]of e)if(r>=t&&r<=n)return!0;return!1}function km(r){let e=r.replace(aO,""),t=0,n=0;for(;n<e.length;){let i=e.codePointAt(n);if(i===void 0)break;vb(i,sO)||(vb(i,oO)?t+=2:t+=1),n+=i>65535?2:1}return t}function bb(r,e){let t=km(r);return r+" ".repeat(Math.max(0,e-t))}function cO(r,e){return r.map((t,n)=>{let i=km(t);for(let o of e){let s=o.cells[n]??"";i=Math.max(i,km(s))}return i})}function jr(r,e){let t=cO(r,e),n=[];n.push(r.map((i,o)=>bb(i,t[o])).join(" ")),n.push(t.map(i=>"-".repeat(i)).join(" "));for(let i of e){let o=i.cells.map((s,a)=>bb(s??"",t[a])).join(" ").trimEnd();n.push(i.highlight?iO(o):o)}return n.join(`
102
- `)}import{red as lO}from"colorette";async function O(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=X(o),console.error(lO(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(r,o)}}async function N(){try{let r=await C.new();return{manager:ce.from(r),toolProvider:r}}catch(r){throw new w(`Failed to initialize device manager: ${r.message}`,"Failed to initialize device manager.")}}import{Command as dO,Option as Tm}from"commander";import{yellow as Om}from"colorette";import{existsSync as Eb}from"fs";import Hr from"ora";function Sb(r,e){let t=r.match(e);return t?t[1]:void 0}function Dm(r){let e=[],t=r.split(/(?=AbilityRecord ID #)/);for(let n of t){let i=n.match(/^\s*state #(\w+)/m);i&&i[1].toUpperCase()==="FOREGROUND"&&e.push({bundleName:Sb(n,/app name \[([^\]]+)\]/),abilityName:Sb(n,/main name \[([^\]]+)\]/)})}return e}function Rm(r){let e=[],t=o=>{typeof o.bundleName=="string"&&e.push({bundleName:o.bundleName,label:typeof o.label=="string"?o.label:void 0})},n;try{n=JSON.parse(r)}catch{n=null}if(Array.isArray(n)){for(let o of n)t(o);if(e.length>0)return e}let i=r.match(/\{[^{}]+\}/g)??[];for(let o of i)try{t(JSON.parse(o))}catch{}return e}function xm(r){let e=r.indexOf("{");if(e===-1)return null;try{return JSON.parse(r.slice(e))}catch{return null}}function Am(r){let e=r.trim();return{success:!/error:\s*failed to start|error code:\s*\d+|the specified ability does not exist/i.test(e),message:e}}function Im(r){let e=r.hapModuleInfos,t=Array.isArray(e)&&e[0]?e[0]:void 0;return{bundleName:r.name,entryModuleName:r.entryModuleName,mainAbility:t?.mainAbility,versionCode:r.versionCode,versionName:r.versionName}}var mr=class{constructor(e){this.hdcPath=e}async listInstalledApps(e){let t=["-t",e,"shell","bm","dump","-a","-l"];m(`Executing: ${this.hdcPath} ${t.join(" ")}`);let n=await k(this.hdcPath,t);if(n.exitCode!==0)throw new Error(`bm dump -a -l failed: ${(n.stderr||n.stdout).trim()}`);return n.stdout}async getAppInfo(e,t){let n=["-t",e,"shell","bm","dump","-n",t];m(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm dump -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}async getForegroundApp(e){let t=["-t",e,"shell","aa","dump","-l"];m(`Executing: ${this.hdcPath} ${t.join(" ")}`);let n=await k(this.hdcPath,t);if(n.exitCode!==0)throw new Error(`aa dump -l failed: ${(n.stderr||n.stdout).trim()}`);return n.stdout}async startApp(e,t,n,i,o){let s=["-t",e,"shell","aa","start"];t&&s.push("-b",t),n&&s.push("-a",n),i&&s.push("-A",i),o&&s.push("-U",o),m(`Executing: ${this.hdcPath} ${s.join(" ")}`);let a=await k(this.hdcPath,s);if(a.exitCode!==0)throw new Error(`aa start failed: ${(a.stderr||a.stdout).trim()}`);return a.stdout}async clearAppData(e,t){let n=["-t",e,"shell","bm","clean","-d","-n",t];m(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm clean -d -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}async clearAppCache(e,t){let n=["-t",e,"shell","bm","clean","-c","-n",t];m(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm clean -c -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}};function uO(r,e){if(e==="json")console.log(JSON.stringify(r,null,2));else if(r.length>0)for(let t of r){let n=t.label||"";console.log(`${t.bundleName} ${n}`)}else console.log(Om("No installed apps found."))}async function pO(r,e,t="default"){let n=await T(r,e),i=new mr(r.hdcPath),o=Hr({text:"Listing installed apps...",color:"cyan"}).start();try{let s=await i.listInstalledApps(n);o.stop();let a=Rm(s);uO(a,t)}catch(s){throw o.stop(),new w(`Failed to list apps: ${s.message}`,"Failed to list apps.")}}function mO(r,e){if(r.length>0)if(e==="json")console.log(JSON.stringify(r,null,2));else for(let t of r)console.log(`${t.bundleName??""}#${t.abilityName??""}`);else console.log(e==="json"?"[]":Om("No foreground app."))}async function fO(r,e,t="default"){let n=await T(r,e),i=new mr(r.hdcPath),o=Hr({text:"Querying foreground app...",color:"cyan"}).start();try{let s=await i.getForegroundApp(n);o.stop();let a=Dm(s);mO(a,t)}catch(s){throw o.stop(),new w(`Failed to get foreground app: ${s.message}`,"Failed to get foreground app.")}}async function gO(r,e,t,n="default"){let i=await T(r,t),o=new mr(r.hdcPath),s=Hr({text:`Querying app info for ${e}...`,color:"cyan"}).start();try{let a=await o.getAppInfo(i,e);s.stop();let c=xm(a);if(!c)throw new w(`No app info found for ${e}. The app may not be installed.`,"No app info found. The app may not be installed.");if(n==="json")console.log(JSON.stringify(c,null,2));else{let l=Im(c);console.log(` bundleName: ${l.bundleName??"-"}`),console.log(` entryModuleName: ${l.entryModuleName??"-"}`),console.log(` mainAbility: ${l.mainAbility??"-"}`),console.log(` versionCode: ${l.versionCode??"-"}`),console.log(` versionName: ${l.versionName??"-"}`)}}catch(a){throw s.stop(),new w(`Failed to get app info: ${a.message}`,"Failed to get app info.")}}async function hO(r,e){if(!e.bundle&&!e.action&&!e.uri)throw new w("At least one of --bundle, --action, or --uri must be provided.","At least one of --bundle, --action, or --uri must be provided.");if(e.bundle&&!e.ability)throw new w("--ability is required when --bundle is specified.","--ability is required when --bundle is specified.");let t=await T(r,e.device),n=new mr(r.hdcPath),i=e.bundle??"(no bundle)",o=Hr({text:`Starting app ${i}...`,color:"cyan"}).start();try{let s=await n.startApp(t,e.bundle,e.ability,e.action,e.uri);o.stop();let{success:a,message:c}=Am(s);if(!a)throw new w(`Failed to start app: ${c}`,"Failed to start app. The app or ability may not be installed.");console.log(`App ${i}: ${c}`)}catch(s){throw o.stop(),new w(`Failed to start app: ${s.message}`,"Failed to start app.")}}async function yO(r,e){let t=await T(r,e.device),n=new le(r),i=Hr({text:`Stopping app ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.forceStopApp(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to stop app.");console.log(`Stopped app ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to stop app.")}}function wO(r,e){if(r.length===0&&!e.shared?.length)throw new w("At least one package file or --shared must be provided.","At least one package file or --shared must be provided.");for(let t of r)if(!Eb(t))throw new w(`HAP file not found: ${t}`,"HAP file not found.");if(e.shared){for(let t of e.shared)if(!Eb(t))throw new w(`Shared HSP file not found: ${t}`,"Shared HSP file not found.")}}function vO(r,e){let t=[];return r.length>0&&t.push(r.length===1?r[0]:`${r.length} packages`),e.shared?.length&&t.push(`${e.shared.length} shared HSP(s)`),t.join(" + ")}async function bO(r,e,t){let n=await T(r,t.device);wO(e,t);let i={replace:t.replace,shared:t.shared,wait:t.wait,user:t.user},o=new le(r),s=vO(e,t),a=Hr({text:`Installing ${s}...`,color:"cyan"}).start();try{await o.installApp(n,e,i),a.stop(),console.log(`Installed ${s}.`)}catch(c){throw a.stop(),new w(c.message,"Failed to install app.")}}async function SO(r,e){let t=await T(r,e.device),n=new le(r),i=Hr({text:`Uninstalling ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.uninstallApp(t,e.bundle);i.stop(),console.log(o?`Uninstalled ${e.bundle}.`:Om(`${e.bundle} was not installed.`))}catch(o){throw i.stop(),new w(`Failed to uninstall app: ${o.message}`,"Failed to uninstall app.")}}async function EO(r,e){P.assertBundleNameStrict(e.bundle);let t=await T(r,e.device),n=new mr(r.hdcPath),i=Hr({text:`Clearing cache for ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.clearAppCache(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to clear app cache.");console.log(`Cleared cache for ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to clear app cache.")}}async function PO(r,e){P.assertBundleNameStrict(e.bundle);let t=await T(r,e.device),n=new mr(r.hdcPath),i=Hr({text:`Clearing data for ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.clearAppData(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to clear app data.");console.log(`Cleared data for ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to clear app data.")}}var Vt=new dO("app").description("Manage apps on a connected device");Vt.command("list").description("List installed apps").option("--device <name|serial>","Target device (name or serial)").addOption(new Tm("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","app","list",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await pO(i,e,t)})});Vt.command("foreground").description("Show current foreground app info").option("--device <name|serial>","Target device (name or serial)").addOption(new Tm("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","app","foreground",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await fO(i,e,t)})});Vt.command("info").description("Show app info").option("--device <name|serial>","Target device (name or serial)").addOption(new Tm("--format <format>","Output format").choices(["default","json"]).default("default")).argument("<bundleName>","Bundle name to query").action(async(r,e)=>{let{device:t,format:n}=e,i={event:v.CommandExecuted,args:["device","app","info","<bundleName>",...n==="json"?["--format","json"]:[],...t?["--device"]:[]]};await O(i,async()=>{let{toolProvider:o}=await N();await gO(o,r,t,n)})});Vt.command("start").description("Start an app on the device").option("--device <name|serial>","Target device (name or serial)").option("--bundle <name>","Bundle name (e.g. com.example.app)").option("--ability <name>","Ability to start (-a)").option("--action <action>","Action to send (-A)").option("--uri <uri>","URI to start with (-U)").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","start",...r.bundle?["--bundle"]:[],...r.ability?["--ability"]:[],...r.action?["--action"]:[],...r.uri?["--uri"]:[],...r.device?["--device"]:[]]};await O(e,async()=>{let{toolProvider:t}=await N();await hO(t,r)})});Vt.command("install").description("Install package(s) on the device").option("--device <name|serial>","Target device (name or serial)").option("--replace","Override install").option("--shared <path>","Inter-app shared HSP path (repeatable)",(r,e)=>[...e,r],[]).option("--wait <seconds>","Install wait time in seconds",r=>parseInt(r,10)).option("--user <userId>","Target user ID").argument("[files...]","Local package path(s) to install (hap/hsp)").action(async(r,e)=>{let t={event:v.CommandExecuted,args:["device","app","install",...r.map(()=>"<file>"),...e.replace?["--replace"]:[],...e.shared?.length?["--shared"]:[],...e.wait!==void 0?["--wait"]:[],...e.user?["--user"]:[],...e.device?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await bO(n,r,e)})});Vt.command("uninstall").description("Uninstall an app from the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","uninstall","--bundle",...r.device?["--device"]:[]]};await O(e,async()=>{let{toolProvider:t}=await N();await SO(t,r)})});Vt.command("stop").description("Stop an app on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","stop","--bundle",...r.device?["--device"]:[]]};await O(e,async()=>{let{toolProvider:t}=await N();await yO(t,r)})});Vt.command("clearcache").description("Clear app cache on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","clearcache","--bundle",...r.device?["--device"]:[]]};await O(e,async()=>{let{toolProvider:t}=await N();await EO(t,r)})});Vt.command("cleardata").description("Clear app data on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","cleardata","--bundle",...r.device?["--device"]:[]]};await O(e,async()=>{let{toolProvider:t}=await N();await PO(t,r)})});import{Command as un}from"commander";import{red as Pb,yellow as CO}from"colorette";import pn from"ora";function Ge(r){let e=`${r.stdout}
103
- ${r.stderr}`;if(/testhelper.*(?:not found|inaccessible)/i.test(e))throw new Error("testhelper is not available on this device. Please upgrade the device system version to support this command.")}var yt=class{constructor(e){this.toolProvider=e}async getDeviceType(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","param","get","const.product.devicetype"])).stdout}async wakeScreen(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","wakeup"])).stdout}async suspendScreen(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","suspend"])).stdout}async getScreenStatus(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-s"])).stdout}async getDisplayInfo(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","DisplayManagerService","-a","-a"])).stdout}async swipeScreen(e,t,n,i,o,s=6e3){let a=await k(this.toolProvider.hdcPath,["-t",e,"shell","uitest","uiInput","swipe",String(t),String(n),String(i),String(o),String(s)]);if(a.exitCode!==0)throw new Error(a.stderr||a.stdout||"swipe failed");return a.stdout}async getTime(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-time"]);return Ge(t),t.stdout}async setTime(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-time",t]);return Ge(n),n.stdout}async getTimezone(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-timezone"]);return Ge(t),t.stdout}async setTimezone(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-timezone",t]);return Ge(n),n.stdout}};function ci(r){let e=r.match(/\[DISPLAY INFO\][\s\S]*?Width:\s*(\d+)[\s\S]*?Height:\s*(\d+)/);return e?{width:Number(e[1]),height:Number(e[2])}:null}function Nm(r){let e=r.match(/Current State:\s*(\w+)/);return e?e[1]:null}var ho=class{constructor(e){this.toolProvider=e}async getDisplayInfo(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","DisplayManagerService","-a","-a"])).stdout}async setScreenTimeout(e,t){return await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-f"]),(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","timeout","-o",String(t)])).stdout}async setScreenNeverSleep(e){return await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","timeout","-r"]),(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-t"])).stdout}};var kO=["phone","tablet"];async function Mm(r,e){let i=(await new yt(r).getDeviceType(e)).trim().toLowerCase();if(!kO.includes(i))throw new w(`This command is only supported on phone and tablet devices (current: ${i||"unknown"}).`,"Unsupported device type.")}async function DO(r,e){let t=await T(r,e),n=new yt(r),i=pn({text:"Waking screen...",color:"cyan"}).start();try{let o=await n.wakeScreen(t);i.stop();let s=o.trim();console.log(s||"Screen woken.")}catch(o){throw i.stop(),new w(`Failed to wake screen: ${o.message}`,"Failed to wake screen.")}}async function RO(r,e){let t=await T(r,e),n=new yt(r),i=pn({text:"Suspending screen...",color:"cyan"}).start();try{let o=await n.suspendScreen(t);i.stop();let s=o.trim();console.log(s||"Screen suspended.")}catch(o){throw i.stop(),new w(`Failed to suspend screen: ${o.message}`,"Failed to suspend screen.")}}async function xO(r,e){let t=await T(r,e),n=new yt(r),i=pn({text:"Querying screen status...",color:"cyan"}).start();try{let o=await n.getScreenStatus(t);i.stop();let s=Nm(o);console.log(s?` Screen State: ${s}`:CO("No screen state found in output."))}catch(o){throw i.stop(),new w(`Failed to get screen status: ${o.message}`,"Failed to get screen status.")}}async function AO(r,e){let t=await T(r,e);await Mm(r,t);let n=new yt(r),i=pn({text:"Unlocking screen...",color:"cyan"}).start();try{await n.wakeScreen(t);let o=await n.getDisplayInfo(t),s=ci(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width/2),c=Math.round(s.height*.98),l=c-Math.round(s.height/2);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Screen unlocked: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to unlock screen: ${o.message}`,"Failed to unlock screen.")}}async function IO(r,e){let t=await T(r,e);await Mm(r,t);let n=new yt(r),i=pn({text:"Opening control center...",color:"cyan"}).start();try{let o=await n.getDisplayInfo(t),s=ci(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width*4/5),c=Math.round(s.height*.02),l=c+Math.round(s.height/3);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Control center opened: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to open control center: ${o.message}`,"Failed to open control center.")}}async function TO(r,e){let t=await T(r,e);await Mm(r,t);let n=new yt(r),i=pn({text:"Opening notification center...",color:"cyan"}).start();try{let o=await n.getDisplayInfo(t),s=ci(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width/5),c=Math.round(s.height*.02),l=c+Math.round(s.height/3);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Notification center opened: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to open notification center: ${o.message}`,"Failed to open notification center.")}}var OO=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;async function NO(r,e,t){let n=await T(r,t),i=new yt(r),o=e!==void 0;if(o&&!OO.test(e))throw new w(`Invalid time format. Time must be in 'YYYY-MM-DD HH:MM:SS' format (e.g. "2026-10-13 17:18:07").`,"Invalid time format.");let s=pn({text:o?`Setting time to ${e}...`:"Getting time...",color:"cyan"}).start();try{let a=o?await i.setTime(n,e):await i.getTime(n);s.stop();let c=a.trim();/^error/i.test(c)?(console.error(Pb(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Time ${o?"set":"get"} failed: ${a.message}`,`Time ${o?"set":"get"} failed.`)}}async function MO(r,e,t){let n=await T(r,t),i=new yt(r),o=e!==void 0,s=pn({text:o?`Setting timezone to ${e}...`:"Getting timezone...",color:"cyan"}).start();try{let a=o?await i.setTimezone(n,e):await i.getTimezone(n);s.stop();let c=a.trim();/^error/i.test(c)?(console.error(Pb(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Timezone ${o?"set":"get"} failed: ${a.message}`,`Timezone ${o?"set":"get"} failed.`)}}var Cb=[new un("wake").description("Wake up the device screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","wake",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await DO(n,e)})}),new un("sleep").description("Turn off the device screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","sleep",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await RO(n,e)})}),new un("status").description("Query screen power state").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","status",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await xO(n,e)})}),new un("unlock").description("Unlock the screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","unlock",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await AO(n,e)})}),new un("open-control-center").description("Open the control center").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","open-control-center",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await IO(n,e)})}),new un("open-notification-center").description("Open the notification center").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","open-notification-center",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await TO(n,e)})}),new un("time").description("Get or set the device time").option("--device <name|serial>","Target device (name or serial)").argument("[datetime]","Datetime to set; omit to get current time").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","time",...r?["<datetime>"]:[],...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await NO(i,r,t)})}),new un("timezone").description("Get or set the device timezone").option("--device <name|serial>","Target device (name or serial)").argument("[timezone]","Timezone to set; omit to get current timezone").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","timezone",...r?["<timezone>"]:[],...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await MO(i,r,t)})})];import{Command as BN,Option as WN}from"commander";import{yellow as VN}from"colorette";import Qs from"ora";import{appendFileSync as uX}from"fs";var Gt={TRACE:10,DEBUG:20,INFO:30,WARN:40,ERROR:50,SILENT:100},Db={10:"TRACE",20:"DEBUG",30:"INFO",40:"WARN",50:"ERROR",100:"SILENT"};function Lm(r){if(typeof r=="number")return r;let e=String(r||"").toUpperCase();return e in Gt?Gt[e]:Gt.INFO}function LO(r){return{write:r}}function _O({useStderr:r}={}){return LO((e,t)=>{let n=`${$O[Db[e.level]]||""}${t}`;r||e.level>=Gt.ERROR?process.stderr.write(n+`
96
+ Last error: ${a.lastError.message||"unknown"}`)}async isAlreadyRunning(e,t){return t?.isRunning===!0||t===void 0&&(await this.listEmulators()).find(i=>i.name===e)?.isRunning===!0?!0:oS(this.hdcPath,e)}async stopEmulator(e){let t=await this.listEmulators(),n=je(e),i=t.find(a=>je(a.name)===n);if(!i)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let o=i.name;return await this.isAlreadyRunning(o,i)?(await this.executeEmulator(["-stop",o]),"stopped"):"already-stopped"}async controlEmulator(e,t){await this.assertControlCommandSupported();let i=(await this.listEmulators()).find(s=>s.name===e);if(!i)throw new w(`Emulator "${e}" not found.`,"Emulator instance not found.");if(!await this.isAlreadyRunning(i.name,i))throw new w(`Emulator "${e}" is not running.`,"Emulator instance is not running.");if(t.type==="battery"&&!(t.assumedCharging?!0:await sS(this.hdcPath,i.name))&&t.level===0)throw new Error("Battery level must be an integer in [1, 100] while the emulator is not charging.");let o=this.buildControlArgs(i.name,t);f(`[EmulatorManager] control ${MO(t)} -> ${Ks(this.emulatorPath,o)}`),await this.runEmulatorChecked(o,{extraReject:t.type==="folded-state"?[TO]:void 0,printOutputOnSuccess:!1})}async assertControlCommandSupported(){let e=this.emulatorPath;if(r.supportedControlPaths.has(e))return;let t=["-version"];f(`Executing: ${Ks(this.emulatorPath,t)}`);let{stdout:n,stderr:i,exitCode:o}=await Gl(this.emulatorPath,t,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1,maxBuffer:1024*1024}),s=[n,i].filter(Boolean).join(`
97
+ `).trim(),a=_O(s);if(o!==0||!a)throw new Error("Emulator scene control commands require Emulator 7.0 or later. Unable to determine the current Emulator version.");if(C.compareVersion(a,NO)<0)throw new Error(`Emulator scene control commands require Emulator 7.0 or later. Current Emulator version is ${a}. Please upgrade DevEco Studio or the Emulator SDK.`);r.supportedControlPaths.add(e)}buildControlArgs(e,t){let n=["-instance",e];switch(t.type){case"shake":return[...n,"-shake"];case"power":return[...n,"-power"];case"rotation":return[...n,"-rotation",t.direction];case"volume":return[...n,"-volume",t.direction];case"folded-state":return[...n,"-foldedState",t.state];case"battery":return[...n,"-battery",String(t.level)];case"battery-status":return[...n,"-batteryStatus",String(t.status)];case"gps":return[...n,"-gps",`-${t.key}`,t.value];case"outdoor-running":return[...n,"-outdoorRunning"];case"outdoor-cycling":return[...n,"-outdoorCycling"];case"driving-navigation":return[...n,"-drivingNavigation"];case"sensor":return[...n,"-sensor",`-${t.key}`,String(t.value)];default:throw new Error(`Unknown emulator control action type: ${t.type}`)}}async executeEmulatorInherit(e){f(`Executing: ${Ks(this.emulatorPath,e)}`);let{exitCode:t}=await Gl(this.emulatorPath,e,{stdio:"inherit",env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1});if(t!==0)throw new Error(`Emulator exited with code ${t===null?"null":t}.`)}async installEmulatorImage(e){let t=["-install","-deviceType",e.deviceType,"-osVersion",e.osVersion];e.force&&t.push("-force"),await this.executeEmulatorInherit(t)}async hasAvailableEmulatorImage(e){let t=await this.listEmulatorImages({deviceType:e.deviceType}),n=Br(e.deviceType),i=Br(e.osVersion);return lS(t).some(o=>Br(o.deviceType)===n&&Br(o.osVersion)===i)}async uninstallEmulatorImage(e){let t=await this.resolveSoftwareVersionsForUninstall(e);if(t.length===0)throw new Error(`No downloaded image matches --os-version "${e.osVersion}" for --device-type "${e.deviceType}".`);let n;try{await this.runUninstallImageChecked(e.deviceType,e.osVersion)}catch(o){if(!OO(o))throw o;n=o}(n!==void 0||await this.hasMatchingDownloadedImage(e))&&await this.runSoftwareVersionFallback(e,t,n)}async listEmulatorImages(e){let t=["-imageList"];e.deviceType&&t.push("-deviceType",e.deviceType),e.downloaded!==void 0&&t.push("-downloaded",e.downloaded?"true":"false");let{stdout:n}=await this.executeEmulator(t);return n}async hasMatchingDownloadedImage(e){return(await this.findMatchingDownloadedImages(e)).length>0}async runSoftwareVersionFallback(e,t,n){try{for(let i of t)await this.runUninstallImageChecked(e.deviceType,i)}catch(i){let o=n!==void 0?`Primary uninstall failed: ${n.message}
98
+ `:"";throw new Error(`${o}Fallback uninstall failed: ${i.message}`,{cause:i})}if(await this.hasMatchingDownloadedImage(e))throw new Error(`Image for --device-type "${e.deviceType}" and --os-version "${e.osVersion}" remains listed as downloaded after uninstallation.`)}async resolveSoftwareVersionsForUninstall(e){let t=await this.findMatchingDownloadedImages(e);return[...new Set(t.map(n=>n.softwareVersion).filter(Boolean))]}async findMatchingDownloadedImages(e){let t=await this.listEmulatorImages({deviceType:e.deviceType,downloaded:!0}),n=dS(t),i=Br(e.deviceType),o=Br(e.osVersion);return n.filter(s=>Br(s.deviceType)===i&&(Br(s.osVersion)===o||Br(s.softwareVersion)===o))}async runUninstallImageChecked(e,t){await this.runEmulatorChecked(["-uninstall","-deviceType",e,"-osVersion",t,"-force"],{printOutputOnSuccess:!0,extraReject:[uS]})}async runEmulatorChecked(e,t){f(`Executing: ${Ks(this.emulatorPath,e)}`);let{stdout:n,stderr:i,exitCode:o}=await Gl(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath},reject:!1,maxBuffer:20*1024*1024}),s=[n,i].filter(Boolean).join(`
99
+ `).trim(),a=/Invalid command|无效命令|鏃犳晥鍛戒护/i.test(s)||/please attach the correct parameter/i.test(s),c=(t?.extraReject??[]).some(d=>d.test(s));if(o!==0||a||c)throw new Error(s||`emulator exited with code ${o===null?"null":o}`);if(t?.printOutputOnSuccess!==!1&&s){let d=(t?.transformOutput?t.transformOutput(s):s).trim();d&&console.log(d)}}async checkExistingVirtualDevice(e){let t=await this.listEmulators(e.instancePath),n=je(e.name),i=t.find(o=>je(o.name)===n);if(i)if(e.force)await this.deleteVirtualDevice(i.name,e.instancePath);else throw new w(`Emulator "${e.name}" already exists. Use \`--force\` to overwrite.`,"Emulator already exists.");return n}buildCreateVirtualDeviceArgs(e){let t=["-create",e.name,"-deviceType",e.deviceType,"-osVersion",e.osVersion];e.instancePath!==void 0&&t.push("-instancePath",e.instancePath),e.imageRoot!==void 0&&t.push("-imageRoot",e.imageRoot),e.screenProfile!==void 0&&t.push("-screenProfile",e.screenProfile),e.screen?.length&&t.push("-screen",...e.screen),e.storage!==void 0&&t.push("-storage",String(e.storage)),e.memory!==void 0&&t.push("-memory",String(e.memory));let n=e.hotBoot??(tS(e.osVersion)?!0:void 0);return n!==void 0&&t.push("-hotBoot",String(n)),t}async createVirtualDevice(e){let t=await this.checkExistingVirtualDevice(e),n=this.buildCreateVirtualDeviceArgs(e);if(await this.runEmulatorChecked(n,{extraReject:[/Device create fail/i,/already exists/i,/Invalid OS version/i,/cannot be empty/i],printOutputOnSuccess:!0,transformOutput:o=>o.split(/\r?\n/).map(s=>s.trim().startsWith("Device create success.")?"Device create success.":s).join(`
100
+ `)}),!await this.waitForEmulatorPresenceByList(t,e.instancePath))throw new w(`Emulator "${e.name}" was reported as created, but it did not appear in the emulator list within the waiting period. Open the device manager list in DevEco Studio, then run this command again.`,"Emulator was reported as created, but it did not appear in the emulator list within the waiting period.")}async waitForEmulatorPresenceByList(e,t,n=1e4,i=500){let o=Date.now()+n;for(;Date.now()<o;){if((await this.listEmulators(t)).some(c=>je(c.name)===e))return!0;await new Promise(c=>setTimeout(c,i))}return!1}async deleteVirtualDevice(e,t){let n=await this.listEmulators(t),i=je(e),o=n.find(c=>je(c.name)===i);if(!o)throw new w(`Emulator "${e}" not found.`,"Emulator not found.");let s=o.name;if(o.isRunning===!0||await this.isAlreadyRunning(s,o))throw new w(`Failed to delete device: ${s}
101
+ The device may be running.`,"Failed to delete device, The device may be running.");let a=["-delete",s];return t!==void 0&&a.push("-instancePath",t),a.push("-force"),await this.runEmulatorChecked(a,{printOutputOnSuccess:!1}),s}};import{yellow as qM,gray as zM}from"colorette";import JM from"ora";import{green as LO}from"colorette";var FO=[[4352,4447],[9001,9002],[11904,42191],[43360,43388],[44032,55203],[63744,64255],[65040,65049],[65072,65135],[65281,65376],[65504,65510],[127744,129535],[131072,173791],[173824,177983],[177984,178207],[178208,183983],[183984,191456]],$O=[[0,31],[127,159],[768,879],[6832,6911],[7616,7679],[8203,8207],[8400,8447],[65024,65039],[65056,65071],[8205,8205]],jO=new RegExp("\x1B\\[([0-9;]*)[a-zA-Z]","g");function pS(r,e){for(let[t,n]of e)if(r>=t&&r<=n)return!0;return!1}function nm(r){let e=r.replace(jO,""),t=0,n=0;for(;n<e.length;){let i=e.codePointAt(n);if(i===void 0)break;pS(i,$O)||(pS(i,FO)?t+=2:t+=1),n+=i>65535?2:1}return t}function fS(r,e){let t=nm(r);return r+" ".repeat(Math.max(0,e-t))}function HO(r,e){return r.map((t,n)=>{let i=nm(t);for(let o of e){let s=o.cells[n]??"";i=Math.max(i,nm(s))}return i})}function zt(r,e){let t=HO(r,e),n=[];n.push(r.map((i,o)=>fS(i,t[o])).join(" ")),n.push(t.map(i=>"-".repeat(i)).join(" "));for(let i of e){let o=i.cells.map((s,a)=>fS(s??"",t[a])).join(" ").trimEnd();n.push(i.highlight?LO(o):o)}return n.join(`
102
+ `)}import{red as UO}from"colorette";async function N(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=Z(o),console.error(UO(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(r,o)}}async function O(){try{let r=await C.new();return{manager:le.from(r),toolProvider:r}}catch(r){throw new w(`Failed to initialize device manager: ${r.message}`,"Failed to initialize device manager.")}}import{Command as BO,Option as lm}from"commander";import{yellow as dm}from"colorette";import{existsSync as gS}from"fs";import Wr from"ora";function mS(r,e){let t=r.match(e);return t?t[1]:void 0}function im(r){let e=[],t=r.split(/(?=AbilityRecord ID #)/);for(let n of t){let i=n.match(/^\s*state #(\w+)/m);i&&i[1].toUpperCase()==="FOREGROUND"&&e.push({bundleName:mS(n,/app name \[([^\]]+)\]/),abilityName:mS(n,/main name \[([^\]]+)\]/)})}return e}function om(r){let e=[],t=o=>{typeof o.bundleName=="string"&&e.push({bundleName:o.bundleName,label:typeof o.label=="string"?o.label:void 0})},n;try{n=JSON.parse(r)}catch{n=null}if(Array.isArray(n)){for(let o of n)t(o);if(e.length>0)return e}let i=r.match(/\{[^{}]+\}/g)??[];for(let o of i)try{t(JSON.parse(o))}catch{}return e}function sm(r){let e=r.indexOf("{");if(e===-1)return null;try{return JSON.parse(r.slice(e))}catch{return null}}function am(r){let e=r.trim();return{success:!/error:\s*failed to start|error code:\s*\d+|the specified ability does not exist/i.test(e),message:e}}function cm(r){let e=r.hapModuleInfos,t=Array.isArray(e)&&e[0]?e[0]:void 0;return{bundleName:r.name,entryModuleName:r.entryModuleName,mainAbility:t?.mainAbility,versionCode:r.versionCode,versionName:r.versionName}}var yr=class{constructor(e){this.hdcPath=e}async listInstalledApps(e){let t=["-t",e,"shell","bm","dump","-a","-l"];f(`Executing: ${this.hdcPath} ${t.join(" ")}`);let n=await k(this.hdcPath,t);if(n.exitCode!==0)throw new Error(`bm dump -a -l failed: ${(n.stderr||n.stdout).trim()}`);return n.stdout}async getAppInfo(e,t){let n=["-t",e,"shell","bm","dump","-n",t];f(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm dump -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}async getForegroundApp(e){let t=["-t",e,"shell","aa","dump","-l"];f(`Executing: ${this.hdcPath} ${t.join(" ")}`);let n=await k(this.hdcPath,t);if(n.exitCode!==0)throw new Error(`aa dump -l failed: ${(n.stderr||n.stdout).trim()}`);return n.stdout}async startApp(e,t,n,i,o){let s=["-t",e,"shell","aa","start"];t&&s.push("-b",t),n&&s.push("-a",n),i&&s.push("-A",i),o&&s.push("-U",o),f(`Executing: ${this.hdcPath} ${s.join(" ")}`);let a=await k(this.hdcPath,s);if(a.exitCode!==0)throw new Error(`aa start failed: ${(a.stderr||a.stdout).trim()}`);return a.stdout}async clearAppData(e,t){let n=["-t",e,"shell","bm","clean","-d","-n",t];f(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm clean -d -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}async clearAppCache(e,t){let n=["-t",e,"shell","bm","clean","-c","-n",t];f(`Executing: ${this.hdcPath} ${n.join(" ")}`);let i=await k(this.hdcPath,n);if(i.exitCode!==0)throw new Error(`bm clean -c -n ${t} failed: ${(i.stderr||i.stdout).trim()}`);return i.stdout}};function WO(r,e){if(e==="json")console.log(JSON.stringify(r,null,2));else if(r.length>0)for(let t of r){let n=t.label||"";console.log(`${t.bundleName} ${n}`)}else console.log(dm("No installed apps found."))}async function VO(r,e,t="default"){let n=await T(r,e),i=new yr(r.hdcPath),o=Wr({text:"Listing installed apps...",color:"cyan"}).start();try{let s=await i.listInstalledApps(n);o.stop();let a=om(s);WO(a,t)}catch(s){throw o.stop(),new w(`Failed to list apps: ${s.message}`,"Failed to list apps.")}}function GO(r,e){if(r.length>0)if(e==="json")console.log(JSON.stringify(r,null,2));else for(let t of r)console.log(`${t.bundleName??""}#${t.abilityName??""}`);else console.log(e==="json"?"[]":dm("No foreground app."))}async function qO(r,e,t="default"){let n=await T(r,e),i=new yr(r.hdcPath),o=Wr({text:"Querying foreground app...",color:"cyan"}).start();try{let s=await i.getForegroundApp(n);o.stop();let a=im(s);GO(a,t)}catch(s){throw o.stop(),new w(`Failed to get foreground app: ${s.message}`,"Failed to get foreground app.")}}async function zO(r,e,t,n="default"){let i=await T(r,t),o=new yr(r.hdcPath),s=Wr({text:`Querying app info for ${e}...`,color:"cyan"}).start();try{let a=await o.getAppInfo(i,e);s.stop();let c=sm(a);if(!c)throw new w(`No app info found for ${e}. The app may not be installed.`,"No app info found. The app may not be installed.");if(n==="json")console.log(JSON.stringify(c,null,2));else{let l=cm(c);console.log(` bundleName: ${l.bundleName??"-"}`),console.log(` entryModuleName: ${l.entryModuleName??"-"}`),console.log(` mainAbility: ${l.mainAbility??"-"}`),console.log(` versionCode: ${l.versionCode??"-"}`),console.log(` versionName: ${l.versionName??"-"}`)}}catch(a){throw s.stop(),new w(`Failed to get app info: ${a.message}`,"Failed to get app info.")}}async function JO(r,e){if(!e.bundle&&!e.action&&!e.uri)throw new w("At least one of --bundle, --action, or --uri must be provided.","At least one of --bundle, --action, or --uri must be provided.");if(e.bundle&&!e.ability)throw new w("--ability is required when --bundle is specified.","--ability is required when --bundle is specified.");let t=await T(r,e.device),n=new yr(r.hdcPath),i=e.bundle??"(no bundle)",o=Wr({text:`Starting app ${i}...`,color:"cyan"}).start();try{let s=await n.startApp(t,e.bundle,e.ability,e.action,e.uri);o.stop();let{success:a,message:c}=am(s);if(!a)throw new w(`Failed to start app: ${c}`,"Failed to start app. The app or ability may not be installed.");console.log(`App ${i}: ${c}`)}catch(s){throw o.stop(),new w(`Failed to start app: ${s.message}`,"Failed to start app.")}}async function KO(r,e){let t=await T(r,e.device),n=new de(r),i=Wr({text:`Stopping app ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.forceStopApp(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to stop app.");console.log(`Stopped app ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to stop app.")}}function YO(r,e){if(r.length===0&&!e.shared?.length)throw new w("At least one package file or --shared must be provided.","At least one package file or --shared must be provided.");for(let t of r)if(!gS(t))throw new w(`HAP file not found: ${t}`,"HAP file not found.");if(e.shared){for(let t of e.shared)if(!gS(t))throw new w(`Shared HSP file not found: ${t}`,"Shared HSP file not found.")}}function XO(r,e){let t=[];return r.length>0&&t.push(r.length===1?r[0]:`${r.length} packages`),e.shared?.length&&t.push(`${e.shared.length} shared HSP(s)`),t.join(" + ")}async function ZO(r,e,t){let n=await T(r,t.device);YO(e,t);let i={replace:t.replace,shared:t.shared,wait:t.wait,user:t.user},o=new de(r),s=XO(e,t),a=Wr({text:`Installing ${s}...`,color:"cyan"}).start();try{await o.installApp(n,e,i),a.stop(),console.log(`Installed ${s}.`)}catch(c){throw a.stop(),new w(c.message,"Failed to install app.")}}async function QO(r,e){let t=await T(r,e.device),n=new de(r),i=Wr({text:`Uninstalling ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.uninstallApp(t,e.bundle);i.stop(),console.log(o?`Uninstalled ${e.bundle}.`:dm(`${e.bundle} was not installed.`))}catch(o){throw i.stop(),new w(`Failed to uninstall app: ${o.message}`,"Failed to uninstall app.")}}async function e_(r,e){P.assertBundleNameStrict(e.bundle);let t=await T(r,e.device),n=new yr(r.hdcPath),i=Wr({text:`Clearing cache for ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.clearAppCache(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to clear app cache.");console.log(`Cleared cache for ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to clear app cache.")}}async function t_(r,e){P.assertBundleNameStrict(e.bundle);let t=await T(r,e.device),n=new yr(r.hdcPath),i=Wr({text:`Clearing data for ${e.bundle}...`,color:"cyan"}).start();try{let o=await n.clearAppData(t,e.bundle);i.stop();let s=o.trim();if(s&&/error|failed|not found|not installed/i.test(s))throw new w(s,"Failed to clear app data.");console.log(`Cleared data for ${e.bundle}.`)}catch(o){throw i.stop(),new w(o.message,"Failed to clear app data.")}}var Jt=new BO("app").description("Manage apps on a connected device");Jt.command("list").description("List installed apps").option("--device <name|serial>","Target device (name or serial)").addOption(new lm("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","app","list",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await VO(i,e,t)})});Jt.command("foreground").description("Show current foreground app info").option("--device <name|serial>","Target device (name or serial)").addOption(new lm("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","app","foreground",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await qO(i,e,t)})});Jt.command("info").description("Show app info").option("--device <name|serial>","Target device (name or serial)").addOption(new lm("--format <format>","Output format").choices(["default","json"]).default("default")).argument("<bundleName>","Bundle name to query").action(async(r,e)=>{let{device:t,format:n}=e,i={event:v.CommandExecuted,args:["device","app","info","<bundleName>",...n==="json"?["--format","json"]:[],...t?["--device"]:[]]};await N(i,async()=>{let{toolProvider:o}=await O();await zO(o,r,t,n)})});Jt.command("start").description("Start an app on the device").option("--device <name|serial>","Target device (name or serial)").option("--bundle <name>","Bundle name (e.g. com.example.app)").option("--ability <name>","Ability to start (-a)").option("--action <action>","Action to send (-A)").option("--uri <uri>","URI to start with (-U)").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","start",...r.bundle?["--bundle"]:[],...r.ability?["--ability"]:[],...r.action?["--action"]:[],...r.uri?["--uri"]:[],...r.device?["--device"]:[]]};await N(e,async()=>{let{toolProvider:t}=await O();await JO(t,r)})});Jt.command("install").description("Install package(s) on the device").option("--device <name|serial>","Target device (name or serial)").option("--replace","Override install").option("--shared <path>","Inter-app shared HSP path (repeatable)",(r,e)=>[...e,r],[]).option("--wait <seconds>","Install wait time in seconds",r=>parseInt(r,10)).option("--user <userId>","Target user ID").argument("[files...]","Local package path(s) to install (hap/hsp)").action(async(r,e)=>{let t={event:v.CommandExecuted,args:["device","app","install",...r.map(()=>"<file>"),...e.replace?["--replace"]:[],...e.shared?.length?["--shared"]:[],...e.wait!==void 0?["--wait"]:[],...e.user?["--user"]:[],...e.device?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await ZO(n,r,e)})});Jt.command("uninstall").description("Uninstall an app from the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","uninstall","--bundle",...r.device?["--device"]:[]]};await N(e,async()=>{let{toolProvider:t}=await O();await QO(t,r)})});Jt.command("stop").description("Stop an app on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","stop","--bundle",...r.device?["--device"]:[]]};await N(e,async()=>{let{toolProvider:t}=await O();await KO(t,r)})});Jt.command("clearcache").description("Clear app cache on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","clearcache","--bundle",...r.device?["--device"]:[]]};await N(e,async()=>{let{toolProvider:t}=await O();await e_(t,r)})});Jt.command("cleardata").description("Clear app data on the device").option("--device <name|serial>","Target device (name or serial)").requiredOption("--bundle <name>","Bundle name").action(async r=>{let e={event:v.CommandExecuted,args:["device","app","cleardata","--bundle",...r.device?["--device"]:[]]};await N(e,async()=>{let{toolProvider:t}=await O();await t_(t,r)})});import{Command as mn}from"commander";import{red as hS,yellow as r_}from"colorette";import gn from"ora";function qe(r){let e=`${r.stdout}
103
+ ${r.stderr}`;if(/testhelper.*(?:not found|inaccessible)/i.test(e))throw new Error("testhelper is not available on this device. Please upgrade the device system version to support this command.")}var wt=class{constructor(e){this.toolProvider=e}async getDeviceType(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","param","get","const.product.devicetype"])).stdout}async wakeScreen(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","wakeup"])).stdout}async suspendScreen(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","suspend"])).stdout}async getScreenStatus(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-s"])).stdout}async getDisplayInfo(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","DisplayManagerService","-a","-a"])).stdout}async swipeScreen(e,t,n,i,o,s=6e3){let a=await k(this.toolProvider.hdcPath,["-t",e,"shell","uitest","uiInput","swipe",String(t),String(n),String(i),String(o),String(s)]);if(a.exitCode!==0)throw new Error(a.stderr||a.stdout||"swipe failed");return a.stdout}async getTime(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-time"]);return qe(t),t.stdout}async setTime(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-time",t]);return qe(n),n.stdout}async getTimezone(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-timezone"]);return qe(t),t.stdout}async setTimezone(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-timezone",t]);return qe(n),n.stdout}};function pi(r){let e=r.match(/\[DISPLAY INFO\][\s\S]*?Width:\s*(\d+)[\s\S]*?Height:\s*(\d+)/);return e?{width:Number(e[1]),height:Number(e[2])}:null}function um(r){let e=r.match(/Current State:\s*(\w+)/);return e?e[1]:null}var ko=class{constructor(e){this.toolProvider=e}async getDisplayInfo(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","DisplayManagerService","-a","-a"])).stdout}async setScreenTimeout(e,t){return await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-f"]),(await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","timeout","-o",String(t)])).stdout}async setScreenNeverSleep(e){return await k(this.toolProvider.hdcPath,["-t",e,"shell","power-shell","timeout","-r"]),(await k(this.toolProvider.hdcPath,["-t",e,"shell","hidumper","-s","PowerManagerService","-a","-t"])).stdout}};var n_=["phone","tablet"];async function pm(r,e){let i=(await new wt(r).getDeviceType(e)).trim().toLowerCase();if(!n_.includes(i))throw new w(`This command is only supported on phone and tablet devices (current: ${i||"unknown"}).`,"Unsupported device type.")}async function i_(r,e){let t=await T(r,e),n=new wt(r),i=gn({text:"Waking screen...",color:"cyan"}).start();try{let o=await n.wakeScreen(t);i.stop();let s=o.trim();console.log(s||"Screen woken.")}catch(o){throw i.stop(),new w(`Failed to wake screen: ${o.message}`,"Failed to wake screen.")}}async function o_(r,e){let t=await T(r,e),n=new wt(r),i=gn({text:"Suspending screen...",color:"cyan"}).start();try{let o=await n.suspendScreen(t);i.stop();let s=o.trim();console.log(s||"Screen suspended.")}catch(o){throw i.stop(),new w(`Failed to suspend screen: ${o.message}`,"Failed to suspend screen.")}}async function s_(r,e){let t=await T(r,e),n=new wt(r),i=gn({text:"Querying screen status...",color:"cyan"}).start();try{let o=await n.getScreenStatus(t);i.stop();let s=um(o);console.log(s?` Screen State: ${s}`:r_("No screen state found in output."))}catch(o){throw i.stop(),new w(`Failed to get screen status: ${o.message}`,"Failed to get screen status.")}}async function a_(r,e){let t=await T(r,e);await pm(r,t);let n=new wt(r),i=gn({text:"Unlocking screen...",color:"cyan"}).start();try{await n.wakeScreen(t);let o=await n.getDisplayInfo(t),s=pi(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width/2),c=Math.round(s.height*.98),l=c-Math.round(s.height/2);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Screen unlocked: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to unlock screen: ${o.message}`,"Failed to unlock screen.")}}async function c_(r,e){let t=await T(r,e);await pm(r,t);let n=new wt(r),i=gn({text:"Opening control center...",color:"cyan"}).start();try{let o=await n.getDisplayInfo(t),s=pi(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width*4/5),c=Math.round(s.height*.02),l=c+Math.round(s.height/3);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Control center opened: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to open control center: ${o.message}`,"Failed to open control center.")}}async function l_(r,e){let t=await T(r,e);await pm(r,t);let n=new wt(r),i=gn({text:"Opening notification center...",color:"cyan"}).start();try{let o=await n.getDisplayInfo(t),s=pi(o);if(!s)throw new Error("Failed to parse screen resolution from display info");let a=Math.round(s.width/5),c=Math.round(s.height*.02),l=c+Math.round(s.height/3);await n.swipeScreen(t,a,c,a,l),i.stop(),console.log(`Notification center opened: swipe (${a}, ${c}) -> (${a}, ${l})`)}catch(o){throw i.stop(),new w(`Failed to open notification center: ${o.message}`,"Failed to open notification center.")}}var d_=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;async function u_(r,e,t){let n=await T(r,t),i=new wt(r),o=e!==void 0;if(o&&!d_.test(e))throw new w(`Invalid time format. Time must be in 'YYYY-MM-DD HH:MM:SS' format (e.g. "2026-10-13 17:18:07").`,"Invalid time format.");let s=gn({text:o?`Setting time to ${e}...`:"Getting time...",color:"cyan"}).start();try{let a=o?await i.setTime(n,e):await i.getTime(n);s.stop();let c=a.trim();/^error/i.test(c)?(console.error(hS(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Time ${o?"set":"get"} failed: ${a.message}`,`Time ${o?"set":"get"} failed.`)}}async function p_(r,e,t){let n=await T(r,t),i=new wt(r),o=e!==void 0,s=gn({text:o?`Setting timezone to ${e}...`:"Getting timezone...",color:"cyan"}).start();try{let a=o?await i.setTimezone(n,e):await i.getTimezone(n);s.stop();let c=a.trim();/^error/i.test(c)?(console.error(hS(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Timezone ${o?"set":"get"} failed: ${a.message}`,`Timezone ${o?"set":"get"} failed.`)}}var yS=[new mn("wake").description("Wake up the device screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","wake",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await i_(n,e)})}),new mn("sleep").description("Turn off the device screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","sleep",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await o_(n,e)})}),new mn("status").description("Query screen power state").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","status",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await s_(n,e)})}),new mn("unlock").description("Unlock the screen").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","unlock",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await a_(n,e)})}),new mn("open-control-center").description("Open the control center").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","open-control-center",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await c_(n,e)})}),new mn("open-notification-center").description("Open the notification center").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","open-notification-center",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await l_(n,e)})}),new mn("time").description("Get or set the device time").option("--device <name|serial>","Target device (name or serial)").argument("[datetime]","Datetime to set; omit to get current time").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","time",...r?["<datetime>"]:[],...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await u_(i,r,t)})}),new mn("timezone").description("Get or set the device timezone").option("--device <name|serial>","Target device (name or serial)").argument("[timezone]","Timezone to set; omit to get current timezone").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","timezone",...r?["<timezone>"]:[],...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await p_(i,r,t)})})];import{Command as bM,Option as SM}from"commander";import{yellow as EM}from"colorette";import ua from"ora";import{appendFileSync as BZ}from"fs";var Kt={TRACE:10,DEBUG:20,INFO:30,WARN:40,ERROR:50,SILENT:100},vS={10:"TRACE",20:"DEBUG",30:"INFO",40:"WARN",50:"ERROR",100:"SILENT"};function fm(r){if(typeof r=="number")return r;let e=String(r||"").toUpperCase();return e in Kt?Kt[e]:Kt.INFO}function f_(r){return{write:r}}function m_({useStderr:r}={}){return f_((e,t)=>{let n=`${g_[vS[e.level]]||""}${t}`;r||e.level>=Kt.ERROR?process.stderr.write(n+`
104
104
  `):process.stdout.write(n+`
105
- `)})}var $O={TRACE:"",DEBUG:"",INFO:"",WARN:"",ERROR:""};function FO(r){let e=new Date(r),t=(n,i=2)=>String(n).padStart(i,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}.${t(e.getMilliseconds(),3)}`}var Fs=class r{name;level;transports;fields;timestamp;constructor(e={}){this.name=e.name||"hm",this.level=Lm(e.level??"info"),this.transports=e.transports||[_O()],this.fields={...e.fields||{}},this.timestamp=e.timestamp!==!1}child(e,t){return new r({name:e?`${this.name}:${e}`:this.name,level:this.level,transports:this.transports,fields:{...this.fields,...t||{}},timestamp:this.timestamp})}withFields(e){return this.child("",e)}setLevel(e){return this.level=Lm(e),this}addTransport(e){return this.transports.push(e),this}isLevelEnabled(e){return Lm(e)>=this.level}trace(e,...t){this._log(Gt.TRACE,e,t)}debug(e,...t){this._log(Gt.DEBUG,e,t)}info(e,...t){this._log(Gt.INFO,e,t)}warn(e,...t){this._log(Gt.WARN,e,t)}error(e,...t){this._log(Gt.ERROR,e,t)}timeStart(e,t=Gt.DEBUG){let n=Date.now();return i=>{let o=Date.now()-n;return this._log(t,`${e} cost ${o}ms${i?" "+i:""}`,[]),o}}_log(e,t,n){if(e<this.level)return;let i;try{i=typeof t=="string"?t:kb(t),n&&n.length&&(i+=" "+n.map(l=>l instanceof Error?`${l.name}: ${l.message}`:typeof l=="string"?l:kb(l)).join(" "))}catch{i=String(t)}let o=jO(this.fields),a=`${this.timestamp?`[${FO(Date.now())}] `:""}[${Db[e]}] [${this.name}]${o} ${i}`,c={level:e,name:this.name,message:i,fields:{...this.fields},ts:Date.now()};for(let l of this.transports)try{l.write(c,a)}catch{}}};function jO(r){let e=Object.keys(r||{});return e.length?" "+e.map(t=>`${t}=${r[t]}`).join(" "):""}function kb(r){try{return JSON.stringify(r)}catch{return String(r)}}var _m=new Fs({name:"hm",level:"info"});function $m(r={}){return _m=new Fs({name:"hm",...r}),_m}function js(r){return _m.child(r,{})}import{spawn as HO}from"child_process";var yo=class extends Error{code;details;constructor(e,t={}){super(e,t.cause?{cause:t.cause}:void 0),this.name=new.target.name,this.code=t.code||new.target.code||"HM_ERROR",this.details=t.details,Error.captureStackTrace&&Error.captureStackTrace(this,new.target)}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}},li=class extends yo{static code="HDC_ERROR";args;stderr;constructor(e,t={}){super(e,{...t,code:t.code||"HDC_ERROR"}),this.args=t.details?.args||[],this.stderr=t.details?.stderr||""}},mn=class extends li{static code="HDC_TIMEOUT";constructor(e,t={}){super(e,{...t,code:"HDC_TIMEOUT"})}},Hs=class extends li{static code="HDC_COMMAND_FAILED";constructor(e,t={}){super(e,{...t,code:"HDC_COMMAND_FAILED"})}},Rt=class extends yo{static code="DEVICE_ERROR";constructor(e,t={}){super(e,{...t,code:t.code||"DEVICE_ERROR"})}},fn=class extends Rt{static code="DEVICE_NOT_FOUND";constructor(e,t={}){super(e,{...t,code:"DEVICE_NOT_FOUND"})}},gn=class extends Rt{static code="DEVICE_FILE_ERROR";constructor(e,t={}){super(e,{...t,code:"DEVICE_FILE_ERROR"})}},fr=class extends yo{static code="RPC_ERROR";endpoint;constructor(e,t={}){super(e,{...t,code:t.code||"RPC_ERROR"}),this.endpoint=t.details?.endpoint||""}},gr=class extends fr{static code="RPC_LIFECYCLE_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_LIFECYCLE_ERROR"})}},Ur=class extends gr{static code="RPC_DISPOSED";constructor(e,t={}){super(e,{...t,code:"RPC_DISPOSED"})}},je=class extends fr{static code="RPC_TRANSPORT_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_TRANSPORT_ERROR"})}},hn=class extends fr{static code="RPC_TIMEOUT";constructor(e,t={}){super(e,{...t,code:"RPC_TIMEOUT"})}},qt=class extends fr{static code="RPC_PROTOCOL_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_PROTOCOL_ERROR"})}},Us=class extends fr{static code="RPC_REMOTE_ERROR";remote;constructor(e,t={}){super(e,{...t,code:"RPC_REMOTE_ERROR"}),this.remote=t.details?.remote}};function Rb(r){return r instanceof je||r instanceof hn||r instanceof qt}function Fm(r){return r instanceof Ur?!1:Rb(r)||r instanceof gr}var Bs=class{args;code;stdout;stderr;durationMs;constructor({args:e,code:t=0,stdout:n="",stderr:i="",durationMs:o=0}){this.args=e,this.code=t,this.stdout=n,this.stderr=i,this.durationMs=o}get ok(){return this.code===0}get command(){return this.args.join(" ")}assertOk(e="hdc command"){if(this.ok)return this;throw new Hs(`${e} failed: ${this.stderr||this.stdout||`exit ${this.code}`}`,{details:{args:this.args,stderr:this.stderr,stdout:this.stdout,code:this.code}})}toString(){return this.command}},Ws=class{bin;host;port;execTimeoutMs;logger;dfx;constructor(e={}){this.bin=e.bin||"hdc",this.host=e.host||"127.0.0.1",this.port=e.port??8710,this.execTimeoutMs=e.execTimeoutMs??1e4,this.logger=e.logger??null,this.dfx=e.dfx??null}async exec(e,t){throw new li("HdcExecutor.exec() must be implemented by subclass")}get serverAddress(){return`${this.host||"127.0.0.1"}:${this.port??8710}`}serverPrefixArgs(){return(!this.host||this.host==="127.0.0.1"||this.host==="localhost")&&(this.port??8710)===8710?[]:["-s",this.serverAddress]}async listTargets(e){let t=await this.exec(["list","targets"],e);return xb(t.stdout)}};function xb(r){let e=String(r||"").trim();return!e||/\[Empty\]/i.test(e)||/^Empty$/i.test(e)?[]:e.split(/\r?\n/).map(t=>t.trim()).filter(t=>t&&!/\[Empty\]/i.test(t)&&!/^Empty$/i.test(t))}function jm(r){let e=[];for(let t of String(r||"").split(/\r?\n/)){let n=t.trim();if(!n||/\[Empty\]/i.test(n)||/^Empty$/i.test(n))continue;let i=/tcp:(\d+)\s+(\S+)/.exec(n);if(!i)continue;let o=Number(i[1]);Number.isInteger(o)&&e.push({hostPort:o,deviceEndpoint:i[2],taskString:`tcp:${o} ${i[2]}`})}return e}function Hm(r){let e=[];for(let t of String(r||"").split(/\r?\n/)){let n=t.trim();if(!n)continue;let i=/^(\S+)\s+(\d+)\s+(\d+)\s+(.*)$/.exec(n);i&&e.push({user:i[1],pid:Number(i[2]),cmd:i[4]})}return e}var di=class extends Ws{env;onStderr;windowsHide;constructor(e={}){super(e),this.env=e.env||process.env,this.onStderr=e.onStderr??null,this.windowsHide=e.windowsHide!==!1}_childEnv(){let e={...this.env};return this.host&&this.host!=="127.0.0.1"&&(e.HDC_SERVER_IP||(e.HDC_SERVER_IP=this.host),e.HDC_SERVER_PORT||(e.HDC_SERVER_PORT=String(this.port))),e}exec(e,t={}){let n=t.timeoutMs??this.execTimeoutMs,i=Date.now(),o=this.dfx?this.dfx.timer("hdc.exec",{cmd:e[0]}):null,s=[...this.serverPrefixArgs(),...e],a=this._childEnv();return new Promise((c,l)=>{let d=this.spawnHdcChild(s,a,o,l);d&&this.attachChildHandlers(d,e,n,i,o,c,l)})}spawnHdcChild(e,t,n,i){try{return m(`Executing: ${this.bin} ${e.join(" ")}`),HO(this.bin,e,{env:t,stdio:["ignore","pipe","pipe"],windowsHide:this.windowsHide})}catch(o){return n&&n({ok:0}),i(new mn(`spawn ${this.bin} failed: ${o.message}`,{cause:o})),null}}attachChildHandlers(e,t,n,i,o,s,a){let c={outChunks:[],errChunks:[],settled:!1,timedOut:!1,timer:null};c.timer=setTimeout(()=>{c.timedOut=!0;try{e.kill("SIGKILL")}catch{}},n),e.stdout?.on("data",l=>{c.outChunks.length<4096&&c.outChunks.push(l)}),e.stderr?.on("data",l=>{c.errChunks.push(l),this.onStderr&&this.onStderr(l.toString())}),e.on("close",l=>{this.finalizeResult(l,t,n,i,o,c,s,a)}),e.on("error",l=>{this.handleChildError(l,t,o,c,a)})}finalizeResult(e,t,n,i,o,s,a,c){if(s.settled)return;s.settled=!0,s.timer&&clearTimeout(s.timer);let l=Buffer.concat(s.outChunks).toString("utf8").trim(),d=Buffer.concat(s.errChunks).toString("utf8").trim(),g=Date.now()-i;if(o&&o({ok:e===0?1:0}),this.dfx&&this.dfx.counter(e===0?"hdc.exec.ok":"hdc.exec.error",1,{cmd:t[0]}),this.logger&&this.logger.debug(`hdc ${t.join(" ")} -> code=${e} (${g}ms)`),s.timedOut){c(new mn(`hdc ${t.join(" ")} timeout after ${n}ms`,{details:{args:t,stdout:l,stderr:d}}));return}a(new Bs({args:t,code:e??-1,stdout:l,stderr:d,durationMs:g}))}handleChildError(e,t,n,i,o){i.settled||(i.settled=!0,i.timer&&clearTimeout(i.timer),n&&n({ok:0}),o(new mn(`hdc ${t.join(" ")} spawn error: ${e.message}`,{cause:e})))}};var Ab=Object.freeze({hdc:{bin:"hdc",host:"127.0.0.1",port:8710,execTimeoutMs:1e4,maxOutputBytes:4194304},device:{autoSelectFirst:!0,queryVersion:!0,newUiTestMinVersion:"6.0.2.2",autoPushResources:!0,resourcesDir:"",fastModeDir:""},rpc:{mode:"fast",framing:"auto",connectTimeoutMs:5e3,requestTimeoutMs:3e4,socketIdleTimeoutMs:3e4,portRange:{start:1e4,end:19999},concurrency:"auto",maxInFlight:16,strictPairing:!1,timeoutKillsConnection:!1,recovery:{enabled:!0,maxAttempts:1,delayMs:200},fast:{connectTimeoutMs:1500,probeOnReuse:!0,keepOnRelease:!0,forceRestartOnProbeFailure:!0},operate:{fastHostPort:19801,startWaitMs:500,processWaitTimeoutMs:15e3,processCheckIntervalMs:200,checkListening:!0,resources:[]}},log:{level:"info",timestamp:!0,transports:["console"],file:""},dfx:{enabled:!0,sinks:["memory"],slowThresholdMs:1e3}}),UO={HM_HDC_BIN:"hdc.bin",HM_HDC_HOST:"hdc.host",HM_HDC_PORT:"hdc.port",HM_LOG_LEVEL:"log.level",HM_RPC_MODE:"rpc.mode",HM_RPC_REQUEST_TIMEOUT:"rpc.requestTimeoutMs"};function Al(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function Um(r){if(typeof structuredClone=="function")try{return structuredClone(r)}catch{}return JSON.parse(JSON.stringify(r))}function xl(r,e){let t=Um(r);for(let[n,i]of Object.entries(e||{}))i!==void 0&&(Al(i)&&Al(t[n])?t[n]=xl(t[n],i):t[n]=Um(i));return t}function BO(r,e){return e.split(".").reduce((t,n)=>{if(!(t==null||typeof t!="object"))return t[n]},r)}function Ib(r,e,t){let n=e.split("."),i=n.pop(),o=r;for(let s of n)Al(o[s])||(o[s]={}),o=o[s];return o[i]=t,r}var Il=class{_data;constructor(e={}){this._data=xl(Ab,WO()),e&&Object.keys(e).length&&(this._data=xl(this._data,e))}slice(e){let t=this.get(e);return Al(t)?t:{}}get(e,t){let n=BO(this._data,e);return n===void 0?t:n}set(e,t){return Ib(this._data,e,t),this}merge(e){return this._data=xl(this._data,e),this}snapshot(){return Um(this._data)}toJSON(){return this.snapshot()}};function WO(){let r={};for(let[e,t]of Object.entries(UO)){let n=process.env[e];if(n===void 0||n==="")continue;let i=n;if(t==="hdc.port"||t==="rpc.requestTimeoutMs"){let o=Number(n);if(Number.isNaN(o))continue;i=o}Ib(r,t,i)}return r}function Vs(r){return new Il(r)}var Tl=class{records;constructor(){this.records=[]}write(e){this.records.push(e)}select(e){return this.records.filter(t=>typeof e=="function"?e(t.name):t.name===e||t.name.startsWith(e+"."))}sum(e){return this.select(e).reduce((t,n)=>t+(n.value||0),0)}count(e){return this.select(e).length}snapshot(){return{counters:Tb(this.records,"counter"),timers:Tb(this.records,"timer"),events:this.records.filter(e=>e.type==="event").map(e=>({name:e.name,fields:e.fields,ts:e.ts}))}}reset(){this.records.length=0}};function Tb(r,e){let t={};for(let n of r){if(n.type!==e)continue;t[n.name]||(t[n.name]={count:0,sum:0,min:1/0,max:0,avg:0});let i=e==="counter"?n.value||0:n.durationMs||0;t[n.name].count+=1,t[n.name].sum+=i,t[n.name].min=Math.min(t[n.name].min,i),t[n.name].max=Math.max(t[n.name].max,i)}for(let n of Object.keys(t))t[n].avg=t[n].sum/t[n].count,t[n].min===1/0&&(t[n].min=0);return t}var Ol=class r{enabled;tags;sinks;slowThresholdMs;logger;constructor(e={}){this.enabled=e.enabled!==!1,this.tags={...e.tags||{}},this.sinks=e.sinks||[new Tl],this.slowThresholdMs=e.slowThresholdMs??1e3,this.logger=e.logger??null}child(e){return new r({enabled:this.enabled,sinks:this.sinks,tags:{...this.tags,...e||{}},slowThresholdMs:this.slowThresholdMs,logger:this.logger})}counter(e,t=1,n={}){this._emit({type:"counter",name:e,value:t,fields:n})}event(e,t={}){this._emit({type:"event",name:e,fields:t})}timer(e,t={}){let n=Date.now();return(i={})=>{let o=Date.now()-n;return this._emit({type:"timer",name:e,fields:{...t,...i},durationMs:o}),this.slowThresholdMs>0&&o>this.slowThresholdMs&&this._emit({type:"event",name:"slow",fields:{...t,...i,metric:e,durationMs:o}}),o}}async span(e,t,n={}){let i=this.timer(e,n);try{let o=await t();return i({ok:1}),this.counter(`${e}.ok`,1,n),o}catch(o){throw i({ok:0}),this.counter(`${e}.error`,1,{...n,code:o?.code||o?.name}),o}}_emit(e){if(!this.enabled)return;let t={type:e.type,name:e.name,value:e.value,durationMs:e.durationMs,fields:{...this.tags,...e.fields||{}},ts:Date.now()};for(let n of this.sinks)try{n.write(t)}catch{}}snapshot(){let e=this.sinks.find(t=>t instanceof Tl);return e?e.snapshot():null}reset(){for(let e of this.sinks)typeof e.reset=="function"&&e.reset()}};function Gs(r={}){return new Ol(r)}function wo(r){return new Promise(e=>setTimeout(e,r))}async function Nl(r,{timeoutMs:e,intervalMs:t=200,firstDelayMs:n=0,description:i="condition"}){let o=Date.now()+e;n>0&&await wo(n);let s;for(;;){if(s=await r(),s)return s;if(Date.now()>=o){let a=new Error(`wait for ${i} timeout after ${e}ms`);throw a.name="TimeoutError",a}await wo(t)}}var vo=class{_tail;locked;constructor(){this._tail=Promise.resolve(),this.locked=!1}async runExclusive(e){let t,n=new Promise(o=>{t=o}),i=this._tail;this._tail=i.then(()=>n),await i.catch(()=>{}),this.locked=!0;try{return await e()}finally{this.locked=!1,t()}}},bo=class{limit;used;_waiters;_idleWaiters;constructor(e=1){this.limit=Math.max(1,e|0),this.used=0,this._waiters=[],this._idleWaiters=[]}get available(){return Math.max(0,this.limit-this.used)}get waiting(){return this._waiters.length}get isIdle(){return this.used===0}acquire(){return new Promise((e,t)=>{this._waiters.push({resolve:e,reject:t}),this._dispatch()})}resize(e){let t=Math.max(1,e|0);t!==this.limit&&(this.limit=t,this._dispatch())}abortAll(e){let t=this._waiters.splice(0);for(let n of t)try{n.reject(e)}catch{}}drain(){return this.used===0?Promise.resolve():new Promise(e=>{this._idleWaiters.push({resolve:e})})}_dispatch(){for(;this._waiters.length>0&&this.used<this.limit;){let e=this._waiters.shift();this.used+=1;let t=!1;e.resolve(()=>{t||(t=!0,this.used-=1,this._dispatch(),this.used===0&&this._idleWaiters.length&&this._resolveIdleWaiters())})}}_resolveIdleWaiters(){let e=this._idleWaiters.splice(0);for(let t of e)t.resolve()}},ui=class{_map;constructor(){this._map=new Map}run(e,t){let n=this._map.get(e);if(n)return n;let o=(async()=>t())().finally(()=>{this._map.get(e)===o&&this._map.delete(e)});return this._map.set(e,o),o}pending(e){return this._map.get(e)||null}has(e){return this._map.has(e)}keys(){return[...this._map.keys()]}};var VO=64*1024*1024,Bm={name:"length-prefixed",frameDelimited:!0,encode(r){let e=Buffer.from(typeof r=="string"?r:JSON.stringify(r),"utf8"),t=Buffer.alloc(4);return t.writeUInt32BE(e.length,0),Buffer.concat([t,e])},decode(r){if(r.length<4)return null;let e=r.readUInt32BE(0);if(e>VO||e<0)throw new qt(`invalid frame length ${e}`);if(r.length<4+e)return null;let t=r.subarray(4,4+e).toString("utf8"),n;try{n=JSON.parse(t)}catch{throw new qt(`response is not valid JSON: ${t.slice(0,200)}`)}return{value:n,rest:r.subarray(4+e)}}},Ml={name:"raw",frameDelimited:!1,encode(r){return Buffer.from(typeof r=="string"?r:JSON.stringify(r),"utf8")},decode(r){let e=r.toString("utf8").trim();if(!e)return null;let t;try{t=JSON.parse(e)}catch{return null}return{value:t,rest:Buffer.alloc(0)}}};function GO(r){if(!r||r.length===0)return null;let e=r[0];return e===123||e===91?"raw":"length-prefixed"}function Wm(r="auto"){return r==="raw"?Ml:r==="length-prefixed"?Bm:qO()}function qO(){let r=null;return{name:"auto",frameDelimited:!1,get detected(){return r},encode(e){return Ml.encode(e)},decode(e){return r||(r=GO(e)),r==="length-prefixed"?Bm.decode(e):Ml.decode(e)}}}var Vm=0;function hr(r="hm"){Vm=(Vm+1)%1e6;let e=new Date().toISOString().replace(/[-:T]/g,"").replace(/\..+/,""),t=Math.random().toString(36).slice(2,8);return`${r}-${e}-${Vm.toString(36)}-${t}`}import Gm from"net";function qm(r,e,t=500){return new Promise(n=>{let i=new Gm.Socket,o=!1,s=a=>{o||(o=!0,i.destroy(),n(a))};i.setTimeout(t),i.once("connect",()=>s(!0)),i.once("timeout",()=>s(!1)),i.once("error",()=>s(!1));try{i.connect(e,r)}catch{s(!1)}})}async function zm({host:r="127.0.0.1",start:e=1e4,end:t=19999,exclude:n}={}){let i=new Set(n||[]);for(let o=e;o<=t;o++){if(i.has(o))continue;if(await JO(r,o))return o}throw new Error(`no free port in range ${e}-${t}`)}var zO=zm;function JO(r,e){return new Promise(t=>{let n=Gm.createServer();n.once("error",()=>t(!1)),n.once("listening",()=>{n.close(()=>t(!0))}),n.listen(e,r)})}async function YO({host:r="127.0.0.1",start:e=1e4,end:t=19999,exclude:n,timeoutMs:i=500,stepDelayMs:o=0}={}){if(!r)throw new Error("getFreeRemotePort requires host");let s=new Set(n||[]);for(let a=e;a<=t;a++){if(s.has(a))continue;if(!await qm(r,a,i))return a;o>0&&await new Promise(l=>setTimeout(l,o))}throw new Error(`no free port on remote ${r} in range ${e}-${t}`)}async function Ob({hdcHost:r="127.0.0.1",start:e,end:t,exclude:n}={}){return!r||r==="127.0.0.1"||r==="localhost"?{port:await zO({host:r||"127.0.0.1",start:e,end:t,exclude:n}),scope:"local"}:{port:await YO({host:r,start:e,end:t,exclude:n,stepDelayMs:50}),scope:"remote"}}function Ll({host:r,port:e,timeoutMs:t=5e3,keepAliveMs:n}){return new Promise((i,o)=>{let s=new Gm.Socket,a=!1,c=l=>{a||(a=!0,s.destroy(),o(l))};s.setTimeout(t),s.once("timeout",()=>{let l=new Error(`connect to ${r}:${e} timeout after ${t}ms`);l.code="ETIMEDOUT",c(l)}),s.once("error",c),s.connect(e,r,()=>{a||(a=!0,s.removeListener("error",c),s.removeListener("timeout",c),n&&n>0&&s.setKeepAlive(!0,n),s.setNoDelay(!0),i(s))})})}function zt(r,e){let t=Nb(r),n=Nb(e),i=Math.max(t.length,n.length);for(let o=0;o<i;o++){let s=t[o]??0,a=n[o]??0;if(s>a)return 1;if(s<a)return-1}return 0}function Nb(r){return String(r||"").trim().split(/[.\-+_]/).filter(Boolean).map(e=>{let t=parseInt(e,10);return Number.isNaN(t)?0:t})}function So(r){let e=/(\d+(?:\.\d+)+)/.exec(String(r||""));return e?e[1]:null}var KO=/^[A-Za-z0-9_@%+=:,./-]+$/,XO=/'/g,ZO="'\\''";function pi(r){let e=r==null?"":String(r);return e===""?"''":KO.test(e)?e:`'${e.replace(XO,ZO)}'`}function xt(r){if(!Array.isArray(r))throw new TypeError("shellJoin expects an array of arguments");return r.filter(e=>e!=null&&e!=="").map(e=>pi(e)).join(" ")}function Jm(r){let e=String(r??"");if(/[\r\n\0]/.test(e))throw new yr("shell command must not contain newline or NUL characters");return e}function wr(r){let e=String(r??"").trim();if(!e)throw new yr("remote path is empty");if(!e.startsWith("/"))throw new yr(`remote path must be absolute: ${JSON.stringify(r)}`);if(/[\r\n\0]/.test(e))throw new yr("remote path must not contain newline or NUL characters");return e}function Ym(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new yr(`invalid pid: ${JSON.stringify(r)}`);return e}function _l(r){let e=String(r??"").trim();if(!/^(localabstract|localfilesystem|tcp|jdwp):[A-Za-z0-9_.-]+$/.test(e))throw new yr(`invalid device endpoint: ${JSON.stringify(r)}`);return e}function $l(r){let e=Number(r);if(!Number.isInteger(e)||e<1||e>65535)throw new yr(`invalid host port: ${JSON.stringify(r)}`);return e}var yr=class extends Error{constructor(e){super(e),this.name="ShellSafetyError"}};import{stat as NN}from"fs/promises";var nN="6.0.2.2";async function Mb(r,e={}){let t=e.minVersion||nN,n=(await r.shellArgs(["file","/system/bin/uitest"])).trim(),i=/x86[ _-]64/.test(n)?"x86_64":"arm64",o=(await r.shellArgs(["/system/bin/uitest","--version"])).trim(),s=iN(o)||o,a=zt(s,t)>=0;return{version:s,arch:i,isNewUiTest:a,endpointStyle:a&&i!=="x86_64"?"unix":"tcp",fileOutput:n}}function iN(r){let e=/(\d+(?:\.\d+)+)/.exec(String(r||""));return e?e[1]:null}import{fileURLToPath as dN}from"url";import{dirname as uN,join as $b}from"path";import{readdirSync as oN}from"fs";import{join as sN,basename as s9}from"path";var aN=/^uitest_agent_v(\d+\.\d+\.\d+)(\.x86_64)?\.so$/,cN="/data/local/tmp/agent.so",Km="UITEST_AGENT_LIBRARY";function lN(r){let e;try{e=oN(r)}catch{return[]}return e.filter(t=>t.endsWith(".so"))}function Lb({dir:r,arch:e,isNewUiTest:t}){let n=e==="x86_64",i=[];for(let s of lN(r)){let a=aN.exec(s);if(!a)continue;let c=!!a[2];if(n!==c)continue;if(n){i.push({fileName:s,version:a[1],x86_64:c});continue}let l=zt(a[1],"1.2.2")>=0;t===l&&i.push({fileName:s,version:a[1],x86_64:c})}if(!i.length)return null;i.sort((s,a)=>zt(a.version,s.version));let o=i[0];return{fileName:o.fileName,localPath:sN(r,o.fileName),version:o.version,x86_64:o.x86_64,remotePath:cN,versionProbe:Km}}function _b(r){let e=String(r||""),t=e.indexOf("#"),n=t>=0?e.slice(t+1):e;return So(n)}var pN=$b(uN(dN(import.meta.url)),"..",".."),mN=$b(pN,"resources"),Fl=class{device;config;logger;dfx;_agentState;constructor({device:e,config:t,logger:n,dfx:i}){this.device=e,this.config=t,this.logger=n?n.child("ResourceMgr"):null,this.dfx=i??null,this._agentState=null}get resourcesDir(){return this.config.get("device.resourcesDir")||mN}async getInfo(e=!1){return this.device.getUitestInfo(e)}async ensureAgent(e={}){if(this._agentState&&!e.force)return this._agentState;let t=await this.getInfo(),n=Lb({dir:this.resourcesDir,arch:t.arch,isNewUiTest:t.isNewUiTest});if(!n)throw new Rt(`no uitest agent found for arch=${t.arch} isNewUiTest=${t.isNewUiTest} in ${this.resourcesDir}`,{details:{resourcesDir:this.resourcesDir}});let i=await this.device.fileExists(n.remotePath),o=null,s=!i;return i&&(o=await this._probeAgentVersion(n.remotePath),(!o||zt(n.version,o)>0)&&(s=!0)),s?(this.logger&&this.logger.info(`update agent.so: local=v${n.version} remote=${o||"none"} (arch=${n.x86_64?"x86_64":"arm64"})`),await this.stopUitestDaemons(),await this.device.rm(n.remotePath),await this._push(n.localPath,n.remotePath,"agent.so"),this.dfx&&this.dfx.counter("resource.agent.update",1,{arch:t.arch})):this.logger&&this.logger.debug(`agent.so up-to-date: v${o}`),this._agentState={candidate:n,updated:s,remoteVersion:o},this._agentState}async repushAgent(){let e=this._agentState?.candidate;e||(e=(await this.ensureAgent()).candidate),this.logger&&this.logger.info(`repush agent.so unconditionally (suspect corruption): ${e.fileName}`),await this.stopUitestDaemons(),await this.device.rm(e.remotePath),await this._push(e.localPath,e.remotePath,"agent.so"),this.dfx&&this.dfx.counter("resource.agent.repush",1,{file:e.fileName}),this._agentState={candidate:e,updated:!0,remoteVersion:e.version}}async _probeAgentVersion(e){try{let t=await this.device.shell(`cat ${pi(e)} | ${xt(["grep","-a",Km])}`);return _b(t)}catch{return null}}async _push(e,t,n){let i=this.dfx?this.dfx.timer("resource.push",{file:n}):null;await this.device.fileSend(e,t),i&&i({ok:1})}async stopUitestDaemons(){let t=(await this.device.findProcesses()).filter(n=>n.cmd.includes("uitest")&&n.cmd.includes("start-daemon")).map(n=>n.pid);for(let n of t)try{await this.device.killProcess(n)}catch(i){this.logger&&this.logger.debug(`kill daemon pid=${n} failed: ${i.message}`)}return t.length&&this.logger&&this.logger.info(`stopped uitest daemons before agent update: [${t.join(", ")}]`),t.length}};import{join as Xm}from"path";import{mkdir as fN,readFile as Fb,writeFile as jb,unlink as gN,readdir as hN}from"fs/promises";function yN(r){return String(r||"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}var wN=Xm($(),"fast-mode"),jl=class{config;logger;_explicitDir;constructor({config:e,dir:t,logger:n}={}){this.config=e,this.logger=n?n.child("FastModeStore"):null,this._explicitDir=t}get dir(){if(this._explicitDir)return this._explicitDir;if(this.config){let e=this.config.get("device.fastModeDir");if(e)return e}return wN}pathFor(e){return Xm(this.dir,`${yN(e)}.json`)}async _ensureDir(){await fN(this.dir,{recursive:!0,mode:448})}async save(e,t){await this._ensureDir();let n=await this.read(e)||{serial:e,createdAt:new Date(0).toISOString(),updatedAt:new Date(0).toISOString(),endpoints:{}};n.serial=e,n.updatedAt=new Date().toISOString(),(!n.createdAt||n.createdAt===new Date(0).toISOString())&&(n.createdAt=n.updatedAt),n.hdcServer=t.hdcServer||n.hdcServer||"",n.endpoints[t.endpoint]={hostPort:t.hostPort,deviceEndpoint:t.deviceEndpoint,style:t.style,agentVersion:t.agentVersion||null,uitestVersion:t.uitestVersion||null,savedAt:n.updatedAt};let i=this.pathFor(e);return await jb(i,JSON.stringify(n,null,2),{mode:384}),this.logger&&this.logger.debug(`saved fast-mode state for ${e}: ${t.endpoint} -> tcp:${t.hostPort}`),n}async read(e){try{let t=await Fb(this.pathFor(e),"utf8"),n=JSON.parse(t);return!n||typeof n!="object"||!n.endpoints?null:n}catch{return null}}async get(e,t){let n=await this.read(e);return n&&n.endpoints&&n.endpoints[t]||null}async forget(e){try{return await gN(this.pathFor(e)),this.logger&&this.logger.debug(`removed fast-mode state for ${e}`),!0}catch{return!1}}async forgetEndpoint(e,t){let n=await this.read(e);return!n||!n.endpoints[t]?!1:(n.endpoints=Object.fromEntries(Object.entries(n.endpoints).filter(([i])=>i!==t)),Object.keys(n.endpoints).length?(await this._ensureDir(),await jb(this.pathFor(e),JSON.stringify(n,null,2),{mode:384}),!0):this.forget(e))}async list(){let e;try{e=await hN(this.dir)}catch{return[]}let t=[];for(let n of e)if(n.endsWith(".json"))try{t.push(JSON.parse(await Fb(Xm(this.dir,n),"utf8")))}catch{}return t}};var vr={AUTO:"auto",PIPELINED:"pipelined",SERIAL:"serial"},qs=class{host;port;name;codec;frameDelimited;concurrency;maxInFlight;strictPairing;timeoutKillsConnection;connectTimeoutMs;requestTimeoutMs;socketIdleTimeoutMs;logger;dfx;socket;buffer;pending;_sem;generation;_closed;_failure;onClose;_serverEchoesRequestId;_seq;stats;constructor(e){this.host=e.host||"127.0.0.1",this.port=e.port,this.name=e.name||"rpc",this.codec=Wm(e.framing||"auto"),this.frameDelimited=this.codec.frameDelimited===!0,this.concurrency=e.concurrency||vr.AUTO,this.maxInFlight=Math.max(1,e.maxInFlight??16),this.strictPairing=e.strictPairing===!0,this.timeoutKillsConnection=e.timeoutKillsConnection===!0,this.connectTimeoutMs=e.connectTimeoutMs??5e3,this.requestTimeoutMs=e.requestTimeoutMs??3e4,this.socketIdleTimeoutMs=e.socketIdleTimeoutMs??3e4,this.logger=e.logger??null,this.dfx=e.dfx??null,this.socket=null,this.buffer=Buffer.alloc(0),this.pending=new Map,this._sem=new bo(this._initialLimit()),this.generation=0,this._closed=!0,this._failure=null,this.onClose=null,this._serverEchoesRequestId=null,this._seq=0,this.stats={connectCount:0,requestCount:0,bytesIn:0,bytesOut:0,maxInFlight:0,timeouts:0,unmatchedResponses:0,queued:0}}get isConnected(){return!!this.socket&&!this.socket.destroyed&&!this._closed}get inFlight(){return this.pending.size}get concurrencyMode(){return this.concurrency===vr.SERIAL?"serial":this.frameDelimited?this.concurrency===vr.PIPELINED?"pipelined":this._serverEchoesRequestId===!0?"pipelined(auto)":"serial(auto)":"serial(raw)"}async connect(e={}){await this.destroy();let t=e.port??this.port,n=e.timeoutMs??this.connectTimeoutMs,i=this.dfx?this.dfx.timer("rpc.connect",{endpoint:this.name}):null;try{this.socket=await Ll({host:this.host,port:t,timeoutMs:n})}catch(a){let c=a;throw i&&i({ok:0}),this.dfx&&this.dfx.counter("rpc.connect.error",1,{endpoint:this.name}),new je(`connect ${this.host}:${t} failed: ${c.message}`,{cause:c,details:{endpoint:this.name,host:this.host,port:t}})}let o=++this.generation;this._postConnectSetup(),i&&i({ok:1}),this.dfx&&this.dfx.counter("rpc.connect.ok",1,{endpoint:this.name});let s=this.socket;s.setTimeout(this.socketIdleTimeoutMs),this._attachSocketHandlers(s,o),this.logger&&this.logger.info(`connected to ${this.host}:${t} (${this.name}, gen=${o})`)}_postConnectSetup(){this._closed=!1,this._failure=null,this.buffer=Buffer.alloc(0),this.pending.clear(),this._serverEchoesRequestId=null,this._sem.resize(this._computeLimit()),this.stats.connectCount+=1}_attachSocketHandlers(e,t){e.on("data",n=>{t===this.generation&&this._onData(n)}),e.on("error",n=>{t===this.generation&&this._fail(new je(`socket error: ${n.message}`,{cause:n}))}),e.on("timeout",()=>{t===this.generation&&this._fail(new hn(`socket idle timeout after ${this.socketIdleTimeoutMs}ms`))}),e.on("close",()=>{t===this.generation&&this._fail(new je("connection closed by peer"))})}_onData(e){this.stats.bytesIn+=e.length,this.buffer=Buffer.concat([this.buffer,e]);try{for(;;){let t=this.codec.decode(this.buffer);if(!t)break;this.buffer=t.rest,this._dispatch(t.value)}}catch(t){let n=t;this._fail(n instanceof qt?n:new qt(`decode failed: ${n.message}`))}}_dispatch(e){let t=e,n=t&&typeof t=="object"?t.request_id:void 0,i=null;if(n!=null&&this.pending.has(n)?i=n:n==null&&(this.pending.size===1&&(i=[...this.pending.keys()][0]),this._noteNoRequestId()),i==null){this.stats.unmatchedResponses+=1,this.dfx&&this.dfx.counter("rpc.response.unmatched",1,{endpoint:this.name,hasId:String(n!=null)}),this.logger&&this.logger.warn(`drop unmatched response (request_id=${n}, pending=${this.pending.size})`),this.strictPairing&&this._fail(new qt(`unmatched response, request_id=${n}, pending=${this.pending.size}`));return}let o=this.pending.get(i);this.pending.delete(i),o.timer&&clearTimeout(o.timer),n!=null&&this._serverEchoesRequestId!==!0&&(this._serverEchoesRequestId=!0,this._applyLimit()),o.resolve(e)}_noteNoRequestId(){this._serverEchoesRequestId!==!1&&(this._serverEchoesRequestId=!1,this._applyLimit(),this.logger&&this.logger.warn("server does not echo request_id, degrade to serial mode for this connection"),this.dfx&&this.dfx.counter("rpc.concurrency.degrade",1,{endpoint:this.name}))}_computeLimit(){return this.concurrency===vr.SERIAL||!this.frameDelimited?1:this.concurrency===vr.PIPELINED?this.maxInFlight:this._serverEchoesRequestId===!0?this.maxInFlight:1}_initialLimit(){return this.concurrency===vr.SERIAL||!this.frameDelimited?1:this.concurrency===vr.PIPELINED?this.maxInFlight:1}_applyLimit(){this._sem.resize(this._computeLimit())}_nextRequestId(e){if(e!=null&&!this.pending.has(String(e)))return String(e);let t=hr();for(;this.pending.has(t);)t=hr();return t}async send(e,t={}){this._assertUsable();let n=await this._acquireSendSlot();try{this._assertUsable();let i=this.generation,o=t.timeoutMs??this.requestTimeoutMs,s=this._nextRequestId(e&&e.request_id),a={...e,request_id:s},c=++this._seq,l=this.dfx?this.dfx.timer("rpc.request",{endpoint:this.name}):null,d=await this._awaitResponse(s,a,i,c,o,l);return l&&l({ok:1}),this.dfx&&this.dfx.counter("rpc.request.ok",1,{endpoint:this.name}),d}finally{n&&n()}}async _acquireSendSlot(){let e=null;try{(this._sem.available<=0||this._sem.waiting>0)&&(this.stats.queued+=1),e=await this._sem.acquire()}catch(t){let n=t;throw new je(`request rejected while queued: ${n.message}`,{cause:n,details:{endpoint:this.name}})}return e}_awaitResponse(e,t,n,i,o,s){return new Promise((a,c)=>{let l={resolve:a,reject:c,timer:null,t0:Date.now(),gen:n,seq:i},d=this._createSettleFn(e,l);l.timer=setTimeout(()=>this._onRequestTimeout(e,o,s,d,c),o),this._registerPending(e,l),this._writeFrame(t,i,d,c)})}_createSettleFn(e,t){return(n,i)=>{this.pending.get(e)===t&&(this.pending.delete(e),t.timer&&clearTimeout(t.timer),n(i))}}_onRequestTimeout(e,t,n,i,o){this.stats.timeouts+=1;let s=new hn(`rpc request ${e} timeout after ${t}ms`,{details:{endpoint:this.name,requestId:e}});n&&n({ok:0,reason:"timeout"}),this.dfx&&this.dfx.counter("rpc.request.error",1,{endpoint:this.name,reason:"timeout"}),i(o,s),this.timeoutKillsConnection&&this._fail(s)}_registerPending(e,t){this.pending.set(e,t),this.stats.requestCount+=1,this.stats.maxInFlight=Math.max(this.stats.maxInFlight,this.pending.size)}_writeFrame(e,t,n,i){let o=!1;try{let s=this.codec.encode(e);this.stats.bytesOut+=s.length,this.logger&&this.logger.debug(`-> ${this.name} #${t} ${JSON.stringify(e).slice(0,300)}`);let a=this.socket;if(!a)throw new je("socket is null");o=a.write(s,c=>{c&&n(i,new je(`write failed: ${c.message}`,{cause:c}))})}catch(s){let a=s;n(i,new je(`write failed: ${a.message}`,{cause:a}));return}!o&&this.logger&&this.logger.debug(`socket backpressure on #${t}`)}_assertUsable(){if(!this.isConnected)throw new je(this._failure?`connection broken: ${this._failure.message}`:"transport is not connected",{cause:this._failure||void 0,details:{endpoint:this.name}})}_fail(e){if(!(this._closed&&this.pending.size===0&&this._sem.waiting===0)&&(this._failure=e,this._rejectAll(e),this._closeSocket(),this.onClose))try{this.onClose(e)}catch{}}_rejectAll(e){let t=[...this.pending.values()];this.pending.clear();for(let n of t){n.timer&&clearTimeout(n.timer);try{n.reject(e)}catch{}}this._sem.abortAll(e)}_closeSocket(){this._closed=!0,this.generation+=1;let e=this.socket;if(this.socket=null,e){e.removeAllListeners();try{e.destroy()}catch{}}}async close(e="closed by client"){let t=new je(`transport closed: ${e}`);this._failure=null,this._rejectAll(t),this._closeSocket(),this.logger&&this.logger.debug(`transport closed: ${e}`)}async destroy(){await this.close("destroy")}getSnapshot(){return{name:this.name,host:this.host,port:this.port,connected:this.isConnected,generation:this.generation,concurrency:this.concurrency,concurrencyMode:this.concurrencyMode,maxInFlight:this._sem.limit,inFlight:this.pending.size,queued:this._sem.waiting,serverEchoesRequestId:this._serverEchoesRequestId,stats:{...this.stats}}}};var Hl="com.ohos.devicetest.hypiumApiHelper",Zm="callHypiumApi";function Ul({module:r,method:e,params:t={},requestId:n}){return{module:r,method:e,params:t,request_id:n||hr()}}function Bl(r){if(!r||typeof r!="object")return!1;let e=r.exception;return e!=null&&e!==""}function Wl(r){return r?r.result:void 0}var ke={IDLE:"IDLE",BOOTING:"BOOTING",RESOURCES_READY:"RESOURCES_READY",PROCESS_RUNNING:"PROCESS_RUNNING",FORWARDED:"FORWARDED",CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",READY:"READY",WARM:"WARM",RESETTING:"RESETTING",ERROR:"ERROR",DISPOSED:"DISPOSED"},zs=class{device;endpoint;config;name;displayName;logger;dfx;mode;state;transport;_mutex;_epoch;_readyFlight;_resetFlight;_disposed;ctx;constructor({device:e,endpoint:t,config:n,logger:i,dfx:o,mode:s}){this.device=e,this.endpoint=t,this.config=n,this.name=t.name,this.displayName=t.displayName||t.name,this.logger=i?i.child(`Rpc:${this.displayName}`):null,this.dfx=o?o.child({endpoint:this.name}):null,this.mode=s||n.get("rpc.mode","stable"),this.state=ke.IDLE,this.transport=null,this._mutex=new vo,this._epoch=0,this._readyFlight=new ui,this._resetFlight=new ui,this._disposed=!1,this.ctx=this._freshContext()}_bumpEpoch(){return this._epoch+=1,this._epoch}_freshContext(){return{hostPort:null,deviceEndpoint:null,pids:[],owned:!1,resourcesPushed:!1,style:null,startedAt:0,startCount:0,resetCount:0}}get endpointConfig(){return this.config.get(`rpc.${this.name}`,{})}get resources(){return this.endpointConfig.resources||[]}get isReady(){return this.state===ke.READY&&!!this.transport&&this.transport.isConnected}async ensureReady(){if(this._disposed)throw new Ur(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});if(this.isReady)return this.ctx;let e=this._resetFlight.pending("reset");if(e){if(await e.catch(()=>{}),this._disposed)throw new Ur(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});if(this.isReady)return this.ctx}return this._readyFlight.run("ready",()=>this._ensureReadyOnce())}async _ensureReadyOnce(){if(this._disposed)throw new Ur(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});return this.isReady?this.ctx:this.mode==="fast"&&await this._tryFastConnect()?this.ctx:(await this._stableFlow(),this.ctx)}async _stableFlow(){let e=this.dfx?this.dfx.timer("rpc.lifecycle.prepare",{mode:"stable"}):null;try{let t=await this.device.getEndpointStyle(),n=this.endpoint.buildDeviceEndpoint(t);this.ctx.style=t,this.ctx.deviceEndpoint=n,await this._ensureResources(),this.state=ke.RESOURCES_READY,await this._ensureProcess(t),this.state=ke.PROCESS_RUNNING;let i=await this._selectStableHostPort(t);return await this._tryForward(i,n)||(i=await this.device.getFreeHostPort({exclude:[i]}),await this._ensureForward(i,n)),this.ctx.hostPort=i,this.state=ke.FORWARDED,await this._connectAndProbe(i,{probe:!0}),this.state=ke.READY,await this._onStableReady(i,n,t,e),this.ctx}catch(t){return this._onStableFlowError(t,e)}}async _onStableReady(e,t,n,i){this.mode==="fast"&&await this._persistFastState({hostPort:e,deviceEndpoint:t,style:n}),i&&i({ok:1}),this.dfx&&this.dfx.counter("rpc.lifecycle.ready",1,{mode:this.mode}),this.logger&&this.logger.info(`ready: tcp:${e} -> ${t} (mode=${this.mode}, owned=${this.ctx.owned})`)}_onStableFlowError(e,t){this.state=ke.ERROR,t&&t({ok:0}),this.dfx&&this.dfx.counter("rpc.lifecycle.error",1,{code:e?.code||e?.name});let n=e instanceof fr?e:new gr(`${this.name} rpc prepare failed: ${e.message}`,{cause:e,details:{endpoint:this.name}});throw this.logger&&this.logger.error(`prepare failed: ${n.message}`),n}async _tryFastConnect(){let e=await this._readFastStateUnchecked(),t=e?.style||await this.device.getEndpointStyle(),n=this.endpoint.buildDeviceEndpoint(t),i=this.config.get("rpc.fast",{}),o=i.connectTimeoutMs??1500,s=i.probeOnReuse!==!1,a=await this._fastPortCandidates(t);for(let c of a)try{return await this._connectAndProbe(c,{probe:s,timeoutMs:o}),await this._onFastConnectSuccess(c,n,t)}catch(l){await this._onFastConnectMiss(l,c)}return await this._cleanupStaleFports(a,e,n),await this._clearFastState(),i.forceRestartOnProbeFailure!==!1&&await this._killEndpointProcesses(),!1}async _onFastConnectSuccess(e,t,n){return this.ctx.hostPort=e,this.ctx.deviceEndpoint=t,this.ctx.style=n,this.ctx.owned=!1,this.state=ke.READY,await this._persistFastState({hostPort:e,deviceEndpoint:t,style:n}),this.dfx&&this.dfx.counter("rpc.fast.hit",1,{hostPort:e}),this.logger&&this.logger.info(`fast mode hit: reused tcp:${e}`),!0}async _onFastConnectMiss(e,t){this.dfx&&this.dfx.counter("rpc.fast.miss",1,{reason:e?.code||e.name,hostPort:t}),this.logger&&this.logger.info(`fast mode miss on tcp:${t} (${e.message}), try next/fallback`),await this._safeCloseTransport("fast miss")}async _cleanupStaleFports(e,t,n){let i=new Set(e);t&&Number.isInteger(t.hostPort)&&i.add(t.hostPort);for(let o of i)await this._removeStaleFport(o,t,n)}async _removeStaleFport(e,t,n){try{let i=t?.deviceEndpoint||n,o=await this.device.fportRemove(e,i);this._logFportRemoval(e,i,o)}catch(i){this.logger&&this.logger.debug(`fast mode fallback: remove stale fport tcp:${e} failed: ${i.message}`)}}_logFportRemoval(e,t,n){this.logger&&(n?this.logger.info(`fast mode fallback: removed stale fport tcp:${e} -> ${t}`):this.logger.debug(`fast mode fallback: fport rm tcp:${e} -> ${t} returned false (may not exist or different endpoint)`))}async _fastPortCandidates(e){let t=[],n=await this._readFastState(e);n&&Number.isInteger(n.hostPort)&&t.push(n.hostPort);let i=this.endpointConfig.fastHostPort;return Number.isInteger(i)&&t.push(i),[...new Set(t)]}async _readFastStateUnchecked(){try{let e=this.device.fastStore;if(!e)return null;let t=await e.get(this.device.serial,this.name);return t||null}catch{return null}}async _readFastState(e){try{let t=this.device.fastStore;if(!t)return null;let n=await t.get(this.device.serial,this.name);if(!n)return null;let i=n;return i.style&&i.style!==e?null:i}catch{return null}}async _persistFastState({hostPort:e,deviceEndpoint:t,style:n}){try{let i=this.device.fastStore;if(!i)return;let o=this.device._uitestInfo||null,s=this.ctx.agentVersion||null;if(!s){let a=await i.get(this.device.serial,this.name).catch(()=>null);a&&a.agentVersion&&(s=a.agentVersion)}await i.save(this.device.serial,{endpoint:this.name,hostPort:e,deviceEndpoint:t,style:n,agentVersion:s,uitestVersion:o?o.version:null,hdcServer:this.device.hdcServer})}catch(i){this.logger&&this.logger.debug(`persist fast state failed: ${i.message}`)}}async _clearFastState(){try{let e=this.device.fastStore;e&&await e.forgetEndpoint(this.device.serial,this.name)}catch{}}async _ensureResources(){await this._ensureManagedResources();let e=this.resources;for(let t of e){if(!await this.device.fileExists(t.remotePath)){await this._pushResource(t,"missing");continue}if(!t.version||!t.versionProbe)continue;let i=await this._probeRemoteVersion(t);(!i||zt(t.version,i)>0)&&(await this._killEndpointProcesses(),await this.device.rm(t.remotePath),await this._pushResource(t,"version"))}this.ctx.resourcesPushed=!0}async _ensureManagedResources(){}async _pushResource(e,t){let n=this.dfx?this.dfx.timer("rpc.lifecycle.push",{reason:t}):null;await this.device.fileSend(e.localPath,e.remotePath),n&&n({ok:1}),this.dfx&&this.dfx.counter("rpc.lifecycle.push",1,{reason:t}),this.logger&&this.logger.info(`push resource ${e.name||e.remotePath} (${t})`)}async _probeRemoteVersion(e){try{let t=await this.device.shell(`cat ${pi(e.remotePath)} | ${xt(["grep","-a",e.versionProbe])}`);if(!t)return null;let n=t.split("#"),i=n.length>1?n[n.length-1]:t;return So(i)}catch{return null}}async _detectProcesses(e){let n=(await this.device.findProcesses()).filter(i=>this.endpoint.matchProcess(i));return n.length?this.endpointConfig.checkListening&&!await this.endpoint.isListening(this.device,e)?[]:n:[]}async _ensureProcess(e){let t=await this._detectProcesses(e);if(t.length){this.ctx.pids=t.map(i=>i.pid),this.ctx.owned=!1;return}await this._killStaleProcesses();let n;try{n=await this._launchAndWaitReady(e)}catch(i){let o=i;this.logger&&this.logger.warn(`${this.name} launch failed, try re-push managed resources: ${o.message}`);try{await this._onLaunchFailure()}catch(s){this.logger&&this.logger.warn(`${this.name} onLaunchFailure hook error: ${s.message}`)}await this._killStaleProcesses(),n=await this._launchAndWaitReady(e)}this.ctx.pids=n.map(i=>i.pid),this.ctx.owned=!0,this.ctx.startedAt=Date.now()}async _killStaleProcesses(){let e=(await this.device.findProcesses()).filter(t=>this.endpoint.matchProcess(t));for(let t of e)await this.device.killProcess(t.pid)}async _onLaunchFailure(){}async _launchAndWaitReady(e){let t=this.endpoint.buildStartCommand({style:e});this.logger&&this.logger.info(`start device process: ${t}`),await this.device.shell(t),this.ctx.startCount+=1,this.dfx&&this.dfx.counter("rpc.lifecycle.start",1);let n=this.endpointConfig;try{return await Nl(async()=>{let i=await this._detectProcesses(e);return i.length?i:null},{timeoutMs:n.processWaitTimeoutMs??15e3,intervalMs:n.processCheckIntervalMs??200,firstDelayMs:n.startWaitMs??500,description:`${this.name} process ready`})}catch(i){throw new gr(`${this.name} process did not become ready: ${i.message}`,{cause:i,details:{endpoint:this.name,startCmd:t}})}}async _ensureForward(e,t){if(!await this._tryForward(e,t))throw new gr(`create fport failed: tcp:${e} -> ${t}`,{details:{endpoint:this.name,hostPort:e,deviceEndpoint:t}})}async _tryForward(e,t){return await this.device.fportAdd(e,t)?!0:!!(await this.device.fportListAll()).find(s=>s.hostPort===e&&s.deviceEndpoint===t)}async _selectStableHostPort(e){if(this.mode==="fast"){let t=await this._readFastState(e),n=this.endpointConfig.fastHostPort,i=t&&Number.isInteger(t.hostPort)&&t.hostPort||n;if(i!=null&&Number.isInteger(i)&&!this.device.fportList.some(s=>s.hostPort===i))return i}return this.device.getFreeHostPort()}async _connectAndProbe(e,{probe:t=!0,timeoutMs:n}={}){let i=new qs({host:this.device.hdcHost,port:e,name:this.name,framing:this.config.get("rpc.framing","auto"),concurrency:this.config.get("rpc.concurrency",vr.AUTO),maxInFlight:this.config.get("rpc.maxInFlight",16),strictPairing:this.config.get("rpc.strictPairing",!1),timeoutKillsConnection:this.config.get("rpc.timeoutKillsConnection",!1),connectTimeoutMs:n??this.config.get("rpc.connectTimeoutMs",5e3),requestTimeoutMs:this.config.get("rpc.requestTimeoutMs",3e4),socketIdleTimeoutMs:this.config.get("rpc.socketIdleTimeoutMs",3e4),logger:this.logger,dfx:this.dfx});await this._safeCloseTransport("reconnect"),await i.connect(),this._bumpEpoch(),i.onClose=o=>{this._onTransportClose(i,o)},this.transport=i,this.state=ke.CONNECTED,t&&await this._probe()}_onTransportClose(e,t){this.transport===e&&(this._bumpEpoch(),(this.state===ke.READY||this.state===ke.CONNECTED)&&(this.state=this.mode==="fast"?ke.WARM:ke.IDLE,this.logger&&this.logger.warn(`connection lost: ${t?t.message:"closed"}`),this.dfx&&this.dfx.counter("rpc.connection.lost",1,{reason:t?.code||"close"})))}async _probe(){let e=this.config.get("rpc.connectTimeoutMs",5e3),t=this.buildProbePayload(),n=await this.transport.send(t,{timeoutMs:e});if(Bl(n)&&this.logger){let i=n.exception;this.logger.debug(`probe got business exception (link is healthy): ${typeof i=="string"?i:JSON.stringify(i)}`)}return Wl(n)}async request(e,t={}){let{timeoutMs:n}=t,i=this.config.get("rpc.recovery",{}),o=i.enabled!==!1,s=Math.max(0,i.maxAttempts??1),a=null,c=0,l=0;for(let d=0;d<=s+1;d++){if(this._disposed)throw new Ur(`${this.name} rpc is disposed, request rejected`,{details:{endpoint:this.name}});let g=this._epoch;try{await this.ensureReady(),g=this._epoch;let y=await this._sendOnce(e,{timeoutMs:n});return this._logRecovered(c+l),y}catch(y){a=y;let E=await this._handleRequestError(y,o,s,g,c,l,i.delayMs);c=E.ownRecoveries,l=E.borrowedRecoveries}}throw a||new gr(`${this.name} rpc request failed`)}_logRecovered(e){e>0&&this.dfx&&this.dfx.counter("rpc.request.recovered",1,{endpoint:this.name})}async _handleRequestError(e,t,n,i,o,s,a){if(this._disposed||!t||!Fm(e))throw e;return this._epoch===i?o=await this._attemptOwnRecovery(e,n,o):s=this._attemptBorrowedRecovery(e,n,s),a&&await wo(a),{ownRecoveries:o,borrowedRecoveries:s}}async _attemptOwnRecovery(e,t,n){if(n>=t)throw e;let i=n+1;return this.dfx&&this.dfx.counter("rpc.request.retry",1,{code:e.code,attempt:i}),this.logger&&this.logger.warn(`recover from ${e.code||e.name}: ${e.message} (retry ${i}/${t})`),await this.reset({reason:e.message,code:e.code}),i}_attemptBorrowedRecovery(e,t,n){let i=n+1;if(i>t)throw e;return this.dfx&&this.dfx.counter("rpc.request.retry.borrowed",1,{code:e.code}),this.logger&&this.logger.debug(`retry after another caller reset (${e.code||e.name})`),i}async _sendOnce(e,{timeoutMs:t}={}){if(!this.transport||!this.transport.isConnected)throw new je("rpc transport is not connected",{details:{endpoint:this.name}});let n=await this.transport.send(e,{timeoutMs:t??this.config.get("rpc.requestTimeoutMs",3e4)});return this.interpret(n)}interpret(e){if(Bl(e)){let t=e.exception,n;if(t instanceof Error)n=t.message;else if(typeof t=="string")n=t;else if(t&&typeof t=="object")try{n=JSON.stringify(t)}catch{n=String(t)}else n=String(t);let i=new Us(`remote exception: ${n}`,{details:{endpoint:this.name,remote:t}});throw this.dfx&&this.dfx.counter("rpc.request.remoteError",1,{endpoint:this.name}),i}return Wl(e)}reset({reason:e="manual",code:t="MANUAL"}={}){return this._resetFlight.run("reset",()=>this._resetOnce({reason:e,code:t}))}async _resetOnce({reason:e="manual",code:t="MANUAL"}={}){if(this._disposed)return;let n=this._readyFlight.pending("ready");if(n&&await n.catch(()=>{}),this._disposed)return;this._bumpEpoch(),this.dfx&&this.dfx.counter("rpc.lifecycle.reset",1,{reason:t}),this.logger&&this.logger.warn(`reset: ${e}`);try{await this._killEndpointProcesses()}catch(s){this.logger&&this.logger.warn(`kill process failed during reset: ${s.message}`)}await this._safeCloseTransport("reset");try{this.ctx.hostPort&&this.ctx.deviceEndpoint&&await this.device.fportRemove(this.ctx.hostPort,this.ctx.deviceEndpoint)}catch(s){this.logger&&this.logger.warn(`remove fport failed during reset: ${s.message}`)}let i=this.ctx.resetCount+1,o=this.ctx.startCount;this.ctx=this._freshContext(),this.ctx.resetCount=i,this.ctx.startCount=o,this.state=ke.IDLE}async release(){if(await this._safeCloseTransport("release"),this.mode==="fast"&&this.config.get("rpc.fast.keepOnRelease",!0)){this.state=ke.WARM,this.dfx&&this.dfx.counter("rpc.release",1,{keep:1}),this.logger&&this.logger.info(`released (keep process & fport on tcp:${this.ctx.hostPort})`);return}await this._removeForward(),await this._killEndpointProcesses(),this.dfx&&this.dfx.counter("rpc.release",1,{keep:0}),this.logger&&this.logger.info("released (process & fport cleaned)"),this.ctx=this._freshContext(),this.state=ke.IDLE}async dispose(){this._disposed=!0,this._bumpEpoch();let e=this._readyFlight.pending("ready");e&&await e.catch(()=>{});let t=this._resetFlight.pending("reset");t&&await t.catch(()=>{}),await this._safeCloseTransport("dispose"),await this._removeForward(),await this._killEndpointProcesses(),this.ctx=this._freshContext(),this.state=ke.DISPOSED}async _removeForward(){let e=new Set;this.ctx.hostPort&&e.add(this.ctx.hostPort),this.mode==="fast"&&this.endpointConfig.fastHostPort&&e.add(this.endpointConfig.fastHostPort);let t=this.ctx.deviceEndpoint||void 0;for(let n of e)try{let i=await this.device.fportRemove(n,t);this.logger&&!i&&this.logger.warn(`remove fport tcp:${n} -> ${t} returned false`)}catch(i){this.logger&&this.logger.debug(`remove fport tcp:${n} failed: ${i.message}`)}}async _killEndpointProcesses(){let t=(await this.device.findProcesses()).filter(n=>this.endpoint.matchProcess(n));for(let n of t)await this.device.killProcess(n.pid);return t.length&&this.logger&&this.logger.info(`killed ${this.name} processes: [${t.map(n=>n.pid).join(", ")}]`),t.length}async _safeCloseTransport(e){if(this.transport){try{await this.transport.close(e)}catch{}this.transport=null}}buildProbePayload(){return{module:"debug",method:"ping",params:{},request_id:void 0}}getSnapshot(){return{name:this.name,mode:this.mode,state:this.state,epoch:this._epoch,disposed:this._disposed,ctx:{...this.ctx},transport:this.transport?this.transport.getSnapshot():null}}};var Qm={name:"operate",displayName:"uitest",socketName:"uitest_socket",devicePort:8012,buildDeviceEndpoint(r){return r==="unix"?`localabstract:${this.socketName}`:`tcp:${this.devicePort}`},buildStartCommand(){return"/system/bin/uitest start-daemon singleness &"},buildStopCommands(r){return r.map(e=>xt(["kill","-9",e]))},matchProcess(r){return r.cmd.includes("uitest start-daemon singleness")&&!r.cmd.includes("--extension-name")},async isListening(r,e){return e==="unix"?(await r.shell(`cat /proc/net/unix | ${xt(["grep",this.socketName])}`)).includes(this.socketName):(await r.shell(`netstat -anp | ${xt(["grep",String(this.devicePort)])}`)).includes("LISTEN")}};var Js=class extends zs{constructor(e){super({...e,endpoint:Qm})}async _ensureManagedResources(){if(this.config.get("device.autoPushResources",!0)===!1||!this.device.resources||typeof this.device.resources.ensureAgent!="function")return;let e=await this.device.resources.ensureAgent();this.ctx.agentVersion=e.candidate.version}async _onLaunchFailure(){this.config.get("device.autoPushResources",!0)!==!1&&(!this.device.resources||typeof this.device.resources.repushAgent!="function"||await this.device.resources.repushAgent())}buildProbePayload(){return Ul({module:Hl,method:"ping",params:{},requestId:hr()})}async call(e,t="",n=[],i={}){let o=Ul({module:Hl,method:Zm,params:{api:e,this:t,args:n,message_type:"hypium"},requestId:hr()});return this.dfx&&this.dfx.counter("rpc.call",1,{api:e}),this.request(o,i)}async ping(e={}){return this.request(this.buildProbePayload(),e)}};function vN(r){if(r!==void 0)return Array.isArray(r)?{value:String(r[0]),pattern:r[1]}:{value:String(r)}}function ef(r){return Hb(r)}function Hb(r){let e={};return r.text!==void 0&&(e.text=vN(r.text)),r.key!==void 0&&(e.key=String(r.key)),r.id!==void 0&&(e.id=String(r.id)),r.type!==void 0&&(e.type=String(r.type)),r.clickable!==void 0&&(e.clickable=!!r.clickable),r.scrollable!==void 0&&(e.scrollable=!!r.scrollable),r.enabled!==void 0&&(e.enabled=!!r.enabled),r.focused!==void 0&&(e.focused=!!r.focused),r.selected!==void 0&&(e.selected=!!r.selected),e}function Ub(r){let e=Hb(r);return r.isBefore&&(e.isBefore=ef(r.isBefore)),r.isAfter&&(e.isAfter=ef(r.isAfter)),r.within&&(e.within=ef(r.within)),e}function bN(r){let e=[];return r.text&&e.push(["On.text",[r.text.value,r.text.pattern??0]]),r.key!==void 0&&e.push(["On.key",[r.key]]),r.id!==void 0&&e.push(["On.id",[r.id]]),r.type!==void 0&&e.push(["On.type",[r.type]]),r.clickable!==void 0&&e.push(["On.clickable",[r.clickable]]),r.scrollable!==void 0&&e.push(["On.scrollable",[r.scrollable]]),r.enabled!==void 0&&e.push(["On.enabled",[r.enabled]]),r.focused!==void 0&&e.push(["On.focused",[r.focused]]),r.selected!==void 0&&e.push(["On.selected",[r.selected]]),e}var qe=class r{spec;constructor(e={}){this.spec=e}static from(e){return new r(Ub(e))}text(e,t){return this.spec.text={value:e,pattern:t},this}key(e){return this.spec.key=e,this}id(e){return this.spec.id=e,this}type(e){return this.spec.type=e,this}clickable(e=!0){return this.spec.clickable=e,this}scrollable(e=!0){return this.spec.scrollable=e,this}enabled(e=!0){return this.spec.enabled=e,this}focused(e=!0){return this.spec.focused=e,this}selected(e=!0){return this.spec.selected=e,this}isBefore(e){return this.spec.isBefore=e.spec,this}isAfter(e){return this.spec.isAfter=e.spec,this}within(e){return this.spec.within=e.spec,this}async buildOn(e){let t=this.spec,n=bN(t);if(n.length===0)throw new Error("Empty selector: at least one lookup condition required");let i=await e.create(n[0][0],n[0][1]);for(let o=1;o<n.length;o++)await e.call(n[o][0],i,n[o][1]);if(t.isBefore){let o=await new r(t.isBefore).buildOn(e);await e.call("On.isBefore",i,[o])}if(t.isAfter){let o=await new r(t.isAfter).buildOn(e);await e.call("On.isAfter",i,[o])}if(t.within){let o=await new r(t.within).buildOn(e);await e.call("On.within",i,[o])}return i}};var Ys=class r{constructor(e,t,n=0){this.host=e;this.selector=t;this.index=n}use(e){return this.host.withComponentRef(this.selector,this.index,t=>e(t))}async click(){await this.use(e=>this.host.rpc.call("Component.click",e,[]))}async doubleClick(){await this.use(e=>this.host.rpc.call("Component.doubleClick",e,[]))}async longClick(){await this.use(e=>this.host.rpc.call("Component.longClick",e,[]))}async inputText(e){await this.use(t=>this.host.rpc.call("Component.inputText",t,[e]))}async clearText(){await this.use(e=>this.host.rpc.call("Component.clearText",e,[]))}async getId(){return String(await this.use(e=>this.host.rpc.call("Component.getId",e,[])))}async getText(){return String(await this.use(e=>this.host.rpc.call("Component.getText",e,[])))}async getType(){return String(await this.use(e=>this.host.rpc.call("Component.getType",e,[])))}async getHint(){return String(await this.use(e=>this.host.rpc.call("Component.getHint",e,[])))}async isClickable(){return!!await this.use(e=>this.host.rpc.call("Component.isClickable",e,[]))}async isScrollable(){return!!await this.use(e=>this.host.rpc.call("Component.isScrollable",e,[]))}async isEnabled(){return!!await this.use(e=>this.host.rpc.call("Component.isEnabled",e,[]))}async isFocused(){return!!await this.use(e=>this.host.rpc.call("Component.isFocused",e,[]))}async isSelected(){return!!await this.use(e=>this.host.rpc.call("Component.isSelected",e,[]))}async getBounds(){return await this.use(t=>this.host.rpc.call("Component.getBounds",t,[]))}async getBoundsCenter(){return await this.use(t=>this.host.rpc.call("Component.getBoundsCenter",t,[]))}async scrollSearch(e){let t=e instanceof qe?e:qe.from(e);return await this.host.withComponentRef(this.selector,this.index,async(i,o)=>{let s=await t.buildOn(o),a=await o.call("Component.scrollSearch",i,[s]);return a?(o.track(String(a)),!0):!1})?new r(this.host,t):null}async dragTo(e){let t=e instanceof r?e.selector:e instanceof qe?e:qe.from(e);await this.host.withComponentRef(this.selector,this.index,async(n,i,o)=>{let s=await t.buildOn(i),c=(await i.call("Driver.findComponents",o,[s])??[]).map(String);if(i.trackAll(c),c.length===0)throw new Error("dragTo target component not found (0 returned)");await i.call("Component.dragTo",n,[c[0]])})}async pinchOut(e){await this.use(t=>this.host.rpc.call("Component.pinchOut",t,[e]))}async pinchIn(e){await this.use(t=>this.host.rpc.call("Component.pinchIn",t,[e]))}async scrollToTop(e=600){await this.use(t=>this.host.rpc.call("Component.scrollToTop",t,[e]))}async scrollToBottom(e=600){await this.use(t=>this.host.rpc.call("Component.scrollToBottom",t,[e]))}};var SN=600,tf=1,Vl=16;function EN(r,e){return Math.hypot(e.x-r.x,e.y-r.y)}function Bb(r,e,t,n){if(n!==void 0&&n>0)return Math.max(tf,Math.round(n/Vl));let i=EN(r,e);if(i<=0||t<=0)return tf;let o=i/t*1e3;return Math.max(tf,Math.round(o/Vl))}function Gl(r,e,t){return Math.round(r+(e-r)*t)}function Wb(r,e,t,n){if(e===null)throw new Error("wait/pressHold before first down, missing start coordinate");for(let i=0;i<n;i++)r.push({pressed:t,x:e.x,y:e.y})}function PN(r,e,t){if(t.pressed)throw new Error("Duplicate down: finger already pressed");let n={x:e.x,y:e.y};t.cur=n,t.pressed=!0,r.push({pressed:t.pressed,x:n.x,y:n.y})}function CN(r,e,t,n){if(n.cur===null)throw new Error("moveTo before down");let i=n.cur,o={x:e.x,y:e.y},s=Bb(i,o,t,e.durationMs);for(let a=1;a<=s;a++){let c=a/s;r.push({pressed:n.pressed,x:Gl(i.x,o.x,c),y:Gl(i.y,o.y,c)})}n.cur=o}function kN(r,e,t,n){if(n.cur===null)throw new Error("move before down");let i=n.cur,o={x:i.x+e.dx,y:i.y+e.dy},s=Bb(i,o,t,e.durationMs);for(let a=1;a<=s;a++){let c=a/s;r.push({pressed:n.pressed,x:Gl(i.x,o.x,c),y:Gl(i.y,o.y,c)})}n.cur=o}function DN(r,e,t){Wb(r,t.cur,t.pressed,Math.max(1,Math.round(e.durationMs/Vl)))}function RN(r,e,t){if(!t.pressed)throw new Error("pressHold before down");Wb(r,t.cur,t.pressed,Math.max(1,Math.round(e.durationMs/Vl)))}function xN(r,e){if(!e.pressed)throw new Error("up before down");e.pressed=!1;let t=e.cur;t!==null&&r.push({pressed:e.pressed,x:t.x,y:t.y})}function AN(r,e){let t=[],n={cur:null,pressed:!1};for(let i of r.actions)switch(i.type){case"down":{PN(t,i,n);break}case"moveTo":{CN(t,i,e,n);break}case"move":{kN(t,i,e,n);break}case"wait":{DN(t,i,n);break}case"pressHold":{RN(t,i,n);break}case"up":{xN(t,n);break}default:{let o=i;throw new Error(`Unknown gesture action: ${JSON.stringify(o)}`)}}return t}function rf(r){if(!r.fingers.length)throw new Error("Gesture requires at least one finger");let e=r.speed??SN,t=r.fingers.map(o=>AN(o,e)),n=Math.max(...t.map(o=>o.length));return{fingers:t.map(o=>{if(o.length===0)return[];let s=o[o.length-1],a=[...o];for(;a.length<n;)a.push({...s});return a}),speed:e}}var IN="PointerMatrix#seed";async function nf(r,e){let{fingers:t,speed:n}=rf(e);if(t.length===0)throw new Error("Empty gesture");let i=t[0].length,o=await r.create("PointerMatrix.create",[t.length,i],IN);for(let s=0;s<t.length;s++)for(let a=0;a<i;a++){let c=t[s][a];await r.call("PointerMatrix.setPoint",o,[s,a,{x:c.x,y:c.y}])}return{ref:o,speed:n}}var Vb="Driver.create",TN="BackendObjectsCleaner";var of="On#seed";async function ql(r,e){let t=e.filter(n=>n&&n!==of);if(t.length!==0)try{for(let n=0;n<t.length;n+=10)await r.call(TN,"",[t.slice(n,n+10)])}catch{}}var yn=class{constructor(e){this.rpc=e}refs=[];async create(e,t=[],n=of){let i=String(await this.rpc.call(e,n,t));return this.refs.push(i),i}async call(e,t,n=[]){return this.rpc.call(e,t,n)}track(e){return e&&e!==of&&this.refs.push(e),e}trackAll(e){for(let t of e)this.track(t);return e}async dispose(){await ql(this.rpc,this.refs),this.refs.length=0}async run(e){try{return await e(this)}finally{await this.dispose()}}};var Ks=class{constructor(e,t,n=0){this.host=e;this.filter=t;this.index=n}use(e){return this.host.withWindowRef(this.filter,this.index,t=>e(t))}async getBundleName(){return String(await this.use(e=>this.host.rpc.call("UiWindow.getBundleName",e,[])))}async isActive(){return!!await this.use(e=>this.host.rpc.call("UiWindow.isActive",e,[]))}async isFocused(){return!!await this.use(e=>this.host.rpc.call("UiWindow.isFocused",e,[]))}async getBounds(){return await this.use(t=>this.host.rpc.call("UiWindow.getBounds",t,[]))}};var Xs=class{constructor(e,t){this.shell=t;this.rpc=e}driverRef=null;rpc;async ensureDriver(){return this.driverRef?this.driverRef:(this.driverRef=String(await this.rpc.call(Vb,"",[])),this.driverRef)}selector(e){return e?qe.from(e):new qe}findComponent(e,t=0){let n=e instanceof qe?e:qe.from(e);return new Ys(this,n,t)}async withComponentRef(e,t,n){let i=await this.ensureDriver();return new yn(this.rpc).run(async s=>{let a=await e.buildOn(s),c=[];for(let l=0;l<8&&(c=(await s.call("Driver.findComponents",i,[a])??[]).map(String),!(c.length>0));l++)await new Promise(g=>setTimeout(g,1e3));if(s.trackAll(c),t>=c.length)throw new Error(`findComponents: no component matched (returned ${c.length}), index ${t} out of range`);return n(c[t],s,i)})}findWindow(e,t=0){return new Ks(this,e,t)}async withWindowRef(e,t,n){let i=await this.ensureDriver();return new yn(this.rpc).run(async s=>{let a;if(t===0){let c=await s.call("Driver.findWindow",i,[ON(e)]);if(!c||c==="null")throw new Error("findWindow: no window matched");a=s.track(String(c))}else throw new Error(`findWindow: only returns a single window, index=${t} not supported`);return n(a,s)})}async gesture(e){await this.swipe(e)}async swipe(e){let t=await this.ensureDriver();await this.withPointerRef(e,async(n,i)=>{await this.rpc.call("Driver.injectMultiPointerAction",t,[n,i])})}async withPointerRef(e,t){return new yn(this.rpc).run(async i=>{let{ref:o,speed:s}=await nf(i,e);return t(o,s,i)})}async screenCapture(e){if(!this.shell)throw new Error("screenCapture requires shell capability (provided via device.uitest)");let t=e.toLowerCase().endsWith(".png")?".png":".jpeg",n=`/data/local/tmp/hypium${t}`;if(await this.shell.shell(`rm -f ${n}`),t===".png"?await this.shell.shell(`uitest screenCap -p ${n}`):await this.shell.shell(`snapshot_display -f ${n}`),!await this.shell.fileRecv(n,e))throw new Error(`screenCapture pull failed: ${n} -> ${e}`)}async setDisplayRotation(e){let t={0:0,90:1,180:2,270:3};if(!(e in t))throw new Error(`rotation must be 0, 90, 180, or 270, got ${e}`);let n=await this.ensureDriver();await this.rpc.call("Driver.setDisplayRotation",n,[t[e]])}async getDisplayRotation(){let e=await this.ensureDriver(),t=await this.rpc.call("Driver.getDisplayRotation",e,[]),n={0:0,1:90,2:180,3:270},i=typeof t=="number"?t:Number(t);return n[i]??i}async setDisplayRotationEnabled(e){let t=await this.ensureDriver();await this.rpc.call("Driver.setDisplayRotationEnabled",t,[e])}async delay(e){await new Promise(t=>setTimeout(t,e))}async pressBack(){let e=await this.ensureDriver();await this.rpc.call("Driver.pressBack",e,[])}async pressHome(){let e=await this.ensureDriver();await this.rpc.call("Driver.pressHome",e,[])}async clickXY(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.click",n,[e,t])}async doubleClick(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.doubleClick",n,[e,t])}async inputText(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.inputText",n,[e,t])}async getDisplaySize(){let e=await this.ensureDriver(),n=await this.rpc.call("Driver.getDisplaySize",e,[]);return{width:n.width??n.x??0,height:n.height??n.y??0}}async assertComponentExist(e,t=!0){let n=e instanceof qe?e:qe.from(e),i=await this.ensureDriver();return new yn(this.rpc).run(async s=>{let a=await n.buildOn(s),l=(await s.call("Driver.findComponents",i,[a])??[]).length>0;return t?l:!l})}async release(){this.driverRef&&(await ql(this.rpc,[this.driverRef]),this.driverRef=null)}};function ON(r){let e={};return r.title!==void 0&&(e.title=typeof r.title=="string"?r.title:r.title.value),r.bundleName!==void 0&&(e.bundleName=r.bundleName),r.active!==void 0&&(e.active=r.active),e}function Gb({config:r,logger:e,dfx:t,executor:n}){if(n)return n;let i={bin:r.get("hdc.bin","hdc"),host:r.get("hdc.host","127.0.0.1"),port:r.get("hdc.port",8710),execTimeoutMs:r.get("hdc.execTimeoutMs",1e4),logger:e,dfx:t};return new di(i)}var Zs=class r{executor;config;logger;dfx;rpcMode;devices;_rpcFactories;constructor({executor:e,config:t,logger:n,dfx:i,rpcMode:o}){this.executor=e,this.config=t,this.logger=n??null,this.dfx=i??null,this.rpcMode=o||t.get("rpc.mode","stable"),this.devices=new Map,this._rpcFactories=new Map}static async create(e={}){let t=e.config&&typeof e.config.get=="function"?e.config:Vs(e.config||{});e.mode&&t.set("rpc.mode",e.mode);let n=e.logger||js("HMDeviceManager"),i=e.dfx||Gs({logger:n,tags:{mode:t.get("rpc.mode")}}),o=Gb({config:t,logger:n,dfx:i,executor:e.executor});return new r({executor:o,config:t,logger:n,dfx:i,rpcMode:t.get("rpc.mode","stable")})}static _default=null;static async getDefault(e={}){return r._default||(r._default=await r.create(e)),r._default}static resetDefault(){r._default=null}async listTargets(){let e=this.dfx?this.dfx.timer("device.listTargets"):null,t=await this.executor.listTargets();return e&&e({count:t.length}),this.logger&&this.logger.info(`list targets -> [${t.join(", ")}]`),t}async listDevices({detail:e=!1}={}){let n=(await this.listTargets()).map(i=>({serial:i,cached:this.devices.has(i)}));if(!e)return n;for(let i of n)try{let s=await(await this.getDevice(i.serial)).getInfo();Object.assign(i,{model:s.model,abi:s.abi,uitestVersion:s.version,endpointStyle:s.endpointStyle})}catch(o){i.error=o.message}return n}async getDevice(e,t={}){let n=this.dfx?this.dfx.timer("device.create"):null,i=await this.listTargets();if(!i.length)throw new fn("no device connected");let o=e;if(o){if(!i.includes(o))throw new fn(`device ${o} is not found, connected: [${i.join(", ")}]`)}else if(this.config.get("device.autoSelectFirst",!0))o=i[0];else throw new fn("serial is required when autoSelectFirst is disabled");let s=this.devices.get(o);if(s)return n&&n({sn:o,reused:1}),s;let a=new mi({serial:o,executor:this.executor,config:this.config,logger:this.logger,dfx:this.dfx,rpcMode:t.rpcMode||this.rpcMode});for(let[l,d]of this._rpcFactories)a.attachRpc(l,d);return(t.queryVersion??this.config.get("device.queryVersion",!0))&&await a.getUitestInfo(),this.devices.set(o,a),n&&n({sn:o,ok:1}),this.dfx&&this.dfx.counter("device.create",1,{sn:o}),this.logger&&this.logger.info(`device created: ${o}`),a}async createDevice(e,t={}){return this.getDevice(e,t)}async connect(e,t={}){return this.getDevice(e,t)}attachRpc(e,t){if(typeof t!="function")throw new fn(`attachRpc(${e}) expects a factory function`);this._rpcFactories.set(e,t);for(let n of this.devices.values())n.attachRpc(e,t);return this}async removeDevice(e){let t=this.devices.get(e);return t?(await t.release(),this.devices.delete(e),!0):!1}async release({disposeRpc:e=!1}={}){for(let t of this.devices.values())e?await t.dispose():await t.release();this.devices.clear()}async dispose(){for(let e of this.devices.values())await e.dispose();this.devices.clear()}};var MN="6.0.2.2",LN={uitest:r=>new Js({device:r,config:r.config,logger:r.logger,dfx:r.dfx,mode:r.rpcMode})},mi=class{serial;executor;config;logger;dfx;hdcHost;hdcPort;execTimeoutMs;rpcMode;_uitestInfo;fportList;resources;fastStore;_rpcs;_rpcFactories;_uitestDriver=null;file;fport;proc;constructor({serial:e,executor:t,config:n,logger:i,dfx:o,rpcMode:s}){this.serial=e,this.executor=t,this.config=n,this.logger=i??null,this.dfx=o?o.child({sn:e}):null,this.hdcHost=n.get("hdc.host","127.0.0.1"),this.hdcPort=n.get("hdc.port",8710),this.execTimeoutMs=n.get("hdc.execTimeoutMs",1e4),this.rpcMode=s||n.get("rpc.mode","stable"),this._uitestInfo=null,this.fportList=[],this.resources=new Fl({device:this,config:n,logger:this.logger,dfx:this.dfx}),this.fastStore=new jl({config:n,logger:this.logger}),this._rpcs=new Map,this._rpcFactories=new Map(Object.entries(LN)),this.file=new sf(this),this.fport=new af(this),this.proc=new cf(this)}get isRemoteHdcServer(){return!!this.hdcHost&&this.hdcHost!=="127.0.0.1"&&this.hdcHost!=="localhost"}get hdcServer(){return`${this.hdcHost||"127.0.0.1"}:${this.hdcPort??8710}`}async exec(e,t={}){let n=["-t",this.serial,...e],i=await this.executor.exec(n,{timeoutMs:t.timeoutMs??this.execTimeoutMs});return this.logger&&this.logger.debug(`hdc ${n.join(" ")} -> ${i.code}`),i}async shell(e,t={}){return Jm(e),(await this.exec(["shell",e],t)).stdout}async shellArgs(e,t={}){return this.shell(xt(e),t)}async fileSend(e,t,n={}){wr(t),await _N(e);let i=await this.exec(["file","send",e,t],n);if(!(i.ok&&i.stdout.includes("FileTransfer finish")))throw new gn(`push ${e} -> ${t} failed: ${i.stderr||i.stdout}`,{details:{localPath:e,remotePath:t}});return this.dfx&&this.dfx.counter("device.file.send",1),!0}async fileRecv(e,t,n={}){if(wr(e),!await this.fileExists(e))throw new gn(`remote file does not exist: ${e}`);let i=await this.exec(["file","recv",e,t],n);if(!(i.ok&&i.stdout.includes("FileTransfer finish")))throw new gn(`pull ${e} -> ${t} failed: ${i.stderr||i.stdout}`,{details:{localPath:t,remotePath:e}});return this.dfx&&this.dfx.counter("device.file.recv",1),!0}async fileExists(e){wr(e);let t=await this.shellArgs(["ls","-ld",e]);return!!t&&!t.includes("No such file or directory")}async isDirectory(e){wr(e);let t=await this.shellArgs(["ls","-ld",e]);return!!t&&t.startsWith("d")&&!t.includes("No such file or directory")}async rm(e,{force:t=!0}={}){return wr(e),await this.shellArgs(t?["rm","-f",e]:["rm",e]),!0}async mkdir(e){return wr(e),await this.shellArgs(["mkdir","-p",e]),!0}async readRemoteText(e){wr(e);let t=await this.shellArgs(["cat",e]);if(t.includes("No such file or directory"))throw new gn(`remote file does not exist: ${e}`);return t}async listDir(e="/data/local/tmp"){wr(e);let t=await this.shellArgs(["ls",e]);return t.includes("No such file or directory")?[]:t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean)}async fportAdd(e,t){$l(e),_l(t);let n=await this.exec(["fport",`tcp:${e}`,t]),i=n.ok&&(n.stdout.includes("result:OK")||n.stdout.toLowerCase().includes("success"));if(i){let o={hostPort:e,deviceEndpoint:t,taskString:`tcp:${e} ${t}`};this.fportList.some(s=>s.hostPort===e)||this.fportList.push(o),this.dfx&&this.dfx.counter("device.fport.add",1)}return i}async fportRemove(e,t){$l(e),t&&_l(t);let n=await this.exec(t?["fport","rm",`tcp:${e}`,t]:["fport","rm",`tcp:${e}`]),i=n.ok&&(n.stdout.includes("result:OK")||n.stdout.toLowerCase().includes("success"));return i&&(this.fportList=this.fportList.filter(o=>o.hostPort!==e),this.dfx&&this.dfx.counter("device.fport.remove",1)),i}async fportListAll(){let e=await this.exec(["fport","ls"]);return jm(e.stdout)}async getFreeHostPort(e={}){let t=this.config.get("rpc.portRange",{start:1e4,end:19999}),n=new Set([...this.fportList.map(o=>o.hostPort),...e.exclude||[]]),{port:i}=await Ob({hdcHost:this.hdcHost,start:e.start??t.start,end:e.end??t.end,exclude:n});return i}async getFreeDevicePort({start:e=4e4,end:t=49999,exclude:n}={}){let i=await this.shell("cat /proc/net/tcp /proc/net/tcp6 2>/dev/null"),o=new Set(n||[]);for(let s of String(i).split(/\r?\n/)){let c=s.trim().split(/\s+/)[1];if(!c||!c.includes(":"))continue;let l=c.split(":")[1],d=parseInt(l,16);Number.isInteger(d)&&o.add(d)}for(let s=e;s<=t;s++)if(!o.has(s))return s;throw new Rt(`no free device port in range ${e}-${t}`)}async findProcesses(){let e=await this.shellArgs(["ps","-ef"]);return Hm(e)}async killProcess(e){let t=Ym(e);return await this.shellArgs(["kill","-9",t]),this.dfx&&this.dfx.counter("device.process.kill",1),!0}async getUitestInfo(e=!1){if(this._uitestInfo&&!e)return this._uitestInfo;let t=await Mb(this,{minVersion:this.config.get("device.newUiTestMinVersion",MN)});return this._uitestInfo={version:t.version,arch:t.arch,isNewUiTest:t.isNewUiTest,endpointStyle:t.endpointStyle},this.logger&&this.logger.info(`uitest info: version=${t.version} arch=${t.arch} endpointStyle=${t.endpointStyle}`),this._uitestInfo}async getEndpointStyle(){return this._uitestInfo||await this.getUitestInfo(),this._uitestInfo.endpointStyle}async getSystemProp(e){let t=e.map(n=>({bin:"getprop",key:n}));for(let n of e){let i=n.startsWith("ro.")?`const.${n.slice(3)}`:n;t.push({bin:"param",key:i})}for(let{bin:n,key:i}of t)try{let o=(await this.shellArgs([n,"get",i])).trim();if(!o||/fail|inaccessible|not found|Get parameter/i.test(o))continue;return o}catch{}return""}async getInfo(){let[e,t,n]=await Promise.all([this.getSystemProp(["ro.product.model","const.product.model"]),this.getSystemProp(["ro.product.cpu.abi","const.product.cpu.abilist"]),this.getUitestInfo()]);return{serial:this.serial,model:e,abi:t,...n}}attachRpc(e,t){if(typeof t!="function")throw new Rt(`attachRpc(${e}) expects a factory function`);return this._rpcFactories.set(e,t),this._rpcs.delete(e),this}rpc(e){let t=this._rpcs.get(e);if(t)return t;let n=this._rpcFactories.get(e);if(!n)throw new Rt(`rpc module "${e}" is not attached, available: [${[...this._rpcFactories.keys()].join(", ")}]`);let i=n(this);return this._rpcs.set(e,i),this.logger&&this.logger.debug(`rpc attached: ${e} -> ${i.name}`),i}get uitestRpc(){return this.rpc("uitest")}get uitest(){return this._uitestDriver||(this._uitestDriver=new Xs(this.uitestRpc,{shell:e=>this.shell(e),fileRecv:(e,t)=>this.fileRecv(e,t)})),this._uitestDriver}static async create(e={}){let t=await Zs.getDefault({config:e.config,mode:e.mode});return e.mode&&t.config.set("rpc.mode",e.mode),t.getDevice(e.serial,{queryVersion:e.queryVersion,rpcMode:e.mode})}get operate(){return this.uitestRpc}async call(e,t="",n=[],i={}){return this.uitestRpc.call(e,t,n,i)}getSnapshot(){return{serial:this.serial,mode:this.rpcMode,rpcs:this.listRpcs(),uitest:this.listRpcs().includes("uitest")?this.uitestRpc.getSnapshot():null}}listRpcs(){return[...this._rpcs.keys()]}async releaseRpc(e){let t=e?[e]:[...this._rpcs.keys()];for(let n of t){let i=this._rpcs.get(n);i&&(await i.release(),this._rpcs.delete(n))}!e&&this._uitestDriver&&(await this._uitestDriver.release(),this._uitestDriver=null)}async disposeRpc(e){let t=e?[e]:[...this._rpcFactories.keys()];for(let n of t){let i=this._rpcs.get(n)||this.rpc(n);i&&await i.dispose(),this._rpcs.delete(n)}!e&&this._uitestDriver&&(await this._uitestDriver.release(),this._uitestDriver=null)}async release(){await this.releaseRpc()}async dispose(){await this.disposeRpc(),await this._clearFports()}async _clearFports(){for(let e of[...this.fportList])try{await this.fportRemove(e.hostPort,e.deviceEndpoint)}catch{}this.fportList=[]}toString(){return`HMDevice(${this.serial})`}},sf=class{device;constructor(e){this.device=e}push(e,t,n){return this.device.fileSend(e,t,n)}pull(e,t,n){return this.device.fileRecv(e,t,n)}exists(e){return this.device.fileExists(e)}isDir(e){return this.device.isDirectory(e)}remove(e,t){return this.device.rm(e,t)}mkdir(e){return this.device.mkdir(e)}readText(e){return this.device.readRemoteText(e)}list(e){return this.device.listDir(e)}},af=class{device;constructor(e){this.device=e}add(e,t){return this.device.fportAdd(e,t)}remove(e,t){return this.device.fportRemove(e,t)}list(){return this.device.fportListAll()}freeHostPort(){return this.device.getFreeHostPort()}},cf=class{device;constructor(e){this.device=e}list(){return this.device.findProcesses()}kill(e){return this.device.killProcess(e)}async find(e){return(await this.device.findProcesses()).filter(n=>n.cmd.includes(e))}};async function _N(r){try{if(!(await NN(r)).isFile())throw new Error("not a file")}catch(e){throw new Rt(`local file does not exist: ${r}`,{cause:e})}}import{fileURLToPath as FN}from"url";import{dirname as jN,join as lf}from"path";import{existsSync as HN}from"fs";var $N={write:(r,e)=>m(e)};$m({name:"uitest",level:"trace",transports:[$N]});function UN(){let r=jN(FN(import.meta.url)),e=[lf(r,"../../resources/uitest"),lf(r,"../src/resources/uitest")];return e.find(t=>HN(lf(t,"uitest_agent_v1.1.9.so")))||e[1]}async function zl(r,e){let t=js("HMDevice"),n=Gs({logger:t,tags:{mode:"fast"}}),i=new di({bin:r,logger:t,dfx:n}),o=Vs({device:{resourcesDir:UN()}}),s=new mi({serial:e,executor:i,config:o,logger:t,dfx:n,rpcMode:o.get("rpc.mode","fast")});return await s.getUitestInfo(),{driver:s.uitest,async dispose(){await s.uitest.release(),await s.release()}}}async function GN(r,e,t="default"){let n=await T(r,e),i=new ho(r),o=Qs({text:"Querying screen size...",color:"cyan"}).start();try{let s=await i.getDisplayInfo(n);o.stop();let a=ci(s);console.log(a?t==="json"?JSON.stringify({width:a.width,height:a.height},null,2):`${a.width}x${a.height}`:VN("No display info found in output."))}catch(s){throw o.stop(),new w(`Failed to get screen size: ${s.message}`,"Failed to get screen size.")}}async function qN(r,e,t){let n=await T(r,t),i=new ho(r),o=e===-1;if(!o&&(e<5e3||e>36e5))throw new w(`Invalid timeout ${e}ms. Use -1 for never sleep, or a value between 5000 and 3600000ms.`,"Invalid screen-off timeout value.");let s=Qs({text:o?"Disabling screen-off...":`Setting screen-off timeout to ${e}ms...`,color:"cyan"}).start();try{o?await i.setScreenNeverSleep(n):await i.setScreenTimeout(n,e),s.stop(),console.log(o?"Screen-off disabled (always on).":`Screen-off timeout set to ${e}ms.`)}catch(a){throw s.stop(),new w(`Failed to set screen-off timeout: ${a.message}`,"Failed to set screen-off timeout.")}}async function zN(r,e,t){let n=await T(r,t),i=Qs({text:`Setting screen rotation to ROTATION_${e}...`,color:"cyan"}).start();try{let{driver:o,dispose:s}=await zl(r.hdcPath,n);try{await o.setDisplayRotation(e)}finally{await s()}i.stop(),console.log(`Screen rotation set to ROTATION_${e}.`)}catch(o){throw i.stop(),new w(`Failed to set screen rotation: ${o.message}`,"Failed to set screen rotation.")}}async function JN(r,e){let t=await T(r,e),n=Qs({text:"Querying screen rotation...",color:"cyan"}).start();try{let{driver:i,dispose:o}=await zl(r.hdcPath,t);try{let s=await i.getDisplayRotation();n.stop(),console.log(`Screen rotation: ROTATION_${s}`)}finally{await o()}}catch(i){throw n.stop(),new w(`Failed to get screen rotation: ${i.message}`,"Failed to get screen rotation.")}}async function YN(r,e,t){let n=await T(r,t),i=Qs({text:`${e?"Locking":"Unlocking"} screen rotation...`,color:"cyan"}).start();try{let{driver:o,dispose:s}=await zl(r.hdcPath,n);try{await o.setDisplayRotationEnabled(!e)}finally{await s()}i.stop(),console.log(e?"Screen rotation locked (auto-rotation disabled).":"Screen rotation unlocked (auto-rotation enabled).")}catch(o){throw i.stop(),new w(`Failed to set rotation lock: ${o.message}`,"Failed to set rotation lock.")}}var fi=new BN("screen").description("Query and manage screen properties");fi.command("size").description("Query screen resolution").option("--device <name|serial>","Target device (name or serial)").addOption(new WN("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","screen","size",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await GN(i,e,t)})});fi.command("rotation").description("Query current screen rotation").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","screen","rotation",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await JN(n,e)})});fi.command("sleeptime").description("Set screen-off timeout in milliseconds; use -1 for never").allowUnknownOption().option("--device <name|serial>","Target device (name or serial)").argument("<ms>","Screen-off timeout in milliseconds; -1 for never").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","screen","sleeptime","<ms>",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await qN(i,Number(r),t)})});fi.command("rotate").description("Set screen rotation (clockwise)").argument("<rotation>","Rotation angle: 0, 90, 180, or 270").option("--device <name|serial>","Target device (name or serial)").action(async(r,e)=>{let{device:t}=e,n=Number(r);if(![0,90,180,270].includes(n))throw new w(`Invalid rotation "${r}". Valid values: 0, 90, 180, 270`,"Invalid rotation value.");let o={event:v.CommandExecuted,args:["device","screen","rotate","<rotation>",...t?["--device"]:[]]};await O(o,async()=>{let{toolProvider:s}=await N();await zN(s,n,t)})});fi.command("rotation-lock").description("Lock or unlock screen rotation (on=lock/disable auto-rotation, off=unlock/enable auto-rotation)").argument("<state>","on or off").option("--device <name|serial>","Target device (name or serial)").action(async(r,e)=>{let{device:t}=e;if(r!=="on"&&r!=="off")throw new w(`Invalid state "${r}". Valid values: on, off`,"Invalid rotation-lock state.");let n={event:v.CommandExecuted,args:["device","screen","rotation-lock","<state>",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await YN(i,r==="on",t)})});import{Command as KN}from"commander";import{gray as XN}from"colorette";import ZN from"ora";var ea=class{constructor(e){this.toolProvider=e}async readClipboard(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-pastedata"]);if(Ge(t),t.exitCode!==0)throw new Error(t.stderr||t.stdout||"read clipboard failed");return t.stdout}async writeClipboard(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-pastedata",t]);if(Ge(n),n.exitCode!==0)throw new Error(n.stderr||n.stdout||"write clipboard failed");return n.stdout}async clearClipboard(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","clear-pastedata"]);if(Ge(t),t.exitCode!==0)throw new Error(t.stderr||t.stdout||"clear clipboard failed");return t.stdout}};async function df(r,e,t,n){let i=await T(r,n),o=new ea(r),s=ZN({text:`Clipboard ${e}...`,color:"cyan"}).start();try{let a;if(e==="read"?a=await o.readClipboard(i):e==="write"?a=await o.writeClipboard(i,t??""):a=await o.clearClipboard(i),s.stop(),e==="read"){let c=a.trim().replace(/^Pasteboard text:\s*/,"");console.log(c||XN("(clipboard is empty)"))}else console.log(`Clipboard ${e==="write"?"written":"cleared"}.`)}catch(a){throw s.stop(),new w(`Clipboard ${e} failed: ${a.message}`,`Clipboard ${e} failed.`)}}var ta=new KN("clipboard").description("Read, write, or clear the device clipboard");ta.command("read").description("Read current clipboard text from the device").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","clipboard","read",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await df(n,"read",void 0,e)})});ta.command("write").description("Write text to the device clipboard").option("--device <name|serial>","Target device (name or serial)").argument("<text>","Text to write to the clipboard").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","clipboard","write",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await df(i,"write",r,t)})});ta.command("clear").description("Clear the device clipboard").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","clipboard","clear",...e?["--device"]:[]]};await O(t,async()=>{let{toolProvider:n}=await N();await df(n,"clear",void 0,e)})});import{Command as QN}from"commander";import{yellow as eM}from"colorette";import{existsSync as tM}from"fs";import uf from"ora";import{execa as Jl}from"execa";var Eo=class{constructor(e){this.toolProvider=e}async fileExists(e,t){let n=this.toolProvider.hdcPath,i=["-t",e,"shell","ls","-l",t];m(`Executing: ${n} ${i.join(" ")}`);let o;try{let{stdout:s,stderr:a}=await Jl(n,i,{env:{...process.env}});o=`${s}
105
+ `)})}var g_={TRACE:"",DEBUG:"",INFO:"",WARN:"",ERROR:""};function h_(r){let e=new Date(r),t=(n,i=2)=>String(n).padStart(i,"0");return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())} ${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}.${t(e.getMilliseconds(),3)}`}var Ys=class r{name;level;transports;fields;timestamp;constructor(e={}){this.name=e.name||"hm",this.level=fm(e.level??"info"),this.transports=e.transports||[m_()],this.fields={...e.fields||{}},this.timestamp=e.timestamp!==!1}child(e,t){return new r({name:e?`${this.name}:${e}`:this.name,level:this.level,transports:this.transports,fields:{...this.fields,...t||{}},timestamp:this.timestamp})}withFields(e){return this.child("",e)}setLevel(e){return this.level=fm(e),this}addTransport(e){return this.transports.push(e),this}isLevelEnabled(e){return fm(e)>=this.level}trace(e,...t){this._log(Kt.TRACE,e,t)}debug(e,...t){this._log(Kt.DEBUG,e,t)}info(e,...t){this._log(Kt.INFO,e,t)}warn(e,...t){this._log(Kt.WARN,e,t)}error(e,...t){this._log(Kt.ERROR,e,t)}timeStart(e,t=Kt.DEBUG){let n=Date.now();return i=>{let o=Date.now()-n;return this._log(t,`${e} cost ${o}ms${i?" "+i:""}`,[]),o}}_log(e,t,n){if(e<this.level)return;let i;try{i=typeof t=="string"?t:wS(t),n&&n.length&&(i+=" "+n.map(l=>l instanceof Error?`${l.name}: ${l.message}`:typeof l=="string"?l:wS(l)).join(" "))}catch{i=String(t)}let o=y_(this.fields),a=`${this.timestamp?`[${h_(Date.now())}] `:""}[${vS[e]}] [${this.name}]${o} ${i}`,c={level:e,name:this.name,message:i,fields:{...this.fields},ts:Date.now()};for(let l of this.transports)try{l.write(c,a)}catch{}}};function y_(r){let e=Object.keys(r||{});return e.length?" "+e.map(t=>`${t}=${r[t]}`).join(" "):""}function wS(r){try{return JSON.stringify(r)}catch{return String(r)}}var mm=new Ys({name:"hm",level:"info"});function gm(r={}){return mm=new Ys({name:"hm",...r}),mm}function Xs(r){return mm.child(r,{})}import{spawn as w_}from"child_process";var Ro=class extends Error{code;details;constructor(e,t={}){super(e,t.cause?{cause:t.cause}:void 0),this.name=new.target.name,this.code=t.code||new.target.code||"HM_ERROR",this.details=t.details,Error.captureStackTrace&&Error.captureStackTrace(this,new.target)}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}},fi=class extends Ro{static code="HDC_ERROR";args;stderr;constructor(e,t={}){super(e,{...t,code:t.code||"HDC_ERROR"}),this.args=t.details?.args||[],this.stderr=t.details?.stderr||""}},hn=class extends fi{static code="HDC_TIMEOUT";constructor(e,t={}){super(e,{...t,code:"HDC_TIMEOUT"})}},Zs=class extends fi{static code="HDC_COMMAND_FAILED";constructor(e,t={}){super(e,{...t,code:"HDC_COMMAND_FAILED"})}},Dt=class extends Ro{static code="DEVICE_ERROR";constructor(e,t={}){super(e,{...t,code:t.code||"DEVICE_ERROR"})}},yn=class extends Dt{static code="DEVICE_NOT_FOUND";constructor(e,t={}){super(e,{...t,code:"DEVICE_NOT_FOUND"})}},wn=class extends Dt{static code="DEVICE_FILE_ERROR";constructor(e,t={}){super(e,{...t,code:"DEVICE_FILE_ERROR"})}},wr=class extends Ro{static code="RPC_ERROR";endpoint;constructor(e,t={}){super(e,{...t,code:t.code||"RPC_ERROR"}),this.endpoint=t.details?.endpoint||""}},vr=class extends wr{static code="RPC_LIFECYCLE_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_LIFECYCLE_ERROR"})}},Vr=class extends vr{static code="RPC_DISPOSED";constructor(e,t={}){super(e,{...t,code:"RPC_DISPOSED"})}},He=class extends wr{static code="RPC_TRANSPORT_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_TRANSPORT_ERROR"})}},vn=class extends wr{static code="RPC_TIMEOUT";constructor(e,t={}){super(e,{...t,code:"RPC_TIMEOUT"})}},Yt=class extends wr{static code="RPC_PROTOCOL_ERROR";constructor(e,t={}){super(e,{...t,code:"RPC_PROTOCOL_ERROR"})}},Qs=class extends wr{static code="RPC_REMOTE_ERROR";remote;constructor(e,t={}){super(e,{...t,code:"RPC_REMOTE_ERROR"}),this.remote=t.details?.remote}};function bS(r){return r instanceof He||r instanceof vn||r instanceof Yt}function hm(r){return r instanceof Vr?!1:bS(r)||r instanceof vr}var ea=class{args;code;stdout;stderr;durationMs;constructor({args:e,code:t=0,stdout:n="",stderr:i="",durationMs:o=0}){this.args=e,this.code=t,this.stdout=n,this.stderr=i,this.durationMs=o}get ok(){return this.code===0}get command(){return this.args.join(" ")}assertOk(e="hdc command"){if(this.ok)return this;throw new Zs(`${e} failed: ${this.stderr||this.stdout||`exit ${this.code}`}`,{details:{args:this.args,stderr:this.stderr,stdout:this.stdout,code:this.code}})}toString(){return this.command}},ta=class{bin;host;port;execTimeoutMs;logger;dfx;constructor(e={}){this.bin=e.bin||"hdc",this.host=e.host||"127.0.0.1",this.port=e.port??8710,this.execTimeoutMs=e.execTimeoutMs??1e4,this.logger=e.logger??null,this.dfx=e.dfx??null}async exec(e,t){throw new fi("HdcExecutor.exec() must be implemented by subclass")}get serverAddress(){return`${this.host||"127.0.0.1"}:${this.port??8710}`}serverPrefixArgs(){return(!this.host||this.host==="127.0.0.1"||this.host==="localhost")&&(this.port??8710)===8710?[]:["-s",this.serverAddress]}async listTargets(e){let t=await this.exec(["list","targets"],e);return SS(t.stdout)}};function SS(r){let e=String(r||"").trim();return!e||/\[Empty\]/i.test(e)||/^Empty$/i.test(e)?[]:e.split(/\r?\n/).map(t=>t.trim()).filter(t=>t&&!/\[Empty\]/i.test(t)&&!/^Empty$/i.test(t))}function ym(r){let e=[];for(let t of String(r||"").split(/\r?\n/)){let n=t.trim();if(!n||/\[Empty\]/i.test(n)||/^Empty$/i.test(n))continue;let i=/tcp:(\d+)\s+(\S+)/.exec(n);if(!i)continue;let o=Number(i[1]);Number.isInteger(o)&&e.push({hostPort:o,deviceEndpoint:i[2],taskString:`tcp:${o} ${i[2]}`})}return e}function wm(r){let e=[];for(let t of String(r||"").split(/\r?\n/)){let n=t.trim();if(!n)continue;let i=/^(\S+)\s+(\d+)\s+(\d+)\s+(.*)$/.exec(n);i&&e.push({user:i[1],pid:Number(i[2]),cmd:i[4]})}return e}var mi=class extends ta{env;onStderr;windowsHide;constructor(e={}){super(e),this.env=e.env||process.env,this.onStderr=e.onStderr??null,this.windowsHide=e.windowsHide!==!1}_childEnv(){let e={...this.env};return this.host&&this.host!=="127.0.0.1"&&(e.HDC_SERVER_IP||(e.HDC_SERVER_IP=this.host),e.HDC_SERVER_PORT||(e.HDC_SERVER_PORT=String(this.port))),e}exec(e,t={}){let n=t.timeoutMs??this.execTimeoutMs,i=Date.now(),o=this.dfx?this.dfx.timer("hdc.exec",{cmd:e[0]}):null,s=[...this.serverPrefixArgs(),...e],a=this._childEnv();return new Promise((c,l)=>{let d=this.spawnHdcChild(s,a,o,l);d&&this.attachChildHandlers(d,e,n,i,o,c,l)})}spawnHdcChild(e,t,n,i){try{return f(`Executing: ${this.bin} ${e.join(" ")}`),w_(this.bin,e,{env:t,stdio:["ignore","pipe","pipe"],windowsHide:this.windowsHide})}catch(o){return n&&n({ok:0}),i(new hn(`spawn ${this.bin} failed: ${o.message}`,{cause:o})),null}}attachChildHandlers(e,t,n,i,o,s,a){let c={outChunks:[],errChunks:[],settled:!1,timedOut:!1,timer:null};c.timer=setTimeout(()=>{c.timedOut=!0;try{e.kill("SIGKILL")}catch{}},n),e.stdout?.on("data",l=>{c.outChunks.length<4096&&c.outChunks.push(l)}),e.stderr?.on("data",l=>{c.errChunks.push(l),this.onStderr&&this.onStderr(l.toString())}),e.on("close",l=>{this.finalizeResult(l,t,n,i,o,c,s,a)}),e.on("error",l=>{this.handleChildError(l,t,o,c,a)})}finalizeResult(e,t,n,i,o,s,a,c){if(s.settled)return;s.settled=!0,s.timer&&clearTimeout(s.timer);let l=Buffer.concat(s.outChunks).toString("utf8").trim(),d=Buffer.concat(s.errChunks).toString("utf8").trim(),g=Date.now()-i;if(o&&o({ok:e===0?1:0}),this.dfx&&this.dfx.counter(e===0?"hdc.exec.ok":"hdc.exec.error",1,{cmd:t[0]}),this.logger&&this.logger.debug(`hdc ${t.join(" ")} -> code=${e} (${g}ms)`),s.timedOut){c(new hn(`hdc ${t.join(" ")} timeout after ${n}ms`,{details:{args:t,stdout:l,stderr:d}}));return}a(new ea({args:t,code:e??-1,stdout:l,stderr:d,durationMs:g}))}handleChildError(e,t,n,i,o){i.settled||(i.settled=!0,i.timer&&clearTimeout(i.timer),n&&n({ok:0}),o(new hn(`hdc ${t.join(" ")} spawn error: ${e.message}`,{cause:e})))}};var ES=Object.freeze({hdc:{bin:"hdc",host:"127.0.0.1",port:8710,execTimeoutMs:1e4,maxOutputBytes:4194304},device:{autoSelectFirst:!0,queryVersion:!0,newUiTestMinVersion:"6.0.2.2",autoPushResources:!0,resourcesDir:"",fastModeDir:""},rpc:{mode:"fast",framing:"auto",connectTimeoutMs:5e3,requestTimeoutMs:3e4,socketIdleTimeoutMs:3e4,portRange:{start:1e4,end:19999},concurrency:"auto",maxInFlight:16,strictPairing:!1,timeoutKillsConnection:!1,recovery:{enabled:!0,maxAttempts:1,delayMs:200},fast:{connectTimeoutMs:1500,probeOnReuse:!0,keepOnRelease:!0,forceRestartOnProbeFailure:!0},operate:{fastHostPort:19801,startWaitMs:500,processWaitTimeoutMs:15e3,processCheckIntervalMs:200,checkListening:!0,resources:[]}},log:{level:"info",timestamp:!0,transports:["console"],file:""},dfx:{enabled:!0,sinks:["memory"],slowThresholdMs:1e3}}),v_={HM_HDC_BIN:"hdc.bin",HM_HDC_HOST:"hdc.host",HM_HDC_PORT:"hdc.port",HM_LOG_LEVEL:"log.level",HM_RPC_MODE:"rpc.mode",HM_RPC_REQUEST_TIMEOUT:"rpc.requestTimeoutMs"};function zl(r){return r!==null&&typeof r=="object"&&!Array.isArray(r)}function vm(r){if(typeof structuredClone=="function")try{return structuredClone(r)}catch{}return JSON.parse(JSON.stringify(r))}function ql(r,e){let t=vm(r);for(let[n,i]of Object.entries(e||{}))i!==void 0&&(zl(i)&&zl(t[n])?t[n]=ql(t[n],i):t[n]=vm(i));return t}function b_(r,e){return e.split(".").reduce((t,n)=>{if(!(t==null||typeof t!="object"))return t[n]},r)}function PS(r,e,t){let n=e.split("."),i=n.pop(),o=r;for(let s of n)zl(o[s])||(o[s]={}),o=o[s];return o[i]=t,r}var Jl=class{_data;constructor(e={}){this._data=ql(ES,S_()),e&&Object.keys(e).length&&(this._data=ql(this._data,e))}slice(e){let t=this.get(e);return zl(t)?t:{}}get(e,t){let n=b_(this._data,e);return n===void 0?t:n}set(e,t){return PS(this._data,e,t),this}merge(e){return this._data=ql(this._data,e),this}snapshot(){return vm(this._data)}toJSON(){return this.snapshot()}};function S_(){let r={};for(let[e,t]of Object.entries(v_)){let n=process.env[e];if(n===void 0||n==="")continue;let i=n;if(t==="hdc.port"||t==="rpc.requestTimeoutMs"){let o=Number(n);if(Number.isNaN(o))continue;i=o}PS(r,t,i)}return r}function ra(r){return new Jl(r)}var Kl=class{records;constructor(){this.records=[]}write(e){this.records.push(e)}select(e){return this.records.filter(t=>typeof e=="function"?e(t.name):t.name===e||t.name.startsWith(e+"."))}sum(e){return this.select(e).reduce((t,n)=>t+(n.value||0),0)}count(e){return this.select(e).length}snapshot(){return{counters:CS(this.records,"counter"),timers:CS(this.records,"timer"),events:this.records.filter(e=>e.type==="event").map(e=>({name:e.name,fields:e.fields,ts:e.ts}))}}reset(){this.records.length=0}};function CS(r,e){let t={};for(let n of r){if(n.type!==e)continue;t[n.name]||(t[n.name]={count:0,sum:0,min:1/0,max:0,avg:0});let i=e==="counter"?n.value||0:n.durationMs||0;t[n.name].count+=1,t[n.name].sum+=i,t[n.name].min=Math.min(t[n.name].min,i),t[n.name].max=Math.max(t[n.name].max,i)}for(let n of Object.keys(t))t[n].avg=t[n].sum/t[n].count,t[n].min===1/0&&(t[n].min=0);return t}var Yl=class r{enabled;tags;sinks;slowThresholdMs;logger;constructor(e={}){this.enabled=e.enabled!==!1,this.tags={...e.tags||{}},this.sinks=e.sinks||[new Kl],this.slowThresholdMs=e.slowThresholdMs??1e3,this.logger=e.logger??null}child(e){return new r({enabled:this.enabled,sinks:this.sinks,tags:{...this.tags,...e||{}},slowThresholdMs:this.slowThresholdMs,logger:this.logger})}counter(e,t=1,n={}){this._emit({type:"counter",name:e,value:t,fields:n})}event(e,t={}){this._emit({type:"event",name:e,fields:t})}timer(e,t={}){let n=Date.now();return(i={})=>{let o=Date.now()-n;return this._emit({type:"timer",name:e,fields:{...t,...i},durationMs:o}),this.slowThresholdMs>0&&o>this.slowThresholdMs&&this._emit({type:"event",name:"slow",fields:{...t,...i,metric:e,durationMs:o}}),o}}async span(e,t,n={}){let i=this.timer(e,n);try{let o=await t();return i({ok:1}),this.counter(`${e}.ok`,1,n),o}catch(o){throw i({ok:0}),this.counter(`${e}.error`,1,{...n,code:o?.code||o?.name}),o}}_emit(e){if(!this.enabled)return;let t={type:e.type,name:e.name,value:e.value,durationMs:e.durationMs,fields:{...this.tags,...e.fields||{}},ts:Date.now()};for(let n of this.sinks)try{n.write(t)}catch{}}snapshot(){let e=this.sinks.find(t=>t instanceof Kl);return e?e.snapshot():null}reset(){for(let e of this.sinks)typeof e.reset=="function"&&e.reset()}};function na(r={}){return new Yl(r)}function xo(r){return new Promise(e=>setTimeout(e,r))}async function Xl(r,{timeoutMs:e,intervalMs:t=200,firstDelayMs:n=0,description:i="condition"}){let o=Date.now()+e;n>0&&await xo(n);let s;for(;;){if(s=await r(),s)return s;if(Date.now()>=o){let a=new Error(`wait for ${i} timeout after ${e}ms`);throw a.name="TimeoutError",a}await xo(t)}}var Do=class{_tail;locked;constructor(){this._tail=Promise.resolve(),this.locked=!1}async runExclusive(e){let t,n=new Promise(o=>{t=o}),i=this._tail;this._tail=i.then(()=>n),await i.catch(()=>{}),this.locked=!0;try{return await e()}finally{this.locked=!1,t()}}},Io=class{limit;used;_waiters;_idleWaiters;constructor(e=1){this.limit=Math.max(1,e|0),this.used=0,this._waiters=[],this._idleWaiters=[]}get available(){return Math.max(0,this.limit-this.used)}get waiting(){return this._waiters.length}get isIdle(){return this.used===0}acquire(){return new Promise((e,t)=>{this._waiters.push({resolve:e,reject:t}),this._dispatch()})}resize(e){let t=Math.max(1,e|0);t!==this.limit&&(this.limit=t,this._dispatch())}abortAll(e){let t=this._waiters.splice(0);for(let n of t)try{n.reject(e)}catch{}}drain(){return this.used===0?Promise.resolve():new Promise(e=>{this._idleWaiters.push({resolve:e})})}_dispatch(){for(;this._waiters.length>0&&this.used<this.limit;){let e=this._waiters.shift();this.used+=1;let t=!1;e.resolve(()=>{t||(t=!0,this.used-=1,this._dispatch(),this.used===0&&this._idleWaiters.length&&this._resolveIdleWaiters())})}}_resolveIdleWaiters(){let e=this._idleWaiters.splice(0);for(let t of e)t.resolve()}},gi=class{_map;constructor(){this._map=new Map}run(e,t){let n=this._map.get(e);if(n)return n;let o=(async()=>t())().finally(()=>{this._map.get(e)===o&&this._map.delete(e)});return this._map.set(e,o),o}pending(e){return this._map.get(e)||null}has(e){return this._map.has(e)}keys(){return[...this._map.keys()]}};var E_=64*1024*1024,bm={name:"length-prefixed",frameDelimited:!0,encode(r){let e=Buffer.from(typeof r=="string"?r:JSON.stringify(r),"utf8"),t=Buffer.alloc(4);return t.writeUInt32BE(e.length,0),Buffer.concat([t,e])},decode(r){if(r.length<4)return null;let e=r.readUInt32BE(0);if(e>E_||e<0)throw new Yt(`invalid frame length ${e}`);if(r.length<4+e)return null;let t=r.subarray(4,4+e).toString("utf8"),n;try{n=JSON.parse(t)}catch{throw new Yt(`response is not valid JSON: ${t.slice(0,200)}`)}return{value:n,rest:r.subarray(4+e)}}},Zl={name:"raw",frameDelimited:!1,encode(r){return Buffer.from(typeof r=="string"?r:JSON.stringify(r),"utf8")},decode(r){let e=r.toString("utf8").trim();if(!e)return null;let t;try{t=JSON.parse(e)}catch{return null}return{value:t,rest:Buffer.alloc(0)}}};function P_(r){if(!r||r.length===0)return null;let e=r[0];return e===123||e===91?"raw":"length-prefixed"}function Sm(r="auto"){return r==="raw"?Zl:r==="length-prefixed"?bm:C_()}function C_(){let r=null;return{name:"auto",frameDelimited:!1,get detected(){return r},encode(e){return Zl.encode(e)},decode(e){return r||(r=P_(e)),r==="length-prefixed"?bm.decode(e):Zl.decode(e)}}}var Em=0;function br(r="hm"){Em=(Em+1)%1e6;let e=new Date().toISOString().replace(/[-:T]/g,"").replace(/\..+/,""),t=Math.random().toString(36).slice(2,8);return`${r}-${e}-${Em.toString(36)}-${t}`}import Pm from"net";function Cm(r,e,t=500){return new Promise(n=>{let i=new Pm.Socket,o=!1,s=a=>{o||(o=!0,i.destroy(),n(a))};i.setTimeout(t),i.once("connect",()=>s(!0)),i.once("timeout",()=>s(!1)),i.once("error",()=>s(!1));try{i.connect(e,r)}catch{s(!1)}})}async function km({host:r="127.0.0.1",start:e=1e4,end:t=19999,exclude:n}={}){let i=new Set(n||[]);for(let o=e;o<=t;o++){if(i.has(o))continue;if(await R_(r,o))return o}throw new Error(`no free port in range ${e}-${t}`)}var k_=km;function R_(r,e){return new Promise(t=>{let n=Pm.createServer();n.once("error",()=>t(!1)),n.once("listening",()=>{n.close(()=>t(!0))}),n.listen(e,r)})}async function x_({host:r="127.0.0.1",start:e=1e4,end:t=19999,exclude:n,timeoutMs:i=500,stepDelayMs:o=0}={}){if(!r)throw new Error("getFreeRemotePort requires host");let s=new Set(n||[]);for(let a=e;a<=t;a++){if(s.has(a))continue;if(!await Cm(r,a,i))return a;o>0&&await new Promise(l=>setTimeout(l,o))}throw new Error(`no free port on remote ${r} in range ${e}-${t}`)}async function kS({hdcHost:r="127.0.0.1",start:e,end:t,exclude:n}={}){return!r||r==="127.0.0.1"||r==="localhost"?{port:await k_({host:r||"127.0.0.1",start:e,end:t,exclude:n}),scope:"local"}:{port:await x_({host:r,start:e,end:t,exclude:n,stepDelayMs:50}),scope:"remote"}}function Ql({host:r,port:e,timeoutMs:t=5e3,keepAliveMs:n}){return new Promise((i,o)=>{let s=new Pm.Socket,a=!1,c=l=>{a||(a=!0,s.destroy(),o(l))};s.setTimeout(t),s.once("timeout",()=>{let l=new Error(`connect to ${r}:${e} timeout after ${t}ms`);l.code="ETIMEDOUT",c(l)}),s.once("error",c),s.connect(e,r,()=>{a||(a=!0,s.removeListener("error",c),s.removeListener("timeout",c),n&&n>0&&s.setKeepAlive(!0,n),s.setNoDelay(!0),i(s))})})}function Xt(r,e){let t=RS(r),n=RS(e),i=Math.max(t.length,n.length);for(let o=0;o<i;o++){let s=t[o]??0,a=n[o]??0;if(s>a)return 1;if(s<a)return-1}return 0}function RS(r){return String(r||"").trim().split(/[.\-+_]/).filter(Boolean).map(e=>{let t=parseInt(e,10);return Number.isNaN(t)?0:t})}function Ao(r){let e=/(\d+(?:\.\d+)+)/.exec(String(r||""));return e?e[1]:null}var D_=/^[A-Za-z0-9_@%+=:,./-]+$/,I_=/'/g,A_="'\\''";function hi(r){let e=r==null?"":String(r);return e===""?"''":D_.test(e)?e:`'${e.replace(I_,A_)}'`}function It(r){if(!Array.isArray(r))throw new TypeError("shellJoin expects an array of arguments");return r.filter(e=>e!=null&&e!=="").map(e=>hi(e)).join(" ")}function Rm(r){let e=String(r??"");if(/[\r\n\0]/.test(e))throw new Sr("shell command must not contain newline or NUL characters");return e}function Er(r){let e=String(r??"").trim();if(!e)throw new Sr("remote path is empty");if(!e.startsWith("/"))throw new Sr(`remote path must be absolute: ${JSON.stringify(r)}`);if(/[\r\n\0]/.test(e))throw new Sr("remote path must not contain newline or NUL characters");return e}function xm(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new Sr(`invalid pid: ${JSON.stringify(r)}`);return e}function ed(r){let e=String(r??"").trim();if(!/^(localabstract|localfilesystem|tcp|jdwp):[A-Za-z0-9_.-]+$/.test(e))throw new Sr(`invalid device endpoint: ${JSON.stringify(r)}`);return e}function td(r){let e=Number(r);if(!Number.isInteger(e)||e<1||e>65535)throw new Sr(`invalid host port: ${JSON.stringify(r)}`);return e}var Sr=class extends Error{constructor(e){super(e),this.name="ShellSafetyError"}};import{stat as uM}from"fs/promises";var M_="6.0.2.2";async function xS(r,e={}){let t=e.minVersion||M_,n=(await r.shellArgs(["file","/system/bin/uitest"])).trim(),i=/x86[ _-]64/.test(n)?"x86_64":"arm64",o=(await r.shellArgs(["/system/bin/uitest","--version"])).trim(),s=L_(o)||o,a=Xt(s,t)>=0;return{version:s,arch:i,isNewUiTest:a,endpointStyle:a&&i!=="x86_64"?"unix":"tcp",fileOutput:n}}function L_(r){let e=/(\d+(?:\.\d+)+)/.exec(String(r||""));return e?e[1]:null}import{fileURLToPath as B_}from"url";import{dirname as W_,join as AS}from"path";import{readdirSync as F_}from"fs";import{join as $_,basename as FQ}from"path";var j_=/^uitest_agent_v(\d+\.\d+\.\d+)(\.x86_64)?\.so$/,H_="/data/local/tmp/agent.so",Dm="UITEST_AGENT_LIBRARY";function U_(r){let e;try{e=F_(r)}catch{return[]}return e.filter(t=>t.endsWith(".so"))}function DS({dir:r,arch:e,isNewUiTest:t}){let n=e==="x86_64",i=[];for(let s of U_(r)){let a=j_.exec(s);if(!a)continue;let c=!!a[2];if(n!==c)continue;if(n){i.push({fileName:s,version:a[1],x86_64:c});continue}let l=Xt(a[1],"1.2.2")>=0;t===l&&i.push({fileName:s,version:a[1],x86_64:c})}if(!i.length)return null;i.sort((s,a)=>Xt(a.version,s.version));let o=i[0];return{fileName:o.fileName,localPath:$_(r,o.fileName),version:o.version,x86_64:o.x86_64,remotePath:H_,versionProbe:Dm}}function IS(r){let e=String(r||""),t=e.indexOf("#"),n=t>=0?e.slice(t+1):e;return Ao(n)}var V_=AS(W_(B_(import.meta.url)),"..",".."),G_=AS(V_,"resources"),rd=class{device;config;logger;dfx;_agentState;constructor({device:e,config:t,logger:n,dfx:i}){this.device=e,this.config=t,this.logger=n?n.child("ResourceMgr"):null,this.dfx=i??null,this._agentState=null}get resourcesDir(){return this.config.get("device.resourcesDir")||G_}async getInfo(e=!1){return this.device.getUitestInfo(e)}async ensureAgent(e={}){if(this._agentState&&!e.force)return this._agentState;let t=await this.getInfo(),n=DS({dir:this.resourcesDir,arch:t.arch,isNewUiTest:t.isNewUiTest});if(!n)throw new Dt(`no uitest agent found for arch=${t.arch} isNewUiTest=${t.isNewUiTest} in ${this.resourcesDir}`,{details:{resourcesDir:this.resourcesDir}});let i=await this.device.fileExists(n.remotePath),o=null,s=!i;return i&&(o=await this._probeAgentVersion(n.remotePath),(!o||Xt(n.version,o)>0)&&(s=!0)),s?(this.logger&&this.logger.info(`update agent.so: local=v${n.version} remote=${o||"none"} (arch=${n.x86_64?"x86_64":"arm64"})`),await this.stopUitestDaemons(),await this.device.rm(n.remotePath),await this._push(n.localPath,n.remotePath,"agent.so"),this.dfx&&this.dfx.counter("resource.agent.update",1,{arch:t.arch})):this.logger&&this.logger.debug(`agent.so up-to-date: v${o}`),this._agentState={candidate:n,updated:s,remoteVersion:o},this._agentState}async repushAgent(){let e=this._agentState?.candidate;e||(e=(await this.ensureAgent()).candidate),this.logger&&this.logger.info(`repush agent.so unconditionally (suspect corruption): ${e.fileName}`),await this.stopUitestDaemons(),await this.device.rm(e.remotePath),await this._push(e.localPath,e.remotePath,"agent.so"),this.dfx&&this.dfx.counter("resource.agent.repush",1,{file:e.fileName}),this._agentState={candidate:e,updated:!0,remoteVersion:e.version}}async _probeAgentVersion(e){try{let t=await this.device.shell(`cat ${hi(e)} | ${It(["grep","-a",Dm])}`);return IS(t)}catch{return null}}async _push(e,t,n){let i=this.dfx?this.dfx.timer("resource.push",{file:n}):null;await this.device.fileSend(e,t),i&&i({ok:1})}async stopUitestDaemons(){let t=(await this.device.findProcesses()).filter(n=>n.cmd.includes("uitest")&&n.cmd.includes("start-daemon")).map(n=>n.pid);for(let n of t)try{await this.device.killProcess(n)}catch(i){this.logger&&this.logger.debug(`kill daemon pid=${n} failed: ${i.message}`)}return t.length&&this.logger&&this.logger.info(`stopped uitest daemons before agent update: [${t.join(", ")}]`),t.length}};import{join as Im}from"path";import{mkdir as q_,readFile as TS,writeFile as NS,unlink as z_,readdir as J_}from"fs/promises";function K_(r){return String(r||"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}var Y_=Im($(),"fast-mode"),nd=class{config;logger;_explicitDir;constructor({config:e,dir:t,logger:n}={}){this.config=e,this.logger=n?n.child("FastModeStore"):null,this._explicitDir=t}get dir(){if(this._explicitDir)return this._explicitDir;if(this.config){let e=this.config.get("device.fastModeDir");if(e)return e}return Y_}pathFor(e){return Im(this.dir,`${K_(e)}.json`)}async _ensureDir(){await q_(this.dir,{recursive:!0,mode:448})}async save(e,t){await this._ensureDir();let n=await this.read(e)||{serial:e,createdAt:new Date(0).toISOString(),updatedAt:new Date(0).toISOString(),endpoints:{}};n.serial=e,n.updatedAt=new Date().toISOString(),(!n.createdAt||n.createdAt===new Date(0).toISOString())&&(n.createdAt=n.updatedAt),n.hdcServer=t.hdcServer||n.hdcServer||"",n.endpoints[t.endpoint]={hostPort:t.hostPort,deviceEndpoint:t.deviceEndpoint,style:t.style,agentVersion:t.agentVersion||null,uitestVersion:t.uitestVersion||null,savedAt:n.updatedAt};let i=this.pathFor(e);return await NS(i,JSON.stringify(n,null,2),{mode:384}),this.logger&&this.logger.debug(`saved fast-mode state for ${e}: ${t.endpoint} -> tcp:${t.hostPort}`),n}async read(e){try{let t=await TS(this.pathFor(e),"utf8"),n=JSON.parse(t);return!n||typeof n!="object"||!n.endpoints?null:n}catch{return null}}async get(e,t){let n=await this.read(e);return n&&n.endpoints&&n.endpoints[t]||null}async forget(e){try{return await z_(this.pathFor(e)),this.logger&&this.logger.debug(`removed fast-mode state for ${e}`),!0}catch{return!1}}async forgetEndpoint(e,t){let n=await this.read(e);return!n||!n.endpoints[t]?!1:(n.endpoints=Object.fromEntries(Object.entries(n.endpoints).filter(([i])=>i!==t)),Object.keys(n.endpoints).length?(await this._ensureDir(),await NS(this.pathFor(e),JSON.stringify(n,null,2),{mode:384}),!0):this.forget(e))}async list(){let e;try{e=await J_(this.dir)}catch{return[]}let t=[];for(let n of e)if(n.endsWith(".json"))try{t.push(JSON.parse(await TS(Im(this.dir,n),"utf8")))}catch{}return t}};var Pr={AUTO:"auto",PIPELINED:"pipelined",SERIAL:"serial"},ia=class{host;port;name;codec;frameDelimited;concurrency;maxInFlight;strictPairing;timeoutKillsConnection;connectTimeoutMs;requestTimeoutMs;socketIdleTimeoutMs;logger;dfx;socket;buffer;pending;_sem;generation;_closed;_failure;onClose;_serverEchoesRequestId;_seq;stats;constructor(e){this.host=e.host||"127.0.0.1",this.port=e.port,this.name=e.name||"rpc",this.codec=Sm(e.framing||"auto"),this.frameDelimited=this.codec.frameDelimited===!0,this.concurrency=e.concurrency||Pr.AUTO,this.maxInFlight=Math.max(1,e.maxInFlight??16),this.strictPairing=e.strictPairing===!0,this.timeoutKillsConnection=e.timeoutKillsConnection===!0,this.connectTimeoutMs=e.connectTimeoutMs??5e3,this.requestTimeoutMs=e.requestTimeoutMs??3e4,this.socketIdleTimeoutMs=e.socketIdleTimeoutMs??3e4,this.logger=e.logger??null,this.dfx=e.dfx??null,this.socket=null,this.buffer=Buffer.alloc(0),this.pending=new Map,this._sem=new Io(this._initialLimit()),this.generation=0,this._closed=!0,this._failure=null,this.onClose=null,this._serverEchoesRequestId=null,this._seq=0,this.stats={connectCount:0,requestCount:0,bytesIn:0,bytesOut:0,maxInFlight:0,timeouts:0,unmatchedResponses:0,queued:0}}get isConnected(){return!!this.socket&&!this.socket.destroyed&&!this._closed}get inFlight(){return this.pending.size}get concurrencyMode(){return this.concurrency===Pr.SERIAL?"serial":this.frameDelimited?this.concurrency===Pr.PIPELINED?"pipelined":this._serverEchoesRequestId===!0?"pipelined(auto)":"serial(auto)":"serial(raw)"}async connect(e={}){await this.destroy();let t=e.port??this.port,n=e.timeoutMs??this.connectTimeoutMs,i=this.dfx?this.dfx.timer("rpc.connect",{endpoint:this.name}):null;try{this.socket=await Ql({host:this.host,port:t,timeoutMs:n})}catch(a){let c=a;throw i&&i({ok:0}),this.dfx&&this.dfx.counter("rpc.connect.error",1,{endpoint:this.name}),new He(`connect ${this.host}:${t} failed: ${c.message}`,{cause:c,details:{endpoint:this.name,host:this.host,port:t}})}let o=++this.generation;this._postConnectSetup(),i&&i({ok:1}),this.dfx&&this.dfx.counter("rpc.connect.ok",1,{endpoint:this.name});let s=this.socket;s.setTimeout(this.socketIdleTimeoutMs),this._attachSocketHandlers(s,o),this.logger&&this.logger.info(`connected to ${this.host}:${t} (${this.name}, gen=${o})`)}_postConnectSetup(){this._closed=!1,this._failure=null,this.buffer=Buffer.alloc(0),this.pending.clear(),this._serverEchoesRequestId=null,this._sem.resize(this._computeLimit()),this.stats.connectCount+=1}_attachSocketHandlers(e,t){e.on("data",n=>{t===this.generation&&this._onData(n)}),e.on("error",n=>{t===this.generation&&this._fail(new He(`socket error: ${n.message}`,{cause:n}))}),e.on("timeout",()=>{t===this.generation&&this._fail(new vn(`socket idle timeout after ${this.socketIdleTimeoutMs}ms`))}),e.on("close",()=>{t===this.generation&&this._fail(new He("connection closed by peer"))})}_onData(e){this.stats.bytesIn+=e.length,this.buffer=Buffer.concat([this.buffer,e]);try{for(;;){let t=this.codec.decode(this.buffer);if(!t)break;this.buffer=t.rest,this._dispatch(t.value)}}catch(t){let n=t;this._fail(n instanceof Yt?n:new Yt(`decode failed: ${n.message}`))}}_dispatch(e){let t=e,n=t&&typeof t=="object"?t.request_id:void 0,i=null;if(n!=null&&this.pending.has(n)?i=n:n==null&&(this.pending.size===1&&(i=[...this.pending.keys()][0]),this._noteNoRequestId()),i==null){this.stats.unmatchedResponses+=1,this.dfx&&this.dfx.counter("rpc.response.unmatched",1,{endpoint:this.name,hasId:String(n!=null)}),this.logger&&this.logger.warn(`drop unmatched response (request_id=${n}, pending=${this.pending.size})`),this.strictPairing&&this._fail(new Yt(`unmatched response, request_id=${n}, pending=${this.pending.size}`));return}let o=this.pending.get(i);this.pending.delete(i),o.timer&&clearTimeout(o.timer),n!=null&&this._serverEchoesRequestId!==!0&&(this._serverEchoesRequestId=!0,this._applyLimit()),o.resolve(e)}_noteNoRequestId(){this._serverEchoesRequestId!==!1&&(this._serverEchoesRequestId=!1,this._applyLimit(),this.logger&&this.logger.warn("server does not echo request_id, degrade to serial mode for this connection"),this.dfx&&this.dfx.counter("rpc.concurrency.degrade",1,{endpoint:this.name}))}_computeLimit(){return this.concurrency===Pr.SERIAL||!this.frameDelimited?1:this.concurrency===Pr.PIPELINED?this.maxInFlight:this._serverEchoesRequestId===!0?this.maxInFlight:1}_initialLimit(){return this.concurrency===Pr.SERIAL||!this.frameDelimited?1:this.concurrency===Pr.PIPELINED?this.maxInFlight:1}_applyLimit(){this._sem.resize(this._computeLimit())}_nextRequestId(e){if(e!=null&&!this.pending.has(String(e)))return String(e);let t=br();for(;this.pending.has(t);)t=br();return t}async send(e,t={}){this._assertUsable();let n=await this._acquireSendSlot();try{this._assertUsable();let i=this.generation,o=t.timeoutMs??this.requestTimeoutMs,s=this._nextRequestId(e&&e.request_id),a={...e,request_id:s},c=++this._seq,l=this.dfx?this.dfx.timer("rpc.request",{endpoint:this.name}):null,d=await this._awaitResponse(s,a,i,c,o,l);return l&&l({ok:1}),this.dfx&&this.dfx.counter("rpc.request.ok",1,{endpoint:this.name}),d}finally{n&&n()}}async _acquireSendSlot(){let e=null;try{(this._sem.available<=0||this._sem.waiting>0)&&(this.stats.queued+=1),e=await this._sem.acquire()}catch(t){let n=t;throw new He(`request rejected while queued: ${n.message}`,{cause:n,details:{endpoint:this.name}})}return e}_awaitResponse(e,t,n,i,o,s){return new Promise((a,c)=>{let l={resolve:a,reject:c,timer:null,t0:Date.now(),gen:n,seq:i},d=this._createSettleFn(e,l);l.timer=setTimeout(()=>this._onRequestTimeout(e,o,s,d,c),o),this._registerPending(e,l),this._writeFrame(t,i,d,c)})}_createSettleFn(e,t){return(n,i)=>{this.pending.get(e)===t&&(this.pending.delete(e),t.timer&&clearTimeout(t.timer),n(i))}}_onRequestTimeout(e,t,n,i,o){this.stats.timeouts+=1;let s=new vn(`rpc request ${e} timeout after ${t}ms`,{details:{endpoint:this.name,requestId:e}});n&&n({ok:0,reason:"timeout"}),this.dfx&&this.dfx.counter("rpc.request.error",1,{endpoint:this.name,reason:"timeout"}),i(o,s),this.timeoutKillsConnection&&this._fail(s)}_registerPending(e,t){this.pending.set(e,t),this.stats.requestCount+=1,this.stats.maxInFlight=Math.max(this.stats.maxInFlight,this.pending.size)}_writeFrame(e,t,n,i){let o=!1;try{let s=this.codec.encode(e);this.stats.bytesOut+=s.length,this.logger&&this.logger.debug(`-> ${this.name} #${t} ${JSON.stringify(e).slice(0,300)}`);let a=this.socket;if(!a)throw new He("socket is null");o=a.write(s,c=>{c&&n(i,new He(`write failed: ${c.message}`,{cause:c}))})}catch(s){let a=s;n(i,new He(`write failed: ${a.message}`,{cause:a}));return}!o&&this.logger&&this.logger.debug(`socket backpressure on #${t}`)}_assertUsable(){if(!this.isConnected)throw new He(this._failure?`connection broken: ${this._failure.message}`:"transport is not connected",{cause:this._failure||void 0,details:{endpoint:this.name}})}_fail(e){if(!(this._closed&&this.pending.size===0&&this._sem.waiting===0)&&(this._failure=e,this._rejectAll(e),this._closeSocket(),this.onClose))try{this.onClose(e)}catch{}}_rejectAll(e){let t=[...this.pending.values()];this.pending.clear();for(let n of t){n.timer&&clearTimeout(n.timer);try{n.reject(e)}catch{}}this._sem.abortAll(e)}_closeSocket(){this._closed=!0,this.generation+=1;let e=this.socket;if(this.socket=null,e){e.removeAllListeners();try{e.destroy()}catch{}}}async close(e="closed by client"){let t=new He(`transport closed: ${e}`);this._failure=null,this._rejectAll(t),this._closeSocket(),this.logger&&this.logger.debug(`transport closed: ${e}`)}async destroy(){await this.close("destroy")}getSnapshot(){return{name:this.name,host:this.host,port:this.port,connected:this.isConnected,generation:this.generation,concurrency:this.concurrency,concurrencyMode:this.concurrencyMode,maxInFlight:this._sem.limit,inFlight:this.pending.size,queued:this._sem.waiting,serverEchoesRequestId:this._serverEchoesRequestId,stats:{...this.stats}}}};var id="com.ohos.devicetest.hypiumApiHelper",Am="callHypiumApi";function od({module:r,method:e,params:t={},requestId:n}){return{module:r,method:e,params:t,request_id:n||br()}}function sd(r){if(!r||typeof r!="object")return!1;let e=r.exception;return e!=null&&e!==""}function ad(r){return r?r.result:void 0}var Re={IDLE:"IDLE",BOOTING:"BOOTING",RESOURCES_READY:"RESOURCES_READY",PROCESS_RUNNING:"PROCESS_RUNNING",FORWARDED:"FORWARDED",CONNECTING:"CONNECTING",CONNECTED:"CONNECTED",READY:"READY",WARM:"WARM",RESETTING:"RESETTING",ERROR:"ERROR",DISPOSED:"DISPOSED"},oa=class{device;endpoint;config;name;displayName;logger;dfx;mode;state;transport;_mutex;_epoch;_readyFlight;_resetFlight;_disposed;ctx;constructor({device:e,endpoint:t,config:n,logger:i,dfx:o,mode:s}){this.device=e,this.endpoint=t,this.config=n,this.name=t.name,this.displayName=t.displayName||t.name,this.logger=i?i.child(`Rpc:${this.displayName}`):null,this.dfx=o?o.child({endpoint:this.name}):null,this.mode=s||n.get("rpc.mode","stable"),this.state=Re.IDLE,this.transport=null,this._mutex=new Do,this._epoch=0,this._readyFlight=new gi,this._resetFlight=new gi,this._disposed=!1,this.ctx=this._freshContext()}_bumpEpoch(){return this._epoch+=1,this._epoch}_freshContext(){return{hostPort:null,deviceEndpoint:null,pids:[],owned:!1,resourcesPushed:!1,style:null,startedAt:0,startCount:0,resetCount:0}}get endpointConfig(){return this.config.get(`rpc.${this.name}`,{})}get resources(){return this.endpointConfig.resources||[]}get isReady(){return this.state===Re.READY&&!!this.transport&&this.transport.isConnected}async ensureReady(){if(this._disposed)throw new Vr(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});if(this.isReady)return this.ctx;let e=this._resetFlight.pending("reset");if(e){if(await e.catch(()=>{}),this._disposed)throw new Vr(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});if(this.isReady)return this.ctx}return this._readyFlight.run("ready",()=>this._ensureReadyOnce())}async _ensureReadyOnce(){if(this._disposed)throw new Vr(`${this.name} rpc is disposed`,{details:{endpoint:this.name}});return this.isReady?this.ctx:this.mode==="fast"&&await this._tryFastConnect()?this.ctx:(await this._stableFlow(),this.ctx)}async _stableFlow(){let e=this.dfx?this.dfx.timer("rpc.lifecycle.prepare",{mode:"stable"}):null;try{let t=await this.device.getEndpointStyle(),n=this.endpoint.buildDeviceEndpoint(t);this.ctx.style=t,this.ctx.deviceEndpoint=n,await this._ensureResources(),this.state=Re.RESOURCES_READY,await this._ensureProcess(t),this.state=Re.PROCESS_RUNNING;let i=await this._selectStableHostPort(t);return await this._tryForward(i,n)||(i=await this.device.getFreeHostPort({exclude:[i]}),await this._ensureForward(i,n)),this.ctx.hostPort=i,this.state=Re.FORWARDED,await this._connectAndProbe(i,{probe:!0}),this.state=Re.READY,await this._onStableReady(i,n,t,e),this.ctx}catch(t){return this._onStableFlowError(t,e)}}async _onStableReady(e,t,n,i){this.mode==="fast"&&await this._persistFastState({hostPort:e,deviceEndpoint:t,style:n}),i&&i({ok:1}),this.dfx&&this.dfx.counter("rpc.lifecycle.ready",1,{mode:this.mode}),this.logger&&this.logger.info(`ready: tcp:${e} -> ${t} (mode=${this.mode}, owned=${this.ctx.owned})`)}_onStableFlowError(e,t){this.state=Re.ERROR,t&&t({ok:0}),this.dfx&&this.dfx.counter("rpc.lifecycle.error",1,{code:e?.code||e?.name});let n=e instanceof wr?e:new vr(`${this.name} rpc prepare failed: ${e.message}`,{cause:e,details:{endpoint:this.name}});throw this.logger&&this.logger.error(`prepare failed: ${n.message}`),n}async _tryFastConnect(){let e=await this._readFastStateUnchecked(),t=e?.style||await this.device.getEndpointStyle(),n=this.endpoint.buildDeviceEndpoint(t),i=this.config.get("rpc.fast",{}),o=i.connectTimeoutMs??1500,s=i.probeOnReuse!==!1,a=await this._fastPortCandidates(t);for(let c of a)try{return await this._connectAndProbe(c,{probe:s,timeoutMs:o}),await this._onFastConnectSuccess(c,n,t)}catch(l){await this._onFastConnectMiss(l,c)}return await this._cleanupStaleFports(a,e,n),await this._clearFastState(),i.forceRestartOnProbeFailure!==!1&&await this._killEndpointProcesses(),!1}async _onFastConnectSuccess(e,t,n){return this.ctx.hostPort=e,this.ctx.deviceEndpoint=t,this.ctx.style=n,this.ctx.owned=!1,this.state=Re.READY,await this._persistFastState({hostPort:e,deviceEndpoint:t,style:n}),this.dfx&&this.dfx.counter("rpc.fast.hit",1,{hostPort:e}),this.logger&&this.logger.info(`fast mode hit: reused tcp:${e}`),!0}async _onFastConnectMiss(e,t){this.dfx&&this.dfx.counter("rpc.fast.miss",1,{reason:e?.code||e.name,hostPort:t}),this.logger&&this.logger.info(`fast mode miss on tcp:${t} (${e.message}), try next/fallback`),await this._safeCloseTransport("fast miss")}async _cleanupStaleFports(e,t,n){let i=new Set(e);t&&Number.isInteger(t.hostPort)&&i.add(t.hostPort);for(let o of i)await this._removeStaleFport(o,t,n)}async _removeStaleFport(e,t,n){try{let i=t?.deviceEndpoint||n,o=await this.device.fportRemove(e,i);this._logFportRemoval(e,i,o)}catch(i){this.logger&&this.logger.debug(`fast mode fallback: remove stale fport tcp:${e} failed: ${i.message}`)}}_logFportRemoval(e,t,n){this.logger&&(n?this.logger.info(`fast mode fallback: removed stale fport tcp:${e} -> ${t}`):this.logger.debug(`fast mode fallback: fport rm tcp:${e} -> ${t} returned false (may not exist or different endpoint)`))}async _fastPortCandidates(e){let t=[],n=await this._readFastState(e);n&&Number.isInteger(n.hostPort)&&t.push(n.hostPort);let i=this.endpointConfig.fastHostPort;return Number.isInteger(i)&&t.push(i),[...new Set(t)]}async _readFastStateUnchecked(){try{let e=this.device.fastStore;if(!e)return null;let t=await e.get(this.device.serial,this.name);return t||null}catch{return null}}async _readFastState(e){try{let t=this.device.fastStore;if(!t)return null;let n=await t.get(this.device.serial,this.name);if(!n)return null;let i=n;return i.style&&i.style!==e?null:i}catch{return null}}async _persistFastState({hostPort:e,deviceEndpoint:t,style:n}){try{let i=this.device.fastStore;if(!i)return;let o=this.device._uitestInfo||null,s=this.ctx.agentVersion||null;if(!s){let a=await i.get(this.device.serial,this.name).catch(()=>null);a&&a.agentVersion&&(s=a.agentVersion)}await i.save(this.device.serial,{endpoint:this.name,hostPort:e,deviceEndpoint:t,style:n,agentVersion:s,uitestVersion:o?o.version:null,hdcServer:this.device.hdcServer})}catch(i){this.logger&&this.logger.debug(`persist fast state failed: ${i.message}`)}}async _clearFastState(){try{let e=this.device.fastStore;e&&await e.forgetEndpoint(this.device.serial,this.name)}catch{}}async _ensureResources(){await this._ensureManagedResources();let e=this.resources;for(let t of e){if(!await this.device.fileExists(t.remotePath)){await this._pushResource(t,"missing");continue}if(!t.version||!t.versionProbe)continue;let i=await this._probeRemoteVersion(t);(!i||Xt(t.version,i)>0)&&(await this._killEndpointProcesses(),await this.device.rm(t.remotePath),await this._pushResource(t,"version"))}this.ctx.resourcesPushed=!0}async _ensureManagedResources(){}async _pushResource(e,t){let n=this.dfx?this.dfx.timer("rpc.lifecycle.push",{reason:t}):null;await this.device.fileSend(e.localPath,e.remotePath),n&&n({ok:1}),this.dfx&&this.dfx.counter("rpc.lifecycle.push",1,{reason:t}),this.logger&&this.logger.info(`push resource ${e.name||e.remotePath} (${t})`)}async _probeRemoteVersion(e){try{let t=await this.device.shell(`cat ${hi(e.remotePath)} | ${It(["grep","-a",e.versionProbe])}`);if(!t)return null;let n=t.split("#"),i=n.length>1?n[n.length-1]:t;return Ao(i)}catch{return null}}async _detectProcesses(e){let n=(await this.device.findProcesses()).filter(i=>this.endpoint.matchProcess(i));return n.length?this.endpointConfig.checkListening&&!await this.endpoint.isListening(this.device,e)?[]:n:[]}async _ensureProcess(e){let t=await this._detectProcesses(e);if(t.length){this.ctx.pids=t.map(i=>i.pid),this.ctx.owned=!1;return}await this._killStaleProcesses();let n;try{n=await this._launchAndWaitReady(e)}catch(i){let o=i;this.logger&&this.logger.warn(`${this.name} launch failed, try re-push managed resources: ${o.message}`);try{await this._onLaunchFailure()}catch(s){this.logger&&this.logger.warn(`${this.name} onLaunchFailure hook error: ${s.message}`)}await this._killStaleProcesses(),n=await this._launchAndWaitReady(e)}this.ctx.pids=n.map(i=>i.pid),this.ctx.owned=!0,this.ctx.startedAt=Date.now()}async _killStaleProcesses(){let e=(await this.device.findProcesses()).filter(t=>this.endpoint.matchProcess(t));for(let t of e)await this.device.killProcess(t.pid)}async _onLaunchFailure(){}async _launchAndWaitReady(e){let t=this.endpoint.buildStartCommand({style:e});this.logger&&this.logger.info(`start device process: ${t}`),await this.device.shell(t),this.ctx.startCount+=1,this.dfx&&this.dfx.counter("rpc.lifecycle.start",1);let n=this.endpointConfig;try{return await Xl(async()=>{let i=await this._detectProcesses(e);return i.length?i:null},{timeoutMs:n.processWaitTimeoutMs??15e3,intervalMs:n.processCheckIntervalMs??200,firstDelayMs:n.startWaitMs??500,description:`${this.name} process ready`})}catch(i){throw new vr(`${this.name} process did not become ready: ${i.message}`,{cause:i,details:{endpoint:this.name,startCmd:t}})}}async _ensureForward(e,t){if(!await this._tryForward(e,t))throw new vr(`create fport failed: tcp:${e} -> ${t}`,{details:{endpoint:this.name,hostPort:e,deviceEndpoint:t}})}async _tryForward(e,t){return await this.device.fportAdd(e,t)?!0:!!(await this.device.fportListAll()).find(s=>s.hostPort===e&&s.deviceEndpoint===t)}async _selectStableHostPort(e){if(this.mode==="fast"){let t=await this._readFastState(e),n=this.endpointConfig.fastHostPort,i=t&&Number.isInteger(t.hostPort)&&t.hostPort||n;if(i!=null&&Number.isInteger(i)&&!this.device.fportList.some(s=>s.hostPort===i))return i}return this.device.getFreeHostPort()}async _connectAndProbe(e,{probe:t=!0,timeoutMs:n}={}){let i=new ia({host:this.device.hdcHost,port:e,name:this.name,framing:this.config.get("rpc.framing","auto"),concurrency:this.config.get("rpc.concurrency",Pr.AUTO),maxInFlight:this.config.get("rpc.maxInFlight",16),strictPairing:this.config.get("rpc.strictPairing",!1),timeoutKillsConnection:this.config.get("rpc.timeoutKillsConnection",!1),connectTimeoutMs:n??this.config.get("rpc.connectTimeoutMs",5e3),requestTimeoutMs:this.config.get("rpc.requestTimeoutMs",3e4),socketIdleTimeoutMs:this.config.get("rpc.socketIdleTimeoutMs",3e4),logger:this.logger,dfx:this.dfx});await this._safeCloseTransport("reconnect"),await i.connect(),this._bumpEpoch(),i.onClose=o=>{this._onTransportClose(i,o)},this.transport=i,this.state=Re.CONNECTED,t&&await this._probe()}_onTransportClose(e,t){this.transport===e&&(this._bumpEpoch(),(this.state===Re.READY||this.state===Re.CONNECTED)&&(this.state=this.mode==="fast"?Re.WARM:Re.IDLE,this.logger&&this.logger.warn(`connection lost: ${t?t.message:"closed"}`),this.dfx&&this.dfx.counter("rpc.connection.lost",1,{reason:t?.code||"close"})))}async _probe(){let e=this.config.get("rpc.connectTimeoutMs",5e3),t=this.buildProbePayload(),n=await this.transport.send(t,{timeoutMs:e});if(sd(n)&&this.logger){let i=n.exception;this.logger.debug(`probe got business exception (link is healthy): ${typeof i=="string"?i:JSON.stringify(i)}`)}return ad(n)}async request(e,t={}){let{timeoutMs:n}=t,i=this.config.get("rpc.recovery",{}),o=i.enabled!==!1,s=Math.max(0,i.maxAttempts??1),a=null,c=0,l=0;for(let d=0;d<=s+1;d++){if(this._disposed)throw new Vr(`${this.name} rpc is disposed, request rejected`,{details:{endpoint:this.name}});let g=this._epoch;try{await this.ensureReady(),g=this._epoch;let y=await this._sendOnce(e,{timeoutMs:n});return this._logRecovered(c+l),y}catch(y){a=y;let E=await this._handleRequestError(y,o,s,g,c,l,i.delayMs);c=E.ownRecoveries,l=E.borrowedRecoveries}}throw a||new vr(`${this.name} rpc request failed`)}_logRecovered(e){e>0&&this.dfx&&this.dfx.counter("rpc.request.recovered",1,{endpoint:this.name})}async _handleRequestError(e,t,n,i,o,s,a){if(this._disposed||!t||!hm(e))throw e;return this._epoch===i?o=await this._attemptOwnRecovery(e,n,o):s=this._attemptBorrowedRecovery(e,n,s),a&&await xo(a),{ownRecoveries:o,borrowedRecoveries:s}}async _attemptOwnRecovery(e,t,n){if(n>=t)throw e;let i=n+1;return this.dfx&&this.dfx.counter("rpc.request.retry",1,{code:e.code,attempt:i}),this.logger&&this.logger.warn(`recover from ${e.code||e.name}: ${e.message} (retry ${i}/${t})`),await this.reset({reason:e.message,code:e.code}),i}_attemptBorrowedRecovery(e,t,n){let i=n+1;if(i>t)throw e;return this.dfx&&this.dfx.counter("rpc.request.retry.borrowed",1,{code:e.code}),this.logger&&this.logger.debug(`retry after another caller reset (${e.code||e.name})`),i}async _sendOnce(e,{timeoutMs:t}={}){if(!this.transport||!this.transport.isConnected)throw new He("rpc transport is not connected",{details:{endpoint:this.name}});let n=await this.transport.send(e,{timeoutMs:t??this.config.get("rpc.requestTimeoutMs",3e4)});return this.interpret(n)}interpret(e){if(sd(e)){let t=e.exception,n;if(t instanceof Error)n=t.message;else if(typeof t=="string")n=t;else if(t&&typeof t=="object")try{n=JSON.stringify(t)}catch{n=String(t)}else n=String(t);let i=new Qs(`remote exception: ${n}`,{details:{endpoint:this.name,remote:t}});throw this.dfx&&this.dfx.counter("rpc.request.remoteError",1,{endpoint:this.name}),i}return ad(e)}reset({reason:e="manual",code:t="MANUAL"}={}){return this._resetFlight.run("reset",()=>this._resetOnce({reason:e,code:t}))}async _resetOnce({reason:e="manual",code:t="MANUAL"}={}){if(this._disposed)return;let n=this._readyFlight.pending("ready");if(n&&await n.catch(()=>{}),this._disposed)return;this._bumpEpoch(),this.dfx&&this.dfx.counter("rpc.lifecycle.reset",1,{reason:t}),this.logger&&this.logger.warn(`reset: ${e}`);try{await this._killEndpointProcesses()}catch(s){this.logger&&this.logger.warn(`kill process failed during reset: ${s.message}`)}await this._safeCloseTransport("reset");try{this.ctx.hostPort&&this.ctx.deviceEndpoint&&await this.device.fportRemove(this.ctx.hostPort,this.ctx.deviceEndpoint)}catch(s){this.logger&&this.logger.warn(`remove fport failed during reset: ${s.message}`)}let i=this.ctx.resetCount+1,o=this.ctx.startCount;this.ctx=this._freshContext(),this.ctx.resetCount=i,this.ctx.startCount=o,this.state=Re.IDLE}async release(){if(await this._safeCloseTransport("release"),this.mode==="fast"&&this.config.get("rpc.fast.keepOnRelease",!0)){this.state=Re.WARM,this.dfx&&this.dfx.counter("rpc.release",1,{keep:1}),this.logger&&this.logger.info(`released (keep process & fport on tcp:${this.ctx.hostPort})`);return}await this._removeForward(),await this._killEndpointProcesses(),this.dfx&&this.dfx.counter("rpc.release",1,{keep:0}),this.logger&&this.logger.info("released (process & fport cleaned)"),this.ctx=this._freshContext(),this.state=Re.IDLE}async dispose(){this._disposed=!0,this._bumpEpoch();let e=this._readyFlight.pending("ready");e&&await e.catch(()=>{});let t=this._resetFlight.pending("reset");t&&await t.catch(()=>{}),await this._safeCloseTransport("dispose"),await this._removeForward(),await this._killEndpointProcesses(),this.ctx=this._freshContext(),this.state=Re.DISPOSED}async _removeForward(){let e=new Set;this.ctx.hostPort&&e.add(this.ctx.hostPort),this.mode==="fast"&&this.endpointConfig.fastHostPort&&e.add(this.endpointConfig.fastHostPort);let t=this.ctx.deviceEndpoint||void 0;for(let n of e)try{let i=await this.device.fportRemove(n,t);this.logger&&!i&&this.logger.warn(`remove fport tcp:${n} -> ${t} returned false`)}catch(i){this.logger&&this.logger.debug(`remove fport tcp:${n} failed: ${i.message}`)}}async _killEndpointProcesses(){let t=(await this.device.findProcesses()).filter(n=>this.endpoint.matchProcess(n));for(let n of t)await this.device.killProcess(n.pid);return t.length&&this.logger&&this.logger.info(`killed ${this.name} processes: [${t.map(n=>n.pid).join(", ")}]`),t.length}async _safeCloseTransport(e){if(this.transport){try{await this.transport.close(e)}catch{}this.transport=null}}buildProbePayload(){return{module:"debug",method:"ping",params:{},request_id:void 0}}getSnapshot(){return{name:this.name,mode:this.mode,state:this.state,epoch:this._epoch,disposed:this._disposed,ctx:{...this.ctx},transport:this.transport?this.transport.getSnapshot():null}}};var Tm={name:"operate",displayName:"uitest",socketName:"uitest_socket",devicePort:8012,buildDeviceEndpoint(r){return r==="unix"?`localabstract:${this.socketName}`:`tcp:${this.devicePort}`},buildStartCommand(){return"/system/bin/uitest start-daemon singleness &"},buildStopCommands(r){return r.map(e=>It(["kill","-9",e]))},matchProcess(r){return r.cmd.includes("uitest start-daemon singleness")&&!r.cmd.includes("--extension-name")},async isListening(r,e){return e==="unix"?(await r.shell(`cat /proc/net/unix | ${It(["grep",this.socketName])}`)).includes(this.socketName):(await r.shell(`netstat -anp | ${It(["grep",String(this.devicePort)])}`)).includes("LISTEN")}};var sa=class extends oa{constructor(e){super({...e,endpoint:Tm})}async _ensureManagedResources(){if(this.config.get("device.autoPushResources",!0)===!1||!this.device.resources||typeof this.device.resources.ensureAgent!="function")return;let e=await this.device.resources.ensureAgent();this.ctx.agentVersion=e.candidate.version}async _onLaunchFailure(){this.config.get("device.autoPushResources",!0)!==!1&&(!this.device.resources||typeof this.device.resources.repushAgent!="function"||await this.device.resources.repushAgent())}buildProbePayload(){return od({module:id,method:"ping",params:{},requestId:br()})}async call(e,t="",n=[],i={}){let o=od({module:id,method:Am,params:{api:e,this:t,args:n,message_type:"hypium"},requestId:br()});return this.dfx&&this.dfx.counter("rpc.call",1,{api:e}),this.request(o,i)}async ping(e={}){return this.request(this.buildProbePayload(),e)}};function X_(r){if(r!==void 0)return Array.isArray(r)?{value:String(r[0]),pattern:r[1]}:{value:String(r)}}function Nm(r){return OS(r)}function OS(r){let e={};return r.text!==void 0&&(e.text=X_(r.text)),r.key!==void 0&&(e.key=String(r.key)),r.id!==void 0&&(e.id=String(r.id)),r.type!==void 0&&(e.type=String(r.type)),r.clickable!==void 0&&(e.clickable=!!r.clickable),r.scrollable!==void 0&&(e.scrollable=!!r.scrollable),r.enabled!==void 0&&(e.enabled=!!r.enabled),r.focused!==void 0&&(e.focused=!!r.focused),r.selected!==void 0&&(e.selected=!!r.selected),e}function _S(r){let e=OS(r);return r.isBefore&&(e.isBefore=Nm(r.isBefore)),r.isAfter&&(e.isAfter=Nm(r.isAfter)),r.within&&(e.within=Nm(r.within)),e}function Z_(r){let e=[];return r.text&&e.push(["On.text",[r.text.value,r.text.pattern??0]]),r.key!==void 0&&e.push(["On.key",[r.key]]),r.id!==void 0&&e.push(["On.id",[r.id]]),r.type!==void 0&&e.push(["On.type",[r.type]]),r.clickable!==void 0&&e.push(["On.clickable",[r.clickable]]),r.scrollable!==void 0&&e.push(["On.scrollable",[r.scrollable]]),r.enabled!==void 0&&e.push(["On.enabled",[r.enabled]]),r.focused!==void 0&&e.push(["On.focused",[r.focused]]),r.selected!==void 0&&e.push(["On.selected",[r.selected]]),e}var ze=class r{spec;constructor(e={}){this.spec=e}static from(e){return new r(_S(e))}text(e,t){return this.spec.text={value:e,pattern:t},this}key(e){return this.spec.key=e,this}id(e){return this.spec.id=e,this}type(e){return this.spec.type=e,this}clickable(e=!0){return this.spec.clickable=e,this}scrollable(e=!0){return this.spec.scrollable=e,this}enabled(e=!0){return this.spec.enabled=e,this}focused(e=!0){return this.spec.focused=e,this}selected(e=!0){return this.spec.selected=e,this}isBefore(e){return this.spec.isBefore=e.spec,this}isAfter(e){return this.spec.isAfter=e.spec,this}within(e){return this.spec.within=e.spec,this}async buildOn(e){let t=this.spec,n=Z_(t);if(n.length===0)throw new Error("Empty selector: at least one lookup condition required");let i=await e.create(n[0][0],n[0][1]);for(let o=1;o<n.length;o++)await e.call(n[o][0],i,n[o][1]);if(t.isBefore){let o=await new r(t.isBefore).buildOn(e);await e.call("On.isBefore",i,[o])}if(t.isAfter){let o=await new r(t.isAfter).buildOn(e);await e.call("On.isAfter",i,[o])}if(t.within){let o=await new r(t.within).buildOn(e);await e.call("On.within",i,[o])}return i}};var aa=class r{constructor(e,t,n=0){this.host=e;this.selector=t;this.index=n}use(e){return this.host.withComponentRef(this.selector,this.index,t=>e(t))}async click(){await this.use(e=>this.host.rpc.call("Component.click",e,[]))}async doubleClick(){await this.use(e=>this.host.rpc.call("Component.doubleClick",e,[]))}async longClick(){await this.use(e=>this.host.rpc.call("Component.longClick",e,[]))}async inputText(e){await this.use(t=>this.host.rpc.call("Component.inputText",t,[e]))}async clearText(){await this.use(e=>this.host.rpc.call("Component.clearText",e,[]))}async getId(){return String(await this.use(e=>this.host.rpc.call("Component.getId",e,[])))}async getText(){return String(await this.use(e=>this.host.rpc.call("Component.getText",e,[])))}async getType(){return String(await this.use(e=>this.host.rpc.call("Component.getType",e,[])))}async getHint(){return String(await this.use(e=>this.host.rpc.call("Component.getHint",e,[])))}async isClickable(){return!!await this.use(e=>this.host.rpc.call("Component.isClickable",e,[]))}async isScrollable(){return!!await this.use(e=>this.host.rpc.call("Component.isScrollable",e,[]))}async isEnabled(){return!!await this.use(e=>this.host.rpc.call("Component.isEnabled",e,[]))}async isFocused(){return!!await this.use(e=>this.host.rpc.call("Component.isFocused",e,[]))}async isSelected(){return!!await this.use(e=>this.host.rpc.call("Component.isSelected",e,[]))}async getBounds(){return await this.use(t=>this.host.rpc.call("Component.getBounds",t,[]))}async getBoundsCenter(){return await this.use(t=>this.host.rpc.call("Component.getBoundsCenter",t,[]))}async scrollSearch(e){let t=e instanceof ze?e:ze.from(e);return await this.host.withComponentRef(this.selector,this.index,async(i,o)=>{let s=await t.buildOn(o),a=await o.call("Component.scrollSearch",i,[s]);return a?(o.track(String(a)),!0):!1})?new r(this.host,t):null}async dragTo(e){let t=e instanceof r?e.selector:e instanceof ze?e:ze.from(e);await this.host.withComponentRef(this.selector,this.index,async(n,i,o)=>{let s=await t.buildOn(i),c=(await i.call("Driver.findComponents",o,[s])??[]).map(String);if(i.trackAll(c),c.length===0)throw new Error("dragTo target component not found (0 returned)");await i.call("Component.dragTo",n,[c[0]])})}async pinchOut(e){await this.use(t=>this.host.rpc.call("Component.pinchOut",t,[e]))}async pinchIn(e){await this.use(t=>this.host.rpc.call("Component.pinchIn",t,[e]))}async scrollToTop(e=600){await this.use(t=>this.host.rpc.call("Component.scrollToTop",t,[e]))}async scrollToBottom(e=600){await this.use(t=>this.host.rpc.call("Component.scrollToBottom",t,[e]))}};var Q_=600,Om=1,cd=16;function eM(r,e){return Math.hypot(e.x-r.x,e.y-r.y)}function MS(r,e,t,n){if(n!==void 0&&n>0)return Math.max(Om,Math.round(n/cd));let i=eM(r,e);if(i<=0||t<=0)return Om;let o=i/t*1e3;return Math.max(Om,Math.round(o/cd))}function ld(r,e,t){return Math.round(r+(e-r)*t)}function LS(r,e,t,n){if(e===null)throw new Error("wait/pressHold before first down, missing start coordinate");for(let i=0;i<n;i++)r.push({pressed:t,x:e.x,y:e.y})}function tM(r,e,t){if(t.pressed)throw new Error("Duplicate down: finger already pressed");let n={x:e.x,y:e.y};t.cur=n,t.pressed=!0,r.push({pressed:t.pressed,x:n.x,y:n.y})}function rM(r,e,t,n){if(n.cur===null)throw new Error("moveTo before down");let i=n.cur,o={x:e.x,y:e.y},s=MS(i,o,t,e.durationMs);for(let a=1;a<=s;a++){let c=a/s;r.push({pressed:n.pressed,x:ld(i.x,o.x,c),y:ld(i.y,o.y,c)})}n.cur=o}function nM(r,e,t,n){if(n.cur===null)throw new Error("move before down");let i=n.cur,o={x:i.x+e.dx,y:i.y+e.dy},s=MS(i,o,t,e.durationMs);for(let a=1;a<=s;a++){let c=a/s;r.push({pressed:n.pressed,x:ld(i.x,o.x,c),y:ld(i.y,o.y,c)})}n.cur=o}function iM(r,e,t){LS(r,t.cur,t.pressed,Math.max(1,Math.round(e.durationMs/cd)))}function oM(r,e,t){if(!t.pressed)throw new Error("pressHold before down");LS(r,t.cur,t.pressed,Math.max(1,Math.round(e.durationMs/cd)))}function sM(r,e){if(!e.pressed)throw new Error("up before down");e.pressed=!1;let t=e.cur;t!==null&&r.push({pressed:e.pressed,x:t.x,y:t.y})}function aM(r,e){let t=[],n={cur:null,pressed:!1};for(let i of r.actions)switch(i.type){case"down":{tM(t,i,n);break}case"moveTo":{rM(t,i,e,n);break}case"move":{nM(t,i,e,n);break}case"wait":{iM(t,i,n);break}case"pressHold":{oM(t,i,n);break}case"up":{sM(t,n);break}default:{let o=i;throw new Error(`Unknown gesture action: ${JSON.stringify(o)}`)}}return t}function _m(r){if(!r.fingers.length)throw new Error("Gesture requires at least one finger");let e=r.speed??Q_,t=r.fingers.map(o=>aM(o,e)),n=Math.max(...t.map(o=>o.length));return{fingers:t.map(o=>{if(o.length===0)return[];let s=o[o.length-1],a=[...o];for(;a.length<n;)a.push({...s});return a}),speed:e}}var cM="PointerMatrix#seed";async function Mm(r,e){let{fingers:t,speed:n}=_m(e);if(t.length===0)throw new Error("Empty gesture");let i=t[0].length,o=await r.create("PointerMatrix.create",[t.length,i],cM);for(let s=0;s<t.length;s++)for(let a=0;a<i;a++){let c=t[s][a];await r.call("PointerMatrix.setPoint",o,[s,a,{x:c.x,y:c.y}])}return{ref:o,speed:n}}var FS="Driver.create",lM="BackendObjectsCleaner";var Lm="On#seed";async function dd(r,e){let t=e.filter(n=>n&&n!==Lm);if(t.length!==0)try{for(let n=0;n<t.length;n+=10)await r.call(lM,"",[t.slice(n,n+10)])}catch{}}var bn=class{constructor(e){this.rpc=e}refs=[];async create(e,t=[],n=Lm){let i=String(await this.rpc.call(e,n,t));return this.refs.push(i),i}async call(e,t,n=[]){return this.rpc.call(e,t,n)}track(e){return e&&e!==Lm&&this.refs.push(e),e}trackAll(e){for(let t of e)this.track(t);return e}async dispose(){await dd(this.rpc,this.refs),this.refs.length=0}async run(e){try{return await e(this)}finally{await this.dispose()}}};var ca=class{constructor(e,t,n=0){this.host=e;this.filter=t;this.index=n}use(e){return this.host.withWindowRef(this.filter,this.index,t=>e(t))}async getBundleName(){return String(await this.use(e=>this.host.rpc.call("UiWindow.getBundleName",e,[])))}async isActive(){return!!await this.use(e=>this.host.rpc.call("UiWindow.isActive",e,[]))}async isFocused(){return!!await this.use(e=>this.host.rpc.call("UiWindow.isFocused",e,[]))}async getBounds(){return await this.use(t=>this.host.rpc.call("UiWindow.getBounds",t,[]))}};var la=class{constructor(e,t){this.shell=t;this.rpc=e}driverRef=null;rpc;async ensureDriver(){return this.driverRef?this.driverRef:(this.driverRef=String(await this.rpc.call(FS,"",[])),this.driverRef)}selector(e){return e?ze.from(e):new ze}findComponent(e,t=0){let n=e instanceof ze?e:ze.from(e);return new aa(this,n,t)}async withComponentRef(e,t,n){let i=await this.ensureDriver();return new bn(this.rpc).run(async s=>{let a=await e.buildOn(s),c=[];for(let l=0;l<8&&(c=(await s.call("Driver.findComponents",i,[a])??[]).map(String),!(c.length>0));l++)await new Promise(g=>setTimeout(g,1e3));if(s.trackAll(c),t>=c.length)throw new Error(`findComponents: no component matched (returned ${c.length}), index ${t} out of range`);return n(c[t],s,i)})}findWindow(e,t=0){return new ca(this,e,t)}async withWindowRef(e,t,n){let i=await this.ensureDriver();return new bn(this.rpc).run(async s=>{let a;if(t===0){let c=await s.call("Driver.findWindow",i,[dM(e)]);if(!c||c==="null")throw new Error("findWindow: no window matched");a=s.track(String(c))}else throw new Error(`findWindow: only returns a single window, index=${t} not supported`);return n(a,s)})}async gesture(e){await this.swipe(e)}async swipe(e){let t=await this.ensureDriver();await this.withPointerRef(e,async(n,i)=>{await this.rpc.call("Driver.injectMultiPointerAction",t,[n,i])})}async withPointerRef(e,t){return new bn(this.rpc).run(async i=>{let{ref:o,speed:s}=await Mm(i,e);return t(o,s,i)})}async screenCapture(e){if(!this.shell)throw new Error("screenCapture requires shell capability (provided via device.uitest)");let t=e.toLowerCase().endsWith(".png")?".png":".jpeg",n=`/data/local/tmp/hypium${t}`;if(await this.shell.shell(`rm -f ${n}`),t===".png"?await this.shell.shell(`uitest screenCap -p ${n}`):await this.shell.shell(`snapshot_display -f ${n}`),!await this.shell.fileRecv(n,e))throw new Error(`screenCapture pull failed: ${n} -> ${e}`)}async setDisplayRotation(e){let t={0:0,90:1,180:2,270:3};if(!(e in t))throw new Error(`rotation must be 0, 90, 180, or 270, got ${e}`);let n=await this.ensureDriver();await this.rpc.call("Driver.setDisplayRotation",n,[t[e]])}async getDisplayRotation(){let e=await this.ensureDriver(),t=await this.rpc.call("Driver.getDisplayRotation",e,[]),n={0:0,1:90,2:180,3:270},i=typeof t=="number"?t:Number(t);return n[i]??i}async setDisplayRotationEnabled(e){let t=await this.ensureDriver();await this.rpc.call("Driver.setDisplayRotationEnabled",t,[e])}async delay(e){await new Promise(t=>setTimeout(t,e))}async pressBack(){let e=await this.ensureDriver();await this.rpc.call("Driver.pressBack",e,[])}async pressHome(){let e=await this.ensureDriver();await this.rpc.call("Driver.pressHome",e,[])}async clickXY(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.click",n,[e,t])}async doubleClick(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.doubleClick",n,[e,t])}async inputText(e,t){let n=await this.ensureDriver();await this.rpc.call("Driver.inputText",n,[e,t])}async getDisplaySize(){let e=await this.ensureDriver(),n=await this.rpc.call("Driver.getDisplaySize",e,[]);return{width:n.width??n.x??0,height:n.height??n.y??0}}async assertComponentExist(e,t=!0){let n=e instanceof ze?e:ze.from(e),i=await this.ensureDriver();return new bn(this.rpc).run(async s=>{let a=await n.buildOn(s),l=(await s.call("Driver.findComponents",i,[a])??[]).length>0;return t?l:!l})}async release(){this.driverRef&&(await dd(this.rpc,[this.driverRef]),this.driverRef=null)}};function dM(r){let e={};return r.title!==void 0&&(e.title=typeof r.title=="string"?r.title:r.title.value),r.bundleName!==void 0&&(e.bundleName=r.bundleName),r.active!==void 0&&(e.active=r.active),e}function $S({config:r,logger:e,dfx:t,executor:n}){if(n)return n;let i={bin:r.get("hdc.bin","hdc"),host:r.get("hdc.host","127.0.0.1"),port:r.get("hdc.port",8710),execTimeoutMs:r.get("hdc.execTimeoutMs",1e4),logger:e,dfx:t};return new mi(i)}var da=class r{executor;config;logger;dfx;rpcMode;devices;_rpcFactories;constructor({executor:e,config:t,logger:n,dfx:i,rpcMode:o}){this.executor=e,this.config=t,this.logger=n??null,this.dfx=i??null,this.rpcMode=o||t.get("rpc.mode","stable"),this.devices=new Map,this._rpcFactories=new Map}static async create(e={}){let t=e.config&&typeof e.config.get=="function"?e.config:ra(e.config||{});e.mode&&t.set("rpc.mode",e.mode);let n=e.logger||Xs("HMDeviceManager"),i=e.dfx||na({logger:n,tags:{mode:t.get("rpc.mode")}}),o=$S({config:t,logger:n,dfx:i,executor:e.executor});return new r({executor:o,config:t,logger:n,dfx:i,rpcMode:t.get("rpc.mode","stable")})}static _default=null;static async getDefault(e={}){return r._default||(r._default=await r.create(e)),r._default}static resetDefault(){r._default=null}async listTargets(){let e=this.dfx?this.dfx.timer("device.listTargets"):null,t=await this.executor.listTargets();return e&&e({count:t.length}),this.logger&&this.logger.info(`list targets -> [${t.join(", ")}]`),t}async listDevices({detail:e=!1}={}){let n=(await this.listTargets()).map(i=>({serial:i,cached:this.devices.has(i)}));if(!e)return n;for(let i of n)try{let s=await(await this.getDevice(i.serial)).getInfo();Object.assign(i,{model:s.model,abi:s.abi,uitestVersion:s.version,endpointStyle:s.endpointStyle})}catch(o){i.error=o.message}return n}async getDevice(e,t={}){let n=this.dfx?this.dfx.timer("device.create"):null,i=await this.listTargets();if(!i.length)throw new yn("no device connected");let o=e;if(o){if(!i.includes(o))throw new yn(`device ${o} is not found, connected: [${i.join(", ")}]`)}else if(this.config.get("device.autoSelectFirst",!0))o=i[0];else throw new yn("serial is required when autoSelectFirst is disabled");let s=this.devices.get(o);if(s)return n&&n({sn:o,reused:1}),s;let a=new yi({serial:o,executor:this.executor,config:this.config,logger:this.logger,dfx:this.dfx,rpcMode:t.rpcMode||this.rpcMode});for(let[l,d]of this._rpcFactories)a.attachRpc(l,d);return(t.queryVersion??this.config.get("device.queryVersion",!0))&&await a.getUitestInfo(),this.devices.set(o,a),n&&n({sn:o,ok:1}),this.dfx&&this.dfx.counter("device.create",1,{sn:o}),this.logger&&this.logger.info(`device created: ${o}`),a}async createDevice(e,t={}){return this.getDevice(e,t)}async connect(e,t={}){return this.getDevice(e,t)}attachRpc(e,t){if(typeof t!="function")throw new yn(`attachRpc(${e}) expects a factory function`);this._rpcFactories.set(e,t);for(let n of this.devices.values())n.attachRpc(e,t);return this}async removeDevice(e){let t=this.devices.get(e);return t?(await t.release(),this.devices.delete(e),!0):!1}async release({disposeRpc:e=!1}={}){for(let t of this.devices.values())e?await t.dispose():await t.release();this.devices.clear()}async dispose(){for(let e of this.devices.values())await e.dispose();this.devices.clear()}};var pM="6.0.2.2",fM={uitest:r=>new sa({device:r,config:r.config,logger:r.logger,dfx:r.dfx,mode:r.rpcMode})},yi=class{serial;executor;config;logger;dfx;hdcHost;hdcPort;execTimeoutMs;rpcMode;_uitestInfo;fportList;resources;fastStore;_rpcs;_rpcFactories;_uitestDriver=null;file;fport;proc;constructor({serial:e,executor:t,config:n,logger:i,dfx:o,rpcMode:s}){this.serial=e,this.executor=t,this.config=n,this.logger=i??null,this.dfx=o?o.child({sn:e}):null,this.hdcHost=n.get("hdc.host","127.0.0.1"),this.hdcPort=n.get("hdc.port",8710),this.execTimeoutMs=n.get("hdc.execTimeoutMs",1e4),this.rpcMode=s||n.get("rpc.mode","stable"),this._uitestInfo=null,this.fportList=[],this.resources=new rd({device:this,config:n,logger:this.logger,dfx:this.dfx}),this.fastStore=new nd({config:n,logger:this.logger}),this._rpcs=new Map,this._rpcFactories=new Map(Object.entries(fM)),this.file=new Fm(this),this.fport=new $m(this),this.proc=new jm(this)}get isRemoteHdcServer(){return!!this.hdcHost&&this.hdcHost!=="127.0.0.1"&&this.hdcHost!=="localhost"}get hdcServer(){return`${this.hdcHost||"127.0.0.1"}:${this.hdcPort??8710}`}async exec(e,t={}){let n=["-t",this.serial,...e],i=await this.executor.exec(n,{timeoutMs:t.timeoutMs??this.execTimeoutMs});return this.logger&&this.logger.debug(`hdc ${n.join(" ")} -> ${i.code}`),i}async shell(e,t={}){return Rm(e),(await this.exec(["shell",e],t)).stdout}async shellArgs(e,t={}){return this.shell(It(e),t)}async fileSend(e,t,n={}){Er(t),await mM(e);let i=await this.exec(["file","send",e,t],n);if(!(i.ok&&i.stdout.includes("FileTransfer finish")))throw new wn(`push ${e} -> ${t} failed: ${i.stderr||i.stdout}`,{details:{localPath:e,remotePath:t}});return this.dfx&&this.dfx.counter("device.file.send",1),!0}async fileRecv(e,t,n={}){if(Er(e),!await this.fileExists(e))throw new wn(`remote file does not exist: ${e}`);let i=await this.exec(["file","recv",e,t],n);if(!(i.ok&&i.stdout.includes("FileTransfer finish")))throw new wn(`pull ${e} -> ${t} failed: ${i.stderr||i.stdout}`,{details:{localPath:t,remotePath:e}});return this.dfx&&this.dfx.counter("device.file.recv",1),!0}async fileExists(e){Er(e);let t=await this.shellArgs(["ls","-ld",e]);return!!t&&!t.includes("No such file or directory")}async isDirectory(e){Er(e);let t=await this.shellArgs(["ls","-ld",e]);return!!t&&t.startsWith("d")&&!t.includes("No such file or directory")}async rm(e,{force:t=!0}={}){return Er(e),await this.shellArgs(t?["rm","-f",e]:["rm",e]),!0}async mkdir(e){return Er(e),await this.shellArgs(["mkdir","-p",e]),!0}async readRemoteText(e){Er(e);let t=await this.shellArgs(["cat",e]);if(t.includes("No such file or directory"))throw new wn(`remote file does not exist: ${e}`);return t}async listDir(e="/data/local/tmp"){Er(e);let t=await this.shellArgs(["ls",e]);return t.includes("No such file or directory")?[]:t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean)}async fportAdd(e,t){td(e),ed(t);let n=await this.exec(["fport",`tcp:${e}`,t]),i=n.ok&&(n.stdout.includes("result:OK")||n.stdout.toLowerCase().includes("success"));if(i){let o={hostPort:e,deviceEndpoint:t,taskString:`tcp:${e} ${t}`};this.fportList.some(s=>s.hostPort===e)||this.fportList.push(o),this.dfx&&this.dfx.counter("device.fport.add",1)}return i}async fportRemove(e,t){td(e),t&&ed(t);let n=await this.exec(t?["fport","rm",`tcp:${e}`,t]:["fport","rm",`tcp:${e}`]),i=n.ok&&(n.stdout.includes("result:OK")||n.stdout.toLowerCase().includes("success"));return i&&(this.fportList=this.fportList.filter(o=>o.hostPort!==e),this.dfx&&this.dfx.counter("device.fport.remove",1)),i}async fportListAll(){let e=await this.exec(["fport","ls"]);return ym(e.stdout)}async getFreeHostPort(e={}){let t=this.config.get("rpc.portRange",{start:1e4,end:19999}),n=new Set([...this.fportList.map(o=>o.hostPort),...e.exclude||[]]),{port:i}=await kS({hdcHost:this.hdcHost,start:e.start??t.start,end:e.end??t.end,exclude:n});return i}async getFreeDevicePort({start:e=4e4,end:t=49999,exclude:n}={}){let i=await this.shell("cat /proc/net/tcp /proc/net/tcp6 2>/dev/null"),o=new Set(n||[]);for(let s of String(i).split(/\r?\n/)){let c=s.trim().split(/\s+/)[1];if(!c||!c.includes(":"))continue;let l=c.split(":")[1],d=parseInt(l,16);Number.isInteger(d)&&o.add(d)}for(let s=e;s<=t;s++)if(!o.has(s))return s;throw new Dt(`no free device port in range ${e}-${t}`)}async findProcesses(){let e=await this.shellArgs(["ps","-ef"]);return wm(e)}async killProcess(e){let t=xm(e);return await this.shellArgs(["kill","-9",t]),this.dfx&&this.dfx.counter("device.process.kill",1),!0}async getUitestInfo(e=!1){if(this._uitestInfo&&!e)return this._uitestInfo;let t=await xS(this,{minVersion:this.config.get("device.newUiTestMinVersion",pM)});return this._uitestInfo={version:t.version,arch:t.arch,isNewUiTest:t.isNewUiTest,endpointStyle:t.endpointStyle},this.logger&&this.logger.info(`uitest info: version=${t.version} arch=${t.arch} endpointStyle=${t.endpointStyle}`),this._uitestInfo}async getEndpointStyle(){return this._uitestInfo||await this.getUitestInfo(),this._uitestInfo.endpointStyle}async getSystemProp(e){let t=e.map(n=>({bin:"getprop",key:n}));for(let n of e){let i=n.startsWith("ro.")?`const.${n.slice(3)}`:n;t.push({bin:"param",key:i})}for(let{bin:n,key:i}of t)try{let o=(await this.shellArgs([n,"get",i])).trim();if(!o||/fail|inaccessible|not found|Get parameter/i.test(o))continue;return o}catch{}return""}async getInfo(){let[e,t,n]=await Promise.all([this.getSystemProp(["ro.product.model","const.product.model"]),this.getSystemProp(["ro.product.cpu.abi","const.product.cpu.abilist"]),this.getUitestInfo()]);return{serial:this.serial,model:e,abi:t,...n}}attachRpc(e,t){if(typeof t!="function")throw new Dt(`attachRpc(${e}) expects a factory function`);return this._rpcFactories.set(e,t),this._rpcs.delete(e),this}rpc(e){let t=this._rpcs.get(e);if(t)return t;let n=this._rpcFactories.get(e);if(!n)throw new Dt(`rpc module "${e}" is not attached, available: [${[...this._rpcFactories.keys()].join(", ")}]`);let i=n(this);return this._rpcs.set(e,i),this.logger&&this.logger.debug(`rpc attached: ${e} -> ${i.name}`),i}get uitestRpc(){return this.rpc("uitest")}get uitest(){return this._uitestDriver||(this._uitestDriver=new la(this.uitestRpc,{shell:e=>this.shell(e),fileRecv:(e,t)=>this.fileRecv(e,t)})),this._uitestDriver}static async create(e={}){let t=await da.getDefault({config:e.config,mode:e.mode});return e.mode&&t.config.set("rpc.mode",e.mode),t.getDevice(e.serial,{queryVersion:e.queryVersion,rpcMode:e.mode})}get operate(){return this.uitestRpc}async call(e,t="",n=[],i={}){return this.uitestRpc.call(e,t,n,i)}getSnapshot(){return{serial:this.serial,mode:this.rpcMode,rpcs:this.listRpcs(),uitest:this.listRpcs().includes("uitest")?this.uitestRpc.getSnapshot():null}}listRpcs(){return[...this._rpcs.keys()]}async releaseRpc(e){let t=e?[e]:[...this._rpcs.keys()];for(let n of t){let i=this._rpcs.get(n);i&&(await i.release(),this._rpcs.delete(n))}!e&&this._uitestDriver&&(await this._uitestDriver.release(),this._uitestDriver=null)}async disposeRpc(e){let t=e?[e]:[...this._rpcFactories.keys()];for(let n of t){let i=this._rpcs.get(n)||this.rpc(n);i&&await i.dispose(),this._rpcs.delete(n)}!e&&this._uitestDriver&&(await this._uitestDriver.release(),this._uitestDriver=null)}async release(){await this.releaseRpc()}async dispose(){await this.disposeRpc(),await this._clearFports()}async _clearFports(){for(let e of[...this.fportList])try{await this.fportRemove(e.hostPort,e.deviceEndpoint)}catch{}this.fportList=[]}toString(){return`HMDevice(${this.serial})`}},Fm=class{device;constructor(e){this.device=e}push(e,t,n){return this.device.fileSend(e,t,n)}pull(e,t,n){return this.device.fileRecv(e,t,n)}exists(e){return this.device.fileExists(e)}isDir(e){return this.device.isDirectory(e)}remove(e,t){return this.device.rm(e,t)}mkdir(e){return this.device.mkdir(e)}readText(e){return this.device.readRemoteText(e)}list(e){return this.device.listDir(e)}},$m=class{device;constructor(e){this.device=e}add(e,t){return this.device.fportAdd(e,t)}remove(e,t){return this.device.fportRemove(e,t)}list(){return this.device.fportListAll()}freeHostPort(){return this.device.getFreeHostPort()}},jm=class{device;constructor(e){this.device=e}list(){return this.device.findProcesses()}kill(e){return this.device.killProcess(e)}async find(e){return(await this.device.findProcesses()).filter(n=>n.cmd.includes(e))}};async function mM(r){try{if(!(await uM(r)).isFile())throw new Error("not a file")}catch(e){throw new Dt(`local file does not exist: ${r}`,{cause:e})}}import{fileURLToPath as hM}from"url";import{dirname as yM,join as Hm}from"path";import{existsSync as wM}from"fs";var gM={write:(r,e)=>f(e)};gm({name:"uitest",level:"trace",transports:[gM]});function vM(){let r=yM(hM(import.meta.url)),e=[Hm(r,"../../resources/uitest"),Hm(r,"../src/resources/uitest")];return e.find(t=>wM(Hm(t,"uitest_agent_v1.1.9.so")))||e[1]}async function ud(r,e){let t=Xs("HMDevice"),n=na({logger:t,tags:{mode:"fast"}}),i=new mi({bin:r,logger:t,dfx:n}),o=ra({device:{resourcesDir:vM()}}),s=new yi({serial:e,executor:i,config:o,logger:t,dfx:n,rpcMode:o.get("rpc.mode","fast")});return await s.getUitestInfo(),{driver:s.uitest,async dispose(){await s.uitest.release(),await s.release()}}}async function PM(r,e,t="default"){let n=await T(r,e),i=new ko(r),o=ua({text:"Querying screen size...",color:"cyan"}).start();try{let s=await i.getDisplayInfo(n);o.stop();let a=pi(s);console.log(a?t==="json"?JSON.stringify({width:a.width,height:a.height},null,2):`${a.width}x${a.height}`:EM("No display info found in output."))}catch(s){throw o.stop(),new w(`Failed to get screen size: ${s.message}`,"Failed to get screen size.")}}async function CM(r,e,t){let n=await T(r,t),i=new ko(r),o=e===-1;if(!o&&(e<5e3||e>36e5))throw new w(`Invalid timeout ${e}ms. Use -1 for never sleep, or a value between 5000 and 3600000ms.`,"Invalid screen-off timeout value.");let s=ua({text:o?"Disabling screen-off...":`Setting screen-off timeout to ${e}ms...`,color:"cyan"}).start();try{o?await i.setScreenNeverSleep(n):await i.setScreenTimeout(n,e),s.stop(),console.log(o?"Screen-off disabled (always on).":`Screen-off timeout set to ${e}ms.`)}catch(a){throw s.stop(),new w(`Failed to set screen-off timeout: ${a.message}`,"Failed to set screen-off timeout.")}}async function kM(r,e,t){let n=await T(r,t),i=ua({text:`Setting screen rotation to ROTATION_${e}...`,color:"cyan"}).start();try{let{driver:o,dispose:s}=await ud(r.hdcPath,n);try{await o.setDisplayRotation(e)}finally{await s()}i.stop(),console.log(`Screen rotation set to ROTATION_${e}.`)}catch(o){throw i.stop(),new w(`Failed to set screen rotation: ${o.message}`,"Failed to set screen rotation.")}}async function RM(r,e){let t=await T(r,e),n=ua({text:"Querying screen rotation...",color:"cyan"}).start();try{let{driver:i,dispose:o}=await ud(r.hdcPath,t);try{let s=await i.getDisplayRotation();n.stop(),console.log(`Screen rotation: ROTATION_${s}`)}finally{await o()}}catch(i){throw n.stop(),new w(`Failed to get screen rotation: ${i.message}`,"Failed to get screen rotation.")}}async function xM(r,e,t){let n=await T(r,t),i=ua({text:`${e?"Locking":"Unlocking"} screen rotation...`,color:"cyan"}).start();try{let{driver:o,dispose:s}=await ud(r.hdcPath,n);try{await o.setDisplayRotationEnabled(!e)}finally{await s()}i.stop(),console.log(e?"Screen rotation locked (auto-rotation disabled).":"Screen rotation unlocked (auto-rotation enabled).")}catch(o){throw i.stop(),new w(`Failed to set rotation lock: ${o.message}`,"Failed to set rotation lock.")}}var wi=new bM("screen").description("Query and manage screen properties");wi.command("size").description("Query screen resolution").option("--device <name|serial>","Target device (name or serial)").addOption(new SM("--format <format>","Output format").choices(["default","json"]).default("default")).action(async r=>{let{device:e,format:t}=r,n={event:v.CommandExecuted,args:["device","screen","size",...t==="json"?["--format","json"]:[],...e?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await PM(i,e,t)})});wi.command("rotation").description("Query current screen rotation").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","screen","rotation",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await RM(n,e)})});wi.command("sleeptime").description("Set screen-off timeout in milliseconds; use -1 for never").allowUnknownOption().option("--device <name|serial>","Target device (name or serial)").argument("<ms>","Screen-off timeout in milliseconds; -1 for never").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","screen","sleeptime","<ms>",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await CM(i,Number(r),t)})});wi.command("rotate").description("Set screen rotation (clockwise)").argument("<rotation>","Rotation angle: 0, 90, 180, or 270").option("--device <name|serial>","Target device (name or serial)").action(async(r,e)=>{let{device:t}=e,n=Number(r);if(![0,90,180,270].includes(n))throw new w(`Invalid rotation "${r}". Valid values: 0, 90, 180, 270`,"Invalid rotation value.");let o={event:v.CommandExecuted,args:["device","screen","rotate","<rotation>",...t?["--device"]:[]]};await N(o,async()=>{let{toolProvider:s}=await O();await kM(s,n,t)})});wi.command("rotation-lock").description("Lock or unlock screen rotation (on=lock/disable auto-rotation, off=unlock/enable auto-rotation)").argument("<state>","on or off").option("--device <name|serial>","Target device (name or serial)").action(async(r,e)=>{let{device:t}=e;if(r!=="on"&&r!=="off")throw new w(`Invalid state "${r}". Valid values: on, off`,"Invalid rotation-lock state.");let n={event:v.CommandExecuted,args:["device","screen","rotation-lock","<state>",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await xM(i,r==="on",t)})});import{Command as DM}from"commander";import{gray as IM}from"colorette";import AM from"ora";var pa=class{constructor(e){this.toolProvider=e}async readClipboard(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-pastedata"]);if(qe(t),t.exitCode!==0)throw new Error(t.stderr||t.stdout||"read clipboard failed");return t.stdout}async writeClipboard(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-pastedata",t]);if(qe(n),n.exitCode!==0)throw new Error(n.stderr||n.stdout||"write clipboard failed");return n.stdout}async clearClipboard(e){let t=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","clear-pastedata"]);if(qe(t),t.exitCode!==0)throw new Error(t.stderr||t.stdout||"clear clipboard failed");return t.stdout}};async function Um(r,e,t,n){let i=await T(r,n),o=new pa(r),s=AM({text:`Clipboard ${e}...`,color:"cyan"}).start();try{let a;if(e==="read"?a=await o.readClipboard(i):e==="write"?a=await o.writeClipboard(i,t??""):a=await o.clearClipboard(i),s.stop(),e==="read"){let c=a.trim().replace(/^Pasteboard text:\s*/,"");console.log(c||IM("(clipboard is empty)"))}else console.log(`Clipboard ${e==="write"?"written":"cleared"}.`)}catch(a){throw s.stop(),new w(`Clipboard ${e} failed: ${a.message}`,`Clipboard ${e} failed.`)}}var fa=new DM("clipboard").description("Read, write, or clear the device clipboard");fa.command("read").description("Read current clipboard text from the device").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","clipboard","read",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await Um(n,"read",void 0,e)})});fa.command("write").description("Write text to the device clipboard").option("--device <name|serial>","Target device (name or serial)").argument("<text>","Text to write to the clipboard").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","clipboard","write",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await Um(i,"write",r,t)})});fa.command("clear").description("Clear the device clipboard").option("--device <name|serial>","Target device (name or serial)").action(async r=>{let{device:e}=r,t={event:v.CommandExecuted,args:["device","clipboard","clear",...e?["--device"]:[]]};await N(t,async()=>{let{toolProvider:n}=await O();await Um(n,"clear",void 0,e)})});import{Command as TM}from"commander";import{yellow as NM}from"colorette";import{existsSync as OM}from"fs";import Bm from"ora";import{execa as pd}from"execa";var To=class{constructor(e){this.toolProvider=e}async fileExists(e,t){let n=this.toolProvider.hdcPath,i=["-t",e,"shell","ls","-l",t];f(`Executing: ${n} ${i.join(" ")}`);let o;try{let{stdout:s,stderr:a}=await pd(n,i,{env:{...process.env}});o=`${s}
106
106
  ${a}`}catch(s){let a=s;if(o=`${a.stdout??""}
107
107
  ${a.stderr??""}
108
- ${a.message??""}`,/no such file or directory/i.test(o))return!1;throw s}return!/no such file or directory/i.test(o)}async deleteFile(e,t){let n=this.toolProvider.hdcPath,i=["-t",e,"shell","rm","-f",t];m(`Executing: ${n} ${i.join(" ")}`);try{let{stdout:o}=await Jl(n,i,{env:{...process.env}});return o}catch(o){return o.stdout??""}}async sendFile(e,t,n){let i=this.toolProvider.hdcPath,o=["-t",e,"file","send",t,n];m(`Executing: ${i} ${o.join(" ")}`);let{stdout:s}=await Jl(i,o,{env:{...process.env}});if(!s.includes("FileTransfer finish"))throw new Error(`File send failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}async recvFile(e,t,n){let i=this.toolProvider.hdcPath,o=["-t",e,"file","recv",t,n];m(`Executing: ${i} ${o.join(" ")}`);let{stdout:s}=await Jl(i,o,{env:{...process.env}});if(!s.includes("FileTransfer finish"))throw new Error(`File recv failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}};async function qb(r,e,t,n,i){let o=await T(r,i),s=e==="send";if(s&&!tM(t))throw new w(`File not found: ${t}`,"File not found.");let a=new le(r),c=uf({text:s?`Sending ${t} to ${n}...`:`Receiving ${t} to ${n}...`,color:"cyan"}).start();try{await a.transferFile(o,e,t,n),c.stop(),console.log(`${s?"Sent to device":"Received from device"}: ${t} -> ${n}`)}catch(l){c.stop();let d=s?"Send":"Recv";throw new w(l.message,`File ${d} failed.`)}}async function rM(r,e,t){let n=await T(r,t),i=new Eo(r),o=uf({text:`Checking ${e}...`,color:"cyan"}).start();try{let s=await i.fileExists(n,e);o.stop(),s?console.log(`exists: ${e}`):(console.log(eM(`not found: ${e}`)),process.exitCode=1)}catch(s){throw o.stop(),new w(`Existence check failed: ${s.message}`,"Existence check failed.")}}async function nM(r,e,t){let n=await T(r,t),i=new Eo(r),o=uf({text:`Deleting ${e}...`,color:"cyan"}).start();try{if(!await i.fileExists(n,e))throw o.stop(),new w(`File not found: ${e}`,"File not found.");let a=await i.deleteFile(n,e);o.stop();let c=a.trim();if(c&&/error|no such file/i.test(c))throw new Error(c);console.log(`Deleted ${e}.`)}catch(s){throw o.stop(),new w(`Delete failed: ${s.message}`,"Delete failed.")}}var Po=new QN("file").description("Transfer files between the host and a connected device");Po.command("send").description("Send a local file to a device").option("--device <name|serial>","Target device (name or serial)").argument("<src>","Local file path to upload").argument("<dst>","Remote path on the device").action(async(r,e,t)=>{let{device:n}=t,i={event:v.CommandExecuted,args:["device","file","send",...n?["--device"]:[]]};await O(i,async()=>{let{toolProvider:o}=await N();await qb(o,"send",r,e,n)})});Po.command("recv").description("Receive a file from a device to the host").option("--device <name|serial>","Target device (name or serial)").argument("<src>","Remote path on the device").argument("<dst>","Local file path to save").action(async(r,e,t)=>{let{device:n}=t,i={event:v.CommandExecuted,args:["device","file","recv",...n?["--device"]:[]]};await O(i,async()=>{let{toolProvider:o}=await N();await qb(o,"recv",r,e,n)})});Po.command("exist").description("Check if a file exists on the device").option("--device <name|serial>","Target device (name or serial)").argument("<path>","Remote path on the device to check").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","file","exist",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await rM(i,r,t)})});Po.command("delete").description("Delete a file on the device").option("--device <name|serial>","Target device (name or serial)").argument("<path>","Remote path on the device to delete").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","file","delete",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await nM(i,r,t)})});import{Command as oM}from"commander";import{red as sM}from"colorette";import{existsSync as aM}from"fs";import cM from"ora";import{basename as iM}from"path";var ra=class{constructor(e){this.toolProvider=e;this.hdc=new le(e)}hdc;async pushFontToDevice(e,t){let n=`/data/local/tmp/${iM(t)}`;return await this.hdc.transferFile(e,"send",t,n),n}async installFont(e,t){let n=await this.pushFontToDevice(e,t),i=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","install-font",n]);return Ge(i),i.stdout}async getFontInfo(e,t){let n=await this.pushFontToDevice(e,t),i=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-fontname",n]);return Ge(i),i.stdout}async uninstallFont(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","uninstall-font",t]);return Ge(n),n.stdout}};async function pf(r,e,t,n){let i=await T(r,n);if(e!=="uninstall"&&!aM(t))throw new w(`Font file not found: ${t}`,"Font file not found.");let o=new ra(r),s=cM({text:`Font ${e} ${t}...`,color:"cyan"}).start();try{let a;e==="install"?a=await o.installFont(i,t):e==="info"?a=await o.getFontInfo(i,t):a=await o.uninstallFont(i,t),s.stop();let c=a.trim();/^error/i.test(c)?(console.error(sM(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(a.message,`Font ${e} failed.`)}}var na=new oM("font").description("Manage device fonts");na.command("install").description("Install a font on the device").option("--device <name|serial>","Target device (name or serial)").argument("<fontpath>","Local font file path to install").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","install","<fontpath>",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await pf(i,"install",r,t)})});na.command("info").description("Get font name from a font file").option("--device <name|serial>","Target device (name or serial)").argument("<fontpath>","Local font file path to query").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","info","<fontpath>",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await pf(i,"info",r,t)})});na.command("uninstall").description("Uninstall a font from the device").option("--device <name|serial>","Target device (name or serial)").argument("<name>","Font name to uninstall").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","uninstall","<name>",...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await pf(i,"uninstall",r,t)})});import{Command as lM}from"commander";import{red as dM}from"colorette";import uM from"ora";var ia=class{constructor(e){this.toolProvider=e}async getViewmode(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","param","get","persist.ace.darkmode"])).stdout}async setViewmode(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-viewmode",t]);return Ge(n),/already set to/i.test(n.stdout)?n.stdout.replace(/^Error:\s*/i,"").trim():n.stdout}};async function pM(r,e,t){let n=await T(r,t),i=new ia(r),o=e!==void 0;if(o&&e!=="dark"&&e!=="light")throw new w(`Invalid viewmode "${e}". Valid values: dark, light`,"Invalid viewmode value.");let s=uM({text:o?`Setting viewmode to ${e}...`:"Getting viewmode...",color:"cyan"}).start();try{let a=o?await i.setViewmode(n,e):await i.getViewmode(n);s.stop();let c=a.trim();/fail/i.test(c)?(console.error(dM(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Viewmode ${o?"set":"get"} failed: ${a.message}`,`Viewmode ${o?"set":"get"} failed.`)}}var zb=new lM("viewmode").description("Get or set the device view mode").option("--device <name|serial>","Target device (name or serial)").argument("[mode]","View mode to set (dark|light); omit to get current").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","viewmode",...r?[r]:[],...t?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await pM(i,r,t)})});function yM(r,e){if(e.size!==0)for(let t of r){if(!t.isEmulator||!t.name)continue;let n=e.get(Fe(t.name));n&&(t.deviceType=n)}}var wM=["Name","Serial","Kind","Device Type"];function vM(r){return{cells:[r.name??r.serial,r.serial,r.isEmulator?"emulator":"device",r.deviceType??"-"],highlight:!0}}function Kb(r,e){return r.isEmulator!==e.isEmulator?r.isEmulator?1:-1:(r.name??r.serial).localeCompare(e.name??e.serial)}function bM(){console.log(fM(" No active devices.")),console.log(gM(" Connect a USB device with debugging enabled, or start an emulator with `devecocli emulator start <name>`."))}function SM(r){let t=[...r].sort(Kb).map(vM);console.log(jr(wM,t))}function EM(r){return{name:r.name??r.serial,serial:r.serial,kind:r.isEmulator?"emulator":"device",deviceType:r.deviceType}}function PM(r){let e=[...r].sort(Kb);console.log(JSON.stringify(e.map(EM),null,2))}async function CM(r,e){if(!r.some(i=>i.isEmulator)||!e.emulatorPath)return;let n=await go.from(e).getDeviceTypeByName();yM(r,n)}async function Jb(r,e,t,n="table"){try{let i=await r.getConnectedEntries();if(await CM(i,e),t?.stop(),n==="json"){PM(i);return}i.length===0?bM():SM(i)}catch(i){throw new w(`Failed to list devices: ${i.message}`,"Failed to list devices.")}finally{t?.stop()}}async function kM(r,e){let t=await r.listDevices();if(t.length<2)return;let n=["Multiple devices connected. Specify a device with:"];for(let i of t){let o=await r.getDeviceName(i.serial);n.push(` ${e} -t ${i.serial} # ${o}`)}throw new w(n.join(`
109
- `),"Multiple devices connected.")}async function DM(r,e,t="table"){e||await kM(r,"devecocli device view");let n=await r.listDevices(),i=await r.getDeviceInfo(n,e);if(!i){if(t==="json"){console.error("No connected device found."),process.exitCode=1;return}throw new w("No connected device found.")}let o=await r.getDeviceDetail(i.serial),s=await r.getDeviceName(i.serial);if(t==="json"){let a={name:s,serial:i.serial,kind:dr(i.serial)?"emulator":"device",deviceType:o.deviceType,osVersion:o.osVersion};console.log(JSON.stringify(a,null,2));return}console.log(` Serial: ${i.serial}`),console.log(` Device Name: ${s}`),o.deviceType&&console.log(` Device Type: ${o.deviceType}`),o.osVersion&&console.log(` OS Version: ${o.osVersion}`)}async function RM(r,e,t,n){let i=await T(r,n),o=new le(r);try{await o.runSqlite3(i,e,t)}catch(s){throw new w(`sqlite3 failed: ${s.message}`,"sqlite3 failed.")}}var Jt=new mM("device").description("Manage connected devices");Jt.command("list").description("List all connected devices").addOption(new Yb("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["device","list",...r.format==="json"?["--format","json"]:[]]};await O(e,async()=>{let{manager:t,toolProvider:n}=await N();if(r.format==="json"){await Jb(t,n,void 0,"json");return}let i=hM({text:"Querying connected devices\u2026",color:"cyan"}).start();await Jb(t,n,i,"table")})});Jt.command("view").description("Show detailed device information").option("-t, --target <serialOrName>","Target device serial or device name").addOption(new Yb("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["device","view",...r.target?["--target"]:[],...r.format==="json"?["--format","json"]:[]]};await O(e,async()=>{let{manager:t}=await N();await DM(t,r.target,r.format)})});Jt.addCommand(Vt);Jt.addCommand(Po);Jt.addCommand(ta);Jt.addCommand(fi);Jt.addCommand(na);Jt.addCommand(zb);for(let r of Cb)Jt.addCommand(r);Jt.command("sqlite3").description("Run sqlite3 on a connected device").allowUnknownOption().option("--device <name|serial>","Target device (name or serial)").argument("<db-path>","SQLite database path on the device").argument("[args...]","Arguments forwarded to sqlite3 as-is").action(async(r,e,t)=>{let n={event:v.CommandExecuted,args:["device","sqlite3",r,...t.device?["--device"]:[]]};await O(n,async()=>{let{toolProvider:i}=await N();await RM(i,r,e,t.device)})});var Xb=Jt;import{Argument as Sf,Command as Ef,InvalidArgumentError as vf,Option as ze}from"commander";import{green as aa,cyan as ko,red as Pf,yellow as vn,gray as bf}from"colorette";import WM from"ora";import xM from"readline/promises";import{execa as Qb}from"execa";import*as wn from"fs/promises";import*as ff from"os";import*as gi from"path";var mf=`1/4:\r
108
+ ${a.message??""}`,/no such file or directory/i.test(o))return!1;throw s}return!/no such file or directory/i.test(o)}async deleteFile(e,t){let n=this.toolProvider.hdcPath,i=["-t",e,"shell","rm","-f",t];f(`Executing: ${n} ${i.join(" ")}`);try{let{stdout:o}=await pd(n,i,{env:{...process.env}});return o}catch(o){return o.stdout??""}}async sendFile(e,t,n){let i=this.toolProvider.hdcPath,o=["-t",e,"file","send",t,n];f(`Executing: ${i} ${o.join(" ")}`);let{stdout:s}=await pd(i,o,{env:{...process.env}});if(!s.includes("FileTransfer finish"))throw new Error(`File send failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}async recvFile(e,t,n){let i=this.toolProvider.hdcPath,o=["-t",e,"file","recv",t,n];f(`Executing: ${i} ${o.join(" ")}`);let{stdout:s}=await pd(i,o,{env:{...process.env}});if(!s.includes("FileTransfer finish"))throw new Error(`File recv failed: ${s.trim()||"hdc returned no output"}`);return s.trim()}};async function jS(r,e,t,n,i){let o=await T(r,i),s=e==="send";if(s&&!OM(t))throw new w(`File not found: ${t}`,"File not found.");let a=new de(r),c=Bm({text:s?`Sending ${t} to ${n}...`:`Receiving ${t} to ${n}...`,color:"cyan"}).start();try{await a.transferFile(o,e,t,n),c.stop(),console.log(`${s?"Sent to device":"Received from device"}: ${t} -> ${n}`)}catch(l){c.stop();let d=s?"Send":"Recv";throw new w(l.message,`File ${d} failed.`)}}async function _M(r,e,t){let n=await T(r,t),i=new To(r),o=Bm({text:`Checking ${e}...`,color:"cyan"}).start();try{let s=await i.fileExists(n,e);o.stop(),s?console.log(`exists: ${e}`):(console.log(NM(`not found: ${e}`)),process.exitCode=1)}catch(s){throw o.stop(),new w(`Existence check failed: ${s.message}`,"Existence check failed.")}}async function MM(r,e,t){let n=await T(r,t),i=new To(r),o=Bm({text:`Deleting ${e}...`,color:"cyan"}).start();try{if(!await i.fileExists(n,e))throw o.stop(),new w(`File not found: ${e}`,"File not found.");let a=await i.deleteFile(n,e);o.stop();let c=a.trim();if(c&&/error|no such file/i.test(c))throw new Error(c);console.log(`Deleted ${e}.`)}catch(s){throw o.stop(),new w(`Delete failed: ${s.message}`,"Delete failed.")}}var No=new TM("file").description("Transfer files between the host and a connected device");No.command("send").description("Send a local file to a device").option("--device <name|serial>","Target device (name or serial)").argument("<src>","Local file path to upload").argument("<dst>","Remote path on the device").action(async(r,e,t)=>{let{device:n}=t,i={event:v.CommandExecuted,args:["device","file","send",...n?["--device"]:[]]};await N(i,async()=>{let{toolProvider:o}=await O();await jS(o,"send",r,e,n)})});No.command("recv").description("Receive a file from a device to the host").option("--device <name|serial>","Target device (name or serial)").argument("<src>","Remote path on the device").argument("<dst>","Local file path to save").action(async(r,e,t)=>{let{device:n}=t,i={event:v.CommandExecuted,args:["device","file","recv",...n?["--device"]:[]]};await N(i,async()=>{let{toolProvider:o}=await O();await jS(o,"recv",r,e,n)})});No.command("exist").description("Check if a file exists on the device").option("--device <name|serial>","Target device (name or serial)").argument("<path>","Remote path on the device to check").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","file","exist",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await _M(i,r,t)})});No.command("delete").description("Delete a file on the device").option("--device <name|serial>","Target device (name or serial)").argument("<path>","Remote path on the device to delete").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","file","delete",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await MM(i,r,t)})});import{Command as FM}from"commander";import{red as $M}from"colorette";import{existsSync as jM}from"fs";import HM from"ora";import{basename as LM}from"path";var ma=class{constructor(e){this.toolProvider=e;this.hdc=new de(e)}hdc;async pushFontToDevice(e,t){let n=`/data/local/tmp/${LM(t)}`;return await this.hdc.transferFile(e,"send",t,n),n}async installFont(e,t){let n=await this.pushFontToDevice(e,t),i=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","install-font",n]);return qe(i),i.stdout}async getFontInfo(e,t){let n=await this.pushFontToDevice(e,t),i=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","get-fontname",n]);return qe(i),i.stdout}async uninstallFont(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","uninstall-font",t]);return qe(n),n.stdout}};async function Wm(r,e,t,n){let i=await T(r,n);if(e!=="uninstall"&&!jM(t))throw new w(`Font file not found: ${t}`,"Font file not found.");let o=new ma(r),s=HM({text:`Font ${e} ${t}...`,color:"cyan"}).start();try{let a;e==="install"?a=await o.installFont(i,t):e==="info"?a=await o.getFontInfo(i,t):a=await o.uninstallFont(i,t),s.stop();let c=a.trim();/^error/i.test(c)?(console.error($M(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(a.message,`Font ${e} failed.`)}}var ga=new FM("font").description("Manage device fonts");ga.command("install").description("Install a font on the device").option("--device <name|serial>","Target device (name or serial)").argument("<fontpath>","Local font file path to install").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","install","<fontpath>",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await Wm(i,"install",r,t)})});ga.command("info").description("Get font name from a font file").option("--device <name|serial>","Target device (name or serial)").argument("<fontpath>","Local font file path to query").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","info","<fontpath>",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await Wm(i,"info",r,t)})});ga.command("uninstall").description("Uninstall a font from the device").option("--device <name|serial>","Target device (name or serial)").argument("<name>","Font name to uninstall").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","font","uninstall","<name>",...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await Wm(i,"uninstall",r,t)})});import{Command as UM}from"commander";import{red as BM}from"colorette";import WM from"ora";var ha=class{constructor(e){this.toolProvider=e}async getViewmode(e){return(await k(this.toolProvider.hdcPath,["-t",e,"shell","param","get","persist.ace.darkmode"])).stdout}async setViewmode(e,t){let n=await k(this.toolProvider.hdcPath,["-t",e,"shell","testhelper","set-viewmode",t]);return qe(n),/already set to/i.test(n.stdout)?n.stdout.replace(/^Error:\s*/i,"").trim():n.stdout}};async function VM(r,e,t){let n=await T(r,t),i=new ha(r),o=e!==void 0;if(o&&e!=="dark"&&e!=="light")throw new w(`Invalid viewmode "${e}". Valid values: dark, light`,"Invalid viewmode value.");let s=WM({text:o?`Setting viewmode to ${e}...`:"Getting viewmode...",color:"cyan"}).start();try{let a=o?await i.setViewmode(n,e):await i.getViewmode(n);s.stop();let c=a.trim();/fail/i.test(c)?(console.error(BM(c)),process.exitCode=1):console.log(c)}catch(a){throw s.stop(),new w(`Viewmode ${o?"set":"get"} failed: ${a.message}`,`Viewmode ${o?"set":"get"} failed.`)}}var HS=new UM("viewmode").description("Get or set the device view mode").option("--device <name|serial>","Target device (name or serial)").argument("[mode]","View mode to set (dark|light); omit to get current").action(async(r,e)=>{let{device:t}=e,n={event:v.CommandExecuted,args:["device","viewmode",...r?[r]:[],...t?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await VM(i,r,t)})});function KM(r,e){if(e.size!==0)for(let t of r){if(!t.isEmulator||!t.name)continue;let n=e.get(je(t.name));n&&(t.deviceType=n)}}var YM=["Name","Serial","Kind","Device Type"];function XM(r){return{cells:[r.name??r.serial,r.serial,r.isEmulator?"emulator":"device",r.deviceType??"-"],highlight:!0}}function WS(r,e){return r.isEmulator!==e.isEmulator?r.isEmulator?1:-1:(r.name??r.serial).localeCompare(e.name??e.serial)}function ZM(){console.log(qM(" No active devices.")),console.log(zM(" Connect a USB device with debugging enabled, or start an emulator with `devecocli emulator start <name>`."))}function QM(r){let t=[...r].sort(WS).map(XM);console.log(zt(YM,t))}function eL(r){return{name:r.name??r.serial,serial:r.serial,kind:r.isEmulator?"emulator":"device",deviceType:r.deviceType}}function tL(r){let e=[...r].sort(WS);console.log(JSON.stringify(e.map(eL),null,2))}async function rL(r,e){if(!r.some(i=>i.isEmulator)||!e.emulatorPath)return;let n=await Co.from(e).getDeviceTypeByName();KM(r,n)}async function US(r,e,t,n="table"){try{let i=await r.getConnectedEntries();if(await rL(i,e),t?.stop(),n==="json"){tL(i);return}i.length===0?ZM():QM(i)}catch(i){throw new w(`Failed to list devices: ${i.message}`,"Failed to list devices.")}finally{t?.stop()}}async function nL(r,e){let t=await r.listDevices();if(t.length<2)return;let n=["Multiple devices connected. Specify a device with:"];for(let i of t){let o=await r.getDeviceName(i.serial);n.push(` ${e} -t ${i.serial} # ${o}`)}throw new w(n.join(`
109
+ `),"Multiple devices connected.")}async function iL(r,e,t="table"){e||await nL(r,"devecocli device view");let n=await r.listDevices(),i=await r.getDeviceInfo(n,e);if(!i){if(t==="json"){console.error("No connected device found."),process.exitCode=1;return}throw new w("No connected device found.")}let o=await r.getDeviceDetail(i.serial),s=await r.getDeviceName(i.serial);if(t==="json"){let a={name:s,serial:i.serial,kind:mr(i.serial)?"emulator":"device",deviceType:o.deviceType,osVersion:o.osVersion};console.log(JSON.stringify(a,null,2));return}console.log(` Serial: ${i.serial}`),console.log(` Device Name: ${s}`),o.deviceType&&console.log(` Device Type: ${o.deviceType}`),o.osVersion&&console.log(` OS Version: ${o.osVersion}`)}async function oL(r,e,t,n){let i=await T(r,n),o=new de(r);try{await o.runSqlite3(i,e,t)}catch(s){throw new w(`sqlite3 failed: ${s.message}`,"sqlite3 failed.")}}var Zt=new GM("device").description("Manage connected devices");Zt.command("list").description("List all connected devices").addOption(new BS("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["device","list",...r.format==="json"?["--format","json"]:[]]};await N(e,async()=>{let{manager:t,toolProvider:n}=await O();if(r.format==="json"){await US(t,n,void 0,"json");return}let i=JM({text:"Querying connected devices\u2026",color:"cyan"}).start();await US(t,n,i,"table")})});Zt.command("view").description("Show detailed device information").option("-t, --target <serialOrName>","Target device serial or device name").addOption(new BS("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["device","view",...r.target?["--target"]:[],...r.format==="json"?["--format","json"]:[]]};await N(e,async()=>{let{manager:t}=await O();await iL(t,r.target,r.format)})});Zt.addCommand(Jt);Zt.addCommand(No);Zt.addCommand(fa);Zt.addCommand(wi);Zt.addCommand(ga);Zt.addCommand(HS);for(let r of yS)Zt.addCommand(r);Zt.command("sqlite3").description("Run sqlite3 on a connected device").allowUnknownOption().option("--device <name|serial>","Target device (name or serial)").argument("<db-path>","SQLite database path on the device").argument("[args...]","Arguments forwarded to sqlite3 as-is").action(async(r,e,t)=>{let n={event:v.CommandExecuted,args:["device","sqlite3",r,...t.device?["--device"]:[]]};await N(n,async()=>{let{toolProvider:i}=await O();await oL(i,r,e,t.device)})});var VS=Zt;import{Argument as Zm,Command as Qm,InvalidArgumentError as Ym,Option as Je}from"commander";import{green as va,cyan as _o,red as eg,yellow as En,gray as Xm}from"colorette";import SL from"ora";import sL from"readline/promises";import{execa as qS}from"execa";import*as Sn from"fs/promises";import*as Gm from"os";import*as vi from"path";var Vm=`1/4:\r
110
110
  ---------------------------------------\r
111
111
  Statement About HarmonyOS and Privacy\r
112
112
  \r
@@ -1276,13 +1276,13 @@ Part I: Chinese mainland.\r
1276
1276
  Part II: Aland Islands, Albania, Andorra, Australia, Austria, Belgium, Bonaire, Bosnia and Herzegovina, Bulgaria, Canada, Croatia, Curacao, Cyprus, Czech Republic, Denmark, Dutch Caribbean, Estonia, Faroe Islands, Finland, France, Germany, Gibraltar, Greece, Greenland, Guernsey, Hungary, Iceland, Israel, Italy, Jersey, Latvia, Liechtenstein, Lithuania, Luxembourg, Malta, Moldova, Monaco, Montenegro, Netherlands, New Zealand, North Macedonia, Norway, Poland, Portugal, Ireland, Romania, Saba, Saint Vincent and the Grenadines, San Marino, Serbia, Sint Eustatius, Sint Maarten, Slovakia, Slovenia, Spain, St. Martin, St. Pierre and Miquelon (France), Sweden, Switzerland, Turkey, Ukraine, United Kingdom, United States, Vatican City.\r
1277
1277
  \r
1278
1278
  Part III: Other countries and regions.\r
1279
- ---------------------------------------\r`;var AM=new Set,Yl=new Map,gf="HarmonyOS_Software_Service_Agreement",eS=["Emulator license agreements are not accepted yet.","","Accept the agreements interactively (shows full text + y/N prompt):"," devecocli emulator license","","Or accept non-interactively (no prompt, for CI/scripts):"," devecocli emulator license accept","","To review the agreement text (read-only):"," devecocli emulator license view"].join(`
1280
- `),tS=eS,hf="HarmonyOS_SDK_Agreement";function rS(r,e){return`${r}\0${e}`}function nS(){AM.clear(),Yl.clear()}var IM=eS,Br=class extends Error{constructor(e=IM){super(e),this.name="EmulatorLicenseBlockedError"}};function iS(r,e){return[r??"",e??""].join(`
1281
- `)}function oS(r){let e=r.normalize("NFKC"),t=e.match(/(\d+)\.(\d+)\.\d+/);if(t)return`${t[1]}.${t[2]}`;let n=e.match(/(\d+)\.(\d+)\b/);return n?`${n[1]}.${n[2]}`:null}function TM(r){return`Emulator${r.trim()}`}function sS(r){let e=TM(r);if(process.platform==="win32"){let n=process.env.LOCALAPPDATA;if(!n)throw new Error("LOCALAPPDATA is not set; cannot resolve .emu_config path.");return gi.join(n,"Huawei",e,".emu_config")}if(process.platform==="darwin")return gi.join(ff.homedir(),"Library","Caches","Huawei",e,".emu_config");let t=process.env.XDG_CACHE_HOME?.trim()||gi.join(ff.homedir(),".cache");return gi.join(t,"Huawei",e,".emu_config")}async function OM(r,e,t){let n=rS(r,e),i=Yl.get(n);if(i!==void 0)return i;let o=await Qb(r,["-version"],{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},reject:!1,maxBuffer:1024*1024}),s=iS(o.stdout,o.stderr).trim();if(o.exitCode!==0||!s)throw new Br(t);return Yl.set(n,s),s}function NM(r){let e=r[0],t=r[r.length-1];return(e==='"'||e==="'")&&e===t?r.slice(1,-1):r}function MM(r){try{let e=JSON.parse(r);if(e&&typeof e=="object"&&!Array.isArray(e)){let t={};for(let[n,i]of Object.entries(e))t[n]={value:typeof i=="string"?i:String(i),delimiter:"json"};return t}}catch{return}}function LM(r){let e=r.trim();if(!(!e||e.startsWith("#")))for(let t of["=",":"]){let n=e.indexOf(t);if(n<=0)continue;let i=e.slice(0,n).trim();if(!i||t===":"&&i.includes("//"))continue;let o=NM(e.slice(n+1).trim());return{key:i,entry:{value:o,delimiter:t}}}}function _M(r){let e={};for(let t of r.split(/\r?\n/)){let n=LM(t);n&&(e[n.key]=n.entry)}return e}function $M(r){let e=r.trim();if(!e)return{};let t=MM(e);return t||_M(r)}function FM(r){return typeof r!="string"?!1:r.normalize("NFKC").trim().toLowerCase()==="agree"}async function aS(r,e,t,n){let i=await OM(r,e,n),o=oS(i);if(!o)throw new Br(n);let s=sS(o),a;try{a=await wn.readFile(s,"utf8")}catch(d){throw d.code==="ENOENT"?new Br(n):d}let l=$M(a)[t];if(!l)throw new Br(n);if(l.delimiter==="=")throw new Br(n);if(!FM(l.value))throw new Br(n)}async function yf(r,e){await aS(r,e,gf,tS)}async function wf(r,e){await aS(r,e,hf,tS)}async function jM(r,e){let t=await Qb(r,["-version"],{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},reject:!1,maxBuffer:1048576}),n=iS(t.stdout,t.stderr).trim();if(t.exitCode!==0||!n)throw new Error(`Emulator -version failed (exit ${String(t.exitCode)}); cannot resolve .emu_config path.`);let i=rS(r,e);return Yl.set(i,n),n}async function cS(r,e){let t=await jM(r,e),n=oS(t);if(!n)throw new Error(`Cannot parse Emulator major.minor from:
1282
- ${t}.`);return sS(n)}function Zb(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function HM(r,e,t){if(!t.startsWith("{"))return!1;try{let n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n[gf]="agree",n[hf]="agree",await wn.writeFile(r,`${JSON.stringify(n,null,2)}
1283
- `,"utf8"),!0}catch{}return!1}async function UM(r,e){let t=gf,n=hf,i=[{k:t,re:new RegExp(`^\\s*${Zb(t)}\\s*[:=]`)},{k:n,re:new RegExp(`^\\s*${Zb(n)}\\s*[:=]`)}],o=e.length===0?[]:e.split(/\r?\n/),s=[],a=new Set;for(let c of o){let l=!1;for(let{k:d,re:g}of i)if(g.test(c)){s.push(`${d}:agree`),a.add(d),l=!0;break}l||s.push(c)}a.has(t)||s.push(`${t}:agree`),a.has(n)||s.push(`${n}:agree`),await wn.writeFile(r,s.join(`
1279
+ ---------------------------------------\r`;var aL=new Set,fd=new Map,qm="HarmonyOS_Software_Service_Agreement",zS=["Emulator license agreements are not accepted yet.","","Accept the agreements interactively (shows full text + y/N prompt):"," devecocli emulator license","","Or accept non-interactively (no prompt, for CI/scripts):"," devecocli emulator license accept","","To review the agreement text (read-only):"," devecocli emulator license view"].join(`
1280
+ `),JS=zS,zm="HarmonyOS_SDK_Agreement";function KS(r,e){return`${r}\0${e}`}function YS(){aL.clear(),fd.clear()}var cL=zS,Gr=class extends Error{constructor(e=cL){super(e),this.name="EmulatorLicenseBlockedError"}};function XS(r,e){return[r??"",e??""].join(`
1281
+ `)}function ZS(r){let e=r.normalize("NFKC"),t=e.match(/(\d+)\.(\d+)\.\d+/);if(t)return`${t[1]}.${t[2]}`;let n=e.match(/(\d+)\.(\d+)\b/);return n?`${n[1]}.${n[2]}`:null}function lL(r){return`Emulator${r.trim()}`}function QS(r){let e=lL(r);if(process.platform==="win32"){let n=process.env.LOCALAPPDATA;if(!n)throw new Error("LOCALAPPDATA is not set; cannot resolve .emu_config path.");return vi.join(n,"Huawei",e,".emu_config")}if(process.platform==="darwin")return vi.join(Gm.homedir(),"Library","Caches","Huawei",e,".emu_config");let t=process.env.XDG_CACHE_HOME?.trim()||vi.join(Gm.homedir(),".cache");return vi.join(t,"Huawei",e,".emu_config")}async function dL(r,e,t){let n=KS(r,e),i=fd.get(n);if(i!==void 0)return i;let o=await qS(r,["-version"],{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},reject:!1,maxBuffer:1024*1024}),s=XS(o.stdout,o.stderr).trim();if(o.exitCode!==0||!s)throw new Gr(t);return fd.set(n,s),s}function uL(r){let e=r[0],t=r[r.length-1];return(e==='"'||e==="'")&&e===t?r.slice(1,-1):r}function pL(r){try{let e=JSON.parse(r);if(e&&typeof e=="object"&&!Array.isArray(e)){let t={};for(let[n,i]of Object.entries(e))t[n]={value:typeof i=="string"?i:String(i),delimiter:"json"};return t}}catch{return}}function fL(r){let e=r.trim();if(!(!e||e.startsWith("#")))for(let t of["=",":"]){let n=e.indexOf(t);if(n<=0)continue;let i=e.slice(0,n).trim();if(!i||t===":"&&i.includes("//"))continue;let o=uL(e.slice(n+1).trim());return{key:i,entry:{value:o,delimiter:t}}}}function mL(r){let e={};for(let t of r.split(/\r?\n/)){let n=fL(t);n&&(e[n.key]=n.entry)}return e}function gL(r){let e=r.trim();if(!e)return{};let t=pL(e);return t||mL(r)}function hL(r){return typeof r!="string"?!1:r.normalize("NFKC").trim().toLowerCase()==="agree"}async function eE(r,e,t,n){let i=await dL(r,e,n),o=ZS(i);if(!o)throw new Gr(n);let s=QS(o),a;try{a=await Sn.readFile(s,"utf8")}catch(d){throw d.code==="ENOENT"?new Gr(n):d}let l=gL(a)[t];if(!l)throw new Gr(n);if(l.delimiter==="=")throw new Gr(n);if(!hL(l.value))throw new Gr(n)}async function Jm(r,e){await eE(r,e,qm,JS)}async function Km(r,e){await eE(r,e,zm,JS)}async function yL(r,e){let t=await qS(r,["-version"],{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},reject:!1,maxBuffer:1048576}),n=XS(t.stdout,t.stderr).trim();if(t.exitCode!==0||!n)throw new Error(`Emulator -version failed (exit ${String(t.exitCode)}); cannot resolve .emu_config path.`);let i=KS(r,e);return fd.set(i,n),n}async function tE(r,e){let t=await yL(r,e),n=ZS(t);if(!n)throw new Error(`Cannot parse Emulator major.minor from:
1282
+ ${t}.`);return QS(n)}function GS(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function wL(r,e,t){if(!t.startsWith("{"))return!1;try{let n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return n[qm]="agree",n[zm]="agree",await Sn.writeFile(r,`${JSON.stringify(n,null,2)}
1283
+ `,"utf8"),!0}catch{}return!1}async function vL(r,e){let t=qm,n=zm,i=[{k:t,re:new RegExp(`^\\s*${GS(t)}\\s*[:=]`)},{k:n,re:new RegExp(`^\\s*${GS(n)}\\s*[:=]`)}],o=e.length===0?[]:e.split(/\r?\n/),s=[],a=new Set;for(let c of o){let l=!1;for(let{k:d,re:g}of i)if(g.test(c)){s.push(`${d}:agree`),a.add(d),l=!0;break}l||s.push(c)}a.has(t)||s.push(`${t}:agree`),a.has(n)||s.push(`${n}:agree`),await Sn.writeFile(r,s.join(`
1284
1284
  `)+(s.length>0?`
1285
- `:""),"utf8")}async function lS(r){await wn.mkdir(gi.dirname(r),{recursive:!0});let e="";try{e=await wn.readFile(r,"utf8")}catch(n){if(n.code!=="ENOENT")throw n}let t=e.trim();await HM(r,e,t)||await UM(r,e)}async function dS(r,e){return console.log(mf),0}var BM="Please read carefully and confirm whether agree to the above agreement? (y/N): ";async function uS(r,e){try{return await yf(r,e),await wf(r,e),!0}catch(t){if(t instanceof Br)return!1;throw t}}async function pS(r,e){if(await uS(r,e))return console.log("Emulator license agreements are already accepted."),0;if(console.log(mf),!process.stdin.isTTY||!process.stdout.isTTY)return console.error("`devecocli emulator license` requires an interactive terminal.\nFor non-interactive environments, use: devecocli emulator license accept"),1;let n=xM.createInterface({input:process.stdin,output:process.stdout}),i;try{i=await n.question(BM)}finally{n.close()}let o=i.trim().toLowerCase();if(o!=="y"&&o!=="yes")return console.error("Agreements not accepted. Emulator features will remain blocked until accepted."),1;try{let s=await cS(r,e);await lS(s),nS()}catch(s){return console.error(s.message),1}return console.log("Emulator license agreements accepted."),0}async function mS(r,e){if(await uS(r,e))return console.log("Emulator license agreements are already accepted."),0;try{let t=await cS(r,e);await lS(t),nS()}catch(t){return console.error(t.message),1}return console.log("Emulator license agreements accepted."),0}async function At(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=X(o),console.error(Pf(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(r,o)}}var VM=["ohos.qemu.hvd.name","const.product.name","const.product.model"],fS=["open","half-open","close","vertical-open","single","double","triple","left-folded-right-half-folded","left-half-folded-right-expanded","left-expanded-right-folded","left-half-folded-right-folded","left-expanded-right-half-folded","left-half-folded-right-half-folded"],GM=`
1285
+ `:""),"utf8")}async function rE(r){await Sn.mkdir(vi.dirname(r),{recursive:!0});let e="";try{e=await Sn.readFile(r,"utf8")}catch(n){if(n.code!=="ENOENT")throw n}let t=e.trim();await wL(r,e,t)||await vL(r,e)}async function nE(r,e){return console.log(Vm),0}var bL="Please read carefully and confirm whether agree to the above agreement? (y/N): ";async function iE(r,e){try{return await Jm(r,e),await Km(r,e),!0}catch(t){if(t instanceof Gr)return!1;throw t}}async function oE(r,e){if(await iE(r,e))return console.log("Emulator license agreements are already accepted."),0;if(console.log(Vm),!process.stdin.isTTY||!process.stdout.isTTY)return console.error("`devecocli emulator license` requires an interactive terminal.\nFor non-interactive environments, use: devecocli emulator license accept"),1;let n=sL.createInterface({input:process.stdin,output:process.stdout}),i;try{i=await n.question(bL)}finally{n.close()}let o=i.trim().toLowerCase();if(o!=="y"&&o!=="yes")return console.error("Agreements not accepted. Emulator features will remain blocked until accepted."),1;try{let s=await tE(r,e);await rE(s),YS()}catch(s){return console.error(s.message),1}return console.log("Emulator license agreements accepted."),0}async function sE(r,e){if(await iE(r,e))return console.log("Emulator license agreements are already accepted."),0;try{let t=await tE(r,e);await rE(t),YS()}catch(t){return console.error(t.message),1}return console.log("Emulator license agreements accepted."),0}async function At(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=Z(o),console.error(eg(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(r,o)}}var EL=["ohos.qemu.hvd.name","const.product.name","const.product.model"],aE=["open","half-open","close","vertical-open","single","double","triple","left-folded-right-half-folded","left-half-folded-right-expanded","left-expanded-right-folded","left-half-folded-right-folded","left-expanded-right-half-folded","left-half-folded-right-half-folded"],PL=`
1286
1286
  Folded state scene mappings:
1287
1287
  foldableFold (3):
1288
1288
  open Fully expanded state
@@ -1305,82 +1305,98 @@ Folded state scene mappings:
1305
1305
  left-half-folded-right-folded
1306
1306
  left-expanded-right-half-folded
1307
1307
  left-half-folded-right-half-folded
1308
- `,qM="6.1.0";function zM(r){let e=r.trim();if(!e)throw new Error("--target must not be empty.");return e}function JM(r){let e=r.trim();if(!fS.includes(e))throw new Error(`Invalid fold state "${r}". Available values: ${fS.join(", ")}`);return e}function hS(r,e,t,n){let i=e.trim();if(!/^-?\d+$/.test(i))throw new Error(`${r} must be an integer in [${t}, ${n}].`);let o=Number(i);if(o<t||o>n)throw new Error(`${r} must be in [${t}, ${n}].`);return o}function yS(r,e,t,n,i){let o=e.trim(),s=Number(o);if(!o||Number.isNaN(s))throw new Error(`${r} must be a number in [${t}, ${n}].`);if(i!==void 0&&!YM(o,i))throw new Error(`${r} supports at most ${i} decimal place(s).`);if(s<t||s>n)throw new Error(`${r} must be in [${t}, ${n}].`);return o}function YM(r,e){let t=r.split(".")[1];return t===void 0||t.length<=e}function hi(r,e,t,n,i){return Number(yS(r,e,t,n,i))}var KM=["Name","Status","Serial","Device Type","OS Version"];function XM(r){return{cells:[r.name,r.status,r.serial??"-",r.deviceType??"-",r.osVersion??"-"],highlight:r.status==="running"}}async function ZM(r,e){let t=await Promise.all(e.map(async n=>{let i=await Zi(r,n,VM);return[n,i]}));return new Map(t)}async function QM(r){let e=await Em(r),t=await ZM(r,e);return{serials:e,params:t}}function eL(r,e,t,n,i){if(e)for(let o of["const.product.name","const.product.model"]){let s=e.get(o);if(!s)continue;let a=t.indexOf(s);if(a===-1)continue;t.splice(a,1),i.set(s,r);let c=n.indexOf(r);c!==-1&&n.splice(c,1);return}}function tL(r,e,t){let n=new Map,i=new Map,o=[...r],s=[...t];for(let a of r){let c=e.get(a),l=c?.get("ohos.qemu.hvd.name");l&&i.set(l,a),t.length>0&&eL(a,c,s,o,n)}for(let a=0;a<s.length&&a<o.length;a++)n.set(s[a],o[a]);return{productSerialMap:n,hvdSerialMap:i}}function rL(r,e,t){let n=r.map(i=>({emu:i,serial:e.get(i.name)??t.get(i.name),effectiveRunning:i.isRunning===!0||t.has(i.name)}));return n.sort((i,o)=>i.effectiveRunning!==o.effectiveRunning?i.effectiveRunning?-1:1:i.emu.name.localeCompare(o.emu.name)),n.map(({emu:i,serial:o,effectiveRunning:s})=>({name:i.name,status:s?"running":"stopped",serial:o??null,deviceType:i.deviceType??null,osVersion:i.osVersion??null}))}async function nL(r,e,t,n){try{let[i,o]=await Promise.all([r.listEmulators(),QM(e)]);if(i.length===0){n?.stop(),console.log(t==="json"?"[]":vn(" No emulator instances found."));return}let s=i.filter(g=>g.isRunning).map(g=>g.name),{productSerialMap:a,hvdSerialMap:c}=tL(o.serials,o.params,s);n?.stop();let l=rL(i,a,c);if(t==="json"){console.log(JSON.stringify(l,null,2));return}let d=l.map(XM);console.log(jr(KM,d))}catch(i){throw n?.stop(),new Error(`Failed to list emulators: ${i.message}`,{cause:i})}}function wS(r,e,t){let n=!1;for(let i=0;i<r.length;i++){let o=r[i];if(o.status!=="rejected")continue;n=!0;let s=o.reason;console.error(Pf(`Failed to ${t} emulator "${e[i]}": ${s.message}`)),s.stdout&&console.error(bf(s.stdout)),s.stderr&&console.error(bf(s.stderr))}return n}var iL=2e3,oL=6e4;async function sL(r,e){let t=Fe(e);return(await Pm(r)).some(i=>Fe(i)===t)}async function vS(r,e,t,n=oL,i=iL){let o=Date.now()+n;for(;Date.now()<o;){if(await sL(r,e)===t)return!0;await new Promise(a=>setTimeout(a,i))}return!1}function aL(r){if(!r)return null;let e=r.indexOf("-bootmode");return e>=0&&e+1<r.length&&r[e+1]==="snapshot"}async function cL(r,e,t,n){let i=await r.startEmulator(t,n);if(i.status==="already-running")return console.log(vn(`Emulator "${t}" is already running.`)),{started:!1,memoryBytes:0,hotBoot:null};console.log(ko(`Starting emulator "${t}"...`));let o=i.tracker,s=0,a=aL(i.args);try{let c=await vS(e,t,!0);console.log(c?aa(`Emulator "${t}" started successfully.`):vn(`Emulator "${t}" was launched but did not appear in hdc list targets within the timeout.`))}finally{if(o)try{s=await o.stop()}catch{}}return{started:!0,memoryBytes:s,hotBoot:a}}async function lL(r,e,t,n){let i=await Promise.allSettled(t.map(a=>cL(r,e,a,n)));if(wS(i,t,"start"))throw new w("One or more emulators failed to start.");let o=i.filter(a=>a.status==="fulfilled").map(a=>a.value).filter(a=>a.started);return{emulatorMemory:o.length===0||o.some(a=>a.memoryBytes===0)?"unknown":ae(o.reduce((a,c)=>a+c.memoryBytes,0)),hotBoot:o.length===0?null:o.every(a=>a.hotBoot===!0)}}async function bS(r,e){let t=e.trim();if(!dr(t))return t;let n=await ce.withHdcPath(r).getDeviceName(t);if(n===t)throw new Error(`Cannot resolve a running emulator with serial "${t}". Use \`devecocli emulator list\` or pass the emulator name instead.`);return n}async function dL(r,e,t){let n=await bS(e,t);if(console.log(ko(`Stopping emulator "${n}"...`)),await r.stopEmulator(n)==="already-stopped"){console.log(vn(`Emulator "${n}" is already stopped.`));return}let o=await vS(e,n,!1);console.log(o?aa(`Emulator "${n}" stopped successfully.`):vn(`Emulator "${n}" stop signal was sent but the instance is still visible in hdc list targets within the waiting period.`))}async function uL(r,e,t){let n=await Promise.allSettled(t.map(i=>dL(r,e,i)));wS(n,t,"stop")}async function It(){let r=await C.new();return{manager:go.from(r),toolProvider:r}}async function Wr(r,e,t){let n={event:v.CommandExecuted,args:["emulator",t,"--target"]};await At(n,async()=>{let i=zM(r.target),o=e(),s=Array.isArray(o)?o:[o],{manager:a,toolProvider:c}=await It(),l=await bS(c.hdcPath,i);for(let d of s)await a.controlEmulator(l,d);console.log(aa(`Emulator "${i}" operation completed.`))})}function pL(r){let e=[];if(Kl(e,"longitude",r.longitude,-180,180,8),Kl(e,"latitude",r.latitude,-90,90,8),Kl(e,"altitude",r.altitude,-1e4,1e4,2),Kl(e,"bearing",r.direction,0,359.99,2,"--direction"),e.length===0)throw new Error("Specify at least one geolocation option.");return(r.longitude===void 0||r.latitude===void 0)&&console.warn(vn("Warning: --longitude and --latitude should be specified together to form a valid location.")),e}function mL(r){let e=[];if(oa(e,"light",r.lightIntensity,0,1e5,!1,"--light-intensity"),oa(e,"humidity",r.humidity,0,100,!1),oa(e,"temperature",r.temperature,-273.1,100,!1),oa(e,"steps",r.steps,0,1e4,!0),oa(e,"heartrate",r.heartrate,0,255,!0),e.length===0)throw new Error("Specify at least one sensor option.");return e}function Kl(r,e,t,n,i,o,s=`--${e}`){t!==void 0&&r.push({type:"gps",key:e,value:yS(s,t,n,i,o)})}function oa(r,e,t,n,i,o,s=`--${e}`){if(t===void 0)return;let a=o?hS(s,t,n,i):hi(s,t,n,i,1);r.push({type:"sensor",key:e,value:a})}function fL(r){let e=[];if(r.status!==void 0){let i=r.status==="charging"?1:0;e.push({type:"battery-status",status:i})}if(r.level!==void 0&&e.push({type:"battery",level:hS("--level",r.level,0,100),assumedCharging:r.status==="charging"}),e.length===0)throw new Error("Specify --level or --status.");let t=e.some(i=>i.type==="battery"&&i.level===0),n=e.some(i=>i.type==="battery-status"&&i.status===0);if(t&&n)throw new Error("Battery level 0 is only allowed while charging; --level 0 cannot be combined with --status discharging.");return e}var Se=new Ef("emulator").description("Manage emulator instances");Se.configureOutput({outputError:(r,e)=>{e(r),/too many arguments/i.test(r)&&e(`
1309
- ${vn("Tip: ")}${bf("An option value containing spaces/parentheses must be quoted. Use:")}
1310
- ${ko('devecocli emulator <subcommand> --<option> "value with spaces"')}
1311
- ${ko('devecocli emulator <subcommand> --<option>="value with spaces"')}
1312
- `)}});Se.hook("preAction",async()=>{(await C.new()).require({studio:qM})});var gL=["phone","foldable","widefold","triplefold","tablet","2in1","2in1 foldable","wearable","tv"];function Cf(r){let e=new ze("--device-type <type>","Emulator device type").choices([...gL]);return r?e.makeOptionMandatory():e}function hL(){return new ze("--device-type <type>","Emulator device type (case-insensitive)").argParser(r=>{if(!r.trim())throw new vf("--device-type must not be empty.");return r}).makeOptionMandatory()}function yL(r){if(r!==void 0){if(r.length>=4&&r.length%4===0&&r.every(e=>/^\d+(?:\.\d+)?$/.test(e)))throw new Error('--screen value must be quoted: --screen "1316 2832 560 6.9".');if(r.length>2)throw new Error("--screen accepts one or two configurations.");for(let[e,t]of r.entries()){let n=t.trim().split(/\s+/),i=r.length===1?"--screen":`--screen configuration ${e+1}`;if(n.length!==4||n.some(o=>o.length===0))throw new Error(`${i} must contain four values: width(px), height(px), DPI, and screen diagonal length(inch).`);hi(`${i} width`,n[0],720,3500),hi(`${i} height`,n[1],720,3500),hi(`${i} DPI`,n[2],240,640),hi(`${i} screen diagonal length`,n[3],3.5,9)}return r}}function wL(r){return["--device-type","--os-version",...r.instancePath!==void 0?["--instance-path"]:[],...r.imageRoot!==void 0?["--image-root"]:[],...r.screenProfile!==void 0?["--screen-profile"]:[],...r.screen!==void 0?["--screen"]:[],...r.storage!==void 0?["--storage"]:[],...r.memory!==void 0?["--memory"]:[],...r.hotBoot!==void 0?["--hot-boot"]:[],...r.force?["--force"]:[]]}function Co(r,e){for(let t of e)if(t in r)return r[t]}function sa(r){return r==null?"":typeof r=="string"?r.trim():String(r).trim()}function gS(r){let e=sa(r).toLowerCase();return e==="true"?"true":e==="false"?"false":e}var vL=["OS Version","Device Type","Software Version","Release Type","Upgradable","Downloaded"],bL="No matching system images found. Try `devecocli emulator image list --all`, then download an image via `devecocli emulator image download ...`.";async function SL(r,e,t){if(!await r.hasAvailableEmulatorImage({deviceType:e,osVersion:t}))throw new Error(`Invalid --os-version value "${t}".
1313
- Run \`devecocli emulator image list --all\` and use an exact OS Version value.`)}function SS(r){try{let e=JSON.parse(r);return Array.isArray(e)?e:null}catch{return null}}function ES(r,e){let t=[];for(let n of r){if(!n||typeof n!="object")continue;let i=n,o=sa(Co(i,["osVersion","OsVersion","OSVersion","os_version"])),s=sa(Co(i,["deviceType","DeviceType","device_type"])),a=gS(Co(i,["downloaded","Downloaded","isDownloaded"])),c=sa(Co(i,["SoftWareVersion","SoftwareVersion","softwareVersion","software_version","version"])),l=sa(Co(i,["releaseType","ReleaseType","release_type"])),d=gS(Co(i,["upgradable","Upgradable","isUpgradable"]));t.push({cells:[o,s,c,l,d,a],highlight:e&&a==="true"})}return t}function EL(r){let e=r.trim();if(!e)return!0;let t=SS(e);return t===null?!1:t.length===0?!0:ES(t,!0).length===0}function PL(r,e){let t=r.trim();if(!t)return"";let n=SS(t);if(!n)return r.trimEnd();let i=ES(n,e);return jr(vL,i)}var Xl=new Ef("image").description("HarmonyOS emulator system images (download, list, remove)");Xl.command("download").description("Download system image").addOption(Cf(!1)).option("--os-version <version>","Example: HarmonyOS 5.1.1(19) or HarmonyOS 6.0.1(21) (required)").option("--force","Overwrite an existing image").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","download",...r.deviceType?["--device-type"]:[],...r.osVersion?["--os-version"]:[],...r.force?["--force"]:[]]};await At(e,async()=>{let{manager:t,toolProvider:n}=await It();await wf(n.emulatorPath,n.sdkPath);let i=r.deviceType?.trim(),o=r.osVersion?.trim();if(!i)throw new w("Error: missing required option '--device-type <type>'","Missing required device type.");if(!o)throw new w("Error: misssing required option '--os-version <version>'","Missing required OS version.");await SL(t,i,o),await t.installEmulatorImage({deviceType:i,osVersion:o,force:r.force===!0})})});Xl.command("remove").description("Remove a downloaded system image").addOption(Cf(!0)).requiredOption("--os-version <version>","Supports both image label (HarmonyOS x.y.z(n)) and softwareVersion").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","remove","--device-type","--os-version"]};await At(e,async()=>{let{manager:t}=await It();await t.uninstallEmulatorImage({deviceType:r.deviceType,osVersion:r.osVersion})})});Xl.command("list").description("List system images").addOption(Cf(!1)).option("--all","List all images (local and remote)").addOption(new ze("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","list",...r.deviceType?["--device-type"]:[],...r.all?["--all"]:[],...r.format!=="table"?["--format"]:[]]};await At(e,async()=>{let{manager:t}=await It(),n;r.all?n=void 0:n=!0;let i=await t.listEmulatorImages({deviceType:r.deviceType,downloaded:n});if(EL(i)){console.log(vn(bL));return}if(r.format==="json"){console.log(i.trimEnd());return}let o=PL(i,r.all===!0);console.log(o)})});Se.addCommand(Xl);var Zl=new Ef("license").description("Review and accept emulator license agreements interactively (prints full text + y/N prompt)");Zl.command("view").description("Review agreement text (read-only, no changes)").action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license","view"]};await At(r,async()=>{let{toolProvider:e}=await It(),t=await dS(e.emulatorPath,e.sdkPath);process.exitCode=t})});Zl.command("accept").description("Accept all emulator license agreements non-interactively (skips review and prompt)").action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license","accept"]};await At(r,async()=>{let{toolProvider:e}=await It(),t=await mS(e.emulatorPath,e.sdkPath);process.exitCode=t})});Zl.action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license"]};await At(r,async()=>{let{toolProvider:e}=await It(),t=await pS(e.emulatorPath,e.sdkPath);process.exitCode=t})});Se.addCommand(Zl);Se.command("shake").description("Trigger shake event").requiredOption("--target <nameOrSerial>","Target emulator name or serial").action(r=>Wr(r,()=>({type:"shake"}),"shake"));Se.command("power").description("Press power button (toggle screen on/off)").requiredOption("--target <nameOrSerial>","Target emulator name or serial").action(r=>Wr(r,()=>({type:"power"}),"power"));Se.command("rotate").description("Rotate emulator").addOption(new ze("--target <nameOrSerial>","Target emulator name or serial").makeOptionMandatory()).addArgument(new Sf("<direction>").choices(["left","right"])).action((r,e)=>Wr(e,()=>({type:"rotation",direction:r}),"rotate"));Se.command("volume").description("Change volume").addOption(new ze("--target <nameOrSerial>","Target emulator name or serial").makeOptionMandatory()).addArgument(new Sf("<direction>").choices(["up","down"])).action((r,e)=>Wr(e,()=>({type:"volume",direction:r}),"volume"));Se.command("fold <state>").description("Set foldable display state").requiredOption("--target <nameOrSerial>","Target emulator name or serial").addHelpText("after",GM).action((r,e)=>Wr(e,()=>({type:"folded-state",state:JM(r)}),"fold"));Se.command("battery").description("Set battery level and/or charging status").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--level <0-100>","Battery level, SOC (charging: 0-100; not charging: 1-100)").addOption(new ze("--status <status>","Charging status").choices(["charging","discharging"])).action(r=>Wr(r,()=>fL(r),"battery"));Se.command("geolocation").description("Inject geographic coordinates and direction").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--longitude <value>","Longitude (-180.0 to 180.0)").option("--latitude <value>","Latitude (-90.0 to 90.0)").option("--altitude <value>","Altitude (-10000.0 to 10000.0)").option("--direction <value>","Heading direction in degrees (0.00 to 359.99)").action(r=>Wr(r,()=>pL(r),"geolocation"));Se.command("scene").description("Start motion simulation scene").requiredOption("--target <nameOrSerial>","Target emulator name or serial").addArgument(new Sf("<type>","Motion simulation scene").choices(["outdoorRunning","outdoorCycling","drivingNavigation"])).action((r,e)=>{let t={outdoorRunning:{type:"outdoor-running"},outdoorCycling:{type:"outdoor-cycling"},drivingNavigation:{type:"driving-navigation"}};return Wr(e,()=>t[r],"scene")});Se.command("sensor").description("Inject sensor data").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--light-intensity <value>","Light sensor (0 to 100000)").option("--humidity <value>","Humidity sensor (0 to 100)").option("--temperature <value>","Temperature sensor (-273.1 to 100)").option("--steps <value>","Steps sensor (integer 0 to 10000)").option("--heartrate <value>","Heart rate sensor (integer 0 to 255)").action(r=>Wr(r,()=>mL(r),"sensor"));Se.command("list").description("List all emulator instances").addOption(new ze("--details","Output the raw JSON of `Emulator -list -details` without transformation").conflicts("format")).addOption(new ze("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["emulator","list",...r.details?["--details"]:[],...r.format!=="table"?["--format"]:[]]};await At(e,async()=>{let{manager:t,toolProvider:n}=await It();if(r.details){let o=await t.listEmulatorDetails();console.log(o.trimEnd());return}let i=r.format==="table"?WM({text:"Listing emulators\u2026",color:"cyan"}).start():void 0;await nL(t,n.hdcPath,r.format,i)})});function CL(r){let e=r.trim();if(!/^\d+$/.test(e))throw new vf("--hdcport must be an integer in [10000, 16555].");let t=Number(e);if(t<1e4||t>16555)throw new vf("--hdcport must be in [10000, 16555].");return t}function kL(r){return{hdcPort:r.hdcport,bootMode:r.bootMode,noWindow:r.window===!1}}function DL(r){return[...r.hdcport!==void 0?["--hdcport"]:[],...r.bootMode!==void 0?["--boot-mode"]:[],...r.window===!1?["--no-window"]:[]]}Se.command("start [names...]").description("Start one or more emulator instances").addOption(new ze("--hdcport <port>","hdc port of the emulator, 10000-16555 (Emulator -hdcport)").argParser(CL)).addOption(new ze("--boot-mode <mode>","Boot mode (Emulator -bootMode): coldboot = cold start keeping user data, snapshot = hot start restoring the last snapshot (needs Quick Boot), reset = wipe data then cold start; overrides the mode chosen when the instance was created").choices(["coldboot","snapshot","reset"])).addOption(new ze("--no-window","Start the emulator without a window (Emulator -noWindow); required on Linux hosts without a GUI")).action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","start",...DL(e)],emulatorMemory:"unknown",hotBoot:null};await At(t,async()=>{let{manager:n,toolProvider:i}=await It();if(await yf(i.emulatorPath,i.sdkPath),!r?.length)throw new w("Error: missing required argument 'names'","Missing required emulator name.");if(r.length>1&&e.hdcport!==void 0)throw new w(`Error: --hdcport cannot target ${r.length} emulators.`,"--hdcport sets the hdc port of a single emulator; pass one name, or omit --hdcport.");let o=await lL(n,i.hdcPath,r,kL(e));t.emulatorMemory=o.emulatorMemory,t.hotBoot=o.hotBoot})});Se.command("stop <names...>").description("Stop one or more emulator instances (by name or serial,e.g.,127.0.0.1:<port>)").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","stop"]};await At(e,async()=>{let{manager:t,toolProvider:n}=await It();if(!r?.length){console.error(Pf("Error: missing required argument 'names'")),process.exitCode=1;return}await uL(t,n.hdcPath,r)})});var RL=Se.command("create <name>").description("Create a local emulator instance.").addOption(hL()).requiredOption("--os-version <version>",'Downloaded image label. which will be quoted in PowerShell (e.g. "HarmonyOS 6.0.1(21)") or be used in the format --os-version="\u2026";For details, run`devecocli emulator image list`').addOption(new ze("--path, --instance-path <path>","Emulator instance path")).option("--image-root <path>","Emulator image path").option("--screen-profile <model>","Emulator screen profile").addOption(new ze("--screen <config...>",'Screen: "width(px) height(px) DPI screen-diagonal-length(inch)" (720-3500, 720-3500, 240-640, 3.5-9); pass two values for a foldable device')).option("--storage <size>","Storage size in GB (2-1023)").option("--memory <size>","Memory size in GB (2-32)").addOption(new ze("--hot-boot <boolean>","Enable or disable hot boot").choices(["true","false"])).option("--force","Overwrite an existing emulator instance");RL.action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","create",...wL(e)]};await At(t,async()=>{if(!e.osVersion.trim())throw new Error("--os-version must not be empty.");let n={name:r,deviceType:e.deviceType,osVersion:e.osVersion,instancePath:e.instancePath,imageRoot:e.imageRoot,screenProfile:e.screenProfile,screen:yL(e.screen),storage:e.storage===void 0?void 0:hi("--storage",e.storage,2,1023),memory:e.memory===void 0?void 0:hi("--memory",e.memory,2,32),hotBoot:e.hotBoot===void 0?void 0:e.hotBoot==="true",force:e.force===!0},{manager:i}=await It();console.log(ko(`Creating emulator "${r}"...`)),await i.createVirtualDevice(n),console.log(aa(`Emulator "${r}" created successfully.`))})});Se.command("delete <name>").description("Delete a local emulator instance").addOption(new ze("--path, --instance-path <path>","Emulator instance path")).action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","delete",...e.instancePath!==void 0?["--instance-path"]:[]]};await At(t,async()=>{let{manager:n}=await It();console.log(ko(`Deleting emulator "${r}"...`));let i=await n.deleteVirtualDevice(r,e.instancePath);console.log(aa(`Emulator "${i}" deleted successfully.`))})});var PS=Se;import{Command as VL}from"commander";import{red as Of,cyan as Yt}from"colorette";import*as GS from"readline";import*as WS from"crypto";import*as CS from"http";import*as kS from"crypto";import{URL as xL}from"url";var Ql=class{server=null;port=0;clientSecret;callbackPath="/callback";resolveCallback=null;rejectCallback=null;timeoutId=null;baseUrl;successRedirectUrl;failedRedirectUrl;constructor(e,t,n,i){this.clientSecret=e,this.baseUrl=t,this.successRedirectUrl=n,this.failedRedirectUrl=i}async start(){return new Promise((e,t)=>{let n=CS.createServer((i,o)=>{this.handleRequest(i,o)});n.keepAliveTimeout=1,n.on("error",i=>{t(new Error("Failed to start local auth server",{cause:i}))}),n.listen(0,"127.0.0.1",()=>{this.server=n;let i=n.address();this.port=i.port,e()})})}async waitForCallback(e=3e4){return new Promise((t,n)=>{this.resolveCallback=i=>{this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),t(i)},this.rejectCallback=i=>{this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),n(i)},this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.rejectCallback?.(new Error("Callback timeout"))},e)})}async stop(){return this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),this.server?new Promise(e=>{let t=this.server;this.server=null,typeof t.closeAllConnections=="function"&&t.closeAllConnections();let n=setTimeout(()=>{e()},100);t.close(()=>{clearTimeout(n),e()})}):Promise.resolve()}handleRequest(e,t){let n=e.headers.host||"";if(![`127.0.0.1:${this.port}`,`localhost:${this.port}`].includes(n.toLowerCase())){t.writeHead(400),t.end("Bad Host");return}let o=new xL(e.url??"",`http://${n}`);if(o.pathname!==this.callbackPath){t.writeHead(404),t.end("Not Found");return}try{let s=o.searchParams;e.method==="POST"?this.readBody(e,t,s):this.handleCallbackRequest(e,t,s,"")}catch(s){t.writeHead(500),t.end("Internal Server Error"),this.rejectCallback?.(s)}}readBody(e,t,n){let i="",o=0,s=65536;e.on("data",a=>{if(o+=a.length,o>s){e.destroy(new Error("Request body too large"));return}i+=a.toString()}),e.on("end",()=>{this.handleCallbackRequest(e,t,n,i)})}handleCallbackRequest(e,t,n,i){try{let o=this.parseParams(n,i),s=o.get("code"),a=o.get("tempToken"),c=o.get("siteId"),l=o.get("quit");if(!this.validateCode(s)){t.writeHead(400),t.end("Bad Request");return}if(this.isQuitRequest(l)){this.handleQuitRequest(t);return}if(!a||!c){t.writeHead(400),t.end("Bad Request");return}let d={tempToken:a,siteId:c,quit:l??void 0};this.resolveCallback?.(d),this.sendSuccessResponse(t)}catch(o){t.writeHead(500),t.end("Internal Server Error"),this.rejectCallback?.(o)}}parseParams(e,t){return t&&t.trim()?new URLSearchParams(t):e}validateCode(e){let t=Buffer.from(e||"","utf8"),n=Buffer.from(this.clientSecret,"utf8");return t.length===n.length&&kS.timingSafeEqual(t,n)}isQuitRequest(e){return e==="true"||e==="access_denied"||e==="quit"}handleQuitRequest(e){this.rejectCallback?.(new Error("User quit the login process")),e.writeHead(302,{Location:`${this.baseUrl}/${this.failedRedirectUrl}`}),e.end()}sendSuccessResponse(e){e.writeHead(302,{Location:`${this.baseUrl}/${this.successRedirectUrl}`}),e.end()}getPort(){return this.port}};import*as at from"fs";import*as bn from"path";import{homedir as OL}from"os";var Vr={};yk(Vr,{LocalCrypto:()=>Vr,decryptForLocalStorage:()=>xf,decryptForLocalStorageFromDirectory:()=>TL,encryptForLocalStorage:()=>Rf,isEncryptedBlob:()=>Af});import*as ue from"fs";import*as Ye from"path";import*as st from"crypto";import*as RS from"os";import{homedir as xS}from"os";var Je=class extends Error{constructor(e){super(e),this.name="DefinedError"}};var ca=Vn.ALGORITHM,AS=Vn.IV_LENGTH,la=Vn.KEY_LENGTH,da=Vn.KEY_LENGTH,yi=Vn.KEK_VERSIONS,ed=process.env.DEVECO_CLI_DATA_DIR?$():Ye.join(xS(),be.CONFIG_DIR_NAME,be.APP_NAME),td=Ye.join(xS(),".local","share",be.APP_NAME,"keys"),Do=Ye.join(ed,be.KEY_FILE_NAME);function DS(r){return RS.platform()==="win32"?`Permission denied. Please run as administrator or grant write permission to ${r}.`:`Permission denied. You can try: sudo chown -R $(whoami) ${r}`}function kf(r){return Ye.join(td,`${r}.bin`)}function IS(){if(!ue.existsSync(ed))try{ue.mkdirSync(ed,{recursive:!0,mode:448})}catch(r){throw r.code==="EACCES"?new Je(DS(ed)):r}if(!ue.existsSync(td))try{ue.mkdirSync(td,{recursive:!0,mode:448})}catch(r){throw r.code==="EACCES"?new Je(DS(Ye.dirname(td))):r}}function TS(){IS();for(let r of yi){let e=kf(r);ue.existsSync(e)||ue.writeFileSync(e,st.randomBytes(la),{mode:384})}}function OS(r){if(!yi.includes(r))throw new Error(`Invalid kekId: ${r}`);TS();let e=kf(r),t=ue.readFileSync(e);if(t.length===la)return t;let n=st.randomBytes(la);return ue.writeFileSync(e,n,{mode:384}),n}function Df(r,e){let t=st.randomBytes(AS),n=OS(e),i=st.createCipheriv(ca,n,t),o=Buffer.concat([i.update(r),i.final()]),s=i.getAuthTag();return{version:1,algorithm:ca,kekId:e,encryptedDek:o.toString("base64"),iv:t.toString("base64"),authTag:s.toString("base64"),timeStamp:Date.now()}}function NS(r,e){return MS(Buffer.from(r.encryptedDek,"base64"),e,r.iv,r.authTag)}function MS(r,e,t,n){let i=st.createDecipheriv(ca,e,Buffer.from(t,"base64"));return i.setAuthTag(Buffer.from(n,"base64")),Buffer.concat([i.update(r),i.final()])}function LS(r,e){return MS(Buffer.from(r.ciphertext,"base64"),e,r.iv,r.authTag).toString("utf8")}function AL(){if(TS(),ue.existsSync(Do))return;let r=st.randomBytes(da),e=Df(r,yi[0]);ue.writeFileSync(Do,JSON.stringify(e,null,2),{mode:384})}function _S(){AL();let r=JSON.parse(ue.readFileSync(Do,"utf8")),e=NS(r,OS(r.kekId));if(e.length===da)return e;let t=st.randomBytes(da),n=Df(t,yi[0]);return ue.writeFileSync(Do,JSON.stringify(n,null,2),{mode:384}),t}function IL(){IS();for(let t of yi){let n=kf(t);ue.existsSync(n)||ue.writeFileSync(n,st.randomBytes(la),{mode:384})}if(ue.existsSync(Do))return;let r=st.randomBytes(da),e=Df(r,yi[0]);ue.writeFileSync(Do,JSON.stringify(e,null,2),{mode:384})}function Rf(r){let e=_S(),t=st.randomBytes(AS),n=st.createCipheriv(ca,e,t),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o=n.getAuthTag();return{version:1,algorithm:ca,ciphertext:i.toString("base64"),iv:t.toString("base64"),authTag:o.toString("base64"),timeStamp:Date.now()}}function xf(r){try{return LS(r,_S())}catch{throw IL(),new Error("Failed to decrypt local ciphertext")}}function TL(r,e){let t=Ye.join(e,be.KEY_FILE_NAME),n=JSON.parse(ue.readFileSync(t,"utf8"));if(!yi.includes(n.kekId))throw new Error(`Invalid kekId: ${n.kekId}`);let i=Ye.join(e,"keys",`${n.kekId}.bin`),o=Ye.resolve(i),s=Ye.resolve(Ye.join(e,"keys"));if(!o.startsWith(s+Ye.sep)&&o!==s)throw new Error("kekId resolves outside the keys directory");let a=ue.readFileSync(o);if(a.length!==la)throw new Error("Invalid external root key");let c=NS(n,a);if(c.length!==da)throw new Error("Invalid external data encryption key");return LS(r,c)}function Af(r){if(!r||typeof r!="object")return!1;let e=r;return e.algorithm==="aes-256-gcm"&&typeof e.ciphertext=="string"&&typeof e.iv=="string"&&typeof e.authTag=="string"}function wt(){return process.env.DEVECO_CLI_AUTH_SOURCE===be.AUTH_SOURCE_DEVECO_CODE}var rd=class{getLocalTokenFilePath(){let e=process.env.DEVECO_CLI_DATA_DIR?$():bn.join(OL(),be.CONFIG_DIR_NAME,be.APP_NAME);return bn.join(e,be.TOKEN_FILE_NAME)}ensureConfigDir(){let e=bn.dirname(this.getLocalTokenFilePath());at.existsSync(e)||at.mkdirSync(e,{recursive:!0,mode:448})}async saveJwtToken(e){if(!e)throw new Error("Token is empty");let t=Vr.encryptForLocalStorage(e);this.ensureConfigDir();let n=this.getLocalTokenFilePath();at.writeFileSync(n,JSON.stringify(t,null,2),{mode:384})}async loadJwtToken(){return wt()?this.loadDevecoCodeToken():this.loadLocalJwtToken()}loadDevecoCodeToken(){if(!wt())return null;let e=process.env.DEVECO_CODE_AUTH_DIR?.trim();if(!e)return null;let t=bn.resolve(e);try{let n=bn.join(t,be.TOKEN_FILE_NAME);if(!at.existsSync(n))return null;let i=JSON.parse(at.readFileSync(n,"utf8"));return Vr.isEncryptedBlob(i)?Vr.decryptForLocalStorageFromDirectory(i,e):null}catch{return null}}async loadLocalJwtToken(){let e=this.getLocalTokenFilePath();try{if(!at.existsSync(e))return null;let t=JSON.parse(at.readFileSync(e,"utf8"));return Vr.isEncryptedBlob(t)?Vr.decryptForLocalStorage(t):null}catch(t){let n=t.code;return n==="EACCES"||n==="EPERM"||n==="ENOENT"||await this.clearToken(),null}}async clearToken(){if(wt()){m("clearToken: skipped, session managed by DevEco Code");return}let e=this.getLocalTokenFilePath();try{at.existsSync(e)&&at.unlinkSync(e)}catch(t){throw new Error("Failed to clear token",{cause:t})}}},Gr=new rd;import{spawn as NL}from"child_process";function ML(r){try{let e=new URL(r);return!(!["http:","https:"].includes(e.protocol)||e.hostname===""||r.includes('"'))}catch{return!1}}function LL(r){return r.replace(/[&|<>()^%!]/g,e=>`^${e}`)}async function $S(r){if(!ML(r))throw new Error(`Invalid URL: ${JSON.stringify(r)}`);let e,t;switch(process.platform){case"win32":e="cmd",t=["/c","start",'""',LL(r)];break;case"darwin":e="open",t=[r];break;default:e="xdg-open",t=[r];break}let n=NL(e,t,{stdio:"ignore",shell:!1,windowsHide:!0});return new Promise((i,o)=>{n.on("error",s=>{o(new Error("Failed to open browser",{cause:s}))}),n.on("close",s=>{s===0?i():o(new Error(`Browser process exited with code ${s}`))})})}function FS(r){let e=r.split(".");return e.length===3&&e.every(t=>t.length>0)}var qr={CHINA:"CN",RUSSIA:"RU",SINGAPORE:"SG",EUROPE:"EU"},wi={CHINA:"zh_CN",RUSSIA:"ru_RU",EUROPE:"de_DE"},nd={CHINA:"1",SINGAPORE:"5",EUROPE:"7",RUSSIA:"8"},_L={[qr.CHINA]:wi.CHINA,[qr.RUSSIA]:wi.RUSSIA,[qr.EUROPE]:wi.EUROPE,[qr.SINGAPORE]:wi.CHINA},$L={[nd.CHINA]:qr.CHINA,[nd.SINGAPORE]:qr.SINGAPORE,[nd.EUROPE]:qr.EUROPE,[nd.RUSSIA]:qr.RUSSIA};function jS(r){return _L[r]??wi.CHINA}function HS(r){return $L[r]??qr.CHINA}var If=class{async getJwtToken(e,t,n,i,o){let s=e.split("&")[0],a=HS(t),c={tempToken:s,site:a,version:be.API_VERSION,appid:o},l=`${n}/${i}`,d=await F.get(l,{params:c});if(d.statusCode!==200)throw new Error(`Failed to get jwtToken: status=${d.statusCode}`);let g=d.data.trim();if(!FS(g))throw new Error("Invalid jwtToken format");return g}},US=new If;var Tf=class{async checkJwtToken(e,t,n=!1){let i={refresh:String(n),jwtToken:e},o=`${t}/${oe.JWT_TOKEN_CHECK_PATH}`,s=await F.get(o,{headers:i});if(s.statusCode!==200)throw new Error(`Failed to check jwtToken: ${s.statusCode}`);return F.parseJson(s)}async refreshToken(e){let t=await Gr.loadJwtToken();return t?this.refreshTokenWithToken(t,e):null}async refreshTokenWithToken(e,t){try{let n={refresh:"true",jwtToken:e},i=`${t}/${oe.JWT_TOKEN_CHECK_PATH}`,o=await F.get(i,{headers:n});if(o.statusCode!==200)return null;let s=F.parseJson(o);return!s.status||!s.userInfo?null:{accessToken:s.userInfo.accessToken,refreshToken:s.userInfo.refreshToken??""}}catch(n){let i=n;return console.error(`Failed to refresh token: ${i.code??""} ${i.message??""}`),null}}async getUserInfoFromJwt(e,t,n=!1){let i=await this.checkJwtToken(e,t,n);return!i.status||!i.userInfo||!i.userInfo.accessToken?(m("jwtToken invalid."),await Gr.clearToken(),null):{userId:i.userInfo.userId??"",userName:i.userInfo.name??"",accessToken:i.userInfo.accessToken,refreshToken:i.userInfo.refreshToken??"",jwtToken:e,countryCode:i.userInfo.nationalCode,language:jS(i.userInfo.nationalCode),isRealName:String(i.userInfo.realName)==="true"}}async fetchUserInfo(e,t){let n=await Gr.loadJwtToken();return n?this.getUserInfoFromJwt(n,e,t):null}},Ro=new Tf;import FL from"querystring";import{spawn as jL}from"child_process";function BS(r){try{let e=JSON.stringify({signInfo:[{agrType:ts.PRIVACY_ID,country:"CN",language:"zh_CN",isAgree:!0}]}),t=FL.stringify({nsp_svc:"as.user.sign",access_token:r,request:e}),n=jL("curl",["-s","-X","POST",ts.TMS_URL,"-H","Content-Type: application/x-www-form-urlencoded","-d",t,"--max-time","5","-o","/dev/null","-w","%{http_code}"],{detached:!0,stdio:["ignore","pipe","ignore"]});n.unref(),n.stdout?.on("data",i=>{let o=i.toString().trim();o==="200"?m("Agreement sign reported successfully"):m(`Agreement sign failed: HTTP ${o}`)}).on("error",()=>{})}catch(e){m(`Agreement sign error: ${e.message}`)}}var id=class{config;server=null;constructor(e){this.config={...rs,...e}}updateConfig(e){this.config={...this.config,...e}}getConfig(){return{...this.config}}async login(){try{m(`Login started, isDevecoCodeAuth: ${wt()}`);let e=this.generateClientSecret();this.server=new Ql(e,oe.CN_LOGIN_URL,this.config.successRedirectUrl,this.config.failedRedirectUrl),await this.server.start(),m(`Local auth server started on port ${this.server.getPort()}`),await this.openLoginPage(this.server.getPort(),e),m("Browser opened for authentication");let t=await this.server.waitForCallback(this.config.timeout);if(m(`Callback received: siteId=${t.siteId}`),t.siteId!=="1")throw new Je("Non-China accounts are not supported.");let n=await US.getJwtToken(t.tempToken,t.siteId,oe.CN_LOGIN_URL,this.config.tempTokenCheckUrl,this.config.appId);m("JWT token received");let i=await Ro.getUserInfoFromJwt(n,oe.CN_LOGIN_URL);if(!i)throw new Je("Login failed: failed to get user info");return m(`User info received: ${i.userName}`),await Gr.saveJwtToken(n),m("JWT token saved"),BS(i.accessToken),i}finally{this.server&&(await this.server.stop(),this.server=null)}}async isLoggedIn(){return await this.getUserInfo(!0)!==null}async logout(){let e=await Gr.loadJwtToken();if(!e)return!1;let n=`${oe.CN_LOGIN_URL}/${this.config.logoutUrl}?jwtToken=${e}`;try{await F.post(n,{timeout:5e3})}catch{m("Logout: server notification failed, local token cleared")}finally{await Gr.clearToken()}return!0}async getUserInfo(e=!0){return Ro.fetchUserInfo(oe.CN_LOGIN_URL,e)}generateClientSecret(){return WS.randomUUID().replace(/-/g,"")}async openLoginPage(e,t){let i=`${oe.CN_LOGIN_URL}/${this.config.authUrl}?port=${e}&appid=${this.config.appId}&code=${t}`;await $S(i)}async refreshToken(){return Ro.refreshToken(oe.CN_LOGIN_URL)}},Ke=new id;function UL(){return wt()?"Not logged in. Please login via DevEco Code first.":"Please run `devecocli auth login` first."}function BL(r){if(r.length===0)return"";let e=Math.max(1,Math.floor(r.length/2));return`${r.slice(0,e)}****`}function WL(r){if(r==null||typeof r!="object")return[];let e=r;if(e.ret&&e.ret.code!==0)throw new Error(`team list request failed: code=${e.ret.code}${e.ret.msg?`, msg=${e.ret.msg}`:""}`);return Array.isArray(e.teams)?e.teams.filter(t=>typeof t=="object"&&t!==null).map(t=>({id:String(t.id??""),upSiteId:Number(t.upSiteId??0),name:BL(String(t.name??"")),countryCode:String(t.countryCode??""),siteId:Number(t.siteId??0),userType:Number(t.userType??0),lastLoginTime:String(t.lastLoginTime??""),isMirror:t.isMirror===!0})).filter(t=>t.id.length>0):[]}var od=class{config;constructor(e){this.config={...rs,...e}}updateConfig(e){this.config={...this.config,...e}}async listTeams(){let e=await Ro.fetchUserInfo(oe.CN_LOGIN_URL,!0);if(!e)throw new Je(UL());let t=await this.fetchTeamList(e.accessToken,e.userId),n=WL(t);return{userId:e.userId,teamList:n}}async fetchTeamList(e,t){let n=this.config.agcTeamListUrl,i;try{i=await F.get(n,{headers:{oauth2Token:e,uid:t,source:"cli",lang:wi.CHINA},timeout:15e3})}catch(o){let s=o.message;throw s.includes("401")?new Je("Token expired. Run `devecocli auth login` again."):new Error(`Network error while listing teams: ${s}`,{cause:o})}if(i.statusCode!==200)throw new Error(`Failed to list teams: HTTP ${i.statusCode}`);return typeof i.data=="string"?JSON.parse(i.data):i.data}},VS=new od;async function Sn(){return VS.listTeams()}async function sd(r,e,t){let n=Date.now(),i=!0,o=null;try{await e()}catch(s){i=!1,o=X(s);let a=t?.(s);if(a)throw a}finally{let s={duration_ms:Date.now()-n,success:i,error_code:o};await D.track(r,s)}}function GL(r){if(r.length===0)return Yt("No teams found for the current user.");let e=["Id","Name"],t=r.map(s=>[s.id,s.name]),n=e.map((s,a)=>Math.max(s.length,...t.map(c=>c[a].length))),i=s=>s.map((a,c)=>a.padEnd(n[c])).join(" "),o=n.map(s=>"-".repeat(s)).join(" ");return[i(e),o,...t.map(i)].join(`
1314
- `)}function qL(){return new Promise(r=>{let e=GS.createInterface({input:process.stdin,output:process.stdout});e.question("",()=>{e.close(),r()})})}var ua=new VL("auth").description("Authentication commands (login, logout, status, team)");async function zL(r){if(r||!process.stdin.isTTY){console.log(Yt(r?"Opening browser for login... (--no-prompt: Enter confirmation skipped)":"Non-interactive terminal: opening browser for login without the Enter confirmation..."));return}console.log(Yt("Press Enter to open browser for login (or pass --no-prompt to skip)...")),await qL()}async function JL(r){if(wt()){console.log(Of("Login is managed by DevEco Code. Login from DevEco Code instead."));return}let e={event:v.CommandExecuted,args:["auth","login"]};await sd(e,async()=>{let t=await Ke.getUserInfo();if(t){console.log(Yt(`Already logged in, User Name:${t.userName}`));return}console.log(Yt("Starting login process...")),await zL(r.prompt===!1);let n=await Ke.login();console.log(Yt(`Login successful. Logged in as ${n.userName}.`))},t=>{throw t instanceof Je||(t instanceof Error?t.message:String(t)).includes("Network connection failed")?t:new Error("Login failed",{cause:t})})}ua.command("login").description("Log in to your Huawei Developer account").option("--no-prompt","Open the browser immediately without the interactive Enter confirmation (agents and non-interactive terminals)").action(async r=>{await JL(r)});ua.command("logout").description("Log out of your Huawei Developer account").action(async()=>{if(wt()){console.log(Of("Login is managed by DevEco Code. Log out from DevEco Code instead."));return}let r={event:v.CommandExecuted,args:["auth","logout"]};await sd(r,async()=>{let e=await Ke.logout();console.log(e?Yt("Logout successful"):Yt("Already logged out."))},e=>new Error("Logout failed",{cause:e}))});ua.command("status").description("Show the currently logged-in user").action(async()=>{let r={event:v.CommandExecuted,args:["auth","status"]};await sd(r,async()=>{let e=await Ke.getUserInfo();if(!e){console.log(Yt("Not logged in"));return}console.log(Yt(`Current user: ${e.userName}`))},()=>{console.log(Yt("Not logged in"))})});var YL=ua.command("team").description("Team-related commands");YL.command("list").description("List team accounts the current user has joined").action(async()=>{let r={event:v.CommandExecuted,args:["auth","team","list"]};await sd(r,async()=>{let e=await Sn();console.log(GL(e.teamList))},e=>{if(e instanceof Je){console.log(Of(e.message));return}throw new Error("Failed to list teams",{cause:e})})});var qS=ua;import{Command as XL}from"commander";import{green as ZL,red as pa,cyan as zS,yellow as JS,dim as YS}from"colorette";import QL from"p-limit";import KL from"ora";var Ie=class{spinner=null;isRunning=!1;start(e){this.spinner?this.spinner.text=e:this.spinner=KL(e),this.spinner.start(),this.isRunning=!0}stop(){this.spinner&&this.isRunning&&(this.spinner.stop(),this.isRunning=!1)}succeed(e){this.spinner&&(this.spinner.succeed(e),this.isRunning=!1)}fail(e){this.spinner&&(this.spinner.fail(e),this.isRunning=!1)}};var e_="deveco";async function t_(r){let e=await ds();if(r.all)return(await gc(e)).map(n=>n.enName);{let n=(await hc(r.skill,e)).find(i=>i.enName===r.skill);if(!n)throw new xo("errorCode",`Skill "${r.skill}" not found`);return[n.enName]}}function r_(r){if(r.all&&r.skill)throw new xo("errorCode","`--all` and `--skill` cannot be specified together.");if(!r.all&&!r.skill)throw new xo("errorCode","Must specify `--all` or `--skill`");let{resolvedPath:e,resolvedProject:t}=Wi(r.path,r.project,r.agent);return t&&Rr(t,"Project directory",r.force),e&&Rr(e,"Directory",r.force),{resolvedPath:e,resolvedProject:t}}function n_(r,e,t){return!!(e||t||r.path||r.project||r.agent)}function i_(){return{agents:[e_],projectAgents:[],customPath:void 0}}async function o_(r,e,t){let n=wt()&&!n_(r,e,t)?i_():await Vi(r,e,t);return{skillNames:await t_(r),targets:n}}async function s_(r,e,t,n){let i=[],o=0,s=r.length,a=QL(5),c=r.map(l=>a(()=>a_(l)));for(let l=0;l<r.length;l++){let d=r[l],g=s>1?` (${l+1}/${s})`:"";t.start(`Installing ${d}${g}...`);let y=await c[l];if(!y.success){t.fail(),console.log(pa(`${d}: Download failed - ${y.error}`)),i.push({success:!1});continue}o+=y.buffer.length,t.stop();let E=await new sr().installArchiveSkill(d,y.buffer,e,n);i.push(...E)}return{results:i,diskBytes:o}}async function a_(r){try{return{buffer:await fp(r),success:!0}}catch(e){return{error:e instanceof Error?e.message:"unknown error",success:!1}}}async function c_(r){let e=new Ie;try{e.start("Installing skill...");let{resolvedPath:t,resolvedProject:n}=r_(r),{skillNames:i,targets:o}=await o_(r,t,n),{results:s,diskBytes:a}=await s_(i,o,e,r.force??!1);return e.stop(),Bi(s),{diskBytes:a,results:s}}catch(t){throw e.stop(),t}}function KS(r){let e=r.length,t=r.filter(s=>s.success&&!s.skipped).length,n=r.filter(s=>s.skipped).length,i=r.filter(s=>!s.success).length,o=[...new Set(r.filter(s=>!s.success&&typeof s.error=="string").map(s=>l_(s.error)))];return{opTotal:e,opSuccess:t,opFailed:i,opSkipped:n,...o.length>0?{failedErrors:o}:{}}}function l_(r){let e=/^([A-Za-z_][A-Za-z0-9_-]*)/.exec(r.trim());return e?e[1].slice(0,32):"error"}var xo=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function d_(r){let e=r;return r instanceof xo?r.code:e.code??e.name??"UnknownError"}function ad(r,e={}){return["skills",r,...e.all?["--all"]:[],...e.long?["--long"]:[],...e.skill?["--skill"]:[],...e.force?["--force"]:[],...e.agent?["--agent",e.agent]:[],...e.project?["--project"]:[],...e.path?["--path"]:[]]}async function cd(r,e,t){let n=Date.now(),i=!0,o=null,s={};try{s=await e()}catch(a){throw i=!1,o=d_(a),a}finally{let a={event:v.SkillOperation,subAction:r,args:t,...s};await D.track(a,{duration_ms:Date.now()-n,success:i,error_code:o})}}function u_(r){return cd("add",async()=>{let{diskBytes:e,results:t}=await c_(r);return{diskUsage:ae(e),...r.skill?{skillName:r.skill}:{},...KS(t)}},ad("add",r))}function p_(r){let{resolvedPath:e,resolvedProject:t}=Wi(r.path,r.project,r.agent);return t&&Rr(t,"Project directory"),e&&Rr(e,"Directory"),{resolvedPath:e,resolvedProject:t}}async function m_(r,e){let t=new Ie;try{t.start("Removing skill...");let{resolvedPath:n,resolvedProject:i}=p_(e);t.stop();let o=await f_(e,r,n,i);return t.stop(),Bi(o),o}catch(n){throw t.stop(),n}}async function f_(r,e,t,n){let i=r.agent||t?await Vi(r,t,n):n?{agents:[],explicitAgents:!1,projectAgents:Le().map(o=>({project:n,agent:o}))}:{agents:Le(),projectAgents:[]};return new sr().removeSkill(e,i)}var ma=new XL("skills").description("Manage HarmonyOS skills");ma.command("list").description("List all available HarmonyOS skills").option("-l, --long","Show detailed information including description and installation status").action(async r=>{try{await cd("list",async()=>{let e=new Ie;try{e.start("Fetching skills...");let t=await ds(),n=await gc(t);if(n.length===0)return e.stop(),console.log(JS("No skills available.")),{resultTotal:0};e.succeed(`Fetched ${n.length} skills`);for(let i of n){if(!r.long){console.log(i.enName);continue}console.log(zS(i.enName)),console.log(YS(i.description));let o=up(i.enName);o.length>0&&console.log(ZL(`Installed for: ${o.join(", ")}`)),console.log()}return{resultTotal:n.length}}finally{e.stop()}},ad("list",r))}catch(e){console.error(pa(e.message)),process.exitCode=1}});ma.command("find <keyword>").description("Search skills by keyword").action(async r=>{try{await cd("find",async()=>{let e=new Ie;try{e.start("Searching skills...");let t=await ds(),n=await hc(r,t);if(n.length===0)return console.log(JS(`No skills found matching '${r}'.`)),e.stop(),{resultTotal:0,queryLen:r.length,keyword:r};e.succeed(`Found ${n.length} skills.`);for(let i of n)console.log(zS(i.enName)),console.log(YS(i.description)),console.log();return{resultTotal:n.length,queryLen:r.length,keyword:r}}finally{e.stop()}},ad("find"))}catch(e){console.error(pa(e.message)),process.exitCode=1}});ma.command("add").description("Install skills to AI agents").option("--all","Install all available skills").option("--agent <agents>","Target agents, comma-separated; Omit to install to all available agents").option("--skill <skill-name>","Name of the skill to install").option("-f, --force","Replace existing Skill content; create missing project or custom target directories").option("--project <path>","Project root directory for skill installation").option("--path <path>","Path to install the skill directly (cannot be used with --project or --agent)").action(async r=>{try{await u_(r)}catch(e){console.error(pa(e.message)),process.exitCode=1}});ma.command("remove").description("Remove an installed skill from AI agents").requiredOption("--skill <skill-name>","Name of the skill to remove").option("--agent <agents>","Target agents, comma-separated.Omit to remove from all available agents").option("--project <path>","Project root directory for skill removal").option("--path <path>","Path for skill removal").action(async r=>{try{await cd("remove",async()=>{let e=await m_(r.skill,r);return{skillName:r.skill,...KS(e)}},ad("remove",r))}catch(e){console.error(pa(e.message)),process.exitCode=1}});var XS=ma;import{Command as $_}from"commander";import{cyan as lE,yellow as F_}from"colorette";import _f from"fs";import g_ from"fs";import h_ from"path";import{pathToFileURL as y_}from"url";function ZS(r,e){return Array.isArray(r)&&r.length>0&&r.every(t=>typeof t=="string"&&e.includes(t))}var Ao=1;function w_(r){return r.plugin??r.default?.plugin}function v_(r,e){for(let n of["install","uninstall","update"])if(typeof r[n]!="function")throw new Error(`Plugin contract invalid: "${n}" must be a function (got ${typeof r[n]}).`);if(r.name!==e.name)throw new Error(`Plugin contract mismatch: expected name "${e.name}", got "${r.name}".`);if(r.version!==e.version)throw new Error(`Plugin contract mismatch: expected version "${e.version}", got "${r.version}".`);let t=Le();if(ZS(r.supportedAgents,t)||b_(r.supportedAgents,t),typeof r.apiVersion!="number")throw new Error(`Plugin contract invalid: "apiVersion" must be a number (got ${typeof r.apiVersion}).`);if(r.apiVersion>Ao)throw new Error(`Plugin "${e.name}" requires plugin API v${r.apiVersion}, but this CLI supports v${Ao}. Upgrade: npm i -g @deveco/deveco-cli@latest`)}function b_(r,e){if(!Array.isArray(r)||r.length===0)throw new Error('Plugin contract invalid: "supportedAgents" must be a non-empty array.');let t=r.find(n=>typeof n!="string"||!e.includes(n));throw new Error(`Plugin contract invalid: "supportedAgents" contains unknown agent "${String(t)}".`)}async function ld(r,e){let t=e.label??`${e.name}@${e.version}`,n=h_.join(r,"index.js");if(!g_.existsSync(n))throw new Error(`Package ${t} has no index.js.`);let i;try{i=await import(y_(n).href)}catch(s){let a=s instanceof Error?s.message:String(s);throw new Error(`Plugin "${e.name}" failed to initialize: ${a}`,{cause:s})}let o=w_(i);if(!o||typeof o!="object")throw new Error(`Package ${t} does not export a plugin object.`);return v_(o,e),o}var QS=[{name:"hometrans",description:"One-line description shown in `plugin list`",npmPackage:"@litingwei621/test-devecocli-plugin2@cli"},{name:"example",description:"hello plugin`",npmPackage:"@example/example-plugin"}];var E_="src/plugins/registry/registry.json",P_=["name","description","npmPackage"];function eE(r){if(!Array.isArray(r))throw new Error(`Invalid plugin registry (${E_}): expected an array.`);let e=new Set;return r.map((t,n)=>{if(typeof t!="object"||t===null)throw new Error(`Invalid plugin registry: entry #${n} must be an object.`);let i=t,o=typeof i.name=="string"&&i.name.trim()!==""?i.name:`#${n}`;for(let a of P_){let c=i[a];if(typeof c!="string"||c.trim()==="")throw new Error(`Invalid plugin registry: entry "${o}" is missing "${a}".`)}let s=t;if(e.has(s.name))throw new Error(`Invalid plugin registry: duplicate plugin name "${s.name}".`);return e.add(s.name),s})}function dd(){return eE(QS)}function ud(r){let e=dd().find(t=>t.name===r);if(!e)throw new Error(`Plugin "${r}" is not in the whitelist. Run devecocli plugin list to see available plugins.`);return e}import Io from"path";import{randomUUID as C_}from"crypto";var k_=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function pd(r){if(!k_.test(r)||r==="."||r==="..")throw new Error(`Invalid plugin name "${r}".`)}function D_(r){return Io.join(r,"plugins","store")}function R_(r){return Io.join(r,"plugins","data")}function br(r,e){return Io.join(D_(r),e)}function fa(r,e,t){return Io.join(br(r,e),t)}function tE(r,e){return Io.join(R_(r),e)}function rE(r,e,t){return Io.join(br(r,e),`.tmp-${t}-${process.pid}-${C_().slice(0,8)}`)}import nE from"fs";import Nf from"path";import{valid as x_}from"semver";var A_=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function iE(r){return A_.test(r)&&x_(r)!==null}async function ga(r){try{return await nE.promises.access(Nf.join(r,"index.js")),!0}catch{return!1}}async function To(r,e){let t=br(r,e),n;try{n=await nE.promises.readdir(t,{withFileTypes:!0})}catch(o){let s=o.code;if(s==="ENOENT"||s==="ENOTDIR")return[];throw o}let i=[];for(let o of n){if(!o.isDirectory()||!iE(o.name)){m(`Ignoring non-version entry in plugin store: ${Nf.join(t,o.name)}`);continue}let s=Nf.join(t,o.name);if(!await ga(s)){m(`Ignoring incomplete plugin version dir (no index.js): ${s}`);continue}i.push(o.name)}return i.sort((o,s)=>Pt(o,s)),i}import{execa as Lf}from"execa";import En from"fs";import Mf from"path";function ha(r){let e=r.trim(),t=e.lastIndexOf("@");if(t<=0)return{name:e,tag:"latest"};let n=e.slice(t+1).trim();return{name:e.slice(0,t),tag:n||"latest"}}function ya(r){let e=r;return(e.shortMessage??e.message??String(r)).split(`
1315
- `)[0].trim()||"unknown error"}function oE(r){let e=r;return e.code==="ENOENT"||/ENOENT/.test(e.originalMessage??e.message??"")}async function I_(r,e,t){m(`Executing: npm pack ${r}@${e}`);try{let{stdout:n}=await Lf("npm",["pack",`${r}@${e}`],{cwd:t}),i=n.trim().split(`
1316
- `).pop()??"";if(!i)throw new Error("npm pack produced no tarball name");return i}catch(n){throw oE(n)?new Error("Failed to run npm (not found on PATH); plugin installation requires npm.",{cause:n}):new Error(`Failed to download ${r}@${e}: ${ya(n)}.`,{cause:n})}}function T_(r,e,t){let n=typeof e.version=="string"?e.version.trim():e["dist-tags"]?.[t]?.trim();if(!n)throw new Error(`no version found for ${r}@${t}`);let i=e.dist??e.versions?.[n]?.dist;if(!i?.tarball||!i?.integrity)throw new Error(`no dist information for ${r}@${n}`);let o=e.apiVersion??e.versions?.[n]?.apiVersion;return{version:n,apiVersion:o,dist:{tarball:i.tarball,integrity:i.integrity}}}async function sE(r){let{name:e,tag:t}=ha(r);m(`Executing: npm view ${e}@${t} --json`);try{let{stdout:n}=await Lf("npm",["view",`${e}@${t}`,"--json"]);return T_(e,ai(JSON.parse(n)),t)}catch(n){throw oE(n)?new Error("Failed to run npm (not found on PATH); plugin installation requires npm.",{cause:n}):new Error(`Failed to fetch metadata for ${r}: ${ya(n)}.`,{cause:n})}}async function O_(r,e,t,n){let i=await I_(r,e.version,t),o=Mf.join(t,i);n?.("verifying");let s=await En.promises.readFile(o);if(!El(s,e.dist.integrity))throw new Error(`Integrity check failed for ${r}@${e.version}.`);n?.("extracting");let a=Mf.join(t,"extract");await En.promises.mkdir(a,{recursive:!0}),m(`Executing: tar -xzf ${i} -C extract`);try{await Lf("tar",["-xzf",o,"-C",a])}catch(l){throw new Error(`Failed to extract ${r}@${e.version}: ${ya(l)}.`,{cause:l})}let c=Mf.join(a,"package");if(!await ga(c))throw new Error(`Failed to extract ${r}@${e.version}: package has no index.js.`);return c}async function N_(r,e,t,n){try{return await En.promises.rename(t,n),{dir:n,created:!0}}catch(i){let o=i.code;if(o==="EEXIST"||o==="ENOTEMPTY"||o==="EPERM"){if(await ga(n))return{dir:n,created:!1};throw new Error(`Cached package for ${r}@${e.version} is incomplete (${n}). Delete it and retry.`,{cause:i})}throw i}}async function aE(r,e,t,n,i){let{name:o}=ha(t),s=br(r,e),a=fa(r,e,n.version);if(await ga(a))return{dir:a,created:!1};await En.promises.rm(a,{recursive:!0,force:!0}).catch(()=>{});try{await En.promises.mkdir(s,{recursive:!0})}catch(l){throw new Error(`Cannot write to plugin store (${s}): ${ya(l)}.`,{cause:l})}let c=rE(r,e,n.version);await En.promises.mkdir(c,{recursive:!0});try{let l=await O_(o,n,c,i);return await N_(e,n,l,a)}finally{await En.promises.rm(c,{recursive:!0,force:!0}).catch(()=>{m(`Failed to clean up plugin temp dir: ${c}`)})}}async function cE(r,e,t){let n=fa(r,e,t);try{await En.promises.rm(n,{recursive:!0,force:!0}),m(`Removed plugin version dir: ${n}`)}catch(i){m(`Failed to remove plugin version dir (${n}): ${ya(i)}`)}}var M_=12e4,L_="DEVECO_CLI_PLUGIN_HOOK_TIMEOUT_MS";function $f(r,e){return r.scope==="project"?`${r.agent}(project:${e})`:`${r.agent}(global)`}function Oo(r){return r instanceof Error?r.message:String(r)}var Pn=class{logs=[];env;constructor(e){this.env=e}get dataDir(){return this.env?.dataDir??$()}get hookTimeoutMs(){if(this.env?.hookTimeoutMs!==void 0)return this.env.hookTimeoutMs;let e=Number(process.env[L_]);return Number.isFinite(e)&&e>0?e:M_}async getExistingAgents(e){return this.env?.getExistingAgents?this.env.getExistingAgents(e):Ec(e)}getSkillsDir(e,t){return this.env?.getSkillsDir?this.env.getSkillsDir(e,t):Lt(e,t)}async listPlugins(){let e=this.dataDir;return Promise.all(dd().map(async t=>{try{return{entry:t,versions:await To(e,t.name)}}catch(n){return{entry:t,versions:[],warning:`Warning: cannot read plugin store (${br(e,t.name)}): ${Oo(n)}.`}}}))}async install(e,t,n){let i=ud(e);pd(e),await this.validateOptions(t);let o=await To(this.dataDir,e),{plugin:s,meta:a,created:c}=await this.prepareLatestPlugin(i,e,n),{targets:l,skipped:d}=await this.resolveTargets(e,s.supportedAgents,t,"install"),g=[],y=0;for(let E of l)g.push(await this.installForTarget(e,E,s,a,o,!!t.force,l.length,++y,n));return c&&!g.some(E=>E.outcome==="installed")&&await cE(this.dataDir,e,a.version),this.appendSkipped(g,e,d,s.supportedAgents),g}async update(e,t,n){let i=ud(e);pd(e),await this.validateOptions(t);let o=await To(this.dataDir,e);if(o.length===0)throw new Error(`Plugin "${e}" is not installed. Run devecocli plugin install ${e} first.`);let{plugin:s,meta:a}=await this.prepareLatestPlugin(i,e,n),{targets:c,skipped:l}=await this.resolveTargets(e,s.supportedAgents,t,"filtered"),d=o.filter(j=>j!==a.version),g=d.length>0?d[d.length-1]:a.version,y=[],E=0;for(let j of c)y.push(await this.updateForTarget(e,j,s,g,a.version,c.length,++E,n));return this.appendSkipped(y,e,l,s.supportedAgents),y}async updateForTarget(e,t,n,i,o,s,a,c){let{ctx:l,label:d}=await this.buildTargetContext(e,t,!1,!0);c?.(`Updating ${d}... (${a}/${s})`);let g={...l,from:i,to:o};try{return await this.runHook("update",n.update,g),{target:t,label:d,outcome:"updated",version:o}}catch(y){return{target:t,label:d,outcome:"failed",error:Oo(y)}}}async uninstall(e,t,n){pd(e),await this.validateOptions(t);let i=await To(this.dataDir,e);if(i.length===0)throw new Error(`Plugin "${e}" is not installed.`);n?.("Loading plugin...");let o=await this.loadNewestPackage(e,i);if(!o.ok)throw new Error(`Cannot load plugin "${e}" to run uninstall (${o.error}). Delete ${br(this.dataDir,e)} manually.`);let{targets:s,skipped:a}=await this.resolveTargets(e,o.plugin.supportedAgents,t,"filtered"),c=[],l=0;for(let d of s)c.push(await this.uninstallForTarget(e,d,o.plugin,o.version,s.length,++l,n));return this.appendSkipped(c,e,a,o.plugin.supportedAgents),c}async uninstallForTarget(e,t,n,i,o,s,a){let{ctx:c,label:l}=await this.buildTargetContext(e,t,!1,!1);a?.(`Uninstalling ${l}... (${s}/${o})`);try{return await this.runHook("uninstall",n.uninstall,c),{target:t,label:l,outcome:"uninstalled",version:i}}catch(d){return{target:t,label:l,outcome:"failed",error:Oo(d)}}}drainLogs(){let e=[...this.logs];return this.logs.length=0,e}async installForTarget(e,t,n,i,o,s,a,c,l){let{ctx:d,label:g}=await this.buildTargetContext(e,t,s,!0),y;if(s&&o.length>0){l?.(`Uninstalling ${g}... (${c}/${a})`);let E=await this.forceUninstallPrevious(e,t,g,d,o);if("failure"in E)return E.failure;y=E.version}return l?.(`Installing ${g}... (${c}/${a})`),this.runInstallHook(t,g,n,i.version,d,y)}async runInstallHook(e,t,n,i,o,s){try{return await this.runHook("install",n.install,o),{target:e,label:t,outcome:"installed",version:i,forceUninstalledVersion:s}}catch(a){return{target:e,label:t,outcome:"failed",error:Oo(a),forceUninstalledVersion:s}}}async forceUninstallPrevious(e,t,n,i,o){let s=await this.loadNewestPackage(e,o);if(!s.ok)return{failure:{target:t,label:n,outcome:"failed",error:`cannot load previous version to run uninstall (${s.error}). Delete ${br(this.dataDir,e)} and retry.`}};try{await this.runHook("uninstall",s.plugin.uninstall,i)}catch(a){return{failure:{target:t,label:n,outcome:"failed",error:`previous version uninstall failed - ${Oo(a)}`}}}return{version:s.version}}async prepareLatestPlugin(e,t,n){n?.("Fetching metadata...");let i=await sE(e.npmPackage);this.gateApiVersion(e.name,i.apiVersion);let o=ha(e.npmPackage).name;n?.(`Downloading ${o}@${i.version}...`);let{dir:s,created:a}=await aE(this.dataDir,t,o,i,l=>n?.(l==="verifying"?"Verifying package integrity...":"Extracting package..."));return n?.("Loading plugin..."),{plugin:await ld(s,{name:t,version:i.version,label:`${o}@${i.version}`}),meta:i,created:a}}resolveProjectRoot(e){if(!e.project)return;let t=Li(e.project);if(!_f.existsSync(t))throw new Error(`Project path "${t}" not found.`);if(!_f.statSync(t).isDirectory())throw new Error(`"${t}" is not a directory.`);return t}async resolveDesiredAgents(e,t){if(!e.agent)return t;let n=await Sc(e.agent);if(n.length===0)throw new Error("--agent requires at least one agent name.");let i=n.filter(o=>!t.includes(o));if(i.length>0)throw new Error(`Agent ${i[0]} not found`);return n}async validateOptions(e){let t=this.resolveProjectRoot(e);await this.resolveDesiredAgents(e,await this.getExistingAgents(t))}async resolveTargets(e,t,n,i){let o=this.resolveProjectRoot(n),s=await this.getExistingAgents(o),a=await this.resolveDesiredAgents(n,s);if(i==="install"&&n.agent){let d=a.find(g=>!t.includes(g));if(d)throw new Error(`Agent ${d} is not supported by plugin "${e}" (supported: ${t.join(", ")}).`)}let c=a.filter(d=>t.includes(d));c.length===0&&__(e,t,s,n,i);let l=d=>({agent:d,scope:o?"project":"global",projectRoot:o});return{targets:c.map(l),skipped:a.filter(d=>!t.includes(d)).map(l)}}skippedResult(e,t,n){let i=this.getSkillsDir(t.agent,t.scope==="project"?t.projectRoot:void 0);return{target:t,label:$f(t,i),outcome:"skipped",error:`not supported by plugin "${e}" (supported: ${n.join(", ")})`}}appendSkipped(e,t,n,i){e.push(...n.map(o=>this.skippedResult(t,o,i)))}async buildTargetContext(e,t,n,i){let o=this.getSkillsDir(t.agent,t.scope==="project"?t.projectRoot:void 0),s=$f(t,o),a=tE(this.dataDir,e);return i&&await _f.promises.mkdir(a,{recursive:!0}).catch(()=>{}),{label:s,ctx:{agent:t.agent,scope:t.scope,projectRoot:t.projectRoot,skillsDir:o,pluginDataDir:a,force:n,log:c=>{this.logs.push({prefix:s,message:c})}}}}async runHook(e,t,n){let i;try{await Promise.race([Promise.resolve().then(()=>t(n)),new Promise((o,s)=>{i=setTimeout(()=>s(new Error(`plugin ${e} hook timed out after ${this.hookTimeoutMs}ms`)),this.hookTimeoutMs)})])}finally{i&&clearTimeout(i)}}async loadNewestPackage(e,t){let n=[...t].sort((o,s)=>Pt(s,o)),i="no loadable version";for(let o of n)try{return{ok:!0,plugin:await ld(fa(this.dataDir,e,o),{name:e,version:o}),version:o}}catch(s){i=Oo(s),m(`Failed to load plugin ${e}@${o}: ${i}`)}return{ok:!1,error:i}}gateApiVersion(e,t){if(t!==void 0&&t>Ao)throw new Error(`Plugin "${e}" requires plugin API v${t}, but this CLI supports v${Ao}. Upgrade: npm i -g @deveco/deveco-cli@latest`)}};function __(r,e,t,n,i){if(i==="install")throw new Error(`Plugin "${r}" supports no agents installed on this system (supported: ${e.join(", ")}; installed: ${t.join(", ")||"none"}).`);let o=[n.agent?`--agent ${n.agent}`:"",n.project?`--project ${n.project}`:""].filter(Boolean).join(" ");throw new Error(`No targets match${o?` ${o}`:""} for plugin "${r}".`)}function j_(r,e){if(r.length===0){console.log("No plugins available.");return}for(let{entry:t,versions:n}of r){if(console.log(t.name),e&&(console.log(` ${t.description}`),console.log(` npm:${t.npmPackage}`)),n.length===0){console.log(" - not installed");continue}for(let i of n)console.log(` v${i} installed`)}}function Ff(r,e){console.log(lE(`${r}:`));for(let s of e){s.forceUninstalledVersion&&console.log(` uninstalled: ${s.label}(v${s.forceUninstalledVersion})`);let a=s.version?`(v${s.version})`:"",c=(s.outcome==="failed"||s.outcome==="skipped")&&s.error?`(${s.error})`:"";console.log(` ${s.outcome}: ${s.label}${a}${c}`)}let t=e.filter(s=>s.outcome==="installed"||s.outcome==="updated"||s.outcome==="uninstalled").length,n=e.filter(s=>s.outcome==="skipped").length,i=e.filter(s=>s.outcome==="failed").length;console.log(),console.log(lE("Finished:")),console.log(` Success: ${t}`),console.log(` Skipped: ${n}`),console.log(` Failed: ${i}`),i>0&&(process.exitCode=1),(t>0||e.some(s=>s.forceUninstalledVersion!==void 0))&&(console.log(),console.log("Restart your agent to load the plugin."))}function H_(r){let e=/^([A-Za-z_][A-Za-z0-9_-]*)/.exec(r.trim());return e?e[1].slice(0,32):"error"}function jf(r){let e=r.filter(i=>i.outcome==="failed"),t=r.filter(i=>i.outcome==="skipped"),n=[...new Set(e.map(i=>H_(i.error??"unknown")))];return{opTotal:r.length,opSuccess:r.length-e.length-t.length,opSkipped:t.length,opFailed:e.length,...n.length>0?{failedErrors:n}:{}}}function U_(r){let e=r;return e.code??e.name??"UnknownError"}function md(r,e,t){return["plugin",r,...t?[t]:[],...e.long?["--long"]:[],...e.agent?["--agent",e.agent]:[],...e.project?["--project"]:[],...e.force?["--force"]:[]]}async function fd(r,e,t){let n=Date.now(),i=!0,o=null,s={};try{s=await e()}catch(a){throw i=!1,o=U_(a),a}finally{let a={event:v.PluginOperation,subAction:r,args:t,...s};await D.track(a,{duration_ms:Date.now()-n,success:i,error_code:o})}}async function B_(r){let t=await new Pn().listPlugins();for(let n of t)n.warning&&console.error(F_(n.warning));return j_(t,r.long===!0),{resultTotal:t.length,installedPlugins:t.filter(n=>n.versions.length>0).length}}function Hf(r){for(let e of r.drainLogs())console.log(` [${e.prefix}] ${e.message}`)}async function W_(r){let e=new Ie,t=new Pn;try{let n=await t.install(r.name,r,i=>e.start(i));return e.stop(),Hf(t),Ff("Plugin Installation",n),jf(n)}finally{e.stop()}}async function V_(r){let e=new Ie,t=new Pn;try{let n=await t.update(r.name,r,i=>e.start(i));return e.stop(),Hf(t),Ff("Plugin Update",n),jf(n)}finally{e.stop()}}async function G_(r){let e=new Ie,t=new Pn;try{let n=await t.uninstall(r.name,r,i=>e.start(i));return e.stop(),Hf(t),Ff("Plugin Uninstall",n),jf(n)}finally{e.stop()}}var wa=new $_("plugin").description("Manage whitelisted AI agent plugins");wa.command("list").description("List whitelisted plugins and downloaded versions").option("-l, --long","Show plugin descriptions and npm coordinates").action(async r=>{await fd("list",()=>B_(r),md("list",r))});wa.command("install <name>").description("Install a whitelisted plugin for detected agents").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").option("-f, --force","Run the previous version uninstall hook before installing").action(async(r,e)=>{await fd("install",()=>W_({name:r,...e}),md("install",e,r))});wa.command("update <name>").description("Update a plugin to the latest published version").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").action(async(r,e)=>{await fd("update",()=>V_({name:r,...e}),md("update",e,r))});wa.command("uninstall <name>").description("Run the plugin uninstall hook for detected agents").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").action(async(r,e)=>{await fd("uninstall",()=>G_({name:r,...e}),md("uninstall",e,r))});var dE=wa;import{Command as q_,InvalidArgumentError as gd}from"commander";import{cyan as Uf,red as pE}from"colorette";import z_ from"ora";function J_(r){return["log",...r.device?["--device"]:[],...r.crash?["--crash"]:[],...r.level?["--level"]:[],...r.bundleName?["--bundle-name"]:[],...r.keyword?["--keyword"]:[],...r.tail!==void 0?["--tail"]:[],...r.from!==void 0?["--from"]:[],...r.to!==void 0?["--to"]:[],...r.follow?["--follow"]:[]]}function Y_(r){return{event:v.CommandExecuted,args:J_(r),logType:r.crash?"crash":"common",level:r.level??"ALL",bundleName:r.bundleName??"ALL"}}function K_(r){return r instanceof w?r.traceMessage:r instanceof Error?r.code??r.name:"UnknownError"}async function X_(r,e){let t=Date.now(),n=!0,i=null;try{await e()}catch(o){n=!1,i=K_(o),console.error(pE(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(r,o).catch(()=>{})}}function Z_(r){try{return P.parsePositiveInteger(r,"tail")}catch{throw new gd("`tail` must be a positive integer.")}}function uE(r,e){try{return P.parseDurationToSeconds(r,e)}catch{throw new gd(`${e} must be a valid duration string (e.g.,30s, 5m or 2.5m).Supported units: s and m.when specified in seconds(with \`s\` or as a raw number), the value must be an integer.`)}}function Q_(r){try{return P.assertHilogLevel(r),r}catch{throw new gd("`level` must be one of: D, I, W, E, F.")}}function e$(r){try{return P.assertBundleNameStrict(r),r}catch(e){throw new gd(e.message)}}function t$(r){if(r.to&&r.follow)throw new Error("`--to` cannot be used with `--follow`.")}async function r$(r,e,t,n,i){return t.crash?await r.getCrashLog(e,t.bundleName):await r.getHilog(e,{level:t.level,bundleName:t.bundleName,keyword:t.keyword,isFollow:!!t.follow,tail:t.tail,fromSeconds:n,toSeconds:i})}function n$(r,e,t,n){let i=P.filterLogsByRelativeWindow(r,t,n);return e.tail?P.getLastLines(i,e.tail):i}var i$=new q_("log").description("Obtain device application logs").configureOutput({outputError:(r,e)=>e(pE(r))}).option("--device <device>","Target device (name or serial)").option("--crash","Only obtain crash logs").option("--level <level>","Log level filter: D, I, W, E, F",Q_).option("--bundle-name <bundle-name>","Filter by application bundle name",e$).option("--keyword <keyword>","Keyword filter").option("--tail <num>","Show only the latest N log lines",Z_).option("--from <start>","Start offset from now, e.g. 30s, 5m, 2.5m, or 120",r=>uE(r,"from")).option("--to <end>","End offset from now, e.g. 30s, 5m, 2.5m, or 120",r=>uE(r,"to")).option("--follow","Follow the log stream in real-time.").action(async r=>{await X_(Y_(r),()=>o$(r))});async function o$(r){let e=z_({text:"Preparing log request\u2026",color:"cyan"}),t=()=>{e.stop(),e.clear()};e.start();try{t$(r);let n=r.from,i=r.to,o=await C.new(),s=new cn(o),a=await s.selectDevice(r.device);if(!a)throw new w("No active devices found.","No active devices found.");m(Uf(`deviceId: ${a}`)),m(Uf(`type: ${r.crash?"Crash logs":"Common logs"}`)),m(Uf("Obtaining logs ...")),e.text="Fetching logs\u2026",r.follow&&t();let c=await r$(s,a,r,n,i);t(),r.crash&&c&&(c=n$(c,r,n,i)),c&&console.log(c)}finally{t()}}var mE=i$;import ba from"path";import zr from"fs";import Vf from"process";import PE from"os";import{Command as v$}from"commander";import{green as vE,red as Bf,cyan as b$,yellow as bE}from"colorette";import we from"fs-extra";import J from"path";import*as hE from"os";import{fileURLToPath as s$}from"url";var fE={17:{sdkVersion:"5.0.5(17)",modelVersion:"5.0.5"},18:{sdkVersion:"5.1.0(18)",modelVersion:"5.1.0"},19:{sdkVersion:"5.1.1(19)",modelVersion:"5.1.1"},20:{sdkVersion:"6.0.0(20)",modelVersion:"6.0.0"},21:{sdkVersion:"6.0.1(21)",modelVersion:"6.0.1"},22:{sdkVersion:"6.0.2(22)",modelVersion:"6.0.2"},23:{sdkVersion:"6.1.0(23)",modelVersion:"6.1.0"},24:{sdkVersion:"6.1.1(24)",modelVersion:"6.1.1"}},a$=["build-profile.json5","AppScope/resources/base/media/layered_image.json","entry/src/main/resources/base/media/layered_image.json"],No=["phone","tablet","2in1","car","wearable","tv"],gE=["entry","src","main","module.json5"];function c$(){let r=import.meta.url,e=s$(r);if(e.includes("dist")){let o=J.dirname(e),s=J.dirname(o);return J.join(s,"templates","application")}let t=J.dirname(e),n=J.dirname(t),i=J.dirname(n);return J.join(i,"templates","application")}function yE(r,e){we.mkdirSync(e,{recursive:!0});for(let t of we.readdirSync(r,{withFileTypes:!0})){let n=J.join(r,t.name),i=J.join(e,t.name);if(t.isDirectory()){yE(n,i);continue}we.existsSync(i)||(we.mkdirSync(J.dirname(i),{recursive:!0}),we.copyFileSync(n,i))}}function va(r,e){let t=we.readFileSync(r,"utf-8"),n=t;for(let[i,o]of e)n=n.replaceAll(i,o);n!==t&&we.writeFileSync(r,n,"utf-8")}function l$(r){if(fE[r])return fE[r];if(r>=26){let e=`${r}.0.0`;return{sdkVersion:e,modelVersion:e}}}function d$(r,e){if(e===22)return;let t=l$(e);t&&(va(J.join(r,"build-profile.json5"),[["6.0.2(22)",t.sdkVersion]]),va(J.join(r,"hvigor","hvigor-config.json5"),[["6.0.2",t.modelVersion]]),va(J.join(r,"oh-package.json5"),[["6.0.2",t.modelVersion]]))}function u$(r){return a$.filter(t=>!we.existsSync(J.join(r,t))).length===0}function p$(r,e){let t=gE.join("/"),n=J.join(r,...gE),i=we.readFileSync(n,"utf-8"),o=/^([ \t]*)"deviceTypes"\s*:\s*\[[\s\S]*?\]/m.exec(i);if(!o)throw new Error(`"deviceTypes" not found in ${t}.`);let s=i.includes(`\r
1308
+ `,CL="6.1.0";function kL(r){let e=r.trim();if(!e)throw new Error("--target must not be empty.");return e}function RL(r){let e=r.trim();if(!aE.includes(e))throw new Error(`Invalid fold state "${r}". Available values: ${aE.join(", ")}`);return e}function lE(r,e,t,n){let i=e.trim();if(!/^-?\d+$/.test(i))throw new Error(`${r} must be an integer in [${t}, ${n}].`);let o=Number(i);if(o<t||o>n)throw new Error(`${r} must be in [${t}, ${n}].`);return o}function dE(r,e,t,n,i){let o=e.trim(),s=Number(o);if(!o||Number.isNaN(s))throw new Error(`${r} must be a number in [${t}, ${n}].`);if(i!==void 0&&!xL(o,i))throw new Error(`${r} supports at most ${i} decimal place(s).`);if(s<t||s>n)throw new Error(`${r} must be in [${t}, ${n}].`);return o}function xL(r,e){let t=r.split(".")[1];return t===void 0||t.length<=e}function bi(r,e,t,n,i){return Number(dE(r,e,t,n,i))}var DL=["Name","Status","Serial","Device Type","OS Version"];function IL(r){return{cells:[r.name,r.status,r.serial??"-",r.deviceType??"-",r.osVersion??"-"],highlight:r.status==="running"}}async function AL(r,e){let t=await Promise.all(e.map(async n=>{let i=await ao(r,n,EL);return[n,i]}));return new Map(t)}async function TL(r){let e=await em(r),t=await AL(r,e);return{serials:e,params:t}}function NL(r,e,t,n,i){if(e)for(let o of["const.product.name","const.product.model"]){let s=e.get(o);if(!s)continue;let a=t.indexOf(s);if(a===-1)continue;t.splice(a,1),i.set(s,r);let c=n.indexOf(r);c!==-1&&n.splice(c,1);return}}function OL(r,e,t){let n=new Map,i=new Map,o=[...r],s=[...t];for(let a of r){let c=e.get(a),l=c?.get("ohos.qemu.hvd.name");l&&i.set(l,a),t.length>0&&NL(a,c,s,o,n)}for(let a=0;a<s.length&&a<o.length;a++)n.set(s[a],o[a]);return{productSerialMap:n,hvdSerialMap:i}}function _L(r,e,t){let n=r.map(i=>({emu:i,serial:e.get(i.name)??t.get(i.name),effectiveRunning:i.isRunning===!0||t.has(i.name)}));return n.sort((i,o)=>i.effectiveRunning!==o.effectiveRunning?i.effectiveRunning?-1:1:i.emu.name.localeCompare(o.emu.name)),n.map(({emu:i,serial:o,effectiveRunning:s})=>({name:i.name,status:s?"running":"stopped",serial:o??null,deviceType:i.deviceType??null,osVersion:i.osVersion??null}))}async function ML(r,e,t,n){try{let[i,o]=await Promise.all([r.listEmulators(),TL(e)]);if(i.length===0){n?.stop(),console.log(t==="json"?"[]":En(" No emulator instances found."));return}let s=i.filter(g=>g.isRunning).map(g=>g.name),{productSerialMap:a,hvdSerialMap:c}=OL(o.serials,o.params,s);n?.stop();let l=_L(i,a,c);if(t==="json"){console.log(JSON.stringify(l,null,2));return}let d=l.map(IL);console.log(zt(DL,d))}catch(i){throw n?.stop(),new Error(`Failed to list emulators: ${i.message}`,{cause:i})}}function uE(r,e,t){let n=!1;for(let i=0;i<r.length;i++){let o=r[i];if(o.status!=="rejected")continue;n=!0;let s=o.reason;console.error(eg(`Failed to ${t} emulator "${e[i]}": ${s.message}`)),s.stdout&&console.error(Xm(s.stdout)),s.stderr&&console.error(Xm(s.stderr))}return n}var LL=2e3,FL=6e4;async function $L(r,e){let t=je(e);return(await tm(r)).some(i=>je(i)===t)}async function pE(r,e,t,n=FL,i=LL){let o=Date.now()+n;for(;Date.now()<o;){if(await $L(r,e)===t)return!0;await new Promise(a=>setTimeout(a,i))}return!1}function jL(r){if(!r)return null;let e=r.indexOf("-bootmode");return e>=0&&e+1<r.length&&r[e+1]==="snapshot"}async function HL(r,e,t,n){let i=await r.startEmulator(t,n);if(i.status==="already-running")return console.log(En(`Emulator "${t}" is already running.`)),{started:!1,memoryBytes:0,hotBoot:null};console.log(_o(`Starting emulator "${t}"...`));let o=i.tracker,s=0,a=jL(i.args);try{let c=await pE(e,t,!0);console.log(c?va(`Emulator "${t}" started successfully.`):En(`Emulator "${t}" was launched but did not appear in hdc list targets within the timeout.`))}finally{if(o)try{s=await o.stop()}catch{}}return{started:!0,memoryBytes:s,hotBoot:a}}async function UL(r,e,t,n){let i=await Promise.allSettled(t.map(a=>HL(r,e,a,n)));if(uE(i,t,"start"))throw new w("One or more emulators failed to start.");let o=i.filter(a=>a.status==="fulfilled").map(a=>a.value).filter(a=>a.started);return{emulatorMemory:o.length===0||o.some(a=>a.memoryBytes===0)?"unknown":ce(o.reduce((a,c)=>a+c.memoryBytes,0)),hotBoot:o.length===0?null:o.every(a=>a.hotBoot===!0)}}async function fE(r,e){let t=e.trim();if(!mr(t))return t;let n=await le.withHdcPath(r).getDeviceName(t);if(n===t)throw new Error(`Cannot resolve a running emulator with serial "${t}". Use \`devecocli emulator list\` or pass the emulator name instead.`);return n}async function BL(r,e,t){let n=await fE(e,t);if(console.log(_o(`Stopping emulator "${n}"...`)),await r.stopEmulator(n)==="already-stopped"){console.log(En(`Emulator "${n}" is already stopped.`));return}let o=await pE(e,n,!1);console.log(o?va(`Emulator "${n}" stopped successfully.`):En(`Emulator "${n}" stop signal was sent but the instance is still visible in hdc list targets within the waiting period.`))}async function WL(r,e,t){let n=await Promise.allSettled(t.map(i=>BL(r,e,i)));uE(n,t,"stop")}async function Tt(){let r=await C.new();return{manager:Co.from(r),toolProvider:r}}async function qr(r,e,t){let n={event:v.CommandExecuted,args:["emulator",t,"--target"]};await At(n,async()=>{let i=kL(r.target),o=e(),s=Array.isArray(o)?o:[o],{manager:a,toolProvider:c}=await Tt(),l=await fE(c.hdcPath,i);for(let d of s)await a.controlEmulator(l,d);console.log(va(`Emulator "${i}" operation completed.`))})}function VL(r){let e=[];if(md(e,"longitude",r.longitude,-180,180,8),md(e,"latitude",r.latitude,-90,90,8),md(e,"altitude",r.altitude,-1e4,1e4,2),md(e,"bearing",r.direction,0,359.99,2,"--direction"),e.length===0)throw new Error("Specify at least one geolocation option.");return(r.longitude===void 0||r.latitude===void 0)&&console.warn(En("Warning: --longitude and --latitude should be specified together to form a valid location.")),e}function GL(r){let e=[];if(ya(e,"light",r.lightIntensity,0,1e5,!1,"--light-intensity"),ya(e,"humidity",r.humidity,0,100,!1),ya(e,"temperature",r.temperature,-273.1,100,!1),ya(e,"steps",r.steps,0,1e4,!0),ya(e,"heartrate",r.heartrate,0,255,!0),e.length===0)throw new Error("Specify at least one sensor option.");return e}function md(r,e,t,n,i,o,s=`--${e}`){t!==void 0&&r.push({type:"gps",key:e,value:dE(s,t,n,i,o)})}function ya(r,e,t,n,i,o,s=`--${e}`){if(t===void 0)return;let a=o?lE(s,t,n,i):bi(s,t,n,i,1);r.push({type:"sensor",key:e,value:a})}function qL(r){let e=[];if(r.status!==void 0){let i=r.status==="charging"?1:0;e.push({type:"battery-status",status:i})}if(r.level!==void 0&&e.push({type:"battery",level:lE("--level",r.level,0,100),assumedCharging:r.status==="charging"}),e.length===0)throw new Error("Specify --level or --status.");let t=e.some(i=>i.type==="battery"&&i.level===0),n=e.some(i=>i.type==="battery-status"&&i.status===0);if(t&&n)throw new Error("Battery level 0 is only allowed while charging; --level 0 cannot be combined with --status discharging.");return e}var Ee=new Qm("emulator").description("Manage emulator instances");Ee.configureOutput({outputError:(r,e)=>{e(r),/too many arguments/i.test(r)&&e(`
1309
+ ${En("Tip: ")}${Xm("An option value containing spaces/parentheses must be quoted. Use:")}
1310
+ ${_o('devecocli emulator <subcommand> --<option> "value with spaces"')}
1311
+ ${_o('devecocli emulator <subcommand> --<option>="value with spaces"')}
1312
+ `)}});Ee.hook("preAction",async()=>{(await C.new()).require({studio:CL})});var zL=["phone","foldable","widefold","triplefold","tablet","2in1","2in1 foldable","wearable","tv"];function tg(r){let e=new Je("--device-type <type>","Emulator device type").choices([...zL]);return r?e.makeOptionMandatory():e}function JL(){return new Je("--device-type <type>","Emulator device type (case-insensitive)").argParser(r=>{if(!r.trim())throw new Ym("--device-type must not be empty.");return r}).makeOptionMandatory()}function KL(r){if(r!==void 0){if(r.length>=4&&r.length%4===0&&r.every(e=>/^\d+(?:\.\d+)?$/.test(e)))throw new Error('--screen value must be quoted: --screen "1316 2832 560 6.9".');if(r.length>2)throw new Error("--screen accepts one or two configurations.");for(let[e,t]of r.entries()){let n=t.trim().split(/\s+/),i=r.length===1?"--screen":`--screen configuration ${e+1}`;if(n.length!==4||n.some(o=>o.length===0))throw new Error(`${i} must contain four values: width(px), height(px), DPI, and screen diagonal length(inch).`);bi(`${i} width`,n[0],720,3500),bi(`${i} height`,n[1],720,3500),bi(`${i} DPI`,n[2],240,640),bi(`${i} screen diagonal length`,n[3],3.5,9)}return r}}function YL(r){return["--device-type","--os-version",...r.instancePath!==void 0?["--instance-path"]:[],...r.imageRoot!==void 0?["--image-root"]:[],...r.screenProfile!==void 0?["--screen-profile"]:[],...r.screen!==void 0?["--screen"]:[],...r.storage!==void 0?["--storage"]:[],...r.memory!==void 0?["--memory"]:[],...r.hotBoot!==void 0?["--hot-boot"]:[],...r.force?["--force"]:[]]}function Oo(r,e){for(let t of e)if(t in r)return r[t]}function wa(r){return r==null?"":typeof r=="string"?r.trim():String(r).trim()}function cE(r){let e=wa(r).toLowerCase();return e==="true"?"true":e==="false"?"false":e}var XL=["OS Version","Device Type","Software Version","Release Type","Upgradable","Downloaded"],ZL="No matching system images found. Try `devecocli emulator image list --all`, then download an image via `devecocli emulator image download ...`.";async function QL(r,e,t){if(!await r.hasAvailableEmulatorImage({deviceType:e,osVersion:t}))throw new Error(`Invalid --os-version value "${t}".
1313
+ Run \`devecocli emulator image list --all\` and use an exact OS Version value.`)}function mE(r){try{let e=JSON.parse(r);return Array.isArray(e)?e:null}catch{return null}}function gE(r,e){let t=[];for(let n of r){if(!n||typeof n!="object")continue;let i=n,o=wa(Oo(i,["osVersion","OsVersion","OSVersion","os_version"])),s=wa(Oo(i,["deviceType","DeviceType","device_type"])),a=cE(Oo(i,["downloaded","Downloaded","isDownloaded"])),c=wa(Oo(i,["SoftWareVersion","SoftwareVersion","softwareVersion","software_version","version"])),l=wa(Oo(i,["releaseType","ReleaseType","release_type"])),d=cE(Oo(i,["upgradable","Upgradable","isUpgradable"]));t.push({cells:[o,s,c,l,d,a],highlight:e&&a==="true"})}return t}function e0(r){let e=r.trim();if(!e)return!0;let t=mE(e);return t===null?!1:t.length===0?!0:gE(t,!0).length===0}function t0(r,e){let t=r.trim();if(!t)return"";let n=mE(t);if(!n)return r.trimEnd();let i=gE(n,e);return zt(XL,i)}var gd=new Qm("image").description("HarmonyOS emulator system images (download, list, remove)");gd.command("download").description("Download system image").addOption(tg(!1)).option("--os-version <version>","Example: HarmonyOS 5.1.1(19) or HarmonyOS 6.0.1(21) (required)").option("--force","Overwrite an existing image").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","download",...r.deviceType?["--device-type"]:[],...r.osVersion?["--os-version"]:[],...r.force?["--force"]:[]]};await At(e,async()=>{let{manager:t,toolProvider:n}=await Tt();await Km(n.emulatorPath,n.sdkPath);let i=r.deviceType?.trim(),o=r.osVersion?.trim();if(!i)throw new w("Error: missing required option '--device-type <type>'","Missing required device type.");if(!o)throw new w("Error: misssing required option '--os-version <version>'","Missing required OS version.");await QL(t,i,o),await t.installEmulatorImage({deviceType:i,osVersion:o,force:r.force===!0})})});gd.command("remove").description("Remove a downloaded system image").addOption(tg(!0)).requiredOption("--os-version <version>","Supports both image label (HarmonyOS x.y.z(n)) and softwareVersion").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","remove","--device-type","--os-version"]};await At(e,async()=>{let{manager:t}=await Tt();await t.uninstallEmulatorImage({deviceType:r.deviceType,osVersion:r.osVersion})})});gd.command("list").description("List system images").addOption(tg(!1)).option("--all","List all images (local and remote)").addOption(new Je("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["emulator","image","list",...r.deviceType?["--device-type"]:[],...r.all?["--all"]:[],...r.format!=="table"?["--format"]:[]]};await At(e,async()=>{let{manager:t}=await Tt(),n;r.all?n=void 0:n=!0;let i=await t.listEmulatorImages({deviceType:r.deviceType,downloaded:n});if(e0(i)){console.log(En(ZL));return}if(r.format==="json"){console.log(i.trimEnd());return}let o=t0(i,r.all===!0);console.log(o)})});Ee.addCommand(gd);var hd=new Qm("license").description("Review and accept emulator license agreements interactively (prints full text + y/N prompt)");hd.command("view").description("Review agreement text (read-only, no changes)").action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license","view"]};await At(r,async()=>{let{toolProvider:e}=await Tt(),t=await nE(e.emulatorPath,e.sdkPath);process.exitCode=t})});hd.command("accept").description("Accept all emulator license agreements non-interactively (skips review and prompt)").action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license","accept"]};await At(r,async()=>{let{toolProvider:e}=await Tt(),t=await sE(e.emulatorPath,e.sdkPath);process.exitCode=t})});hd.action(async()=>{let r={event:v.CommandExecuted,args:["emulator","license"]};await At(r,async()=>{let{toolProvider:e}=await Tt(),t=await oE(e.emulatorPath,e.sdkPath);process.exitCode=t})});Ee.addCommand(hd);Ee.command("shake").description("Trigger shake event").requiredOption("--target <nameOrSerial>","Target emulator name or serial").action(r=>qr(r,()=>({type:"shake"}),"shake"));Ee.command("power").description("Press power button (toggle screen on/off)").requiredOption("--target <nameOrSerial>","Target emulator name or serial").action(r=>qr(r,()=>({type:"power"}),"power"));Ee.command("rotate").description("Rotate emulator").addOption(new Je("--target <nameOrSerial>","Target emulator name or serial").makeOptionMandatory()).addArgument(new Zm("<direction>").choices(["left","right"])).action((r,e)=>qr(e,()=>({type:"rotation",direction:r}),"rotate"));Ee.command("volume").description("Change volume").addOption(new Je("--target <nameOrSerial>","Target emulator name or serial").makeOptionMandatory()).addArgument(new Zm("<direction>").choices(["up","down"])).action((r,e)=>qr(e,()=>({type:"volume",direction:r}),"volume"));Ee.command("fold <state>").description("Set foldable display state").requiredOption("--target <nameOrSerial>","Target emulator name or serial").addHelpText("after",PL).action((r,e)=>qr(e,()=>({type:"folded-state",state:RL(r)}),"fold"));Ee.command("battery").description("Set battery level and/or charging status").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--level <0-100>","Battery level, SOC (charging: 0-100; not charging: 1-100)").addOption(new Je("--status <status>","Charging status").choices(["charging","discharging"])).action(r=>qr(r,()=>qL(r),"battery"));Ee.command("geolocation").description("Inject geographic coordinates and direction").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--longitude <value>","Longitude (-180.0 to 180.0)").option("--latitude <value>","Latitude (-90.0 to 90.0)").option("--altitude <value>","Altitude (-10000.0 to 10000.0)").option("--direction <value>","Heading direction in degrees (0.00 to 359.99)").action(r=>qr(r,()=>VL(r),"geolocation"));Ee.command("scene").description("Start motion simulation scene").requiredOption("--target <nameOrSerial>","Target emulator name or serial").addArgument(new Zm("<type>","Motion simulation scene").choices(["outdoorRunning","outdoorCycling","drivingNavigation"])).action((r,e)=>{let t={outdoorRunning:{type:"outdoor-running"},outdoorCycling:{type:"outdoor-cycling"},drivingNavigation:{type:"driving-navigation"}};return qr(e,()=>t[r],"scene")});Ee.command("sensor").description("Inject sensor data").requiredOption("--target <nameOrSerial>","Target emulator name or serial").option("--light-intensity <value>","Light sensor (0 to 100000)").option("--humidity <value>","Humidity sensor (0 to 100)").option("--temperature <value>","Temperature sensor (-273.1 to 100)").option("--steps <value>","Steps sensor (integer 0 to 10000)").option("--heartrate <value>","Heart rate sensor (integer 0 to 255)").action(r=>qr(r,()=>GL(r),"sensor"));Ee.command("list").description("List all emulator instances").addOption(new Je("--details","Output the raw JSON of `Emulator -list -details` without transformation").conflicts("format")).addOption(new Je("--format <format>","Output format").choices(["table","json"]).default("table")).action(async r=>{let e={event:v.CommandExecuted,args:["emulator","list",...r.details?["--details"]:[],...r.format!=="table"?["--format"]:[]]};await At(e,async()=>{let{manager:t,toolProvider:n}=await Tt();if(r.details){let o=await t.listEmulatorDetails();console.log(o.trimEnd());return}let i=r.format==="table"?SL({text:"Listing emulators\u2026",color:"cyan"}).start():void 0;await ML(t,n.hdcPath,r.format,i)})});function r0(r){let e=r.trim();if(!/^\d+$/.test(e))throw new Ym("--hdcport must be an integer in [10000, 16555].");let t=Number(e);if(t<1e4||t>16555)throw new Ym("--hdcport must be in [10000, 16555].");return t}function n0(r){return{hdcPort:r.hdcport,bootMode:r.bootMode,noWindow:r.window===!1}}function i0(r){return[...r.hdcport!==void 0?["--hdcport"]:[],...r.bootMode!==void 0?["--boot-mode"]:[],...r.window===!1?["--no-window"]:[]]}Ee.command("start [names...]").description("Start one or more emulator instances").addOption(new Je("--hdcport <port>","hdc port of the emulator, 10000-16555 (Emulator -hdcport)").argParser(r0)).addOption(new Je("--boot-mode <mode>","Boot mode (Emulator -bootMode): coldboot = cold start keeping user data, snapshot = hot start restoring the last snapshot (needs Quick Boot), reset = wipe data then cold start; overrides the mode chosen when the instance was created").choices(["coldboot","snapshot","reset"])).addOption(new Je("--no-window","Start the emulator without a window (Emulator -noWindow); required on Linux hosts without a GUI")).action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","start",...i0(e)],emulatorMemory:"unknown",hotBoot:null};await At(t,async()=>{let{manager:n,toolProvider:i}=await Tt();if(await Jm(i.emulatorPath,i.sdkPath),!r?.length)throw new w("Error: missing required argument 'names'","Missing required emulator name.");if(r.length>1&&e.hdcport!==void 0)throw new w(`Error: --hdcport cannot target ${r.length} emulators.`,"--hdcport sets the hdc port of a single emulator; pass one name, or omit --hdcport.");let o=await UL(n,i.hdcPath,r,n0(e));t.emulatorMemory=o.emulatorMemory,t.hotBoot=o.hotBoot})});Ee.command("stop <names...>").description("Stop one or more emulator instances (by name or serial,e.g.,127.0.0.1:<port>)").action(async r=>{let e={event:v.CommandExecuted,args:["emulator","stop"]};await At(e,async()=>{let{manager:t,toolProvider:n}=await Tt();if(!r?.length){console.error(eg("Error: missing required argument 'names'")),process.exitCode=1;return}await WL(t,n.hdcPath,r)})});var o0=Ee.command("create <name>").description("Create a local emulator instance.").addOption(JL()).requiredOption("--os-version <version>",'Downloaded image label. which will be quoted in PowerShell (e.g. "HarmonyOS 6.0.1(21)") or be used in the format --os-version="\u2026";For details, run`devecocli emulator image list`').addOption(new Je("--path, --instance-path <path>","Emulator instance path")).option("--image-root <path>","Emulator image path").option("--screen-profile <model>","Emulator screen profile").addOption(new Je("--screen <config...>",'Screen: "width(px) height(px) DPI screen-diagonal-length(inch)" (720-3500, 720-3500, 240-640, 3.5-9); pass two values for a foldable device')).option("--storage <size>","Storage size in GB (2-1023)").option("--memory <size>","Memory size in GB (2-32)").addOption(new Je("--hot-boot <boolean>","Enable or disable hot boot").choices(["true","false"])).option("--force","Overwrite an existing emulator instance");o0.action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","create",...YL(e)]};await At(t,async()=>{if(!e.osVersion.trim())throw new Error("--os-version must not be empty.");let n={name:r,deviceType:e.deviceType,osVersion:e.osVersion,instancePath:e.instancePath,imageRoot:e.imageRoot,screenProfile:e.screenProfile,screen:KL(e.screen),storage:e.storage===void 0?void 0:bi("--storage",e.storage,2,1023),memory:e.memory===void 0?void 0:bi("--memory",e.memory,2,32),hotBoot:e.hotBoot===void 0?void 0:e.hotBoot==="true",force:e.force===!0},{manager:i}=await Tt();console.log(_o(`Creating emulator "${r}"...`)),await i.createVirtualDevice(n),console.log(va(`Emulator "${r}" created successfully.`))})});Ee.command("delete <name>").description("Delete a local emulator instance").addOption(new Je("--path, --instance-path <path>","Emulator instance path")).action(async(r,e)=>{let t={event:v.CommandExecuted,args:["emulator","delete",...e.instancePath!==void 0?["--instance-path"]:[]]};await At(t,async()=>{let{manager:n}=await Tt();console.log(_o(`Deleting emulator "${r}"...`));let i=await n.deleteVirtualDevice(r,e.instancePath);console.log(va(`Emulator "${i}" deleted successfully.`))})});var hE=Ee;import{Command as E0}from"commander";import{red as lg,cyan as Qt}from"colorette";import*as $E from"readline";import*as LE from"crypto";import*as yE from"http";import*as wE from"crypto";import{URL as s0}from"url";var yd=class{server=null;port=0;clientSecret;callbackPath="/callback";resolveCallback=null;rejectCallback=null;timeoutId=null;baseUrl;successRedirectUrl;failedRedirectUrl;constructor(e,t,n,i){this.clientSecret=e,this.baseUrl=t,this.successRedirectUrl=n,this.failedRedirectUrl=i}async start(){return new Promise((e,t)=>{let n=yE.createServer((i,o)=>{this.handleRequest(i,o)});n.keepAliveTimeout=1,n.on("error",i=>{t(new Error("Failed to start local auth server",{cause:i}))}),n.listen(0,"127.0.0.1",()=>{this.server=n;let i=n.address();this.port=i.port,e()})})}async waitForCallback(e=3e4){return new Promise((t,n)=>{this.resolveCallback=i=>{this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),t(i)},this.rejectCallback=i=>{this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),n(i)},this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.rejectCallback?.(new Error("Callback timeout"))},e)})}async stop(){return this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=null),this.server?new Promise(e=>{let t=this.server;this.server=null,typeof t.closeAllConnections=="function"&&t.closeAllConnections();let n=setTimeout(()=>{e()},100);t.close(()=>{clearTimeout(n),e()})}):Promise.resolve()}handleRequest(e,t){let n=e.headers.host||"";if(![`127.0.0.1:${this.port}`,`localhost:${this.port}`].includes(n.toLowerCase())){t.writeHead(400),t.end("Bad Host");return}let o=new s0(e.url??"",`http://${n}`);if(o.pathname!==this.callbackPath){t.writeHead(404),t.end("Not Found");return}try{let s=o.searchParams;e.method==="POST"?this.readBody(e,t,s):this.handleCallbackRequest(e,t,s,"")}catch(s){t.writeHead(500),t.end("Internal Server Error"),this.rejectCallback?.(s)}}readBody(e,t,n){let i="",o=0,s=65536;e.on("data",a=>{if(o+=a.length,o>s){e.destroy(new Error("Request body too large"));return}i+=a.toString()}),e.on("end",()=>{this.handleCallbackRequest(e,t,n,i)})}handleCallbackRequest(e,t,n,i){try{let o=this.parseParams(n,i),s=o.get("code"),a=o.get("tempToken"),c=o.get("siteId"),l=o.get("quit");if(!this.validateCode(s)){t.writeHead(400),t.end("Bad Request");return}if(this.isQuitRequest(l)){this.handleQuitRequest(t);return}if(!a||!c){t.writeHead(400),t.end("Bad Request");return}let d={tempToken:a,siteId:c,quit:l??void 0};this.resolveCallback?.(d),this.sendSuccessResponse(t)}catch(o){t.writeHead(500),t.end("Internal Server Error"),this.rejectCallback?.(o)}}parseParams(e,t){return t&&t.trim()?new URLSearchParams(t):e}validateCode(e){let t=Buffer.from(e||"","utf8"),n=Buffer.from(this.clientSecret,"utf8");return t.length===n.length&&wE.timingSafeEqual(t,n)}isQuitRequest(e){return e==="true"||e==="access_denied"||e==="quit"}handleQuitRequest(e){this.rejectCallback?.(new Error("User quit the login process")),e.writeHead(302,{Location:`${this.baseUrl}/${this.failedRedirectUrl}`}),e.end()}sendSuccessResponse(e){e.writeHead(302,{Location:`${this.baseUrl}/${this.successRedirectUrl}`}),e.end()}getPort(){return this.port}};import*as ct from"fs";import*as Pn from"path";import{homedir as d0}from"os";var zr={};KR(zr,{LocalCrypto:()=>zr,decryptForLocalStorage:()=>og,decryptForLocalStorageFromDirectory:()=>l0,encryptForLocalStorage:()=>ig,isEncryptedBlob:()=>sg});import*as pe from"fs";import*as Ye from"path";import*as at from"crypto";import*as bE from"os";import{homedir as SE}from"os";var Ke=class extends Error{constructor(e){super(e),this.name="DefinedError"}};var ba=zn.ALGORITHM,EE=zn.IV_LENGTH,Sa=zn.KEY_LENGTH,Ea=zn.KEY_LENGTH,Si=zn.KEK_VERSIONS,wd=process.env.DEVECO_CLI_DATA_DIR?$():Ye.join(SE(),Se.CONFIG_DIR_NAME,Se.APP_NAME),vd=Ye.join(SE(),".local","share",Se.APP_NAME,"keys"),Mo=Ye.join(wd,Se.KEY_FILE_NAME);function vE(r){return bE.platform()==="win32"?`Permission denied. Please run as administrator or grant write permission to ${r}.`:`Permission denied. You can try: sudo chown -R $(whoami) ${r}`}function rg(r){return Ye.join(vd,`${r}.bin`)}function PE(){if(!pe.existsSync(wd))try{pe.mkdirSync(wd,{recursive:!0,mode:448})}catch(r){throw r.code==="EACCES"?new Ke(vE(wd)):r}if(!pe.existsSync(vd))try{pe.mkdirSync(vd,{recursive:!0,mode:448})}catch(r){throw r.code==="EACCES"?new Ke(vE(Ye.dirname(vd))):r}}function CE(){PE();for(let r of Si){let e=rg(r);pe.existsSync(e)||pe.writeFileSync(e,at.randomBytes(Sa),{mode:384})}}function kE(r){if(!Si.includes(r))throw new Error(`Invalid kekId: ${r}`);CE();let e=rg(r),t=pe.readFileSync(e);if(t.length===Sa)return t;let n=at.randomBytes(Sa);return pe.writeFileSync(e,n,{mode:384}),n}function ng(r,e){let t=at.randomBytes(EE),n=kE(e),i=at.createCipheriv(ba,n,t),o=Buffer.concat([i.update(r),i.final()]),s=i.getAuthTag();return{version:1,algorithm:ba,kekId:e,encryptedDek:o.toString("base64"),iv:t.toString("base64"),authTag:s.toString("base64"),timeStamp:Date.now()}}function RE(r,e){return xE(Buffer.from(r.encryptedDek,"base64"),e,r.iv,r.authTag)}function xE(r,e,t,n){let i=at.createDecipheriv(ba,e,Buffer.from(t,"base64"));return i.setAuthTag(Buffer.from(n,"base64")),Buffer.concat([i.update(r),i.final()])}function DE(r,e){return xE(Buffer.from(r.ciphertext,"base64"),e,r.iv,r.authTag).toString("utf8")}function a0(){if(CE(),pe.existsSync(Mo))return;let r=at.randomBytes(Ea),e=ng(r,Si[0]);pe.writeFileSync(Mo,JSON.stringify(e,null,2),{mode:384})}function IE(){a0();let r=JSON.parse(pe.readFileSync(Mo,"utf8")),e=RE(r,kE(r.kekId));if(e.length===Ea)return e;let t=at.randomBytes(Ea),n=ng(t,Si[0]);return pe.writeFileSync(Mo,JSON.stringify(n,null,2),{mode:384}),t}function c0(){PE();for(let t of Si){let n=rg(t);pe.existsSync(n)||pe.writeFileSync(n,at.randomBytes(Sa),{mode:384})}if(pe.existsSync(Mo))return;let r=at.randomBytes(Ea),e=ng(r,Si[0]);pe.writeFileSync(Mo,JSON.stringify(e,null,2),{mode:384})}function ig(r){let e=IE(),t=at.randomBytes(EE),n=at.createCipheriv(ba,e,t),i=Buffer.concat([n.update(r,"utf8"),n.final()]),o=n.getAuthTag();return{version:1,algorithm:ba,ciphertext:i.toString("base64"),iv:t.toString("base64"),authTag:o.toString("base64"),timeStamp:Date.now()}}function og(r){try{return DE(r,IE())}catch{throw c0(),new Error("Failed to decrypt local ciphertext")}}function l0(r,e){let t=Ye.join(e,Se.KEY_FILE_NAME),n=JSON.parse(pe.readFileSync(t,"utf8"));if(!Si.includes(n.kekId))throw new Error(`Invalid kekId: ${n.kekId}`);let i=Ye.join(e,"keys",`${n.kekId}.bin`),o=Ye.resolve(i),s=Ye.resolve(Ye.join(e,"keys"));if(!o.startsWith(s+Ye.sep)&&o!==s)throw new Error("kekId resolves outside the keys directory");let a=pe.readFileSync(o);if(a.length!==Sa)throw new Error("Invalid external root key");let c=RE(n,a);if(c.length!==Ea)throw new Error("Invalid external data encryption key");return DE(r,c)}function sg(r){if(!r||typeof r!="object")return!1;let e=r;return e.algorithm==="aes-256-gcm"&&typeof e.ciphertext=="string"&&typeof e.iv=="string"&&typeof e.authTag=="string"}function vt(){return process.env.DEVECO_CLI_AUTH_SOURCE===Se.AUTH_SOURCE_DEVECO_CODE}var bd=class{getLocalTokenFilePath(){let e=process.env.DEVECO_CLI_DATA_DIR?$():Pn.join(d0(),Se.CONFIG_DIR_NAME,Se.APP_NAME);return Pn.join(e,Se.TOKEN_FILE_NAME)}ensureConfigDir(){let e=Pn.dirname(this.getLocalTokenFilePath());ct.existsSync(e)||ct.mkdirSync(e,{recursive:!0,mode:448})}async saveJwtToken(e){if(!e)throw new Error("Token is empty");let t=zr.encryptForLocalStorage(e);this.ensureConfigDir();let n=this.getLocalTokenFilePath();ct.writeFileSync(n,JSON.stringify(t,null,2),{mode:384})}async loadJwtToken(){return vt()?this.loadDevecoCodeToken():this.loadLocalJwtToken()}loadDevecoCodeToken(){if(!vt())return null;let e=process.env.DEVECO_CODE_AUTH_DIR?.trim();if(!e)return null;let t=Pn.resolve(e);try{let n=Pn.join(t,Se.TOKEN_FILE_NAME);if(!ct.existsSync(n))return null;let i=JSON.parse(ct.readFileSync(n,"utf8"));return zr.isEncryptedBlob(i)?zr.decryptForLocalStorageFromDirectory(i,e):null}catch{return null}}async loadLocalJwtToken(){let e=this.getLocalTokenFilePath();try{if(!ct.existsSync(e))return null;let t=JSON.parse(ct.readFileSync(e,"utf8"));return zr.isEncryptedBlob(t)?zr.decryptForLocalStorage(t):null}catch(t){let n=t.code;return n==="EACCES"||n==="EPERM"||n==="ENOENT"||await this.clearToken(),null}}async clearToken(){if(vt()){f("clearToken: skipped, session managed by DevEco Code");return}let e=this.getLocalTokenFilePath();try{ct.existsSync(e)&&ct.unlinkSync(e)}catch(t){throw new Error("Failed to clear token",{cause:t})}}},Jr=new bd;import{spawn as u0}from"child_process";function p0(r){try{let e=new URL(r);return!(!["http:","https:"].includes(e.protocol)||e.hostname===""||r.includes('"'))}catch{return!1}}function f0(r){return r.replace(/[&|<>()^%!]/g,e=>`^${e}`)}async function AE(r){if(!p0(r))throw new Error(`Invalid URL: ${JSON.stringify(r)}`);let e,t;switch(process.platform){case"win32":e="cmd",t=["/c","start",'""',f0(r)];break;case"darwin":e="open",t=[r];break;default:e="xdg-open",t=[r];break}let n=u0(e,t,{stdio:"ignore",shell:!1,windowsHide:!0});return new Promise((i,o)=>{n.on("error",s=>{o(new Error("Failed to open browser",{cause:s}))}),n.on("close",s=>{s===0?i():o(new Error(`Browser process exited with code ${s}`))})})}function TE(r){let e=r.split(".");return e.length===3&&e.every(t=>t.length>0)}var Kr={CHINA:"CN",RUSSIA:"RU",SINGAPORE:"SG",EUROPE:"EU"},Ei={CHINA:"zh_CN",RUSSIA:"ru_RU",EUROPE:"de_DE"},Sd={CHINA:"1",SINGAPORE:"5",EUROPE:"7",RUSSIA:"8"},m0={[Kr.CHINA]:Ei.CHINA,[Kr.RUSSIA]:Ei.RUSSIA,[Kr.EUROPE]:Ei.EUROPE,[Kr.SINGAPORE]:Ei.CHINA},g0={[Sd.CHINA]:Kr.CHINA,[Sd.SINGAPORE]:Kr.SINGAPORE,[Sd.EUROPE]:Kr.EUROPE,[Sd.RUSSIA]:Kr.RUSSIA};function NE(r){return m0[r]??Ei.CHINA}function OE(r){return g0[r]??Kr.CHINA}var ag=class{async getJwtToken(e,t,n,i,o){let s=e.split("&")[0],a=OE(t),c={tempToken:s,site:a,version:Se.API_VERSION,appid:o},l=`${n}/${i}`,d=await j.get(l,{params:c});if(d.statusCode!==200)throw new Error(`Failed to get jwtToken: status=${d.statusCode}`);let g=d.data.trim();if(!TE(g))throw new Error("Invalid jwtToken format");return g}},_E=new ag;var cg=class{async checkJwtToken(e,t,n=!1){let i={refresh:String(n),jwtToken:e},o=`${t}/${oe.JWT_TOKEN_CHECK_PATH}`,s=await j.get(o,{headers:i});if(s.statusCode!==200)throw new Error(`Failed to check jwtToken: ${s.statusCode}`);return j.parseJson(s)}async refreshToken(e){let t=await Jr.loadJwtToken();return t?this.refreshTokenWithToken(t,e):null}async refreshTokenWithToken(e,t){try{let n={refresh:"true",jwtToken:e},i=`${t}/${oe.JWT_TOKEN_CHECK_PATH}`,o=await j.get(i,{headers:n});if(o.statusCode!==200)return null;let s=j.parseJson(o);return!s.status||!s.userInfo?null:{accessToken:s.userInfo.accessToken,refreshToken:s.userInfo.refreshToken??""}}catch(n){let i=n;return console.error(`Failed to refresh token: ${i.code??""} ${i.message??""}`),null}}async getUserInfoFromJwt(e,t,n=!1){let i=await this.checkJwtToken(e,t,n);return!i.status||!i.userInfo||!i.userInfo.accessToken?(f("jwtToken invalid."),await Jr.clearToken(),null):{userId:i.userInfo.userId??"",userName:i.userInfo.name??"",accessToken:i.userInfo.accessToken,refreshToken:i.userInfo.refreshToken??"",jwtToken:e,countryCode:i.userInfo.nationalCode,language:NE(i.userInfo.nationalCode),isRealName:String(i.userInfo.realName)==="true"}}async fetchUserInfo(e,t){let n=await Jr.loadJwtToken();return n?this.getUserInfoFromJwt(n,e,t):null}},Lo=new cg;import h0 from"querystring";import{spawn as y0}from"child_process";function ME(r){try{let e=JSON.stringify({signInfo:[{agrType:fs.PRIVACY_ID,country:"CN",language:"zh_CN",isAgree:!0}]}),t=h0.stringify({nsp_svc:"as.user.sign",access_token:r,request:e}),n=y0("curl",["-s","-X","POST",fs.TMS_URL,"-H","Content-Type: application/x-www-form-urlencoded","-d",t,"--max-time","5","-o","/dev/null","-w","%{http_code}"],{detached:!0,stdio:["ignore","pipe","ignore"]});n.unref(),n.stdout?.on("data",i=>{let o=i.toString().trim();o==="200"?f("Agreement sign reported successfully"):f(`Agreement sign failed: HTTP ${o}`)}).on("error",()=>{})}catch(e){f(`Agreement sign error: ${e.message}`)}}var Ed=class{config;server=null;constructor(e){this.config={...ms,...e}}updateConfig(e){this.config={...this.config,...e}}getConfig(){return{...this.config}}async login(){try{f(`Login started, isDevecoCodeAuth: ${vt()}`);let e=this.generateClientSecret();this.server=new yd(e,oe.CN_LOGIN_URL,this.config.successRedirectUrl,this.config.failedRedirectUrl),await this.server.start(),f(`Local auth server started on port ${this.server.getPort()}`),await this.openLoginPage(this.server.getPort(),e),f("Browser opened for authentication");let t=await this.server.waitForCallback(this.config.timeout);if(f(`Callback received: siteId=${t.siteId}`),t.siteId!=="1")throw new Ke("Non-China accounts are not supported.");let n=await _E.getJwtToken(t.tempToken,t.siteId,oe.CN_LOGIN_URL,this.config.tempTokenCheckUrl,this.config.appId);f("JWT token received");let i=await Lo.getUserInfoFromJwt(n,oe.CN_LOGIN_URL);if(!i)throw new Ke("Login failed: failed to get user info");return f(`User info received: ${i.userName}`),await Jr.saveJwtToken(n),f("JWT token saved"),ME(i.accessToken),i}finally{this.server&&(await this.server.stop(),this.server=null)}}async isLoggedIn(){return await this.getUserInfo(!0)!==null}async logout(){let e=await Jr.loadJwtToken();if(!e)return!1;let n=`${oe.CN_LOGIN_URL}/${this.config.logoutUrl}?jwtToken=${e}`;try{await j.post(n,{timeout:5e3})}catch{f("Logout: server notification failed, local token cleared")}finally{await Jr.clearToken()}return!0}async getUserInfo(e=!0){return Lo.fetchUserInfo(oe.CN_LOGIN_URL,e)}generateClientSecret(){return LE.randomUUID().replace(/-/g,"")}async openLoginPage(e,t){let i=`${oe.CN_LOGIN_URL}/${this.config.authUrl}?port=${e}&appid=${this.config.appId}&code=${t}`;await AE(i)}async refreshToken(){return Lo.refreshToken(oe.CN_LOGIN_URL)}},Xe=new Ed;function v0(){return vt()?"Not logged in. Please login via DevEco Code first.":"Please run `devecocli auth login` first."}function b0(r){if(r.length===0)return"";let e=Math.max(1,Math.floor(r.length/2));return`${r.slice(0,e)}****`}function S0(r){if(r==null||typeof r!="object")return[];let e=r;if(e.ret&&e.ret.code!==0)throw new Error(`team list request failed: code=${e.ret.code}${e.ret.msg?`, msg=${e.ret.msg}`:""}`);return Array.isArray(e.teams)?e.teams.filter(t=>typeof t=="object"&&t!==null).map(t=>({id:String(t.id??""),upSiteId:Number(t.upSiteId??0),name:b0(String(t.name??"")),countryCode:String(t.countryCode??""),siteId:Number(t.siteId??0),userType:Number(t.userType??0),lastLoginTime:String(t.lastLoginTime??""),isMirror:t.isMirror===!0})).filter(t=>t.id.length>0):[]}var Pd=class{config;constructor(e){this.config={...ms,...e}}updateConfig(e){this.config={...this.config,...e}}async listTeams(){let e=await Lo.fetchUserInfo(oe.CN_LOGIN_URL,!0);if(!e)throw new Ke(v0());let t=await this.fetchTeamList(e.accessToken,e.userId),n=S0(t);return{userId:e.userId,teamList:n}}async fetchTeamList(e,t){let n=this.config.agcTeamListUrl,i;try{i=await j.get(n,{headers:{oauth2Token:e,uid:t,source:"cli",lang:Ei.CHINA},timeout:15e3})}catch(o){let s=o.message;throw s.includes("401")?new Ke("Token expired. Run `devecocli auth login` again."):new Error(`Network error while listing teams: ${s}`,{cause:o})}if(i.statusCode!==200)throw new Error(`Failed to list teams: HTTP ${i.statusCode}`);return typeof i.data=="string"?JSON.parse(i.data):i.data}},FE=new Pd;async function Cn(){return FE.listTeams()}async function Cd(r,e,t){let n=Date.now(),i=!0,o=null;try{await e()}catch(s){i=!1,o=Z(s);let a=t?.(s);if(a)throw a}finally{let s={duration_ms:Date.now()-n,success:i,error_code:o};await R.track(r,s)}}function P0(r){if(r.length===0)return Qt("No teams found for the current user.");let e=["Id","Name"],t=r.map(s=>[s.id,s.name]),n=e.map((s,a)=>Math.max(s.length,...t.map(c=>c[a].length))),i=s=>s.map((a,c)=>a.padEnd(n[c])).join(" "),o=n.map(s=>"-".repeat(s)).join(" ");return[i(e),o,...t.map(i)].join(`
1314
+ `)}function C0(){return new Promise(r=>{let e=$E.createInterface({input:process.stdin,output:process.stdout});e.question("",()=>{e.close(),r()})})}var Pa=new E0("auth").description("Authentication commands (login, logout, status, team)");async function k0(r){if(r||!process.stdin.isTTY){console.log(Qt(r?"Opening browser for login... (--no-prompt: Enter confirmation skipped)":"Non-interactive terminal: opening browser for login without the Enter confirmation..."));return}console.log(Qt("Press Enter to open browser for login (or pass --no-prompt to skip)...")),await C0()}async function R0(r){if(vt()){console.log(lg("Login is managed by DevEco Code. Login from DevEco Code instead."));return}let e={event:v.CommandExecuted,args:["auth","login"]};await Cd(e,async()=>{let t=await Xe.getUserInfo();if(t){console.log(Qt(`Already logged in, User Name:${t.userName}`));return}console.log(Qt("Starting login process...")),await k0(r.prompt===!1);let n=await Xe.login();console.log(Qt(`Login successful. Logged in as ${n.userName}.`))},t=>{throw t instanceof Ke||(t instanceof Error?t.message:String(t)).includes("Network connection failed")?t:new Error("Login failed",{cause:t})})}Pa.command("login").description("Log in to your Huawei Developer account").option("--no-prompt","Open the browser immediately without the interactive Enter confirmation (agents and non-interactive terminals)").action(async r=>{await R0(r)});Pa.command("logout").description("Log out of your Huawei Developer account").action(async()=>{if(vt()){console.log(lg("Login is managed by DevEco Code. Log out from DevEco Code instead."));return}let r={event:v.CommandExecuted,args:["auth","logout"]};await Cd(r,async()=>{let e=await Xe.logout();console.log(e?Qt("Logout successful"):Qt("Already logged out."))},e=>new Error("Logout failed",{cause:e}))});Pa.command("status").description("Show the currently logged-in user").action(async()=>{let r={event:v.CommandExecuted,args:["auth","status"]};await Cd(r,async()=>{let e=await Xe.getUserInfo();if(!e){console.log(Qt("Not logged in"));return}console.log(Qt(`Current user: ${e.userName}`))},()=>{console.log(Qt("Not logged in"))})});var x0=Pa.command("team").description("Team-related commands");x0.command("list").description("List team accounts the current user has joined").action(async()=>{let r={event:v.CommandExecuted,args:["auth","team","list"]};await Cd(r,async()=>{let e=await Cn();console.log(P0(e.teamList))},e=>{if(e instanceof Ke){console.log(lg(e.message));return}throw new Error("Failed to list teams",{cause:e})})});var jE=Pa;import{Command as I0}from"commander";import{green as A0,red as Ca,cyan as HE,yellow as UE,dim as BE}from"colorette";import T0 from"p-limit";import D0 from"ora";var Te=class{spinner=null;isRunning=!1;start(e){this.spinner?this.spinner.text=e:this.spinner=D0(e),this.spinner.start(),this.isRunning=!0}stop(){this.spinner&&this.isRunning&&(this.spinner.stop(),this.isRunning=!1)}succeed(e){this.spinner&&(this.spinner.succeed(e),this.isRunning=!1)}fail(e){this.spinner&&(this.spinner.fail(e),this.isRunning=!1)}};var N0="deveco";async function O0(r){let e=await Es();if(r.all)return(await Oc(e)).map(n=>n.enName);{let n=(await _c(r.skill,e)).find(i=>i.enName===r.skill);if(!n)throw new Fo("errorCode",`Skill "${r.skill}" not found`);return[n.enName]}}function _0(r){if(r.all&&r.skill)throw new Fo("errorCode","`--all` and `--skill` cannot be specified together.");if(!r.all&&!r.skill)throw new Fo("errorCode","Must specify `--all` or `--skill`");let{resolvedPath:e,resolvedProject:t}=Zi(r.path,r.project,r.agent);return t&&Tr(t,"Project directory",r.force),e&&Tr(e,"Directory",r.force),{resolvedPath:e,resolvedProject:t}}function M0(r,e,t){return!!(e||t||r.path||r.project||r.agent)}function L0(){return{agents:[N0],projectAgents:[],customPath:void 0}}async function F0(r,e,t){let n=vt()&&!M0(r,e,t)?L0():await Qi(r,e,t);return{skillNames:await O0(r),targets:n}}async function $0(r,e,t,n){let i=[],o=0,s=r.length,a=T0(5),c=r.map(l=>a(()=>j0(l)));for(let l=0;l<r.length;l++){let d=r[l],g=s>1?` (${l+1}/${s})`:"";t.start(`Installing ${d}${g}...`);let y=await c[l];if(!y.success){t.fail(),console.log(Ca(`${d}: Download failed - ${y.error}`)),i.push({success:!1});continue}o+=y.buffer.length,t.stop();let E=await new dr().installArchiveSkill(d,y.buffer,e,n);i.push(...E)}return{results:i,diskBytes:o}}async function j0(r){try{return{buffer:await Gp(r),success:!0}}catch(e){return{error:e instanceof Error?e.message:"unknown error",success:!1}}}async function H0(r){let e=new Te;try{e.start("Installing skill...");let{resolvedPath:t,resolvedProject:n}=_0(r),{skillNames:i,targets:o}=await F0(r,t,n),{results:s,diskBytes:a}=await $0(i,o,e,r.force??!1);return e.stop(),Xi(s),{diskBytes:a,results:s}}catch(t){throw e.stop(),t}}function WE(r){let e=r.length,t=r.filter(s=>s.success&&!s.skipped).length,n=r.filter(s=>s.skipped).length,i=r.filter(s=>!s.success).length,o=[...new Set(r.filter(s=>!s.success&&typeof s.error=="string").map(s=>U0(s.error)))];return{opTotal:e,opSuccess:t,opFailed:i,opSkipped:n,...o.length>0?{failedErrors:o}:{}}}function U0(r){let e=/^([A-Za-z_][A-Za-z0-9_-]*)/.exec(r.trim());return e?e[1].slice(0,32):"error"}var Fo=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function B0(r){let e=r;return r instanceof Fo?r.code:e.code??e.name??"UnknownError"}function kd(r,e={}){return["skills",r,...e.all?["--all"]:[],...e.long?["--long"]:[],...e.skill?["--skill"]:[],...e.force?["--force"]:[],...e.agent?["--agent",e.agent]:[],...e.project?["--project"]:[],...e.path?["--path"]:[]]}async function Rd(r,e,t){let n=Date.now(),i=!0,o=null,s={};try{s=await e()}catch(a){throw i=!1,o=B0(a),a}finally{let a={event:v.SkillOperation,subAction:r,args:t,...s};await R.track(a,{duration_ms:Date.now()-n,success:i,error_code:o})}}function W0(r){return Rd("add",async()=>{let{diskBytes:e,results:t}=await H0(r);return{diskUsage:ce(e),...r.skill?{skillName:r.skill}:{},...WE(t)}},kd("add",r))}function V0(r){let{resolvedPath:e,resolvedProject:t}=Zi(r.path,r.project,r.agent);return t&&Tr(t,"Project directory"),e&&Tr(e,"Directory"),{resolvedPath:e,resolvedProject:t}}async function G0(r,e){let t=new Te;try{t.start("Removing skill...");let{resolvedPath:n,resolvedProject:i}=V0(e);t.stop();let o=await q0(e,r,n,i);return t.stop(),Xi(o),o}catch(n){throw t.stop(),n}}async function q0(r,e,t,n){let i=r.agent||t?await Qi(r,t,n):n?{agents:[],explicitAgents:!1,projectAgents:Le().map(o=>({project:n,agent:o}))}:{agents:Le(),projectAgents:[]};return new dr().removeSkill(e,i)}var ka=new I0("skills").description("Manage HarmonyOS skills");ka.command("list").description("List all available HarmonyOS skills").option("-l, --long","Show detailed information including description and installation status").action(async r=>{try{await Rd("list",async()=>{let e=new Te;try{e.start("Fetching skills...");let t=await Es(),n=await Oc(t);if(n.length===0)return e.stop(),console.log(UE("No skills available.")),{resultTotal:0};e.succeed(`Fetched ${n.length} skills`);for(let i of n){if(!r.long){console.log(i.enName);continue}console.log(HE(i.enName)),console.log(BE(i.description));let o=Bp(i.enName);o.length>0&&console.log(A0(`Installed for: ${o.join(", ")}`)),console.log()}return{resultTotal:n.length}}finally{e.stop()}},kd("list",r))}catch(e){console.error(Ca(e.message)),process.exitCode=1}});ka.command("find <keyword>").description("Search skills by keyword").action(async r=>{try{await Rd("find",async()=>{let e=new Te;try{e.start("Searching skills...");let t=await Es(),n=await _c(r,t);if(n.length===0)return console.log(UE(`No skills found matching '${r}'.`)),e.stop(),{resultTotal:0,queryLen:r.length,keyword:r};e.succeed(`Found ${n.length} skills.`);for(let i of n)console.log(HE(i.enName)),console.log(BE(i.description)),console.log();return{resultTotal:n.length,queryLen:r.length,keyword:r}}finally{e.stop()}},kd("find"))}catch(e){console.error(Ca(e.message)),process.exitCode=1}});ka.command("add").description("Install skills to AI agents").option("--all","Install all available skills").option("--agent <agents>","Target agents, comma-separated; Omit to install to all available agents").option("--skill <skill-name>","Name of the skill to install").option("-f, --force","Replace existing Skill content; create missing project or custom target directories").option("--project <path>","Project root directory for skill installation").option("--path <path>","Path to install the skill directly (cannot be used with --project or --agent)").action(async r=>{try{await W0(r)}catch(e){console.error(Ca(e.message)),process.exitCode=1}});ka.command("remove").description("Remove an installed skill from AI agents").requiredOption("--skill <skill-name>","Name of the skill to remove").option("--agent <agents>","Target agents, comma-separated.Omit to remove from all available agents").option("--project <path>","Project root directory for skill removal").option("--path <path>","Path for skill removal").action(async r=>{try{await Rd("remove",async()=>{let e=await G0(r.skill,r);return{skillName:r.skill,...WE(e)}},kd("remove",r))}catch(e){console.error(Ca(e.message)),process.exitCode=1}});var VE=ka;import{Command as yF}from"commander";import{cyan as rP,yellow as wF}from"colorette";import Td from"fs";import pF from"path";import z0 from"fs";import J0 from"path";import{pathToFileURL as K0}from"url";function GE(r,e){return Array.isArray(r)&&r.length>0&&r.every(t=>typeof t=="string"&&e.includes(t))}var $o=1;function Y0(r){return r.plugin??r.default?.plugin}function X0(r,e){for(let n of["install","uninstall","update"])if(typeof r[n]!="function")throw new Error(`Plugin contract invalid: "${n}" must be a function (got ${typeof r[n]}).`);if(r.name!==e.name)throw new Error(`Plugin contract mismatch: expected name "${e.name}", got "${r.name}".`);if(r.version!==e.version)throw new Error(`Plugin contract mismatch: expected version "${e.version}", got "${r.version}".`);let t=Le();if(r.supportedAgents===void 0?r.supportedAgents=t:GE(r.supportedAgents,t)||Z0(r.supportedAgents,t),typeof r.apiVersion!="number")throw new Error(`Plugin contract invalid: "apiVersion" must be a number (got ${typeof r.apiVersion}).`);if(r.apiVersion>$o)throw new Error(`Plugin "${e.name}" requires plugin API v${r.apiVersion}, but this CLI supports v${$o}. Upgrade: npm i -g @deveco/deveco-cli@latest`)}function Z0(r,e){if(!Array.isArray(r)||r.length===0)throw new Error('Plugin contract invalid: "supportedAgents" must be a non-empty array.');let t=r.find(n=>typeof n!="string"||!e.includes(n));throw new Error(`Plugin contract invalid: "supportedAgents" contains unknown agent "${String(t)}".`)}async function xd(r,e){let t=e.label??`${e.name}@${e.version}`,n=J0.join(r,"index.js");if(!z0.existsSync(n))throw new Error(`Package ${t} has no index.js.`);let i;try{i=await import(K0(n).href)}catch(s){let a=s instanceof Error?s.message:String(s);throw new Error(`Plugin "${e.name}" failed to initialize: ${a}`,{cause:s})}let o=Y0(i);if(!o||typeof o!="object")throw new Error(`Package ${t} does not export a plugin object.`);return X0(o,e),o}var qE=[{name:"hometrans",description:"App migration tool",npmPackage:"@litingwei621/test-devecocli-plugin3@deveco-cli"}];var eF="src/plugins/registry/registry.json",tF=["name","description","npmPackage"];function zE(r){if(!Array.isArray(r))throw new Error(`Invalid plugin registry (${eF}): expected an array.`);let e=new Set;return r.map((t,n)=>{if(typeof t!="object"||t===null)throw new Error(`Invalid plugin registry: entry #${n} must be an object.`);let i=t,o=typeof i.name=="string"&&i.name.trim()!==""?i.name:`#${n}`;for(let a of tF){let c=i[a];if(typeof c!="string"||c.trim()==="")throw new Error(`Invalid plugin registry: entry "${o}" is missing "${a}".`)}let s=t;if(e.has(s.name))throw new Error(`Invalid plugin registry: duplicate plugin name "${s.name}".`);return e.add(s.name),s})}function Dd(){return zE(qE)}function Id(r){let e=Dd().find(t=>t.name===r);if(!e)throw new Error(`Plugin "${r}" is not in the whitelist. Run devecocli plugin list to see available plugins.`);return e}import jo from"path";import{randomUUID as rF}from"crypto";var nF=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function Ad(r){if(!nF.test(r)||r==="."||r==="..")throw new Error(`Invalid plugin name "${r}".`)}function iF(r){return jo.join(r,"plugins","store")}function oF(r){return jo.join(r,"plugins","data")}function Cr(r,e){return jo.join(iF(r),e)}function Ra(r,e,t){return jo.join(Cr(r,e),t)}function JE(r,e){return jo.join(oF(r),e)}function KE(r,e,t){return jo.join(Cr(r,e),`.tmp-${t}-${process.pid}-${rF().slice(0,8)}`)}import YE from"fs";import dg from"path";import{valid as sF}from"semver";var aF=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function XE(r){return aF.test(r)&&sF(r)!==null}async function xa(r){try{return await YE.promises.access(dg.join(r,"index.js")),!0}catch{return!1}}async function Ho(r,e){let t=Cr(r,e),n;try{n=await YE.promises.readdir(t,{withFileTypes:!0})}catch(o){let s=o.code;if(s==="ENOENT"||s==="ENOTDIR")return[];throw o}let i=[];for(let o of n){if(!o.isDirectory()||!XE(o.name)){f(`Ignoring non-version entry in plugin store: ${dg.join(t,o.name)}`);continue}let s=dg.join(t,o.name);if(!await xa(s)){f(`Ignoring incomplete plugin version dir (no index.js): ${s}`);continue}i.push(o.name)}return i.sort((o,s)=>Ct(o,s)),i}import{execa as pg}from"execa";import kn from"fs";import ug from"path";function Da(r){let e=r.trim(),t=e.lastIndexOf("@");if(t<=0)return{name:e,tag:"latest"};let n=e.slice(t+1).trim();return{name:e.slice(0,t),tag:n||"latest"}}function Ia(r){let e=r;return(e.shortMessage??e.message??String(r)).split(`
1315
+ `)[0].trim()||"unknown error"}function ZE(r){let e=r;return e.code==="ENOENT"||/ENOENT/.test(e.originalMessage??e.message??"")}async function cF(r,e,t){f(`Executing: npm pack ${r}@${e}`);try{let{stdout:n}=await pg("npm",["pack",`${r}@${e}`],{cwd:t}),i=n.trim().split(`
1316
+ `).pop()??"";if(!i)throw new Error("npm pack produced no tarball name");return i}catch(n){throw ZE(n)?new Error("Failed to run npm (not found on PATH); plugin installation requires npm.",{cause:n}):new Error(`Failed to download ${r}@${e}: ${Ia(n)}.`,{cause:n})}}function lF(r,e,t){let n=typeof e.version=="string"?e.version.trim():e["dist-tags"]?.[t]?.trim();if(!n)throw new Error(`no version found for ${r}@${t}`);let i=e.dist??e.versions?.[n]?.dist;if(!i?.tarball||!i?.integrity)throw new Error(`no dist information for ${r}@${n}`);let o=e.apiVersion??e.versions?.[n]?.apiVersion;return{version:n,apiVersion:o,dist:{tarball:i.tarball,integrity:i.integrity}}}async function QE(r){let{name:e,tag:t}=Da(r);f(`Executing: npm view ${e}@${t} --json`);try{let{stdout:n}=await pg("npm",["view",`${e}@${t}`,"--json"]);return lF(e,ui(JSON.parse(n)),t)}catch(n){throw ZE(n)?new Error("Failed to run npm (not found on PATH); plugin installation requires npm.",{cause:n}):new Error(`Failed to fetch metadata for ${r}: ${Ia(n)}.`,{cause:n})}}async function dF(r,e,t,n){let i=await cF(r,e.version,t),o=ug.join(t,i);n?.("verifying");let s=await kn.promises.readFile(o);if(!Hl(s,e.dist.integrity))throw new Error(`Integrity check failed for ${r}@${e.version}.`);n?.("extracting");let a=ug.join(t,"extract");await kn.promises.mkdir(a,{recursive:!0}),f(`Executing: tar -xzf ${i} -C extract`);try{await pg("tar",["-xzf",o,"-C",a])}catch(l){throw new Error(`Failed to extract ${r}@${e.version}: ${Ia(l)}.`,{cause:l})}let c=ug.join(a,"package");if(!await xa(c))throw new Error(`Failed to extract ${r}@${e.version}: package has no index.js.`);return c}async function uF(r,e,t,n){try{return await kn.promises.rename(t,n),{dir:n,created:!0}}catch(i){let o=i.code;if(o!=="EEXIST"&&o!=="ENOTEMPTY"&&o!=="EPERM")throw i;if(await xa(n))return{dir:n,created:!1};throw new Error(`Cached package for ${r}@${e.version} is incomplete (${n}). Delete it and retry.`,{cause:i})}}async function eP(r,e,t,n,i){let{name:o}=Da(t),s=Cr(r,e),a=Ra(r,e,n.version);if(await xa(a))return{dir:a,created:!1};await kn.promises.rm(a,{recursive:!0,force:!0}).catch(()=>{});try{await kn.promises.mkdir(s,{recursive:!0})}catch(l){throw new Error(`Cannot write to plugin store (${s}): ${Ia(l)}.`,{cause:l})}let c=KE(r,e,n.version);await kn.promises.mkdir(c,{recursive:!0});try{let l=await dF(o,n,c,i);return await uF(e,n,l,a)}finally{await kn.promises.rm(c,{recursive:!0,force:!0}).catch(()=>{f(`Failed to clean up plugin temp dir: ${c}`)})}}async function tP(r,e,t){let n=Ra(r,e,t);try{await kn.promises.rm(n,{recursive:!0,force:!0}),f(`Removed plugin version dir: ${n}`)}catch(i){f(`Failed to remove plugin version dir (${n}): ${Ia(i)}`)}}var fF=12e4,mF="DEVECO_CLI_PLUGIN_HOOK_TIMEOUT_MS";function fg(r){return pF.dirname(r)}function Pi(r){return r instanceof Error?r.message:String(r)}var Rn=class{logs=[];env;constructor(e){this.env=e}get dataDir(){return this.env?.dataDir??$()}get hookTimeoutMs(){if(this.env?.hookTimeoutMs!==void 0)return this.env.hookTimeoutMs;let e=Number(process.env[mF]);return Number.isFinite(e)&&e>0?e:fF}async getExistingAgents(e){return this.env?.getExistingAgents?this.env.getExistingAgents(e):Hc(e)}getSkillsDir(e,t){return this.env?.getSkillsDir?this.env.getSkillsDir(e,t):Ft(e,t)}async listPlugins(){let e=this.dataDir;return Promise.all(Dd().map(async t=>{try{return{entry:t,versions:await Ho(e,t.name)}}catch(n){return{entry:t,versions:[],warning:`Warning: cannot read plugin store (${Cr(e,t.name)}): ${Pi(n)}.`}}}))}async install(e,t,n){let i=Id(e);Ad(e),await this.validateOptions(t);let o=await Ho(this.dataDir,e),{plugin:s,meta:a,created:c}=await this.prepareLatestPlugin(i,e,n),{targets:l,skipped:d}=await this.resolveTargets(e,s.supportedAgents,t);await this.ensureProjectSkillsDirs(l,t);let g=[],y=0;for(let E of l)g.push(await this.installForTarget(e,E,s,a,o,!!t.force,l.length,++y,n));return c&&!g.some(E=>E.outcome==="installed")&&await tP(this.dataDir,e,a.version),this.appendSkipped(g,e,d,s.supportedAgents),g}async update(e,t,n){let i=Id(e);Ad(e),await this.validateOptions(t);let o=await Ho(this.dataDir,e),{plugin:s,meta:a}=await this.prepareLatestPlugin(i,e,n),{targets:c,skipped:l}=await this.resolveTargets(e,s.supportedAgents,t);await this.ensureProjectSkillsDirs(c,t);let d=o.length>0?o[o.length-1]:a.version,g=[],y=0;for(let E of c)g.push(await this.updateForTarget(e,E,s,d,a.version,c.length,++y,n));return this.appendSkipped(g,e,l,s.supportedAgents),g}async updateForTarget(e,t,n,i,o,s,a,c){let{ctx:l,label:d}=await this.buildTargetContext(e,t,!1,!0);c?.(`Updating ${d}... (${a}/${s})`);let g={...l,from:i,to:o};try{return await this.runHook("update",n.update,g),{target:t,label:d,outcome:"updated",version:o}}catch(y){return{target:t,label:d,outcome:"failed",error:Pi(y)}}}async uninstall(e,t,n){Ad(e),await this.validateOptions(t);let i=await Ho(this.dataDir,e);if(i.length===0)throw new Error(`Plugin "${e}" is not installed.`);n?.("Loading plugin...");let o=await this.loadNewestPackage(e,i);if(!o.ok)throw new Error(`Cannot load plugin "${e}" to run uninstall (${o.error}). Delete ${Cr(this.dataDir,e)} manually.`);let{targets:s,skipped:a}=await this.resolveTargets(e,o.plugin.supportedAgents,t),c=[],l=0;for(let d of s)c.push(await this.uninstallForTarget(e,d,o.plugin,o.version,s.length,++l,n));return this.appendSkipped(c,e,a,o.plugin.supportedAgents),c}async uninstallForTarget(e,t,n,i,o,s,a){let{ctx:c,label:l}=await this.buildTargetContext(e,t,!1,!1);a?.(`Uninstalling ${l}... (${s}/${o})`);try{return await this.runHook("uninstall",n.uninstall,c),{target:t,label:l,outcome:"uninstalled",version:i}}catch(d){return{target:t,label:l,outcome:"failed",error:Pi(d)}}}drainLogs(){let e=[...this.logs];return this.logs.length=0,e}async installForTarget(e,t,n,i,o,s,a,c,l){let{ctx:d,label:g}=await this.buildTargetContext(e,t,s,!0),y;if(s&&o.length>0){l?.(`Uninstalling ${g}... (${c}/${a})`);let E=await this.forceUninstallPrevious(e,t,g,d,o);if("failure"in E)return E.failure;y=E.version}return l?.(`Installing ${g}... (${c}/${a})`),this.runInstallHook(t,g,n,i.version,d,y)}async runInstallHook(e,t,n,i,o,s){try{return await this.runHook("install",n.install,o),{target:e,label:t,outcome:"installed",version:i,forceUninstalledVersion:s}}catch(a){return{target:e,label:t,outcome:"failed",error:Pi(a),forceUninstalledVersion:s}}}async forceUninstallPrevious(e,t,n,i,o){let s=await this.loadNewestPackage(e,o);if(!s.ok)return{failure:{target:t,label:n,outcome:"failed",error:`cannot load previous version to run uninstall (${s.error}). Delete ${Cr(this.dataDir,e)} and retry.`}};try{await this.runHook("uninstall",s.plugin.uninstall,i)}catch(a){return{failure:{target:t,label:n,outcome:"failed",error:`previous version uninstall failed - ${Pi(a)}`}}}return{version:s.version}}async prepareLatestPlugin(e,t,n){n?.("Fetching metadata...");let i=await QE(e.npmPackage);this.gateApiVersion(e.name,i.apiVersion);let o=Da(e.npmPackage).name;n?.(`Downloading ${o}@${i.version}...`);let{dir:s,created:a}=await eP(this.dataDir,t,o,i,l=>n?.(l==="verifying"?"Verifying package integrity...":"Extracting package..."));return n?.("Loading plugin..."),{plugin:await xd(s,{name:t,version:i.version,label:`${o}@${i.version}`}),meta:i,created:a}}resolveProjectRoot(e){if(!e.project)return;let t=Wi(e.project);if(!Td.existsSync(t))throw new Error(`Project path "${t}" not found.`);if(!Td.statSync(t).isDirectory())throw new Error(`"${t}" is not a directory.`);return t}async resolveDesiredAgents(e,t){if(!e.agent)return t;let n=await jc(e.agent);if(n.length===0)throw new Error("--agent requires at least one agent name.");let i=n.filter(o=>!t.includes(o));if(i.length>0)throw new Error(`Agent ${i[0]} not found`);return n}async validateOptions(e){let t=this.resolveProjectRoot(e);await this.resolveDesiredAgents(e,await this.getExistingAgents(t))}async resolveTargets(e,t,n){let i=this.resolveProjectRoot(n),o=await this.getExistingAgents(i),s=await this.resolveDesiredAgents(n,o);if(n.agent){let d=s.find(g=>!t.includes(g));if(d)throw new Error(`Agent ${d} is not supported by plugin "${e}" (supported: ${t.join(", ")}).`)}let a=s.filter(d=>t.includes(d));a.length===0&&hF(e,t,o);let c=d=>({agent:d,scope:i?"project":"global",projectRoot:i}),l=i&&!n.agent?a.filter(d=>this.isProjectAgentActive(d,i)):a;return{targets:l.map(c),skipped:gF(s,a,l,c)}}isProjectAgentActive(e,t){return this.env?.isProjectAgentActive?this.env.isProjectAgentActive(e,t):Zn(e,t)||Vi(t,e)}async ensureProjectSkillsDirs(e,t){if(t.agent)for(let n of e){if(n.scope!=="project"||!n.projectRoot)continue;let i=this.getSkillsDir(n.agent,n.projectRoot);try{await Td.promises.mkdir(i,{recursive:!0})}catch(o){f(`Failed to create project skills dir ${i}: ${Pi(o)}`)}}}skippedResult(e,t,n){let i=this.getSkillsDir(t.target.agent,t.target.scope==="project"?t.target.projectRoot:void 0),o=t.reason==="agent-project-root-missing"?"agent-project-root-missing":`not supported by plugin "${e}" (supported: ${n.join(", ")})`;return{target:t.target,label:fg(i),outcome:"skipped",error:o}}appendSkipped(e,t,n,i){e.push(...n.map(o=>this.skippedResult(t,o,i)))}async buildTargetContext(e,t,n,i){let o=this.getSkillsDir(t.agent,t.scope==="project"?t.projectRoot:void 0),s=fg(o),a=JE(this.dataDir,e);return i&&await Td.promises.mkdir(a,{recursive:!0}).catch(()=>{}),{label:s,ctx:{agent:t.agent,scope:t.scope,projectRoot:t.projectRoot,skillsDir:o,pluginDataDir:a,force:n,log:c=>{this.logs.push({prefix:s,message:c})}}}}async runHook(e,t,n){let i;try{await Promise.race([Promise.resolve().then(()=>t(n)),new Promise((o,s)=>{i=setTimeout(()=>s(new Error(`plugin ${e} hook timed out after ${this.hookTimeoutMs}ms`)),this.hookTimeoutMs)})])}finally{i&&clearTimeout(i)}}async loadNewestPackage(e,t){let n=[...t].sort((o,s)=>Ct(s,o)),i="no loadable version";for(let o of n)try{return{ok:!0,plugin:await xd(Ra(this.dataDir,e,o),{name:e,version:o}),version:o}}catch(s){i=Pi(s),f(`Failed to load plugin ${e}@${o}: ${i}`)}return{ok:!1,error:i}}gateApiVersion(e,t){if(t!==void 0&&t>$o)throw new Error(`Plugin "${e}" requires plugin API v${t}, but this CLI supports v${$o}. Upgrade: npm i -g @deveco/deveco-cli@latest`)}};function gF(r,e,t,n){return[...r.filter(i=>!e.includes(i)).map(i=>({target:n(i),reason:"unsupported"})),...e.filter(i=>!t.includes(i)).map(i=>({target:n(i),reason:"agent-project-root-missing"}))]}function hF(r,e,t){throw new Error(`Plugin "${r}" supports no agents installed on this system (supported: ${e.join(", ")}; installed: ${t.join(", ")||"none"}).`)}var vF=["Name","Version","Status"],bF=["Name","Version","Status","NpmPackage","Desc"];function SF(r,e){if(r.length===0){console.log("No plugins available.");return}let t=[];for(let{entry:n,versions:i}of r){let o=e?[n.npmPackage,n.description]:[];if(i.length===0){t.push({cells:[n.name,"-","not installed",...o]});continue}for(let s of i)t.push({cells:[n.name,`v${s}`,"installed",...o],highlight:!0})}console.log(zt(e?bF:vF,t))}function mg(r,e){console.log(rP(`${r}:`));for(let s of e){s.forceUninstalledVersion&&console.log(` uninstalled: ${s.label} (v${s.forceUninstalledVersion})`);let a=s.version?` (v${s.version})`:"",c=(s.outcome==="failed"||s.outcome==="skipped")&&s.error?` (${s.error})`:"";console.log(` ${s.outcome}: ${s.label}${a}${c}`)}let t=e.filter(s=>s.outcome==="installed"||s.outcome==="updated"||s.outcome==="uninstalled").length,n=e.filter(s=>s.outcome==="skipped").length,i=e.filter(s=>s.outcome==="failed").length;console.log(),console.log(rP("Finished:")),console.log(` Success: ${t}`),console.log(` Skipped: ${n}`),console.log(` Failed: ${i}`),i>0&&(process.exitCode=1),(t>0||e.some(s=>s.forceUninstalledVersion!==void 0))&&(console.log(),console.log("Restart your agent to load the plugin."))}function EF(r){let e=/^([A-Za-z_][A-Za-z0-9_-]*)/.exec(r.trim());return e?e[1].slice(0,32):"error"}function gg(r){let e=r.filter(i=>i.outcome==="failed"),t=r.filter(i=>i.outcome==="skipped"),n=[...new Set(e.map(i=>EF(i.error??"unknown")))];return{opTotal:r.length,opSuccess:r.length-e.length-t.length,opSkipped:t.length,opFailed:e.length,...n.length>0?{failedErrors:n}:{}}}function PF(r){let e=r;return e.code??e.name??"UnknownError"}function Nd(r,e,t){return["plugin",r,...t?[t]:[],...e.long?["--long"]:[],...e.agent?["--agent",e.agent]:[],...e.project?["--project"]:[],...e.force?["--force"]:[]]}async function Od(r,e,t){let n=Date.now(),i=!0,o=null,s={};try{s=await e()}catch(a){throw i=!1,o=PF(a),a}finally{let a={event:v.PluginOperation,subAction:r,args:t,...s};await R.track(a,{duration_ms:Date.now()-n,success:i,error_code:o})}}async function CF(r){let t=await new Rn().listPlugins();for(let n of t)n.warning&&console.error(wF(n.warning));return SF(t,r.long===!0),{resultTotal:t.length,installedPlugins:t.filter(n=>n.versions.length>0).length}}function hg(r){for(let e of r.drainLogs())console.log(` [${e.prefix}] ${e.message}`)}async function kF(r){let e=new Te,t=new Rn;try{let n=await t.install(r.name,r,i=>e.start(i));return e.stop(),hg(t),mg("Plugin Installation",n),gg(n)}finally{e.stop()}}async function RF(r){let e=new Te,t=new Rn;try{let n=await t.update(r.name,r,i=>e.start(i));return e.stop(),hg(t),mg("Plugin Update",n),gg(n)}finally{e.stop()}}async function xF(r){let e=new Te,t=new Rn;try{let n=await t.uninstall(r.name,r,i=>e.start(i));return e.stop(),hg(t),mg("Plugin Uninstall",n),gg(n)}finally{e.stop()}}var Aa=new yF("plugin").description("Manage whitelisted AI agent plugins");Aa.command("list").description("List whitelisted plugins and downloaded versions").option("-l, --long","Show plugin descriptions and npm coordinates").action(async r=>{await Od("list",()=>CF(r),Nd("list",r))});Aa.command("install <name>").description("Install a whitelisted plugin for detected agents").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").option("-f, --force","Run the previous version uninstall hook before installing").action(async(r,e)=>{await Od("install",()=>kF({name:r,...e}),Nd("install",e,r))});Aa.command("update <name>").description("Update a plugin to the latest published version").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").action(async(r,e)=>{await Od("update",()=>RF({name:r,...e}),Nd("update",e,r))});Aa.command("uninstall <name>").description("Run the plugin uninstall hook for detected agents").option("--agent <agents>","Target agents, comma-separated; omit to target all detected agents").option("--project <path>","Project root directory; switches targets to project scope").action(async(r,e)=>{await Od("uninstall",()=>xF({name:r,...e}),Nd("uninstall",e,r))});var nP=Aa;import*as kr from"fs";import{Command as cj,InvalidArgumentError as Vo}from"commander";import{cyan as _g,red as UP}from"colorette";import lj from"ora";var _d=["cpp_crash","js_error","app_freeze"];function Ci(r){return _d.includes(r)}var _=class extends Error{code;verdict;constructor(e,t,n){super(t),this.name="FaultLogError",this.code=e,this.verdict=n}};var DF=/^\s*#\d+\s+pc\s+[0-9a-fA-F]+\s+\S+/,IF=/^\s*at\s+\S+\s*\([^)]*\.(ets|ts|js):\d+:\d+\)/,Ta=/(?:^|\n)\s*Reason\s*:([^\n]*)/,vg=/(?:^|\n)\s*Registers\s*:/i,AF=/(?:^|\n)\s*Timestamp\s*:/i,TF=/(?:^|\n)\s*(?:Pid|Process)\s*:/i,sP=/(?:^|\n)\s*Fault thread info\s*:/i,aP=/(?:^|\n)\s*Process life time\s*:/i,bg=/(?:^|\n)\s*Error message\s*:/i,Sg=/(?:^|\n)\s*Stacktrace\s*:/i,Eg=/(?:^|\n)\s*MSG\s*(?::|=)/i,Md=/\b(THREAD_BLOCK_6S|APP_INPUT_BLOCK|LIFECYCLE_TIMEOUT)\b/,NF=/(?:^|\n)\s*(?:Tid|Name)\s*:/,yg=/\b(SIGSEGV|SIGABRT|SIGBUS|SIGILL|SIGFPE|SIGPIPE|Signal)\b/i,wg=/\b(TypeError|SyntaxError|RangeError|ReferenceError|EvalError|URIError|Error)\b/,OF=/^\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d+\s+/,_F=/^(-+\s+beginning\s+of\s+\w+\s+-+$|\[\s*\d+-\d+\s+\d+:\d+:\d+\.\d+\s+\d+:\d+\s+\w\/)/,MF=[[/#Basic Statistical/i,"#Basic Statistical \u7EDF\u8BA1\u6BB5"],[/#CpuFreq Usage/i,"#CpuFreq Usage \u9891\u70B9\u6BB5"],[/#ThreadInfos\s+Tid\s*:/i,"#ThreadInfos Tid \u7EBF\u7A0B\u4FE1\u606F\u5934"],[/(?:^|\n)\s*SnapshotTime\s*:/i,"SnapshotTime \u5FEB\u7167\u65F6\u95F4\u6233\u5B57\u6BB5"],[/SubmitterStacktrace/,"SubmitterStacktrace \u63D0\u4EA4\u8005\u6808\u6BB5"],[/(?:^|\n)\s*StaticsDuration\s*:/i,"StaticsDuration \u7EDF\u8BA1\u65F6\u957F\u5B57\u6BB5"]];function Ld(r,e){let t=e.exec(r);return t!==null&&t[1]!==void 0&&t[1]!==""?t[1].trim():null}function LF(r){let e=0,t=[Ta,vg,AF,TF,sP,aP,bg,Sg,Eg,Md];for(let n of t)n.test(r)&&(e+=1);return e>=2}function cP(r){let e=[];for(let t of r.split(`
1317
+ `))if(DF.test(t)&&e.push(t.trim()),e.length>=3)break;return e}function lP(r){let e=[];for(let t of r.split(`
1318
+ `))if(IF.test(t)&&e.push(t.trim()),e.length>=3)break;return e}function dP(r){return r.split(`
1319
+ `).filter(e=>NF.test(e)).length}function FF(r,e){let t=[],n=Ld(r,Ta);n!==null&&yg.test(n)&&t.push(`Reason \u5B57\u6BB5\u4E3A Signal \u5F62\u6001\uFF1A${n}`),vg.test(r)&&t.push("\u5B58\u5728 Registers \u6BB5"),sP.test(r)&&t.push("\u5B58\u5728 Fault thread info \u6BB5"),aP.test(r)&&t.push("\u5B58\u5728 Process life time \u6BB5");let i=cP(r);return i.length>0&&t.push(`Native \u6808\u5E27\u5F62\u5982 #NN pc <\u5730\u5740> <\u8DEF\u5F84>\uFF08\u547D\u4E2D ${i.length} \u5E27\uFF09`),e?n!==null&&yg.test(n)&&t.length>=3?{type:"cpp_crash",evidence:t}:null:i.length>0?{type:"cpp_crash",evidence:t}:null}function $F(r,e){let t=[],n=Ld(r,Ta);n!==null&&wg.test(n)&&t.push(`Reason \u5B57\u6BB5\u4E3A JS \u9519\u8BEF\u7C7B\u540D\uFF1A${n}`),bg.test(r)&&t.push("\u5B58\u5728 Error message \u5B57\u6BB5"),Sg.test(r)&&t.push("\u5B58\u5728 Stacktrace \u5B57\u6BB5");let i=lP(r);return i.length>0&&t.push(`JS \u6808\u5E27\u5F62\u5982 at f(path.ets:\u884C:\u5217)\uFF08\u547D\u4E2D ${i.length} \u5E27\uFF09`),e?n!==null&&wg.test(n)&&t.length>=3?{type:"js_error",evidence:t}:null:i.length>0?{type:"js_error",evidence:t}:null}function jF(r,e){let t=[],n=Md.exec(r);n!==null&&t.push(`Reason/\u4E8B\u4EF6\u540D\u4E3A\u51BB\u5C4F\u7C7B\u578B\uFF1A${n[1]}`),Eg.test(r)&&t.push("\u5B58\u5728 MSG \u5B57\u6BB5\uFF08\u627F\u8F7D\u4E3B\u7EBF\u7A0B\u961F\u5217\uFF09");let i=dP(r);return i>=2&&t.push("\u591A\u7EBF\u7A0B\u5206\u8282\u7ED3\u6784\uFF08Tid/Name \u5206\u5757\uFF09"),e?n!==null&&t.length>=3?{type:"app_freeze",evidence:t}:null:i>=2||n!==null?{type:"app_freeze",evidence:t}:null}function HF(r){return MF.filter(([e])=>e.test(r)).map(([,e])=>e)}function UF(r,e){if(r.trim()==="")return{reason:"empty",detail:"\u8F93\u5165\u4E3A\u7A7A\u6587\u4EF6\u6216\u65E0\u5185\u5BB9"};let t=r.split(`
1320
+ `).filter(i=>i.trim()!=="");return t.length===0?{reason:"empty",detail:"\u8F93\u5165\u4E3A\u7A7A\u6587\u4EF6\u6216\u65E0\u5185\u5BB9"}:e?null:t.filter(i=>OF.test(i)).length/t.length>.6?{reason:"hilog_stream",detail:"\u8F93\u5165\u4E3A HiLog \u6D41\u6C34\u65E5\u5FD7\uFF0C\u975E FaultLog\uFF0C\u65E0\u6CD5\u8FDB\u884C\u6545\u969C\u7C7B\u578B\u5206\u8BCA"}:_F.test(t[0])?{reason:"other_platform",detail:"\u8F93\u5165\u4E3A\u5176\u4ED6\u5E73\u53F0\u65E5\u5FD7\uFF0C\u975E\u672C\u5E73\u53F0\u6545\u969C\u65E5\u5FD7"}:null}function uP(r,e){if(e!=="cpp_crash")return null;let t=[],n=Ld(r,Ta)??"";if(/\bsigsegv\b/i.test(n)){let i=/0x[0-9a-fA-F]+/i.exec(n);if(i!==null){let o=Number.parseInt(i[0],16);o>0&&o<65536&&t.push(`\u5D29\u6E83\u5730\u5740 ${i[0]} \u843D\u5728\u4F4E\u5730\u5740\u533A\u95F4\uFF0C\u7591\u4F3C\u8E29\u5185\u5B58\u76EE\u6807`)}}if(/0x[a-fA-F0-9]{8}\b/i.test(r)){let i=/\b0x(61616161|deadbeef|beefbeef|00)+\b/i.exec(r);i!==null&&t.push(`\u7591\u4F3C\u586B\u5145\u6A21\u5F0F\u547D\u4E2D\uFF1A0x${i[1]}`)}return/SIGABRT/i.test(n)&&/stack|overflow|corrupt/i.test(r)&&t.push("SIGABRT \u4E14\u4E0A\u4E0B\u6587\u542B stack/corrupt \u5173\u952E\u5B57"),t.length===0?{suspected:!1,confidence:"low",evidence:["\u672A\u547D\u4E2D\u8E29\u5185\u5B58\u6B63\u5411\u7279\u5F81"]}:{suspected:!0,confidence:t.length>=2?"medium":"low",evidence:t}}function pP(r,e,t){return e?r.type==="app_freeze"?r.evidence.length>=3?"high":"medium":r.evidence.length>=4?"high":"medium":t?"medium":"low"}function BF(r,e,t){if(!t)return r==="cpp_crash"?"\u672A\u547D\u4E2D Native \u6808\u5E27\u6B63\u5411\u7279\u5F81":r==="js_error"?"\u672A\u547D\u4E2D JS \u6808\u5E27\u6B63\u5411\u7279\u5F81":"\u672A\u547D\u4E2D\u591A\u7EBF\u7A0B\u5206\u8282\u6216\u51BB\u5C4F\u4E8B\u4EF6\u540D\u6B63\u5411\u7279\u5F81";let n=Ld(e,Ta),i=[];return r==="cpp_crash"?(n!==null&&yg.test(n)||i.push("Signal \u5F62\u6001\u7684 Reason"),vg.test(e)||i.push("Registers \u6BB5"),cP(e).length===0&&i.push("Native \u6808\u5E27")):r==="js_error"?(n!==null&&wg.test(n)||i.push("JS \u9519\u8BEF\u7C7B\u540D\u7684 Reason"),bg.test(e)||i.push("Error message \u5B57\u6BB5"),Sg.test(e)||i.push("Stacktrace \u5B57\u6BB5"),lP(e).length===0&&i.push("JS \u6808\u5E27")):(Md.test(e)||i.push("\u51BB\u5C4F\u4E8B\u4EF6\u540D"),Eg.test(e)||i.push("MSG \u5B57\u6BB5"),dP(e)<2&&i.push("\u591A\u7EBF\u7A0B\u5206\u8282")),i.length>0?`\u7F3A\u5C11\uFF1A${i.join("\u3001")}`:"\u6B63\u5411\u7279\u5F81\u672A\u8FBE\u5230\u5B8C\u6574\u65E5\u5FD7\u5224\u5B9A\u9608\u503C"}function Fd(r,e,t){let n=new Set(r.map(i=>i.type));return _d.filter(i=>!n.has(i)).map(i=>({type:i,reason:BF(i,t,e)}))}function iP(r,e){let t=r.find(n=>n.type===e);if(t===void 0)throw new _("INTERNAL_ERROR",`identify \u5185\u90E8\u9519\u8BEF\uFF1A\u7F3A\u5C11 ${e} \u68C0\u6D4B\u547D\u4E2D`);return t}function WF(r,e,t){let n={type:r.type,confidence:pP(r,e,!1),completeness:e?"full":"fragment",evidence:r.evidence,excluded:Fd([r],e,t),candidates:[],filename_hint:""};if(r.type==="cpp_crash"&&(n.memory_corruption_suspect=uP(t,r.type)??void 0),r.type==="app_freeze"){let i=Md.exec(t);i!==null&&(n.subtype=i[1])}return n}function VF(r,e){let t=iP(r,"cpp_crash"),n=iP(r,"js_error");return{type:"cpp_crash",confidence:"medium",completeness:"fragment",evidence:t.evidence,excluded:Fd([t,n],!1,e),candidates:[{type:"js_error",confidence:"low",evidence:n.evidence,arbitrable:!0}],memory_corruption_suspect:uP(e,"cpp_crash")??void 0,filename_hint:""}}function oP(r,e,t){if(r.length===1)return WF(r[0],e,t);let n=new Set(r.map(i=>i.type));return n.has("cpp_crash")&&n.has("js_error")&&!e?VF(r,t):{type:"unknown",confidence:"low",completeness:e?"full":"fragment",evidence:[],excluded:Fd(r,e,t),candidates:r.map(i=>({type:i.type,confidence:pP(i,e,!1),evidence:i.evidence,arbitrable:!1})),filename_hint:""}}function GF(r){return{type:"unknown",confidence:"low",completeness:"fragment",evidence:[],excluded:[],candidates:[],filename_hint:"",out_of_scope:r}}function qF(r,e){let t=[];for(let n of[FF,$F,jF]){let i=n(r,e);i!==null&&t.push(i)}return t}function zF(r){let e=r.length>=3;return{type:"sample_stack",confidence:e?"high":"medium",completeness:e?"full":"fragment",evidence:[`\u91C7\u6837\u6808(\u589E\u5F3A\u65E5\u5FD7)\u7ED3\u6784\u6807\u8BB0\uFF1A${r.join("\u3001")}`],excluded:[{type:"cpp_crash",reason:"\u8F93\u5165\u4E3A\u91C7\u6837\u6808(\u589E\u5F3A\u65E5\u5FD7)\uFF1Anative \u5E27\u4E3A\u5468\u671F\u5FEB\u7167\uFF0C\u975E\u5D29\u6E83 faultlog"},{type:"js_error",reason:"\u8F93\u5165\u4E3A\u91C7\u6837\u6808(\u589E\u5F3A\u65E5\u5FD7)\uFF1A\u65E0 JS \u9519\u8BEF Reason / Stacktrace \u7ED3\u6784"},{type:"app_freeze",reason:"\u8F93\u5165\u4E3A\u91C7\u6837\u6808(\u589E\u5F3A\u65E5\u5FD7)\uFF1A\u65E0\u51BB\u5C4F\u4E8B\u4EF6\u540D / MSG \u5B57\u6BB5\uFF0C\u9700\u914D\u5957\u51BB\u5C4F faultlog \u5B9A\u7C7B"}],candidates:[],filename_hint:""}}function JF(r,e){return{type:"unknown",confidence:"low",completeness:r?"full":"fragment",evidence:[],excluded:Fd([],r,e),candidates:[],filename_hint:""}}function $d(r){let e=LF(r),t=UF(r,e);if(t!==null)return GF(t);let n=HF(r),i=qF(r,e);if(i.length>0&&e){let o=oP(i,e,r);return n.length>0&&(o.evidence=[...o.evidence,`\u540C\u65F6\u68C0\u51FA\u91C7\u6837\u6808(\u589E\u5F3A\u65E5\u5FD7)\u7ED3\u6784\u6807\u8BB0\uFF08${n.length} \u9879\uFF09\uFF0C\u53EF\u4F5C\u4E3A\u51BB\u5C4F\u5206\u6790\u914D\u5957\u8BC1\u636E`]),o}return n.length>=2?zF(n):i.length===0?JF(e,r):oP(i,e,r)}import*as jd from"fs";import*as fP from"path";var Na=20*1024*1024,mP=256*1024,gP=256*1024;function KF(r){return r.replace(/\r\n/g,`
1321
+ `).replace(/\r/g,`
1322
+ `)}function YF(r){return r.startsWith("\uFEFF")?r.slice(1):r}function Pg(r,e){let t=r.length,n;if(t<=e)n=r.toString("utf8");else{let i=Math.floor(e/2),o=r.subarray(0,i).toString("utf8"),s=r.subarray(Math.max(0,t-i)).toString("utf8");n=`${o}
1323
+ \u2026\uFF08\u4E2D\u6BB5\u7701\u7565\uFF09\u2026
1324
+ ${s}`}return YF(KF(n))}function ki(r,e){let t=jd.statSync(r,{throwIfNoEntry:!1});if(t===void 0||!t.isFile())throw new _("FILE_NOT_FOUND",`Fault log not found or not a regular file: ${r}`);if(t.size>Na)throw new _("INPUT_OVERSIZED",`Fault log exceeds ${Na/1024/1024}MB limit (size=${t.size}). Provide a smaller or complete file.`);let n=jd.readFileSync(r),i=$d(Pg(n,mP+gP));return i.filename_hint=e??fP.basename(r),i}function Oa(r,e="pasted.log"){let t=Buffer.from(r,"utf8");if(t.length>Na)throw new _("INPUT_OVERSIZED",`Fault log content exceeds ${Na/1024/1024}MB limit (size=${t.length}). Provide a smaller or complete log.`);let n=$d(Pg(t,mP+gP));return n.filename_hint=e,n}import*as hP from"fs";var XF=[/^(\d{4})[-/](\d{2})[-/](\d{2})[ \-T](\d{2}):(\d{2}):(\d{2})(?:[.:](\d{1,6}))?$/,/^(\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})(?:\.(\d{1,6}))?$/,/^(\d{4})(\d{2})(\d{2})-?(\d{2})(\d{2})(\d{2})(\d{0,6})$/],ZF={jan:1,feb:2,mar:3,apr:4,may:5,jun:6,jul:7,aug:8,sep:9,oct:10,nov:11,dec:12};function Uo(r){let e=r.replace(/\r\n/g,`
1325
+ `).replace(/\r/g,`
1326
+ `);return(e.startsWith("\uFEFF")?e.slice(1):e).split(`
1327
+ `)}function _a(r){return Uo(hP.readFileSync(r,"utf8"))}function Hd(r){return r.slice(r.lastIndexOf("/")+1)}function Bo(r,e,t,n=!0){let i=-1;for(let a=0;a<r.length;a++)if(e.test(r[a])){i=a;break}if(i<0)return[[],-1];let o=r.length;for(let a=i+1;a<r.length;a++)if(t.test(r[a])){o=a;break}let s=n?i:i+1;return[r.slice(s,o),i]}function Ri(r,e){let t=new Map(Object.entries(e)),n={};for(let i of r){if(t.size===0)break;for(let o of[...t.keys()]){let s=t.get(o);if(s===void 0)continue;let a=s.exec(i);a!==null&&a[1]!==void 0&&a[1].trim()!==""&&(n[o]=a[1].trim(),t.delete(o))}}return n}function yP(r,e){let t=new Map([["",[]]]);for(let o of e)t.set(o,[]);let n="",i=[...e];for(let o of r){for(let s=0;s<i.length;s++)if(o.trimStart().startsWith(i[s])){n=i[s],i=i.slice(s+1);break}t.get(n)?.push(o)}return t}function wP(r,e,t,n,i,o,s){let a=new Date(r,e-1,t,n,i,o,s);return a.getFullYear()!==r||a.getMonth()!==e-1||a.getDate()!==t||a.getHours()!==n||a.getMinutes()!==i||a.getSeconds()!==o||a.getMilliseconds()!==s?null:a}function QF(r){let e=/\w{3} (\w{3}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})/.exec(r);if(e===null)return null;let t=ZF[e[1].toLowerCase()]??0;return t===0?null:wP(Number.parseInt(e[6],10),t,Number.parseInt(e[2],10),Number.parseInt(e[3],10),Number.parseInt(e[4],10),Number.parseInt(e[5],10),0)}function Wo(r){if(!r)return null;let e=r.trim();for(let t of XF){let n=t.exec(e);if(n===null)continue;let i=(n[7]??"").padEnd(6,"0").slice(0,6),o=Math.floor(Number.parseInt(i,10)/1e3),s=wP(Number.parseInt(n[1],10),Number.parseInt(n[2],10),Number.parseInt(n[3],10),Number.parseInt(n[4],10),Number.parseInt(n[5],10),Number.parseInt(n[6],10),o);if(s!==null)return s}return QF(e)}function Ud(r){if(r===null)return"";let e=t=>String(t).padStart(2,"0");return`${r.getFullYear()}-${e(r.getMonth()+1)}-${e(r.getDate())} ${e(r.getHours())}:${e(r.getMinutes())}:${e(r.getSeconds())}.${String(r.getMilliseconds()).padStart(3,"0")}`}var e$=/(?<src_pid>\d+):(?<src_tid>\d+) to (?<dst_pid>\d+):(?<dst_tid>\d+) code (?<code>\S+) wait:(?<wait>[\d.]+) s(?: frz_state:(?<frz_state>\d+))?/,bP=/(?:catcher stacktrace for |Binder catcher stacktrace, type is \w+, )pid : (?<pid>\d+)/;function Ma(r){return{pid:r.srcPid,tid:r.srcTid}}function La(r){return{pid:r.dstPid,tid:r.dstTid}}function Nt(r){return`${r.pid}:${r.tid}`}function Cg(r,e){return r.pid===e.pid&&r.tid===e.tid}function Bd(r,e,t){let n=e.get(r.pid)??"",i=t?.get(Nt(r))??"",o=[];for(let a of[n,i])a!==""&&!o.includes(a)&&o.push(a);let s=`${r.pid}:${r.tid}`;return o.length>0&&(s+=`(${o.join("/")})`),r.tid==="0"&&(s+="(binder\u7EBF\u7A0B\u8017\u5C3D,IPC FULL)"),s}function t$(r,e,t){r.trans.push({srcPid:t.groups?.src_pid??"",srcTid:t.groups?.src_tid??"",dstPid:t.groups?.dst_pid??"",dstTid:t.groups?.dst_tid??"",code:t.groups?.code??"",waitSeconds:Number.parseFloat(t.groups?.wait??"0"),frzState:t.groups?.frz_state??"",isAsync:e.trimStart().startsWith("async"),raw:e.trim()})}function SP(r){let e={trans:[],peers:new Map},[t]=Bo(r,/(?<!Peer)BinderCatcher --/,/end time:|^-{5,}\s*$/,!0);if(t.length===0)return e;let n=t.length;for(let i=0;i<t.length;i++){let o=t[i];if(o.includes("PeerBinder Stacktrace")||bP.test(o)){n=i;break}let s=e$.exec(o);s!==null&&t$(e,o,s)}return r$(t.slice(n),e),e}function r$(r,e){let t=[];for(let n=0;n<r.length;n++){let i=bP.exec(r[n]);i!==null&&t.push({index:n,pid:i.groups?.pid??""})}for(let n=0;n<t.length;n++){let i=t[n],o=n+1<t.length?t[n+1].index:r.length,s=r.slice(i.index,o),a=/Process name:(.*)/.exec(s.join(`
1328
+ `));e.peers.set(i.pid,{pid:i.pid,processName:a!==null?a[1].trim():""})}}function n$(r,e){return r.srcPid!==e.pid?!1:r.srcTid===e.tid||e.tid==="0"}function i$(r,e){return r.dstPid!==e.pid?!1:r.dstTid===e.tid||r.dstTid==="0"}function o$(r,e,t){return t?n$(r,e)?La(r):null:i$(r,e)?Ma(r):null}function EP(r,e,t){let n={pid:e,tid:t},i=r.trans.filter(d=>!d.isAsync),o=[n];for(let d of i)for(let g of[Ma(d),La(d)])g.pid===e&&!o.some(y=>Cg(y,g))&&o.push(g);let s=vP(i,o,!0),a=vP(i,o,!1),c=m$([...s,...a]),l={faultNode:n,anchor:o,chain:null,notes:[]};return c.length>0?(l.chain={edges:f$(c),cycles:p$(c)},c.some(d=>d.dstTid==="0")&&l.notes.push("\u4F20\u64AD\u94FE\u4E2D\u5B58\u5728\u5BF9\u7AEFtid\u4E3A0\u7684\u8C03\u7528\uFF0C\u5BF9\u5E94\u8FDB\u7A0Bbinder\u7EBF\u7A0B\u8017\u5C3D\uFF08IPC FULL\uFF09")):l.notes.push("\u6545\u969C\u8FDB\u7A0B\u672A\u53C2\u4E0Ebinder\u540C\u6B65\u901A\u4FE1\uFF0C\u6545\u969C\u7EBF\u7A0B\u672A\u963B\u585E\u5728IPC\u4E0A"),l}function vP(r,e,t){let n=new Set(e.map(Nt)),i=[...e],o=[];for(;i.length>0;){let s=i.pop();if(s===void 0)break;for(let a of r){let c=o$(a,s,t);c!==null&&(o.includes(a)||o.push(a),n.has(Nt(c))||(n.add(Nt(c)),i.push(c)))}}return o}function s$(r){let e={outgoing:new Map,incoming:new Map,nodeOfKey:new Map};for(let t of r){let n=Ma(t),i=La(t),o=Nt(n),s=Nt(i);e.nodeOfKey.set(o,n),e.nodeOfKey.set(s,i),e.outgoing.set(o,[...e.outgoing.get(o)??[],i]),e.incoming.set(s,[...e.incoming.get(s)??[],n])}return e}function a$(r){let e=new Set,t=[];for(let n of r.outgoing.keys()){if(e.has(n))continue;e.add(n);let i=[{key:n,next:0}];for(;i.length>0;){let o=i[i.length-1];if(o===void 0)break;let a=(r.outgoing.get(o.key)??[])[o.next];if(a===void 0){t.push(o.key),i.pop();continue}o.next+=1;let c=Nt(a);!e.has(c)&&r.outgoing.has(c)&&(e.add(c),i.push({key:c,next:0}))}}return t}function c$(r,e,t){t.add(e);let n=[e];for(let i=0;i<n.length;i++){let o=n[i];if(o!==void 0)for(let s of r.incoming.get(o)??[]){let a=Nt(s);!t.has(a)&&r.outgoing.has(a)&&(t.add(a),n.push(a))}}return n.map(i=>r.nodeOfKey.get(i)).filter(i=>i!==void 0)}function l$(r,e){let t=new Set,n=[];for(let i=e.length-1;i>=0;i--){let o=e[i];o===void 0||t.has(o)||n.push(c$(r,o,t))}return n}function d$(r,e,t){let n=[],i=r;for(;i!==void 0&&!Cg(i,e);)n.push(i),i=t.get(Nt(i));return i===void 0?[]:[e,...n.reverse()]}function u$(r,e){let t=Nt(r),n=new Map,i=new Set([t]),o=[r];for(;o.length>0;){let s=o.shift();if(s===void 0)break;for(let a of e.outgoing.get(Nt(s))??[]){if(Cg(a,r))return d$(s,r,n);let c=Nt(a);!i.has(c)&&e.outgoing.has(c)&&(i.add(c),n.set(c,s),o.push(a))}}return null}function p$(r){let e=s$(r),t=l$(e,a$(e)),n=[];for(let i of t){let o=i[0];if(o===void 0)continue;let s=u$(o,e);s!==null&&s.length>0&&n.push(s)}return n}function f$(r){return[...r].sort((e,t)=>t.waitSeconds-e.waitSeconds)}function m$(r){let e=[],t=new Set;for(let n of r)t.has(n.raw)||(t.add(n.raw),e.push(n));return e}var kg=/^\s*Tid:(\d+)(?:,|\s)+Name:(.*)/,PP=/^#\d+ [\w\s]+ .*/,CP=/at\s+(\w+)\s+\((.*\.\w+):\d+:\d+\)/,g$=[[/has been crashed/,"\u76EE\u6807\u8FDB\u7A0BCrash\uFF1A\u6293\u6808\u65F6\u8FDB\u7A0B\u5DF2\u6536\u5230crash\uFF0C\u8BF7\u53C2\u8003\u9644\u8FD1\u65F6\u95F4\u70B9\u7684Crash\u65E5\u5FD7"],[/SIGDUMP error/,"\u76EE\u6807\u8FDB\u7A0B\u5728dump\u5806\u6808\u524D\u5C31\u5DF2\u7ECF\u9000\u51FA"],[/is dumping/,"\u76EE\u6807\u8FDB\u7A0B\u6B63\u5728dump\uFF0C\u77ED\u65F6\u95F4\u5185\u8FDE\u7EED\u8BF7\u6C42\uFF0C\u8BF7\u53C2\u8003\u9644\u8FD1\u65F6\u95F4\u70B9\u8BE5\u8FDB\u7A0B\u7684\u5176\u4ED6\u62A5\u9519\u65E5\u5FD7"],[/State:\tS \(sleeping\)/,"dump\u5806\u6808\u65F6\u8FDB\u7A0B\u6B63\u5728\u7761\u7720"],[/errno\(2\)/,"\u76EE\u6807\u8FDB\u7A0B\u65E0\u54CD\u5E94\u4FE1\u53F7\uFF0C\u8D85\u65F6\u540E\u5DF2\u7ECF\u9000\u51FA"],[/pid\(\d+\) process has exited/,"dump\u5806\u6808\u5931\u8D25\uFF0C\u8FDB\u7A0B\u5DF2\u7ECF\u9000\u51FA"],[/Failed to dump normal stacktrace/,"\u6B63\u5E38\u6293\u6808\u5931\u8D25"]];function h$(r,e){let t=r.raw.replace(/^#\d+ pc \w+/,"");t=t.replace(/\([\da-fA-F]{16,}\)/g,"").trim(),r.brief=t;let n=e[3]??"";e.length>3&&(n.startsWith("/system")||n.startsWith("/vendor")||n.startsWith("/prod"))||r.raw.includes("libarkweb_engine.so")||r.raw.includes("[shmm]")?r.area="system":e.length>3&&n.startsWith("/data")&&(r.area="app")}function y$(r){r.brief=r.raw.replace(/^#\d+/,"").trim(),r.area=r.raw.includes("/foundation/arkui")?"system":"app"}function Wd(r){let e=r.trim().split(/\s+/),t={raw:r,brief:"",isNative:e.length>1&&e[1]==="pc",area:"other"};return t.isNative?h$(t,e):y$(t),t}function kP(r){let e=[];for(let t of r)(PP.test(t)||CP.test(t))&&e.push(Wd(t));return e}function Vd(r){let e=new Map,t=null;for(let n of r){let i=kg.exec(n);if(i!==null){t={tid:i[1],name:i[2].trim(),frames:[]},e.set(t.tid,t);continue}t!==null&&(PP.test(n)||CP.test(n))&&t.frames.push(Wd(n))}return e}function w$(r,e){for(let[t,n]of g$)if(t.test(r)){let i=r.trim();if(!e.has(i))return e.add(i),`${i} \uFF08${n}\uFF09`}return null}function RP(r){let e=[],t=new Set;for(let n of r){let i=w$(n,t);i!==null&&e.push(i)}return e}var v$=/^\*{3,}\s*$/,b$=/Catche stack trace end time:|BinderCatcher --|PeerBinderCatcher|^-{5,}\s*$/,S$=/^Tid:\d+(?:,|\s)+Name:/,E$=/\s+(\d+)\s+(\d+\.\d+)%\s+\d+\.\d+%\s+\d+\.\d+%\s+\d+\s+\d+\s+(.*)/,P$={module_name:/Module name:(.*)/,reason:/Reason:(.*)/,process_name:/(?:PROCESS_NAME|Process name):(.*)/,pid:/(?:PID = |Pid:|pid=)(.*)/},C$={start_time:/start time:(.*)/,event_name:/EVENTNAME = (.*)/,timestamp:/TIMESTAMP = (.*)/,pid:/(?:PID = |Pid:|pid=)(.*)/,tid:/(?:TID = |Tid:|tid=)(.*)/,uid:/(?:UID = |Uid:|uid=)(.*)/,module_name:/MODULE_NAME = (.*)/,process_name:/(?:PROCESS_NAME = |PROCESS_NAME:)(.*)/,msg:/MSG =(.*)/,fault_time:/Fault time:(.*)/};function k$(){return{start_time:"",event_name:"",timestamp:"",pid:"",tid:"",uid:"",module_name:"",process_name:"",msg:"",fault_time:""}}function R$(r){let e=r.length;for(let n=0;n<r.length;n++)if(r[n].includes("start time:")){e=n;break}let t=Ri(r.slice(0,e),P$);return{reason:t.reason??"",module_name:t.module_name??"",process_name:t.process_name??"",pid:t.pid??""}}function x$(r){let e=-1,t=-1;for(let i=0;i<r.length;i++)if(e<0&&/start time:/.test(r[i])&&(e=i),/MSG =/.test(r[i])){t=i+2;break}if(e<0||t<0)return k$();let n=Ri(r.slice(e,t),C$);return{start_time:n.start_time??"",event_name:n.event_name??"",timestamp:n.timestamp??"",pid:n.pid??"",tid:n.tid??"",uid:n.uid??"",module_name:n.module_name??"",process_name:n.process_name??"",msg:n.msg??"",fault_time:n.fault_time??""}}function D$(r){let e=[];for(let t=0;t<r.length;t++)v$.test(r[t])&&e.push(t);if(e.length>=2){let t=e[1];return[r.slice(0,t),r.slice(t)]}return[r,[]]}function xP(r){let e=x$(r),[t]=Bo(r,S$,b$),n=Vd(t),i=RP(t);return{msg:e,stacks:n,stack_errors:i}}function I$(r){let e=new Map,[t]=Bo(r,/--\[cpuusage\]--/,/cpuusage end time:/);for(let n of t){let i=E$.exec(n);if(i!==null){let o=i[1],s=Hd(i[3].trim());e.has(o)||e.set(o,s)}}return e}function A$(r){let[e]=Bo(r,/FfrtCallback:|FfrtCatcher -- start time/,/FfrtCatcher -- end time/);for(let t of e){let n=/worker tid (\d+) queue task is running, task id (\d+)/.exec(t);if(n!==null)return n[1]}return""}function T$(r){let e=new Map(r.cpuProcessNames);for(let[i,o]of r.binder.peers)o.processName!==""&&e.set(i,Hd(o.processName));let t=Gd(r),n=Rg(r);return t!==""&&n!==""&&e.set(t,Hd(n)),e}function Gd(r){return r.warning.msg.pid||r.header.pid}function Rg(r){return r.warning.msg.process_name||r.header.process_name||r.header.module_name}function DP(r){return r.ffrtTid!==""?r.ffrtTid:r.warning.msg.tid||Gd(r)}function IP(r){let e=r.warning.msg;return Wo(e.fault_time)||Wo(e.msg)||Wo(e.timestamp)}function AP(r){if(r.length===0)throw new _("FILE_NOT_FOUND","\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A");let e=R$(r),[t,n]=D$(r),i=xP(t),o=n.length>0?xP(n):null,s={reason:e.reason||i.msg.event_name,header:e,warning:i,block:o,binder:SP(r),cpuProcessNames:I$(r),ffrtTid:A$(r),processNames:new Map};return s.processNames=T$(s),s}var N$=["Fault thread info:","Registers:","Other thread info:","Memory near registers:","FaultStack:","Maps:","OpenFiles:","HiLog:"],O$={device_info:/Device info:(.*)/,build_version:/Build info:(.*)/,module_name:/Module name:(.*)/,app_version:/Version:(.*)/,is_pre_installed:/PreInstalled:(.*)/,foreground:/Foreground:(.*)/,pid:/Pid:(.*)/,uid:/Uid:(.*)/,process_name:/Process name:(.*)/,process_life_time:/Process life time:(.*)/,timestamp:/Timestamp:(.*)/,reason:/Reason:(.*)/,last_fatal_message:/LastFatalMessage:(.*)/};function _$(r){let e=-1;for(let n=0;n<r.length;n++)if(r[n].includes("*** GWP-ASan detected a memory error ***")){e=n;break}if(e<0)return"";let t=r.length;for(let n=e;n<r.length;n++)if(r[n].includes("* End GWP-ASan report *")){t=n+1;break}return r.slice(e,t).join(`
1329
+ `).replace(/\n+$/,"")}function TP(r){if(r.length===0)throw new _("FILE_NOT_FOUND","\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A");let e=yP(r,[...N$]),t=Ri(e.get("")??[],O$),n=Vd(e.get("Fault thread info:")??[]);return{header:{device_info:t.device_info??"",build_version:t.build_version??"",module_name:t.module_name??"",app_version:t.app_version??"",is_pre_installed:t.is_pre_installed??"",foreground:t.foreground??"",pid:t.pid??"",uid:t.uid??"",process_name:t.process_name??"",process_life_time:t.process_life_time??"",timestamp:t.timestamp??"",reason:t.reason??"",last_fatal_message:t.last_fatal_message??""},faultStack:n.size>0?[...n.values()][0]:null,gwpAsanText:_$(r)}}var M$={module_name:/Module name:(.*)/,process_name:/Process name:(.*)/,package_name:/Package name:(.*)/,pid:/Pid:(.*)/,uid:/Uid:(.*)/,fault_time:/Fault time:(.*)/,timestamp:/Timestamp:(.*)/,reason:/Reason:(.*)/,error_name:/Error name:(.*)/,error_message:/Error message:(.*)/,error_code:/Error code:(.*)/,page:/page:(.*)/,app_version:/Version:(.*)/,fingerprint:/Fingerprint:(.*)/},L$=/^\s*(?:#\d+\s+)?at\s+\S+\s*\(.*:\d+:\d+\)/;function NP(r){if(r.length===0)throw new _("FILE_NOT_FOUND","\u6587\u4EF6\u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A");let e=Ri(r,M$),t="",n="";for(let i of r){let o=kg.exec(i);if(o!==null){t=o[1],n=o[2].trim();break}}return{header:{module_name:e.module_name??"",process_name:e.process_name??"",package_name:e.package_name??"",pid:e.pid??"",uid:e.uid??"",fault_time:e.fault_time??"",timestamp:e.timestamp??"",reason:e.reason??"",error_name:e.error_name??"",error_message:e.error_message??"",error_code:e.error_code??"",page:e.page??"",app_version:e.app_version??"",fingerprint:e.fingerprint??""},faultTid:t,faultThreadName:n,frames:F$(r)}}function F$(r){let e=-1;for(let n=0;n<r.length;n++)if(r[n].trim()==="Stacktrace:"){e=n;break}if(e<0)return[];let t=[];for(let n=e+1;n<r.length;n++){let i=r[n];if(i.trim()!==""){if(!L$.test(i))break;t.push(i)}}return t}function xg(r){for(let e=0;e<r.length;e++)if(r[e].trimStart().startsWith("HiLog:"))return r.slice(e).join(`
1330
+ `);return""}import*as Fa from"fs";import*as qd from"path";var OP={high:0,medium:1,low:2},_P={full:0,fragment:1},$$=/(\d{13,17})(?:\D*)$/;function j$(r){if(r.length>=14&&(r.startsWith("19")||r.startsWith("20"))){let e=Number.parseInt(r.slice(4,6),10),t=Number.parseInt(r.slice(6,8),10),n=Number.parseInt(r.slice(8,10),10),i=Number.parseInt(r.slice(10,12),10),o=Number.parseInt(r.slice(12,14),10);if(e<1||e>12||t<1||t>31||n>23||i>59||o>59)return null;let s=r.slice(14,17),a=0;s!==""&&(a=Math.round(Number.parseInt(s,10)*1e3/10**s.length));let c=new Date(Number.parseInt(r.slice(0,4),10),e-1,t,n,i,o,a);return Number.isNaN(c.getTime())||c.getDate()!==t?null:c.getTime()}if(r.length===13){let e=Number.parseInt(r,10);return Number.isNaN(e)?null:e}return null}function H$(r){let e=$$.exec(qd.basename(r));if(e!==null){let n=j$(e[1]);if(n!==null)return n}let t=Fa.statSync(r,{throwIfNoEntry:!1});return t!==void 0?t.mtimeMs:0}function MP(r,e){let t=Fa.readdirSync(r,{withFileTypes:!0});for(let n of t){let i=qd.join(r,n.name);n.isDirectory()?MP(i,e):n.isFile()&&e.push(i)}}function U$(r){try{let e=ki(r);return{type:e.type,confidence:e.confidence,completeness:e.completeness}}catch{return{type:"unreadable",confidence:"low",completeness:"fragment"}}}function B$(r,e){let t=OP[r.confidence]-OP[e.confidence];if(t!==0)return t;let n=_P[r.completeness]-_P[e.completeness];return n!==0?n:r.timeMs!==e.timeMs?e.timeMs-r.timeMs:r.path.localeCompare(e.path)}function Dg(r){let e=Fa.statSync(r,{throwIfNoEntry:!1});if(e===void 0)throw new _("FILE_NOT_FOUND",`\u8DEF\u5F84\u4E0D\u5B58\u5728: ${r}`);if(e.isFile())throw new _("INVALID_INPUT",`\u9884\u671F\u4E3A\u76EE\u5F55: ${r}`);let t=[];MP(r,t);let n=[],i={};for(let o of t){let s=U$(o);i[s.type]=(i[s.type]??0)+1,Ci(s.type)&&n.push({path:o,type:s.type,confidence:s.confidence,completeness:s.completeness,timeMs:H$(o)})}return n.sort(B$),{candidates:n,typeCounts:i}}function LP(r){if(!Ci(r.type)){let e=r.out_of_scope!==void 0?`\uFF08${r.out_of_scope.detail}\uFF09`:"";throw new _("UNRECOGNIZED_LOG",`\u65E0\u6CD5\u89E3\u6790\u8BE5\u65E5\u5FD7\uFF1A\u8BC6\u522B\u4E3A ${r.type}\uFF0C\u4EC5\u652F\u6301 cpp_crash / js_error / app_freeze${e}`,r)}return r.type}function zd(r){if(r.path!==void 0){let e=ki(r.path),t=LP(e),n=_a(r.path);return FP(t,e,n,{kind:"file",path:r.path})}if(r.content!==void 0){let e=Oa(r.content),t=LP(e),n=Uo(r.content);return FP(t,e,n,{kind:"file",path:e.filename_hint})}throw new _("INVALID_INPUT","\u5FC5\u987B\u63D0\u4F9B\u65E5\u5FD7\u6587\u4EF6\u8DEF\u5F84\u6216\u65E5\u5FD7\u5185\u5BB9")}function Ig(r){let{candidates:e,typeCounts:t}=Dg(r);if(e.length===0){let a=Object.entries(t).map(([c,l])=>`${c}=${l}`).join(", ");throw new _("UNRECOGNIZED_LOG",`\u672A\u5728 ${r} \u4E2D\u627E\u5230\u53EF\u5206\u6790\u7684\u6545\u969C\u65E5\u5FD7\uFF08\u652F\u6301 cpp_crash / js_error / app_freeze\uFF09`+(a!==""?`\uFF1B\u626B\u63CF\u6587\u4EF6\u5224\u5B9A\u5206\u5E03\uFF1A${a}`:""))}let n=e[0],i=zd({path:n.path}),o=e.map(a=>({path:a.path,type:a.type,confidence:a.confidence,completeness:a.completeness})),s={kind:"directory",path:r,candidates:o};return i.source=s,i}function Ag(r){if(r.path!==void 0){let e=xg(_a(r.path));if(e==="")throw new _("INVALID_INPUT","\u65E5\u5FD7\u4E2D\u672A\u627E\u5230 HiLog \u533A\u6BB5");return e}if(r.content!==void 0){let e=xg(Uo(r.content));if(e==="")throw new _("INVALID_INPUT","\u65E5\u5FD7\u4E2D\u672A\u627E\u5230 HiLog \u533A\u6BB5");return e}throw new _("INVALID_INPUT","\u5FC5\u987B\u63D0\u4F9B\u65E5\u5FD7\u6587\u4EF6\u8DEF\u5F84\u6216\u65E5\u5FD7\u5185\u5BB9")}function FP(r,e,t,n){let i;return r==="app_freeze"?i=G$(AP(t)):r==="cpp_crash"?i=q$(TP(t)):i=z$(NP(t)),{schemaVersion:"1.0.0",logType:r,...e.subtype!==void 0?{subtype:e.subtype}:{},source:n,identify:e,"key-report":i}}function W$(r,e,t){let n=r.frzState!==""?{"frz-state":r.frzState}:{};return{from:Bd(Ma(r),e,t),to:Bd(La(r),e,t),relation:"\u540C\u6B65\u7B49\u5F85","wait-seconds":r.waitSeconds,code:r.code,...n}}function V$(r,e){let t=new Map,n=r.block!==null?[r.warning,r.block]:[r.warning];for(let i of n)for(let[o,s]of i.stacks)s.name!==""&&t.set(`${e}:${o}`,s.name);return t}function $P(r,e,t,n){let i=t!==null?t.frames.map(s=>s.raw):[],o={role:r,tid:e,name:t!==null?t.name:"",frames:i};return i.length===0&&(o.note=n.length>0?n.join("\uFF1B"):"\u672A\u6293\u5230\u8BE5\u7EBF\u7A0B\u5806\u6808"),o}function G$(r){let e=Gd(r),t=Rg(r),n=DP(r),i=IP(r),o={\u6545\u969C\u65F6\u95F4:i!==null?Ud(i):r.warning.msg.fault_time||r.warning.msg.timestamp,PID:e,\u8FDB\u7A0B\u540D:t,\u6545\u969C\u7C7B\u578B:"appfreeze",...r.reason!==""?{\u6545\u969C\u539F\u56E0:r.reason}:{}},s=[$P("fault",n,r.warning.stacks.get(n)??null,r.warning.stack_errors)];r.block!==null&&s.push($P("fault-secondary",n,r.block.stacks.get(n)??null,r.block.stack_errors));let a=EP(r.binder,e,n),c=V$(r,e),l={"basic-info":o,threads:s,binders:a.chain!==null?a.chain.edges.map(d=>W$(d,r.processNames,c)):[]};return a.notes.length>0&&(l["binder-notes"]=a.notes),a.chain!==null&&a.chain.cycles.length>0&&(l.cycles=a.chain.cycles.map(d=>{let g=d.map(y=>Bd(y,r.processNames,c));return`${g.join(" -> ")} -> ${g[0]}`})),l}function q$(r){let e={\u6545\u969C\u65F6\u95F4:r.header.timestamp,PID:r.header.pid,\u8FDB\u7A0B\u540D:r.header.process_name||r.header.module_name,\u6545\u969C\u7C7B\u578B:"cppcrash",...r.header.reason!==""?{\u6545\u969C\u539F\u56E0:r.header.reason}:{},...r.header.last_fatal_message!==""?{LastFatalMessage:r.header.last_fatal_message}:{}},t=r.faultStack,n={"basic-info":e,threads:[{role:"fault",tid:t!==null?t.tid:"",name:t!==null?t.name:"",frames:t!==null?t.frames.map(i=>i.raw):[],...t===null||t.frames.length===0?{note:"\u672A\u89E3\u6790\u5230\u5D29\u6E83\u7EBF\u7A0B\u5806\u6808"}:{}}],binders:[]};return r.gwpAsanText!==""&&(n["gwp-asan"]=r.gwpAsanText),n}function z$(r){return{"basic-info":{\u6545\u969C\u65F6\u95F4:r.header.fault_time||r.header.timestamp,PID:r.header.pid,\u8FDB\u7A0B\u540D:r.header.process_name||r.header.package_name||r.header.module_name,\u6545\u969C\u7C7B\u578B:"jserror",...r.header.reason!==""||r.header.error_name!==""?{\u6545\u969C\u539F\u56E0:r.header.reason||r.header.error_name}:{},...r.header.error_message!==""?{\u9519\u8BEF\u4FE1\u606F:r.header.error_message}:{}},threads:[{role:"fault",tid:r.faultTid,name:r.faultThreadName,frames:r.frames,...r.frames.length===0?{note:"\u672A\u89E3\u6790\u5230 Stacktrace \u5E27"}:{}}],binders:[]}}function Tg(r){let e=r["key-report"],t=["=".repeat(60)];t.push("\u3010\u57FA\u672C\u4FE1\u606F\u3011"),t.push(...J$(e["basic-info"]));for(let n of e.threads)t.push(...K$(n.role==="fault"?"\u6545\u969C\u7EBF\u7A0B\u5806\u6808":"\u6545\u969C\u7EBF\u7A0B\u5806\u6808\uFF08\u4E8C\u6B21\u6293\u6808\uFF09",n));return t.push(...Y$(e)),e["gwp-asan"]!==void 0&&e["gwp-asan"]!==""&&(t.push("\u3010GWP-ASan \u539F\u59CB\u62A5\u544A\u3011"),t.push(e["gwp-asan"])),t.join(`
1331
+ `)}function J$(r){let e=[],t=r.\u8FDB\u7A0B\u540D??"";for(let[n,i]of Object.entries(r))if(n!=="\u8FDB\u7A0B\u540D"){if(n==="PID"){i!==""&&t!==""?e.push(`PID\uFF1A${i} \u8FDB\u7A0B\u540D\uFF1A${t}`):i!==""?e.push(`PID\uFF1A${i}`):t!==""&&e.push(`\u8FDB\u7A0B\u540D\uFF1A${t}`);continue}i!==""&&e.push(`${n}\uFF1A${i}`)}return e}function K$(r,e){let t=[`\u3010${r}\u3011`];return(e.tid!==""||e.name!=="")&&t.push(`Tid:${e.tid}, Name:${e.name}`),e.frames.forEach((n,i)=>{/^\s*#\d+/.test(n)?t.push(`#${String(i).padStart(2,"0")} ${Wd(n).brief}`):t.push(n.trim())}),e.frames.length===0&&e.note===void 0&&t.push("\u672A\u83B7\u53D6\u5230\u8BE5\u7EBF\u7A0B\u5806\u6808"),e.note!==void 0&&t.push(`\u8BF4\u660E\uFF1A${e.note}`),t}function Y$(r){let e=r["binder-notes"]??[];if(r.binders.length===0&&e.length===0)return[];let t=["\u3010binder \u4F20\u64AD\u94FE\u3011"];if(r.binders.length>0){t.push("\u4F20\u64AD\u94FE\u8C03\u7528\u8FB9\uFF08\u6309\u7B49\u5F85\u65F6\u957F\u964D\u5E8F\uFF09\uFF1A");for(let n of r.binders){let i=n["frz-state"]!==void 0?` frz_state:${n["frz-state"]}`:"";t.push(` ${n.from} -> ${n.to} ${n.relation} ${n["wait-seconds"].toFixed(2)}s${i}`)}}for(let n of r.cycles??[])t.push(`\u26A0 \u68C0\u6D4B\u5230binder\u6B7B\u9501\u73AF\uFF1A${n}`);for(let n of e)t.push(`\u63D0\u793A\uFF1A${n}`);return t}var X$="#Basic Statistical",Z$="#CpuFreq Usage",Q$="#ThreadInfos Tid:",ej=/^StaticsDuration:\s+(\d+)\s+ms/,tj=/^CpuTime:\s+(\d+)\s+ms/,rj=/^cpu(\d+) Usage (\d+.\d+)%/;function Ng(r,e){let t,n,i;if(r.path!==void 0)t=ki(r.path),n=_a(r.path),i=r.path;else if(r.content!==void 0)t=Oa(r.content),n=Uo(r.content),i=t.filename_hint;else throw new _("INVALID_INPUT","\u5FC5\u987B\u63D0\u4F9B\u91C7\u6837\u6808\u6587\u4EF6\u8DEF\u5F84\u6216\u91C7\u6837\u6808\u5185\u5BB9");if(t.type!=="sample_stack")throw new _("INVALID_INPUT",`\u8BE5\u65E5\u5FD7\u4E0D\u662F\u91C7\u6837\u6808\u6587\u4EF6\uFF08\u5224\u5B9A\u4E3A ${t.type}\uFF09\uFF0C--stack \u4EC5\u652F\u6301\u91C7\u6837\u6808\u65E5\u5FD7`);let o=ij(n);return{schemaVersion:"1.0.0",logType:"sample_stack",source:{kind:"file",path:i},identify:t,summary:nj(n,o.size),hotspots:sj(o,e)}}function jP(r){let e=-1,t=-1,n=-1;for(let i=0;i<r.length;i++){let o=r[i];o.includes(X$)&&(e=i),o.includes(Z$)&&(t=i),o.includes(Q$)&&(n=i)}return[e,t,n]}function nj(r,e){let[t,n,i]=jP(r),o=0,s=0;if(t>=0){let c=n>=0?n:r.length;for(let l of r.slice(t,c)){let d=ej.exec(l);d!==null&&(o=Number.parseInt(d[1],10));let g=tj.exec(l);g!==null&&(s=Number.parseInt(g[1],10))}}let a={};if(n>=0){let c=i>=0?i:r.length;for(let l of r.slice(n,c)){let d=rj.exec(l);d!==null&&(a[d[1]]=Number.parseFloat(d[2]))}}return{"statics-duration-ms":o,"cpu-time-ms":s,"cpu-usage":a,"snapshot-count":e}}function ij(r){let[,,e]=jP(r),t=e>=0?r.slice(e):[],n=[],i=[],o=-1;for(let a=0;a<t.length;a++){let c=t[a];if(c.includes("Timestamp:")||c.includes("SnapshotTime:")){n.push(a),i.push(Wo(c.slice(c.indexOf(":")+1).trim()));continue}o<0&&c.includes("SubmitterStacktrace")&&(o=a)}let s=new Map;for(let a=0;a<n.length;a++){let c=i[a];if(c==null)continue;let l=n[a]+1,d=a+1<n.length?n[a+1]:o>=0?o:t.length;s.set(c.getTime(),{date:c,frames:kP(t.slice(l,d))})}return s}function oj(r){let e=[];for(let t=r.frames.length-1;t>=0;t--){let n=r.frames[t];n.area!=="system"&&(n.brief.includes("anonymous")||e.push(n.brief))}return e.length>0?e:null}function sj(r,e){let t=new Map,n=new Map,i=[...r.keys()].sort((s,a)=>s-a);for(let s of i){let a=r.get(s);if(a===void 0)continue;let c=oj(a);if(c===null)continue;let l=c[0],d=t.get(l);d===void 0?t.set(l,[a.date]):d.push(a.date),n.set(s,c)}let o=[...t.entries()].sort((s,a)=>a[1].length-s[1].length).map(([s,a])=>({"parent-node":s,count:a.length,"total-snapshots":r.size,chains:a.sort((c,l)=>c.getTime()-l.getTime()).map(c=>({timestamp:Ud(c),calls:n.get(c.getTime())??[]}))}));return e!==void 0?o.slice(0,e):o}function Og(r){let e=r.summary,t=["=".repeat(24),"\u91C7\u6837\u6808\u5206\u6790\u62A5\u544A","=".repeat(24),"\u3010\u57FA\u672C\u4FE1\u606F\u3011",`StaticsDuration: ${e["statics-duration-ms"]}ms`,`CpuTime: ${e["cpu-time-ms"]}ms`],n=Object.entries(e["cpu-usage"]);if(n.length===0)t.push("CPU\u4F7F\u7528\u7387: \u672A\u83B7\u53D6\u5230");else{t.push("CPU\u4F7F\u7528\u7387:");for(let[i,o]of n)t.push(` CPU${i}: ${o}%`)}return t.push(`\u5FEB\u7167\u603B\u6570: ${e["snapshot-count"]}`),t.push("\u3010\u7236\u8282\u70B9\u7EDF\u8BA1\u3011"),r.hotspots.length===0?t.push("\u672A\u89E3\u6790\u5230\u4E1A\u52A1\u5E27\u70ED\u70B9"):aj(t,r.hotspots),t.join(`
1332
+ `)}function aj(r,e){let t=Math.max(...e.map(n=>n["parent-node"].length))+2;e.forEach((n,i)=>{i>0&&r.push("");let o=n.count*100/n["total-snapshots"],s=Number.isInteger(o)?`${o}%`:`${o.toFixed(1)}%`;r.push(`${n["parent-node"].padEnd(t)}\u51FA\u73B0\u6B21\u6570: ${n.count}/${n["total-snapshots"]} \u5360\u6BD4: ${s}`),r.push(" \u8C03\u7528\u94FE:"),n.chains.forEach((a,c)=>{r.push(` [\u5FEB\u7167${c+1}] ${a.calls.join(" -> ")}`)})})}var dj=new Set(["default","json","report"]),uj=new Set(["default","json","report","hilog"]),pj=20;function fj(r){return["log",...r.device?["--device"]:[],...r.crash?["--crash"]:[],...r.stack?["--stack"]:[],...r.path?["--path"]:[],...r.format?["--format"]:[],...r.limit!==void 0?["--limit"]:[],...r.level?["--level"]:[],...r.bundleName?["--bundle-name"]:[],...r.keyword?["--keyword"]:[],...r.tail!==void 0?["--tail"]:[],...r.from!==void 0?["--from"]:[],...r.to!==void 0?["--to"]:[],...r.follow?["--follow"]:[]]}function mj(r){return{event:v.CommandExecuted,args:fj(r),operation:r.path!==void 0?"local_identify":r.crash?"faultlogger_report":"hilog",logType:r.stack?"stack":r.crash?"crash":"common",bundleName:r.bundleName??"ALL"}}function gj(r){return r instanceof w?r.traceMessage:r instanceof Error?r.code??r.name:"UnknownError"}function hj(r){return r.out_of_scope!==void 0?"out_of_scope":r.type==="unknown"?r.candidates.length>0?"ambiguous":"unknown":"identified"}function yj(r){let e=r.source;return("candidates"in e?e.candidates?.[0]?.path:void 0)??e.path}function wj(r){try{let t=kr.openSync(r,"r");try{let n=Buffer.alloc(2048),i=kr.readSync(t,n,0,2048,0),o=/(?:^|\n)\s*Module name:\s*([^\r\n]+)/.exec(n.toString("utf-8",0,i)),s=o!==null?o[1].trim():"";return s!==""?s:void 0}finally{kr.closeSync(t)}}catch{return}}function vj(r){return r.replace(/[^\s:,,]*[\\/][^\s]*/g,e=>{if(e==="/"||e==="\\")return e;let t=e.slice(e.lastIndexOf(".")+1);return/^[A-Za-z0-9]{1,10}$/.test(t)?`***.${t}`:"***"})}function bj(r,e,t){let n=t?.verdict??e?.identify;if(n===void 0)return r;let i=hj(n);if(Ci(n.type)?r.faultType=n.type:i!=="identified"&&(r.faultType=i),e!==void 0){let o=wj(yj(e));o!==void 0&&(r.bundleName=o)}return r}async function Sj(r,e){let t=Date.now(),n=!0,i=null,o,s,a;try{s=await e()}catch(c){n=!1,i=gj(c),o=c.message,c instanceof _&&(a=c),console.error(UP(c.message)),process.exitCode=1}finally{bj(r,s,a),r.errorMessage=o===void 0?void 0:vj(o);let c={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(r,c).catch(()=>{})}}function Ej(r){try{return P.parsePositiveInteger(r,"tail")}catch{throw new Vo("`tail` must be a positive integer.")}}function Pj(r){try{return P.parsePositiveInteger(r,"limit")}catch{throw new Vo("`limit` must be a positive integer.")}}function Cj(r){if(!uj.has(r))throw new Vo("`--format` must be one of: default, json, report, hilog.");return r}function HP(r,e){try{return P.parseDurationToSeconds(r,e)}catch{throw new Vo(`${e} must be a valid duration string (e.g.,30s, 5m or 2.5m).Supported units: s and m.when specified in seconds(with \`s\` or as a raw number), the value must be an integer.`)}}function kj(r){try{return P.assertHilogLevel(r),r}catch{throw new Vo("`level` must be one of: D, I, W, E, F.")}}function Rj(r){try{return P.assertBundleNameStrict(r),r}catch(e){throw new Vo(e.message)}}function xj(r){if(r.to&&r.follow)throw new _("INVALID_ARGUMENTS","`--to` cannot be used with `--follow`.")}function Dj(r){if(r.stack===!0&&r.crash===!0)throw new _("INVALID_ARGUMENTS","`--stack` cannot be used with `--crash`.");if(r.stack===!0&&r.path===void 0)throw new _("INVALID_ARGUMENTS","`--stack` requires a local sample stack file (use --path).");if(r.path!==void 0&&r.crash!==!0&&r.stack!==!0)throw new _("INVALID_ARGUMENTS","`--path` requires `--crash` or `--stack`.");if(r.limit!==void 0&&r.stack!==!0)throw new _("INVALID_ARGUMENTS","`--limit` is only valid with `--stack`.");if(r.format!==void 0){if(r.crash!==!0&&r.stack!==!0)throw new _("INVALID_ARGUMENTS","`--format` is only valid with `--crash` or `--stack`.");if(r.path===void 0)throw new _("INVALID_ARGUMENTS","`--format` requires a local fault log (use --path).");if(r.stack===!0&&!dj.has(r.format))throw new _("INVALID_ARGUMENTS","`--format` must be one of: default, json, report.")}}function Ij(r){let e=[];if(r.device!==void 0&&e.push("--device"),r.level!==void 0&&e.push("--level"),r.bundleName!==void 0&&e.push("--bundle-name"),r.keyword!==void 0&&e.push("--keyword"),r.follow===!0&&e.push("--follow"),r.tail!==void 0&&e.push("--tail"),r.from!==void 0&&e.push("--from"),r.to!==void 0&&e.push("--to"),e.length>0)throw new _("INVALID_ARGUMENTS",`\`--path\` cannot be combined with device log options: ${e.join(", ")}.`)}function BP(r){if(!kr.existsSync(r))throw new _("FILE_NOT_FOUND",`\u8DEF\u5F84\u4E0D\u5B58\u5728\uFF1A${r}`);return kr.statSync(r).isDirectory()?"directory":"file"}function WP(r){console.log(JSON.stringify(r,null,2))}function Aj(r,e,t){if(BP(r)!=="file")throw new _("INVALID_INPUT",`\u91C7\u6837\u6808\u5206\u6790\u4EC5\u652F\u6301\u6587\u4EF6\u8DEF\u5F84\uFF0C\u6536\u5230\u76EE\u5F55\uFF1A${r}`);let i=Ng({path:r},t);if(e==="json")return WP(i),i;let o=Og(i);return e==="report"?(console.log(o),i):(console.log(`\u5206\u6790\u6587\u4EF6\uFF1A${r}`),console.log(o),i)}function Tj(r,e){let t=BP(r),n=t==="directory"?Ig(r):zd({path:r}),i=t==="directory"?n.source.candidates?.[0]?.path??r:r;if(e==="hilog")return console.log(Ag({path:i})),n;if(e==="json")return WP(n),n;let o=Tg(n);return e==="report"?(console.log(o),n):(t==="directory"?(console.log(`\u5206\u6790\u76EE\u5F55\uFF1A${r}`),console.log(`\u9009\u4E2D\u65E5\u5FD7\uFF1A${i}`)):console.log(`\u5206\u6790\u6587\u4EF6\uFF1A${r}`),console.log(o),n)}function Nj(r){Ij(r);let e=r.path??"",t=r.format??"default";return r.stack===!0?Aj(e,t,r.limit??pj):Tj(e,t)}async function Oj(r,e,t,n,i){return t.crash?await r.getCrashLog(e,t.bundleName):await r.getHilog(e,{level:t.level,bundleName:t.bundleName,keyword:t.keyword,isFollow:!!t.follow,tail:t.tail,fromSeconds:n,toSeconds:i})}function _j(r,e,t,n){let i=P.filterLogsByRelativeWindow(r,t,n);return e.tail?P.getLastLines(i,e.tail):i}var Mj=new cj("log").description("Obtain device application logs").configureOutput({outputError:(r,e)=>e(UP(r))}).option("--device <device>","Target device (name or serial)").option("--crash","Only obtain crash logs").option("--stack","Analyze a local sample stack file (requires --path)").option("--path <path>","Local fault log file or directory to analyze (requires --crash or --stack)").option("--format <format>","Output format: default, json, report (plus hilog with --crash)",Cj).option("--limit <num>","Max hotspots shown by --stack",Pj).option("--level <level>","Log level filter: D, I, W, E, F",kj).option("--bundle-name <bundle-name>","Filter by application bundle name",Rj).option("--keyword <keyword>","Keyword filter").option("--tail <num>","Show only the latest N log lines",Ej).option("--from <start>","Start offset from now, e.g. 30s, 5m, 2.5m, or 120",r=>HP(r,"from")).option("--to <end>","End offset from now, e.g. 30s, 5m, 2.5m, or 120",r=>HP(r,"to")).option("--follow","Follow the log stream in real-time.").action(async r=>{await Sj(mj(r),()=>Lj(r))});async function Lj(r){if(Dj(r),r.stack===!0||r.path!==void 0)return Nj(r);await Fj(r)}async function Fj(r){let e=lj({text:"Preparing log request\u2026",color:"cyan"}),t=()=>{e.stop(),e.clear()};e.start();try{xj(r);let n=r.from,i=r.to,o=await C.new(),s=new un(o),a=await s.selectDevice(r.device);if(!a)throw new w("No active devices found.","No active devices found.");f(_g(`deviceId: ${a}`)),f(_g(`type: ${r.crash?"Crash logs":"Common logs"}`)),f(_g("Obtaining logs ...")),e.text="Fetching logs\u2026",r.follow&&t();let c=await Oj(s,a,r,n,i);t(),r.crash&&c&&(c=_j(c,r,n,i)),c&&console.log(c)}finally{t()}}var VP=Mj;import ja from"path";import Yr from"fs";import Fg from"process";import eC from"os";import{Command as Xj}from"commander";import{green as YP,red as Mg,cyan as Zj,yellow as XP}from"colorette";import ve from"fs-extra";import J from"path";import*as zP from"os";import{fileURLToPath as $j}from"url";var GP={17:{sdkVersion:"5.0.5(17)",modelVersion:"5.0.5"},18:{sdkVersion:"5.1.0(18)",modelVersion:"5.1.0"},19:{sdkVersion:"5.1.1(19)",modelVersion:"5.1.1"},20:{sdkVersion:"6.0.0(20)",modelVersion:"6.0.0"},21:{sdkVersion:"6.0.1(21)",modelVersion:"6.0.1"},22:{sdkVersion:"6.0.2(22)",modelVersion:"6.0.2"},23:{sdkVersion:"6.1.0(23)",modelVersion:"6.1.0"},24:{sdkVersion:"6.1.1(24)",modelVersion:"6.1.1"}},jj=["build-profile.json5","AppScope/resources/base/media/layered_image.json","entry/src/main/resources/base/media/layered_image.json"],Go=["phone","tablet","2in1","car","wearable","tv"],qP=["entry","src","main","module.json5"];function Hj(){let r=import.meta.url,e=$j(r);if(e.includes("dist")){let o=J.dirname(e),s=J.dirname(o);return J.join(s,"templates","application")}let t=J.dirname(e),n=J.dirname(t),i=J.dirname(n);return J.join(i,"templates","application")}function JP(r,e){ve.mkdirSync(e,{recursive:!0});for(let t of ve.readdirSync(r,{withFileTypes:!0})){let n=J.join(r,t.name),i=J.join(e,t.name);if(t.isDirectory()){JP(n,i);continue}ve.existsSync(i)||(ve.mkdirSync(J.dirname(i),{recursive:!0}),ve.copyFileSync(n,i))}}function $a(r,e){let t=ve.readFileSync(r,"utf-8"),n=t;for(let[i,o]of e)n=n.replaceAll(i,o);n!==t&&ve.writeFileSync(r,n,"utf-8")}function Uj(r){if(GP[r])return GP[r];if(r>=26){let e=`${r}.0.0`;return{sdkVersion:e,modelVersion:e}}}function Bj(r,e){if(e===22)return;let t=Uj(e);t&&($a(J.join(r,"build-profile.json5"),[["6.0.2(22)",t.sdkVersion]]),$a(J.join(r,"hvigor","hvigor-config.json5"),[["6.0.2",t.modelVersion]]),$a(J.join(r,"oh-package.json5"),[["6.0.2",t.modelVersion]]))}function Wj(r){return jj.filter(t=>!ve.existsSync(J.join(r,t))).length===0}function Vj(r,e){let t=qP.join("/"),n=J.join(r,...qP),i=ve.readFileSync(n,"utf-8"),o=/^([ \t]*)"deviceTypes"\s*:\s*\[[\s\S]*?\]/m.exec(i);if(!o)throw new Error(`"deviceTypes" not found in ${t}.`);let s=i.includes(`\r
1317
1333
  `)?`\r
1318
1334
  `:`
1319
- `,a=o[1],c=e.map((d,g)=>`${a} "${d}"${g<e.length-1?",":""}`).join(s),l=`${a}"deviceTypes": [${s}${c}${s}${a}]`;we.writeFileSync(n,i.replace(o[0],()=>l),"utf-8")}function m$(){return Buffer.from([137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,1,0,0,0,1,8,2,0,0,0,144,119,83,222,0,0,0,12,73,68,65,84,8,215,99,248,255,255,255,0,5,254,2,254,0,0,0,0,73,69,78,68,174,66,96,130])}function f$(r){return hE.platform()==="darwin"?J.join(r,"Contents","plugins","codegenie-plugin","previewProjectTemplate"):J.join(r,"plugins","codegenie-plugin","previewProjectTemplate")}function g$(r,e){let t=f$(e);if(!we.existsSync(t))return!1;let n=[["AppScope/resources/base/media/background.png","AppScope/resources/base/media/background.png"],["AppScope/resources/base/media/foreground.png","AppScope/resources/base/media/foreground.png"],["entry/src/main/resources/base/media/background.png","entry/src/main/resources/base/media/background.png"],["entry/src/main/resources/base/media/foreground.png","entry/src/main/resources/base/media/foreground.png"],["entry/src/main/resources/base/media/startIcon.png","entry/src/main/resources/base/media/startIcon.png"]];for(let[i,o]of n){let s=J.join(t,i),a=J.join(r,o);we.existsSync(s)&&(we.mkdirSync(J.dirname(a),{recursive:!0}),we.copyFileSync(s,a))}return!0}function h$(r){let e=m$(),t=["AppScope/resources/base/media/background.png","AppScope/resources/base/media/foreground.png","entry/src/main/resources/base/media/background.png","entry/src/main/resources/base/media/foreground.png","entry/src/main/resources/base/media/startIcon.png"];for(let n of t){let i=J.join(r,n);we.mkdirSync(J.dirname(i),{recursive:!0}),we.writeFileSync(i,e)}}function y$(r,e){e&&g$(r,e)||h$(r)}function w$(r){let e=[J.join(r,"gitignore.txt"),J.join(r,"entry","gitignore.txt")];for(let t of e)if(we.existsSync(t)){let n=J.dirname(t);we.renameSync(t,J.join(n,".gitignore"))}}function wE(r,e,t,n,i,o){let s=c$();if(!we.existsSync(s))throw new Error(`Template directory not found: ${s}`);we.mkdirSync(r,{recursive:!0}),yE(s,r),w$(r),y$(r,o),va(J.join(r,"AppScope","resources","base","element","string.json"),[["MyApplication",e]]),va(J.join(r,"AppScope","app.json5"),[["com.example.myapplication",t]]),p$(r,i),d$(r,n);let a=u$(r);if(!a)throw new Error("Template integrity check failed.");return{projectRoot:r,appName:e,bundleName:t,apiLevel:n,deviceTypes:i,verified:a}}function S$(r){if(r.length<1||r.length>200)throw new Ee("errorCode",`App name length must be 1-200 characters. Current: ${r.length}`);if(!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(r))throw new Ee("errorCode","Application name must start with a letter (a-z, A-Z) and contain only letters, digits, and underscores")}function E$(r){if(!r||r.length===0)return[No[0]];let e=r.map(n=>n.toLowerCase()),t=r.filter((n,i)=>!No.includes(e[i]));if(t.length>0)throw new Ee("errorCode",`Unsupported device type(s): ${t.map(n=>`"${n}"`).join(", ")}. Supported types: ${No.join(", ")}`);return[...new Set(e)]}function CE(r){if(PE.platform()==="win32"){let t=r.replace(/\\/g,"/");return t=t.replace(/\/+/g,"/"),t}return r.replace(/\/+/g,"/")}function SE(r){if(r.length===0)throw new Ee("errorCode","Project path cannot be empty.");if(r.length>120)throw new Ee("errorCode",`Project path cannot exceed 120 characters (current: ${r.length}).`);let e=PE.platform();if(!(e==="win32"?/^[a-zA-Z0-9._\-:\\/]+$/:/^[a-zA-Z0-9._\-/]+$/).test(r)){let o=e==="win32"?"letters, digits, dots, underscores, hyphens, colons, slashes (/) or backslashes (\\)":"letters, digits, dots, underscores, hyphens or slashes (/)";throw new Ee("errorCode",`Project path can only contain ${o}.`)}let n=CE(r);if(/[\u4e00-\u9fff]/.test(n))throw new Ee("errorCode","Project path cannot contain Chinese characters.");if(n.endsWith("."))throw new Ee("errorCode","Project path cannot end with a dot (.)")}function P$(r){let e=r,t=ba.parse(r).root;for(;e!==t;){if(zr.existsSync(e))return e;e=ba.dirname(e)}return zr.existsSync(t)?t:null}function EE(r){let e=P$(r);if(!e)throw new Ee("errorCode",`No existing parent directory found for '${r}'. Cannot create project directory.`);try{zr.accessSync(e,zr.constants.W_OK)}catch{throw new Ee("errorCode",`No write permission for directory '${e}'. Cannot create project here.`)}let t=ba.join(e,`.deveco_write_test_${Date.now()}`);try{zr.writeFileSync(t,"test"),zr.unlinkSync(t)}catch{throw new Ee("errorCode",`No write permission for directory '${e}'. Cannot create project here.`)}}function C$(r){return`com.example.${r.toLowerCase()}`}function k$(r,e){if(e){let i=CE(e),o=ba.resolve(i);if(zr.existsSync(o)){if(zr.readdirSync(o).length>0)throw new Ee("errorCode",`Directory '${o}' is not empty. Cannot create project here.`)}else EE(o);return o}let t=Vf.cwd(),n=ba.join(t,r);if(zr.existsSync(n))throw new Ee("errorCode",`Directory '${n}' already exists. Cannot create project here.`);return EE(n),n}function D$(r,e){let t=e?.getMaxApiLevel(),n=23;if(r.apiLevel){let i=Number(r.apiLevel);if(!Number.isInteger(i)||i<17)throw new Ee("errorCode",`Invalid API version ${r.apiLevel}. API version 17 or higher is required.`);if(t!==void 0){if(i>t)throw new Ee("errorCode",`Invalid API version ${r.apiLevel}. Your SDK supports API version 17-${t}`)}else if(i>n)throw new Ee("errorCode",`Invalid API version ${r.apiLevel}. Without DevEco Studio, supported range is API version 17-${n}`);return i}return t!==void 0?t:23}async function R$(){try{return await C.new()}catch(r){console.error(bE(`DevEco Studio not found: ${r.message}`)),console.log(bE("Use placeholder API level instead."));return}}var Ee=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};async function Wf(r,e,t,n){let i={event:v.CommandExecuted,args:["create"],apiLevel:n?.apiLevel??null},o={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(i,o).catch(()=>{})}function x$(r){console.log(`
1320
- `+vE("Project created successfully.")),console.log(`Project root: ${r.projectRoot}`),console.log(`App name: ${r.appName}`),console.log(`Bundle name: ${r.bundleName}`),console.log(`API level: ${r.apiLevel}`),console.log(`Device types: ${r.deviceTypes.join(", ")}`),console.log(vE("Template integrity check passed."))}var A$=new v$("create").description("Scaffold a new HarmonyOS application project").option("--project-path <path>","Project directory path (default: ./<app-name>)").option("--app-name <name>","Application name").option("--bundle-name <bundle>","Bundle name (auto-derived as com.example.<app-name> if omitted)").option("--api-level <level>","API level (auto-detected from SDK if omitted; minimum: 17)").option("--device-types <types...>",`Device types written to module.json5 (default: ${No[0]}; supported: ${No.join(", ")})`).action(async r=>{let e=Date.now();try{r.appName||(console.error(Bf("Error: --app-name is required")),await Wf(e,!1,"errorCode",r),Vf.exit(1));let t=r.appName;S$(t);let n=E$(r.deviceTypes),i=r.bundleName||C$(t);P.assertBundleNameStrict(i),r.projectPath&&SE(r.projectPath);let o=k$(t,r.projectPath);SE(o),console.log(b$("Initializing project...")),console.log(`Project path: ${o}`),console.log(`App name: ${t}`),console.log(`Bundle name: ${i}`),console.log(`Device types: ${n.join(", ")}`);let s=await R$(),a=D$(r,s);console.log(`API level: ${a}`);let c=s?.devecoStudioPath,l=wE(o,t,i,a,n,c);x$(l),await Wf(e,!0,null,r)}catch(t){let n=t,o=t instanceof Ee?t.code:n.code??n.name??"UnknownError";console.error(Bf(`
1321
- Failed to create project.`)),console.error(Bf(n.message)),await Wf(e,!1,o,r),Vf.exit(1)}}),kE=A$;import{Command as I$}from"commander";import{red as T$,cyan as RE}from"colorette";function xE(r){return[...new Set([...r.agents,...r.projectAgents.map(({agent:e})=>e)])]}async function DE(r,e,t,n){await D.track(r,{duration_ms:Date.now()-e,success:t,error_code:n}).catch(()=>{})}async function O$(r,e,t,n,i){let o={event:v.SkillConfigOperation,subAction:"install",targetType:t?"path":n?"project":"global",agents:xE(r)},s=Date.now();try{let a=await new sr().installBundledSkill(e,r,i),c=a.every(l=>l.success);return await DE(o,s,c,c?null:"SKILL_INSTALL_FAILED"),a}catch(a){let c=a instanceof Error?a.code??a.name:"UnknownError";throw await DE(o,s,!1,c),a}}async function N$(r,e,t){let n=[];for(let{project:i,agent:o}of r.projectAgents){let s=await kc(o,i,t);n.push(s)}for(let i of r.agents){let o=await kc(i,e,t);n.push(o)}return n}async function M$(r,e){let t=[];for(let n of r){if(!kr[n])continue;let o=await kp(n,process.cwd(),e);t.push(o)}return t}function Gf(r){return r!=="qoder"&&r!=="dsh"&&!!kr[r]}async function L$(r,e,t){let n=xE(r).find(l=>!Gf(l));if(t.agent&&n)throw new Error(`${n} does not support MCP configuration via DevEco CLI. Use --skill instead, or use other supported agents for MCP.`);let i=t.force??!1,o=r.projectAgents.filter(l=>Gf(l.agent)),s=r.agents.filter(Gf);if(o.length===0&&s.length===0)throw new Error("No agents supporting MCP configuration found; use --skill");let a={...r,projectAgents:o,agents:s},c=e?await N$(a,e,i):await M$(a.agents,i);c.length>0&&(console.log(RE("MCP Configuration:")),Dp(c))}async function _$(r,e,t){let n={event:v.Init,subAction:"install",targetType:e?"project":"global",agentName:t.agent},i=Date.now(),o=!0,s=null;try{await L$(r,e,t)}catch(a){throw o=!1,s=a instanceof Error?a.code??a.name:"UnknownError",a}finally{let a={duration_ms:Date.now()-i,success:o,error_code:s};await D.track(n,a)}}async function $$(r){if(r.path&&r.mcp)throw new Error("--path applies to Skill installation only; remove --mcp");if(r.skill&&r.mcp)throw new Error("Cannot use `--skill` and `--mcp` together. Use `--skill` for skill installation only, or `--mcp` for MCP configuration only.");let{resolvedPath:e,resolvedProject:t}=Wi(r.path,r.project,r.agent);if(t&&Rr(t,"Project directory",r.force),e&&Rr(e,"Directory",r.force),r.mcp){let s=await Rp(r,t);await _$(s,t,r);return}let n=await Vi(r,e,t),i=Xn(),o=await O$(n,i,e,t,r.force??!1);console.log(),o.length>0&&(console.log(RE("Skill Installation:")),Bi(o))}var F$=new I$("init").description("Install the deveco-cli skill or configure the deveco-mcp server into AI agents").option("--agent <agents>","Target agents, comma-separated; installs to all available agents if omitted").option("--project <path>","Project root directory for skill or MCP configuration").option("--path <path>","Path to install the skill directly (cannot be used with --project or --agent)").option("--skill","Install the deveco-cli skill only (same as default behavior; explicit for symmetry with --mcp)").option("--mcp","Configure the deveco-mcp server (syntax checking for .ets and C/C++) only; no skill installation").option("-f, --force","Replace existing Skill content or MCP configuration; create missing target directories").action(async r=>{try{await $$(r)}catch(e){console.error(T$(e instanceof Error?e.message:String(e))),process.exitCode=1}}),AE=F$;import{Command as z0}from"commander";import{McpServer as O0}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as N0}from"@modelcontextprotocol/sdk/server/stdio.js";import*as xa from"fs";import*as Jo from"path";import{z as De}from"zod";import hd from"path";function OE(r,e,t,n,i){if(e.isError)return{};let o=e.content?.[0]?.text??"";if(!o)return{};let s;switch(r){case"check":s=j$(o);break;case"hover":s={hit:Mo(o)!=null};break;case"definition":case"declaration":s=IE(o,t,n,i,!0);break;case"references":s=U$(o);break;case"implementation":s=IE(o,t,n,i,!1);break;case"documentSymbol":s=B$(o);break;case"callHierarchy":s=W$(o,t,n,i);break;case"workspaceSymbol":s=V$(o,t);break;default:s={}}return s}function NE(r){let e=Array.isArray(r.files)?r.files[0]:r.file;return typeof e!="string"||!e?void 0:hd.extname(e).toLowerCase().replace(/^\./,"")||void 0}function Mo(r){let e=r.indexOf(": ");if(e<0)return;let t=r.slice(e+2).trim();if(!(!t||t==="no result"))try{return JSON.parse(t)}catch{return}}function j$(r){let e={total:0,error:0,warn:0,info:0},t=new Set,n=" => Diagnostic: ";for(let o of r.split(`
1322
- `)){let s=o.indexOf(n);if(s<0)continue;let a;try{a=JSON.parse(o.slice(s+n.length))}catch{continue}if(Array.isArray(a))for(let c of a)c&&typeof c=="object"&&H$(c,e,t)}let i={diagTotal:e.total,diagError:e.error,diagWarn:e.warn,diagInfo:e.info};return t.size>0&&(i.rules=[...t]),i}function H$(r,e,t){e.total++;let n=r.severity;n===1?e.error++:n===2?e.warn++:(n===3||n===4)&&e.info++,typeof r.source=="string"&&t.add(r.source)}function U$(r){let e=Mo(r),t=Array.isArray(e)?e:[],n=new Set;for(let i of t){let o=i?.uri;typeof o=="string"&&n.add(o)}return{refTotal:t.length,fileCount:n.size}}function IE(r,e,t,n,i){let o=Mo(r);if(o==null)return{found:!1};let s=Array.isArray(o)?o:[o],a=s[0]?.uri;return i?{found:!0,sameFile:G$(a,e),sourceType:LE(a,t,n)}:{implTotal:s.length,found:!0}}function B$(r){let e=Mo(r),t=Array.isArray(e)?e:[],n=0,i=new Map,o=s=>{for(let a of s){if(!a||typeof a!="object")continue;n++;let c=a.kind;typeof c=="number"&&i.set(c,(i.get(c)??0)+1);let l=a.children;Array.isArray(l)&&o(l)}};return o(t),{symbolTotal:n,kindDist:qf(i)}}function W$(r,e,t,n){let o=Mo(r)?.calls,s=Array.isArray(o)?o:[],a=e.direction,c=new Map;for(let l of s){if(!l||typeof l!="object")continue;let g=(a==="incoming"?l.from:l.to)?.uri,y=LE(g,t,n);c.set(y,(c.get(y)??0)+1)}return{callsTotal:s.length,calleeSrcDist:qf(c)}}function V$(r,e){let t=Mo(r),n=Array.isArray(t)?t:[],i=new Map,o=0;for(let c of n){if(!c||typeof c!="object")continue;let l=c.kind;typeof l=="number"&&i.set(l,(i.get(l)??0)+1);let d=c.tags;(Array.isArray(d)&&d.includes(1)||c.deprecated===!0)&&o++}let s={resultTotal:n.length,kindDist:qf(i),deprecatedHit:o},a=e.query;return typeof a=="string"&&(s.queryLen=a.length),s}function ME(r){if(typeof r!="string"||!r)return null;let e=r;return e.startsWith("file://")&&(e=e.slice(7),process.platform==="win32"&&e.startsWith("/")&&(e=e.slice(1))),e}function LE(r,e,t){let n=ME(r);return n?e&&TE(n,e)?"user_project":t&&TE(n,t)?"sdk":"system":"unknown"}function G$(r,e){let t=ME(r),n=e.file;return!t||typeof n!="string"?!1:yd(t)===yd(n)}function yd(r){try{return hd.resolve(r).replace(/\\/g,"/").toLowerCase()}catch{return r.replace(/\\/g,"/").toLowerCase()}}function TE(r,e){let t=hd.relative(yd(e),yd(r));return t!==""&&!t.startsWith("..")&&!hd.isAbsolute(t)}function qf(r){let e={};for(let[t,n]of r)e[String(t)]=n;return e}var wd=class{constructor(e,t,n,i){this.telemetry=e;this.getAceServerPid=t;this.getProjectPath=n;this.getSdkPath=i}tools=new Map;add(e,t){return this.tools.set(e.name,{definition:e,handler:t}),this}getAll(){return Array.from(this.tools.values())}registerToServer(e){for(let{definition:t,handler:n}of this.getAll())e.registerTool(t.name,{description:t.description,inputSchema:t.inputSchema},(async i=>this.invokeTool(t.name,i,n)))}async invokeTool(e,t,n){if(h.debug(`[telemetry] mcp tool call: ${e}`),!this.telemetry)return n(t);let i=ae(process.memoryUsage().rss),o=await this.resolveLspMemory(),s=Date.now(),a=!0,c=null,l;try{l=await n(t)}catch(d){throw a=!1,c=d instanceof Error?d.code??d.name:"UnknownError",d}finally{await this.trackToolCall(e,t,l,s,i,o,a,c)}return l}async trackToolCall(e,t,n,i,o,s,a,c){if(!this.telemetry)return;let l=n?.isError===!0,d=n&&!l?OE(e,n,t,this.getProjectPath?.()??"",this.getSdkPath?.()??""):{},g=l?!1:a,y=l&&n?q$(n):c,E={event:v.McpToolCall,subAction:e,mcpMemory:o,lspMemory:s,fileExt:NE(t),...d};typeof t.direction=="string"&&(E.direction=t.direction),await this.telemetry.track(E,{duration_ms:Date.now()-i,success:g,error_code:y})}async resolveLspMemory(){let e=this.getAceServerPid?.()??null;if(e===null)return"unknown";let t=await ft(e);return t===null?"unknown":ae(Number(t)*1024)}};function q$(r){let e=r.content.map(t=>t.text).join(`
1323
- `);return/not ready|not initialized|initializing|please retry|retry \d+s|syncing|C\+\+ project initialization failed/i.test(e)?"NotReady":/No project detected|PROJECT_PATH|no project path/i.test(e)?"NoProject":/Missing.*parameter|invalid parameters|Unknown feature|must be|Must specify|cannot be used together|invalid/i.test(e)?"BadRequest":/Too many files|Maximum allowed/i.test(e)?"TooManyFiles":/does not exist|not exist|not found|No valid|not a .ets|not a supported|Unsupported/i.test(e)?"InvalidFile":"ToolError"}function zf(r,e,t,n){return new wd(r,e,t,n)}import*as Tt from"fs";import*as He from"path";function _E(r){return"method"in r&&!("id"in r)}import{spawn as $E}from"child_process";import*as FE from"crypto";import{EventEmitter as z$}from"events";import*as Jr from"fs";import*as jE from"net";import*as Kt from"path";var J$=50*1024*1024,Y$=60*1e3,K$=10*1e3,X$=64*1024;function Z$(r){let e=Kt.resolve(r).replace(/\\/g,"/");return e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),process.platform==="win32"?e.toLowerCase():e}function Q$(r){return FE.createHash("sha1").update(Z$(r)).digest("hex").slice(0,12)}function e0(r){let e=Kt.resolve(r),t=e.split(Kt.sep),n=t.lastIndexOf("out");return n>0?t.slice(0,n+1).join(Kt.sep):Kt.dirname(e)}var Cn=class extends z${constructor(t){super();this.config=t}process=null;buffer=Buffer.alloc(0);isClosing=!1;socket=null;_ownsProcess=!1;get pid(){return this.process?.pid??null}get ownsProcess(){return this._ownsProcess}get isSocketMode(){return this.socket!==null}ensureDirectories(){let t=Kt.join(this.config.logPath,"lspLog");return Jr.existsSync(t)||Jr.mkdirSync(t,{recursive:!0}),Jr.existsSync(this.config.indexingDataLocation)||Jr.mkdirSync(this.config.indexingDataLocation,{recursive:!0}),t}async start(t){this.config.useSocket&&this.config.projectPath?await this.startSocket(t):await this.startStdio(t)}async startStdio(t){this._ownsProcess=!0;let n=this.ensureDirectories();f.debug(`[LspClient] serverMaxSize=${t}MB`);let i=bs({serverPath:this.config.serverPath,lspLogPath:n,serverMaxSize:t}),o=Zn(this.config.nodePath);f.debug(`[LspClient] Starting process: node ${i.join(" ")}`),f.debug(`[LspClient] nodePath: ${o}`),this.process=$E(o,i,{cwd:this.config.cwd||process.cwd(),stdio:["pipe","pipe","pipe"],windowsHide:!0}),this.bindProcessEvents(!0,!0),await new Promise(s=>setTimeout(s,500)),f.info("[LspClient] start lsp process success")}async startSocket(t){let n=this.ensureDirectories(),i=this.config.projectPath,o=e0(this.config.serverPath),s=Kt.join(i,".idea",".deveco","arkts",".cache",`lsp-socket-${Q$(o)}.properties`),a=this.tryReadPortFile(s);if(a!==null)try{f.info(`[LspClient] Port file found (lspSocketPort=${a}), connecting to existing server`),this._ownsProcess=!1,await this.connectSocket(a),f.info("[LspClient] Connected to existing socket server");return}catch(d){f.warn(`[LspClient] Failed to connect to existing socket server (port=${a}): ${d instanceof Error?d.message:d}, falling back to spawn`)}let c=3,l=null;for(let d=1;d<=c;d++)try{d===1?f.info("[LspClient] Spawning server in socket mode"):f.info(`[LspClient] Retry ${d}/${c} spawning socket server`),this._ownsProcess=!0,await this.spawnSocketServer(t,n,i),f.info("[LspClient] Socket server started and connected");return}catch(g){l=g instanceof Error?g:new Error(String(g)),f.warn(`[LspClient] Spawn attempt ${d}/${c} failed: ${l.message}`),this.cleanupSpawnResidue()}throw new Error(`Failed to start socket server after ${c} attempts: ${l?.message}`)}cleanupSpawnResidue(){if(this.process){try{this.process.exitCode===null&&this.process.signalCode===null&&this.process.kill()}catch{}this.process=null}if(this.socket){try{this.socket.destroy()}catch{}this.socket=null}}tryReadPortFile(t){try{if(!Jr.existsSync(t))return null;let i=Jr.readFileSync(t,"utf8").match(/lspSocketPort\s*=\s*(\d+)/);if(i){let o=parseInt(i[1],10);if(Number.isFinite(o)&&o>0)return o}return null}catch{return null}}async spawnSocketServer(t,n,i){f.debug(`[LspClient] serverMaxSize=${t}MB`);let o=bs({serverPath:this.config.serverPath,lspLogPath:n,serverMaxSize:t,transportFlag:"--scope=multi",projectPath:i}),s=Zn(this.config.nodePath);f.debug(`[LspClient] Starting process (socket): node ${o.join(" ")}`),f.debug(`[LspClient] nodePath: ${s}`),this.process=$E(s,o,{cwd:this.config.cwd||process.cwd(),stdio:["pipe","pipe","pipe"],windowsHide:!0,detached:!0});let a=await this.waitForPortFromStdout(Y$);f.debug(`[LspClient] LSP_SOCKET_LISTENING port=${a}`),await this.connectSocket(a),this.bindProcessEvents(!0,!1)}waitForPortFromStdout(t){return new Promise((n,i)=>{let o=this.process?.stdout;if(!o){i(new Error("LSP server failed to start: no stdout"));return}let s=/LSP_SOCKET_LISTENING:(\d+)/,a="",c=setTimeout(()=>{o.removeListener("data",l),i(new Error("LSP server failed to start: port not received within timeout"))},t),l=d=>{a+=d.toString("utf8");let g=a.match(s);if(g){clearTimeout(c),o.removeListener("data",l),n(parseInt(g[1],10));return}a=a.slice(-X$)};o.on("data",l)})}connectSocket(t){return new Promise((n,i)=>{let o=jE.connect(t,"127.0.0.1"),s=setTimeout(()=>{o.destroy(),i(new Error(`TCP connection to LSP socket timed out (port ${t})`))},K$);o.on("connect",()=>{clearTimeout(s),this.socket=o,this.bindSocketEvents(o),n()}),o.on("error",a=>{clearTimeout(s),i(new Error(`TCP connection to LSP socket failed: ${a.message}`))})})}bindSocketEvents(t){t.on("data",n=>this.handleData(n)),t.on("error",n=>{f.error(`[LspClient] socket error: ${n.message}`),this.isClosing||this.emit("error",n)}),t.on("close",()=>{f.info("[LspClient] socket closed"),this.isClosing||this.emit("error",new Error("LSP socket closed"))})}attachProcess(t,n){if(this.process)throw new Error("[LspClient] process already attached");this._ownsProcess=!0,this.process=t,this.bindProcessEvents(n?.stderrAsError??!0,!0),f.info("[LspClient] attached to external process")}bindProcessEvents(t=!0,n=!0){this.process&&(n&&this.process.stdout?.on("data",i=>{this.handleData(i)}),this.process.stderr?.on("data",i=>{let o=i.toString("utf8").trim();f.error(`[LspClient] stderr: ${o}`),!this.isClosing&&t&&this.emit("error",new Error(`[LspClient] stderr: ${o}`))}),this.process.on("exit",i=>{f.info(`[LSP EXIT] code=${i}`),this.isClosing||this.emit("error",new Error(`LSP process exited with code ${i}`))}))}sendRaw(t,n){let i=this.buildLspMessage(t);if(this.socket&&!this.socket.destroyed&&this.socket.writable){f.debug(`[LspClient] [SOCKET SEND] ${n}: ${t.slice(0,200)}`),this.socket.write(i,"utf8");return}if(!this.process?.stdin?.writable){f.warn("[LspClient] Cannot send message, no writable transport");return}f.debug(`[LspClient] send message: ${n}`),this.process.stdin.write(i,"utf8")}send(t,n,i){let o={jsonrpc:"2.0",method:t,params:n};i!==void 0&&(o.id=i),this.sendRaw(JSON.stringify(o),t)}sendNotification(t,n){this.sendRaw(JSON.stringify({jsonrpc:"2.0",method:t,params:n}),t)}sendRequest(t,n,i){this.sendRaw(JSON.stringify({jsonrpc:"2.0",id:i,method:t,params:n}),t)}buildLspMessage(t){return`Content-Length: ${Buffer.from(t,"utf8").length}\r
1335
+ `,a=o[1],c=e.map((d,g)=>`${a} "${d}"${g<e.length-1?",":""}`).join(s),l=`${a}"deviceTypes": [${s}${c}${s}${a}]`;ve.writeFileSync(n,i.replace(o[0],()=>l),"utf-8")}function Gj(){return Buffer.from([137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,1,0,0,0,1,8,2,0,0,0,144,119,83,222,0,0,0,12,73,68,65,84,8,215,99,248,255,255,255,0,5,254,2,254,0,0,0,0,73,69,78,68,174,66,96,130])}function qj(r){return zP.platform()==="darwin"?J.join(r,"Contents","plugins","codegenie-plugin","previewProjectTemplate"):J.join(r,"plugins","codegenie-plugin","previewProjectTemplate")}function zj(r,e){let t=qj(e);if(!ve.existsSync(t))return!1;let n=[["AppScope/resources/base/media/background.png","AppScope/resources/base/media/background.png"],["AppScope/resources/base/media/foreground.png","AppScope/resources/base/media/foreground.png"],["entry/src/main/resources/base/media/background.png","entry/src/main/resources/base/media/background.png"],["entry/src/main/resources/base/media/foreground.png","entry/src/main/resources/base/media/foreground.png"],["entry/src/main/resources/base/media/startIcon.png","entry/src/main/resources/base/media/startIcon.png"]];for(let[i,o]of n){let s=J.join(t,i),a=J.join(r,o);ve.existsSync(s)&&(ve.mkdirSync(J.dirname(a),{recursive:!0}),ve.copyFileSync(s,a))}return!0}function Jj(r){let e=Gj(),t=["AppScope/resources/base/media/background.png","AppScope/resources/base/media/foreground.png","entry/src/main/resources/base/media/background.png","entry/src/main/resources/base/media/foreground.png","entry/src/main/resources/base/media/startIcon.png"];for(let n of t){let i=J.join(r,n);ve.mkdirSync(J.dirname(i),{recursive:!0}),ve.writeFileSync(i,e)}}function Kj(r,e){e&&zj(r,e)||Jj(r)}function Yj(r){let e=[J.join(r,"gitignore.txt"),J.join(r,"entry","gitignore.txt")];for(let t of e)if(ve.existsSync(t)){let n=J.dirname(t);ve.renameSync(t,J.join(n,".gitignore"))}}function KP(r,e,t,n,i,o){let s=Hj();if(!ve.existsSync(s))throw new Error(`Template directory not found: ${s}`);ve.mkdirSync(r,{recursive:!0}),JP(s,r),Yj(r),Kj(r,o),$a(J.join(r,"AppScope","resources","base","element","string.json"),[["MyApplication",e]]),$a(J.join(r,"AppScope","app.json5"),[["com.example.myapplication",t]]),Vj(r,i),Bj(r,n);let a=Wj(r);if(!a)throw new Error("Template integrity check failed.");return{projectRoot:r,appName:e,bundleName:t,apiLevel:n,deviceTypes:i,verified:a}}function Qj(r){if(r.length<1||r.length>200)throw new Pe("errorCode",`App name length must be 1-200 characters. Current: ${r.length}`);if(!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(r))throw new Pe("errorCode","Application name must start with a letter (a-z, A-Z) and contain only letters, digits, and underscores")}function eH(r){if(!r||r.length===0)return[Go[0]];let e=r.map(n=>n.toLowerCase()),t=r.filter((n,i)=>!Go.includes(e[i]));if(t.length>0)throw new Pe("errorCode",`Unsupported device type(s): ${t.map(n=>`"${n}"`).join(", ")}. Supported types: ${Go.join(", ")}`);return[...new Set(e)]}function tC(r){if(eC.platform()==="win32"){let t=r.replace(/\\/g,"/");return t=t.replace(/\/+/g,"/"),t}return r.replace(/\/+/g,"/")}function ZP(r){if(r.length===0)throw new Pe("errorCode","Project path cannot be empty.");if(r.length>120)throw new Pe("errorCode",`Project path cannot exceed 120 characters (current: ${r.length}).`);let e=eC.platform();if(!(e==="win32"?/^[a-zA-Z0-9._\-:\\/]+$/:/^[a-zA-Z0-9._\-/]+$/).test(r)){let o=e==="win32"?"letters, digits, dots, underscores, hyphens, colons, slashes (/) or backslashes (\\)":"letters, digits, dots, underscores, hyphens or slashes (/)";throw new Pe("errorCode",`Project path can only contain ${o}.`)}let n=tC(r);if(/[\u4e00-\u9fff]/.test(n))throw new Pe("errorCode","Project path cannot contain Chinese characters.");if(n.endsWith("."))throw new Pe("errorCode","Project path cannot end with a dot (.)")}function tH(r){let e=r,t=ja.parse(r).root;for(;e!==t;){if(Yr.existsSync(e))return e;e=ja.dirname(e)}return Yr.existsSync(t)?t:null}function QP(r){let e=tH(r);if(!e)throw new Pe("errorCode",`No existing parent directory found for '${r}'. Cannot create project directory.`);try{Yr.accessSync(e,Yr.constants.W_OK)}catch{throw new Pe("errorCode",`No write permission for directory '${e}'. Cannot create project here.`)}let t=ja.join(e,`.deveco_write_test_${Date.now()}`);try{Yr.writeFileSync(t,"test"),Yr.unlinkSync(t)}catch{throw new Pe("errorCode",`No write permission for directory '${e}'. Cannot create project here.`)}}function rH(r){return`com.example.${r.toLowerCase()}`}function nH(r,e){if(e){let i=tC(e),o=ja.resolve(i);if(Yr.existsSync(o)){if(Yr.readdirSync(o).length>0)throw new Pe("errorCode",`Directory '${o}' is not empty. Cannot create project here.`)}else QP(o);return o}let t=Fg.cwd(),n=ja.join(t,r);if(Yr.existsSync(n))throw new Pe("errorCode",`Directory '${n}' already exists. Cannot create project here.`);return QP(n),n}function iH(r,e){let t=e?.getMaxApiLevel(),n=23;if(r.apiLevel){let i=Number(r.apiLevel);if(!Number.isInteger(i)||i<17)throw new Pe("errorCode",`Invalid API version ${r.apiLevel}. API version 17 or higher is required.`);if(t!==void 0){if(i>t)throw new Pe("errorCode",`Invalid API version ${r.apiLevel}. Your SDK supports API version 17-${t}`)}else if(i>n)throw new Pe("errorCode",`Invalid API version ${r.apiLevel}. Without DevEco Studio, supported range is API version 17-${n}`);return i}return t!==void 0?t:23}async function oH(){try{return await C.new()}catch(r){console.error(XP(`DevEco Studio not found: ${r.message}`)),console.log(XP("Use placeholder API level instead."));return}}var Pe=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};async function Lg(r,e,t,n){let i={event:v.CommandExecuted,args:["create"],apiLevel:n?.apiLevel??null},o={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(i,o).catch(()=>{})}function sH(r){console.log(`
1336
+ `+YP("Project created successfully.")),console.log(`Project root: ${r.projectRoot}`),console.log(`App name: ${r.appName}`),console.log(`Bundle name: ${r.bundleName}`),console.log(`API level: ${r.apiLevel}`),console.log(`Device types: ${r.deviceTypes.join(", ")}`),console.log(YP("Template integrity check passed."))}var aH=new Xj("create").description("Scaffold a new HarmonyOS application project").option("--project-path <path>","Project directory path (default: ./<app-name>)").option("--app-name <name>","Application name").option("--bundle-name <bundle>","Bundle name (auto-derived as com.example.<app-name> if omitted)").option("--api-level <level>","API level (auto-detected from SDK if omitted; minimum: 17)").option("--device-types <types...>",`Device types written to module.json5 (default: ${Go[0]}; supported: ${Go.join(", ")})`).action(async r=>{let e=Date.now();try{r.appName||(console.error(Mg("Error: --app-name is required")),await Lg(e,!1,"errorCode",r),Fg.exit(1));let t=r.appName;Qj(t);let n=eH(r.deviceTypes),i=r.bundleName||rH(t);P.assertBundleNameStrict(i),r.projectPath&&ZP(r.projectPath);let o=nH(t,r.projectPath);ZP(o),console.log(Zj("Initializing project...")),console.log(`Project path: ${o}`),console.log(`App name: ${t}`),console.log(`Bundle name: ${i}`),console.log(`Device types: ${n.join(", ")}`);let s=await oH(),a=iH(r,s);console.log(`API level: ${a}`);let c=s?.devecoStudioPath,l=KP(o,t,i,a,n,c);sH(l),await Lg(e,!0,null,r)}catch(t){let n=t,o=t instanceof Pe?t.code:n.code??n.name??"UnknownError";console.error(Mg(`
1337
+ Failed to create project.`)),console.error(Mg(n.message)),await Lg(e,!1,o,r),Fg.exit(1)}}),rC=aH;import{Command as cH}from"commander";import{red as lH,cyan as iC}from"colorette";function oC(r){return[...new Set([...r.agents,...r.projectAgents.map(({agent:e})=>e)])]}async function nC(r,e,t,n){await R.track(r,{duration_ms:Date.now()-e,success:t,error_code:n}).catch(()=>{})}async function dH(r,e,t,n,i){let o={event:v.SkillConfigOperation,subAction:"install",targetType:t?"path":n?"project":"global",agents:oC(r)},s=Date.now();try{let a=await new dr().installBundledSkill(e,r,i),c=a.every(l=>l.success);return await nC(o,s,c,c?null:"SKILL_INSTALL_FAILED"),a}catch(a){let c=a instanceof Error?a.code??a.name:"UnknownError";throw await nC(o,s,!1,c),a}}async function uH(r,e,t){let n=[];for(let{project:i,agent:o}of r.projectAgents){let s=await Wc(o,i,t);n.push(s)}for(let i of r.agents){let o=await Wc(i,e,t);n.push(o)}return n}async function pH(r,e){let t=[];for(let n of r){if(!Ar[n])continue;let o=await rf(n,process.cwd(),e);t.push(o)}return t}function $g(r){return r!=="qoder"&&r!=="dsh"&&!!Ar[r]}async function fH(r,e,t){let n=oC(r).find(l=>!$g(l));if(t.agent&&n)throw new Error(`${n} does not support MCP configuration via DevEco CLI. Use --skill instead, or use other supported agents for MCP.`);let i=t.force??!1,o=r.projectAgents.filter(l=>$g(l.agent)),s=r.agents.filter($g);if(o.length===0&&s.length===0)throw new Error("No agents supporting MCP configuration found; use --skill");let a={...r,projectAgents:o,agents:s},c=e?await uH(a,e,i):await pH(a.agents,i);c.length>0&&(console.log(iC("MCP Configuration:")),nf(c))}async function mH(r,e,t){let n={event:v.Init,subAction:"install",targetType:e?"project":"global",agentName:t.agent},i=Date.now(),o=!0,s=null;try{await fH(r,e,t)}catch(a){throw o=!1,s=a instanceof Error?a.code??a.name:"UnknownError",a}finally{let a={duration_ms:Date.now()-i,success:o,error_code:s};await R.track(n,a)}}async function gH(r){if(r.path&&r.mcp)throw new Error("--path applies to Skill installation only; remove --mcp");if(r.skill&&r.mcp)throw new Error("Cannot use `--skill` and `--mcp` together. Use `--skill` for skill installation only, or `--mcp` for MCP configuration only.");let{resolvedPath:e,resolvedProject:t}=Zi(r.path,r.project,r.agent);if(t&&Tr(t,"Project directory",r.force),e&&Tr(e,"Directory",r.force),r.mcp){let s=await of(r,t);await mH(s,t,r);return}let n=await Qi(r,e,t),i=ti(),o=await dH(n,i,e,t,r.force??!1);console.log(),o.length>0&&(console.log(iC("Skill Installation:")),Xi(o))}var hH=new cH("init").description("Install the deveco-cli skill or configure the deveco-mcp server into AI agents").option("--agent <agents>","Target agents, comma-separated; installs to all available agents if omitted").option("--project <path>","Project root directory for skill or MCP configuration").option("--path <path>","Path to install the skill directly (cannot be used with --project or --agent)").option("--skill","Install the deveco-cli skill only (same as default behavior; explicit for symmetry with --mcp)").option("--mcp","Configure the deveco-mcp server (syntax checking for .ets and C/C++) only; no skill installation").option("-f, --force","Replace existing Skill content or MCP configuration; create missing target directories").action(async r=>{try{await gH(r)}catch(e){console.error(lH(e instanceof Error?e.message:String(e))),process.exitCode=1}}),sC=hH;import{Command as kU}from"commander";import{McpServer as dU}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as uU}from"@modelcontextprotocol/sdk/server/stdio.js";import*as za from"fs";import*as ss from"path";import{z as xe}from"zod";import Jd from"path";function lC(r,e,t,n,i){if(e.isError)return{};let o=e.content?.[0]?.text??"";if(!o)return{};let s;switch(r){case"check":s=yH(o);break;case"hover":s={hit:qo(o)!=null};break;case"definition":case"declaration":s=aC(o,t,n,i,!0);break;case"references":s=vH(o);break;case"implementation":s=aC(o,t,n,i,!1);break;case"documentSymbol":s=bH(o);break;case"callHierarchy":s=SH(o,t,n,i);break;case"workspaceSymbol":s=EH(o,t);break;default:s={}}return s}function dC(r){let e=Array.isArray(r.files)?r.files[0]:r.file;return typeof e!="string"||!e?void 0:Jd.extname(e).toLowerCase().replace(/^\./,"")||void 0}function qo(r){let e=r.indexOf(": ");if(e<0)return;let t=r.slice(e+2).trim();if(!(!t||t==="no result"))try{return JSON.parse(t)}catch{return}}function yH(r){let e={total:0,error:0,warn:0,info:0},t=new Set,n=" => Diagnostic: ";for(let o of r.split(`
1338
+ `)){let s=o.indexOf(n);if(s<0)continue;let a;try{a=JSON.parse(o.slice(s+n.length))}catch{continue}if(Array.isArray(a))for(let c of a)c&&typeof c=="object"&&wH(c,e,t)}let i={diagTotal:e.total,diagError:e.error,diagWarn:e.warn,diagInfo:e.info};return t.size>0&&(i.rules=[...t]),i}function wH(r,e,t){e.total++;let n=r.severity;n===1?e.error++:n===2?e.warn++:(n===3||n===4)&&e.info++,typeof r.source=="string"&&t.add(r.source)}function vH(r){let e=qo(r),t=Array.isArray(e)?e:[],n=new Set;for(let i of t){let o=i?.uri;typeof o=="string"&&n.add(o)}return{refTotal:t.length,fileCount:n.size}}function aC(r,e,t,n,i){let o=qo(r);if(o==null)return{found:!1};let s=Array.isArray(o)?o:[o],a=s[0]?.uri;return i?{found:!0,sameFile:PH(a,e),sourceType:pC(a,t,n)}:{implTotal:s.length,found:!0}}function bH(r){let e=qo(r),t=Array.isArray(e)?e:[],n=0,i=new Map,o=s=>{for(let a of s){if(!a||typeof a!="object")continue;n++;let c=a.kind;typeof c=="number"&&i.set(c,(i.get(c)??0)+1);let l=a.children;Array.isArray(l)&&o(l)}};return o(t),{symbolTotal:n,kindDist:jg(i)}}function SH(r,e,t,n){let o=qo(r)?.calls,s=Array.isArray(o)?o:[],a=e.direction,c=new Map;for(let l of s){if(!l||typeof l!="object")continue;let g=(a==="incoming"?l.from:l.to)?.uri,y=pC(g,t,n);c.set(y,(c.get(y)??0)+1)}return{callsTotal:s.length,calleeSrcDist:jg(c)}}function EH(r,e){let t=qo(r),n=Array.isArray(t)?t:[],i=new Map,o=0;for(let c of n){if(!c||typeof c!="object")continue;let l=c.kind;typeof l=="number"&&i.set(l,(i.get(l)??0)+1);let d=c.tags;(Array.isArray(d)&&d.includes(1)||c.deprecated===!0)&&o++}let s={resultTotal:n.length,kindDist:jg(i),deprecatedHit:o},a=e.query;return typeof a=="string"&&(s.queryLen=a.length),s}function uC(r){if(typeof r!="string"||!r)return null;let e=r;return e.startsWith("file://")&&(e=e.slice(7),process.platform==="win32"&&e.startsWith("/")&&(e=e.slice(1))),e}function pC(r,e,t){let n=uC(r);return n?e&&cC(n,e)?"user_project":t&&cC(n,t)?"sdk":"system":"unknown"}function PH(r,e){let t=uC(r),n=e.file;return!t||typeof n!="string"?!1:Kd(t)===Kd(n)}function Kd(r){try{return Jd.resolve(r).replace(/\\/g,"/").toLowerCase()}catch{return r.replace(/\\/g,"/").toLowerCase()}}function cC(r,e){let t=Jd.relative(Kd(e),Kd(r));return t!==""&&!t.startsWith("..")&&!Jd.isAbsolute(t)}function jg(r){let e={};for(let[t,n]of r)e[String(t)]=n;return e}var Yd=class{constructor(e,t,n,i){this.telemetry=e;this.getAceServerPid=t;this.getProjectPath=n;this.getSdkPath=i}tools=new Map;add(e,t){return this.tools.set(e.name,{definition:e,handler:t}),this}getAll(){return Array.from(this.tools.values())}registerToServer(e){for(let{definition:t,handler:n}of this.getAll())e.registerTool(t.name,{description:t.description,inputSchema:t.inputSchema},(async i=>this.invokeTool(t.name,i,n)))}async invokeTool(e,t,n){if(h.debug(`[telemetry] mcp tool call: ${e}`),!this.telemetry)return n(t);let i=ce(process.memoryUsage().rss),o=await this.resolveLspMemory(),s=Date.now(),a=!0,c=null,l;try{l=await n(t)}catch(d){throw a=!1,c=d instanceof Error?d.code??d.name:"UnknownError",d}finally{await this.trackToolCall(e,t,l,s,i,o,a,c)}return l}async trackToolCall(e,t,n,i,o,s,a,c){if(!this.telemetry)return;let l=n?.isError===!0,d=n&&!l?lC(e,n,t,this.getProjectPath?.()??"",this.getSdkPath?.()??""):{},g=l?!1:a,y=l&&n?CH(n):c,E={event:v.McpToolCall,subAction:e,mcpMemory:o,lspMemory:s,fileExt:dC(t),...d};typeof t.direction=="string"&&(E.direction=t.direction),await this.telemetry.track(E,{duration_ms:Date.now()-i,success:g,error_code:y})}async resolveLspMemory(){let e=this.getAceServerPid?.()??null;if(e===null)return"unknown";let t=await gt(e);return t===null?"unknown":ce(Number(t)*1024)}};function CH(r){let e=r.content.map(t=>t.text).join(`
1339
+ `);return/not ready|not initialized|initializing|please retry|retry \d+s|syncing|C\+\+ project initialization failed/i.test(e)?"NotReady":/No project detected|PROJECT_PATH|no project path/i.test(e)?"NoProject":/Missing.*parameter|invalid parameters|Unknown feature|must be|Must specify|cannot be used together|invalid/i.test(e)?"BadRequest":/Too many files|Maximum allowed/i.test(e)?"TooManyFiles":/does not exist|not exist|not found|No valid|not a .ets|not a supported|Unsupported/i.test(e)?"InvalidFile":"ToolError"}function Hg(r,e,t,n){return new Yd(r,e,t,n)}import*as Ot from"fs";import*as Ue from"path";function fC(r){return"method"in r&&!("id"in r)}import{spawn as mC}from"child_process";import*as gC from"crypto";import{EventEmitter as kH}from"events";import*as Xr from"fs";import*as hC from"net";import*as er from"path";var RH=50*1024*1024,xH=60*1e3,DH=10*1e3,IH=64*1024;function AH(r){let e=er.resolve(r).replace(/\\/g,"/");return e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),process.platform==="win32"?e.toLowerCase():e}function TH(r){return gC.createHash("sha1").update(AH(r)).digest("hex").slice(0,12)}function NH(r){let e=er.resolve(r),t=e.split(er.sep),n=t.lastIndexOf("out");return n>0?t.slice(0,n+1).join(er.sep):er.dirname(e)}var xn=class extends kH{constructor(t){super();this.config=t}process=null;buffer=Buffer.alloc(0);isClosing=!1;socket=null;_ownsProcess=!1;get pid(){return this.process?.pid??null}get ownsProcess(){return this._ownsProcess}get isSocketMode(){return this.socket!==null}ensureDirectories(){let t=er.join(this.config.logPath,"lspLog");return Xr.existsSync(t)||Xr.mkdirSync(t,{recursive:!0}),Xr.existsSync(this.config.indexingDataLocation)||Xr.mkdirSync(this.config.indexingDataLocation,{recursive:!0}),t}async start(t){this.config.useSocket&&this.config.projectPath?await this.startSocket(t):await this.startStdio(t)}async startStdio(t){this._ownsProcess=!0;let n=this.ensureDirectories();m.debug(`[LspClient] serverMaxSize=${t}MB`);let i=Ns({serverPath:this.config.serverPath,lspLogPath:n,serverMaxSize:t}),o=ri(this.config.nodePath);m.debug(`[LspClient] Starting process: node ${i.join(" ")}`),m.debug(`[LspClient] nodePath: ${o}`),this.process=mC(o,i,{cwd:this.config.cwd||process.cwd(),stdio:["pipe","pipe","pipe"],windowsHide:!0}),this.bindProcessEvents(!0,!0),await new Promise(s=>setTimeout(s,500)),m.info("[LspClient] start lsp process success")}async startSocket(t){let n=this.ensureDirectories(),i=this.config.projectPath,o=NH(this.config.serverPath),s=er.join(i,".idea",".deveco","arkts",".cache",`lsp-socket-${TH(o)}.properties`),a=this.tryReadPortFile(s);if(a!==null)try{m.info(`[LspClient] Port file found (lspSocketPort=${a}), connecting to existing server`),this._ownsProcess=!1,await this.connectSocket(a),m.info("[LspClient] Connected to existing socket server");return}catch(d){m.warn(`[LspClient] Failed to connect to existing socket server (port=${a}): ${d instanceof Error?d.message:d}, falling back to spawn`)}let c=3,l=null;for(let d=1;d<=c;d++)try{d===1?m.info("[LspClient] Spawning server in socket mode"):m.info(`[LspClient] Retry ${d}/${c} spawning socket server`),this._ownsProcess=!0,await this.spawnSocketServer(t,n,i),m.info("[LspClient] Socket server started and connected");return}catch(g){l=g instanceof Error?g:new Error(String(g)),m.warn(`[LspClient] Spawn attempt ${d}/${c} failed: ${l.message}`),this.cleanupSpawnResidue()}throw new Error(`Failed to start socket server after ${c} attempts: ${l?.message}`)}cleanupSpawnResidue(){if(this.process){try{this.process.exitCode===null&&this.process.signalCode===null&&this.process.kill()}catch{}this.process=null}if(this.socket){try{this.socket.destroy()}catch{}this.socket=null}}tryReadPortFile(t){try{if(!Xr.existsSync(t))return null;let i=Xr.readFileSync(t,"utf8").match(/lspSocketPort\s*=\s*(\d+)/);if(i){let o=parseInt(i[1],10);if(Number.isFinite(o)&&o>0)return o}return null}catch{return null}}async spawnSocketServer(t,n,i){m.debug(`[LspClient] serverMaxSize=${t}MB`);let o=Ns({serverPath:this.config.serverPath,lspLogPath:n,serverMaxSize:t,transportFlag:"--scope=multi",projectPath:i}),s=ri(this.config.nodePath);m.debug(`[LspClient] Starting process (socket): node ${o.join(" ")}`),m.debug(`[LspClient] nodePath: ${s}`),this.process=mC(s,o,{cwd:this.config.cwd||process.cwd(),stdio:["pipe","pipe","pipe"],windowsHide:!0,detached:!0});let a=await this.waitForPortFromStdout(xH);m.debug(`[LspClient] LSP_SOCKET_LISTENING port=${a}`),await this.connectSocket(a),this.bindProcessEvents(!0,!1)}waitForPortFromStdout(t){return new Promise((n,i)=>{let o=this.process?.stdout;if(!o){i(new Error("LSP server failed to start: no stdout"));return}let s=/LSP_SOCKET_LISTENING:(\d+)/,a="",c=setTimeout(()=>{o.removeListener("data",l),i(new Error("LSP server failed to start: port not received within timeout"))},t),l=d=>{a+=d.toString("utf8");let g=a.match(s);if(g){clearTimeout(c),o.removeListener("data",l),n(parseInt(g[1],10));return}a=a.slice(-IH)};o.on("data",l)})}connectSocket(t){return new Promise((n,i)=>{let o=hC.connect(t,"127.0.0.1"),s=setTimeout(()=>{o.destroy(),i(new Error(`TCP connection to LSP socket timed out (port ${t})`))},DH);o.on("connect",()=>{clearTimeout(s),this.socket=o,this.bindSocketEvents(o),n()}),o.on("error",a=>{clearTimeout(s),i(new Error(`TCP connection to LSP socket failed: ${a.message}`))})})}bindSocketEvents(t){t.on("data",n=>this.handleData(n)),t.on("error",n=>{m.error(`[LspClient] socket error: ${n.message}`),this.isClosing||this.emit("error",n)}),t.on("close",()=>{m.info("[LspClient] socket closed"),this.isClosing||this.emit("error",new Error("LSP socket closed"))})}attachProcess(t,n){if(this.process)throw new Error("[LspClient] process already attached");this._ownsProcess=!0,this.process=t,this.bindProcessEvents(n?.stderrAsError??!0,!0),m.info("[LspClient] attached to external process")}bindProcessEvents(t=!0,n=!0){this.process&&(n&&this.process.stdout?.on("data",i=>{this.handleData(i)}),this.process.stderr?.on("data",i=>{let o=i.toString("utf8").trim();m.error(`[LspClient] stderr: ${o}`),!this.isClosing&&t&&this.emit("error",new Error(`[LspClient] stderr: ${o}`))}),this.process.on("exit",i=>{m.info(`[LSP EXIT] code=${i}`),this.isClosing||this.emit("error",new Error(`LSP process exited with code ${i}`))}))}sendRaw(t,n){let i=this.buildLspMessage(t);if(this.socket&&!this.socket.destroyed&&this.socket.writable){m.debug(`[LspClient] [SOCKET SEND] ${n}: ${t.slice(0,200)}`),this.socket.write(i,"utf8");return}if(!this.process?.stdin?.writable){m.warn("[LspClient] Cannot send message, no writable transport");return}m.debug(`[LspClient] send message: ${n}`),this.process.stdin.write(i,"utf8")}send(t,n,i){let o={jsonrpc:"2.0",method:t,params:n};i!==void 0&&(o.id=i),this.sendRaw(JSON.stringify(o),t)}sendNotification(t,n){this.sendRaw(JSON.stringify({jsonrpc:"2.0",method:t,params:n}),t)}sendRequest(t,n,i){this.sendRaw(JSON.stringify({jsonrpc:"2.0",id:i,method:t,params:n}),t)}buildLspMessage(t){return`Content-Length: ${Buffer.from(t,"utf8").length}\r
1324
1340
  \r
1325
1341
  ${t}`}handleData(t){for(this.buffer=Buffer.concat([this.buffer,t]);;){let n=this.buffer.indexOf(`\r
1326
1342
  \r
1327
- `);if(n===-1)break;let o=this.buffer.slice(0,n).toString("ascii").match(/Content-Length:\s*(\d+)/i);if(!o){f.warn("[LspClient] Invalid LSP header, drop until next packet"),this.buffer=this.buffer.slice(n+4);continue}let s=parseInt(o[1],10);if(!Number.isFinite(s)||s<0||s>J$){f.warn(`[LspClient] Invalid Content-Length: ${o[1]}, drop until next packet`),this.buffer=this.buffer.slice(n+4);continue}let a=n+4,c=a+s;if(this.buffer.length<c)break;let l=this.buffer.slice(a,c).toString("utf8"),d=this.recoverFramedJson(l);if(d&&d.rest.length>0){f.warn(`[LspClient] recovered mixed LSP frame, bodyLen=${l.length}, restLen=${d.rest.length}`),this.logSocketRecv(d.json),this.emit("message",d.json),this.buffer=Buffer.concat([Buffer.from(d.rest,"utf8"),this.buffer.slice(c)]);continue}this.logSocketRecv(l),this.emit("message",l),this.buffer=this.buffer.slice(c)}}logSocketRecv(t){this.socket&&f.debug(`[LspClient] [SOCKET RECV] ${t.slice(0,200)}`)}waitForExitOrTimeout(t){let n=this.process;return!n||n.exitCode!==null||n.signalCode!==null?Promise.resolve():new Promise(i=>{let o=!1,s=()=>{o||(o=!0,clearTimeout(c),n.off("exit",a),i())},a=()=>s();n.once("exit",a);let c=setTimeout(s,t)})}recoverFramedJson(t){let n=t.search(/\S/);if(n<0||t[n]!=="{"&&t[n]!=="[")return null;let i=0,o=!1,s=!1;for(let a=n;a<t.length;a++){let c=t[a];if(o){if(s){s=!1;continue}if(c==="\\"){s=!0;continue}c==='"'&&(o=!1);continue}if(c==='"'){o=!0;continue}if(c==="{"||c==="["){i++;continue}if((c==="}"||c==="]")&&(i--,i===0)){let l=t.slice(n,a+1),d=t.slice(a+1);return{json:l,rest:d}}}return null}stop(){if(this.isClosing=!0,this.socket){this.socket.destroy(),this.socket=null,this.process=null;return}let t=this.process;if(!t)return;if(this.process=null,t.exitCode===null&&t.signalCode===null)try{t.kill()}catch{}}};var kn=class{callbacks=new Map;pending=new Map;timeouts=new Map;registerPending(e,t,n){return new Promise((i,o)=>{let s;n>0&&(s=setTimeout(()=>{this.pending.delete(e),this.timeouts.delete(e),o(new Error(`LSP request '${t}' (id=${e}) timeout after ${n}ms`))},n),this.timeouts.set(e,s)),this.pending.set(e,{resolve:i,reject:o,method:t,timer:s})})}resolvePending(e,t){this.clearTimeout(e);let n=this.pending.get(e);return n?(n.resolve(t),this.pending.delete(e),!0):!1}rejectPending(e,t){this.clearTimeout(e);let n=this.pending.get(e);return n?(n.reject(t),this.pending.delete(e),!0):!1}register(e,t){this.callbacks.set(e,t)}emit(e,t,n){f.debug(`[RequestCallbackManager] emit, method: ${t}, key: ${e}`),this.clearTimeout(e);let i=this.callbacks.get(e);if(i)try{i(t,n)}finally{this.callbacks.delete(e)}else{let o=[...this.callbacks.keys()].map(s=>String(s));f.debug(`[RequestCallbackManager] emit: NO callback for key='${e}', registered keys=[${o.join(",")}]`)}}registerTimeout(e,t,n,i){let o=this.timeouts.get(e);o&&clearTimeout(o);let s=setTimeout(()=>{f.debug(`[RequestCallbackManager] timeout, key=${e}, method=${t}`);try{i()}finally{this.timeouts.delete(e)}},n);this.timeouts.set(e,s)}clearTimeout(e){let t=this.timeouts.get(e);t&&(clearTimeout(t),this.timeouts.delete(e))}deleteCallback(e){this.callbacks.delete(e)}hasCallback(e){return this.callbacks.has(e)||this.pending.has(e)}clear(e){this.clearTimeout(e);let t=this.pending.get(e);t&&(t.reject(new Error(`Request '${t.method}' (id=${e}) cancelled`)),this.pending.delete(e)),this.callbacks.delete(e)}rejectAll(e){for(let[,t]of this.pending)t.reject(e);this.pending.clear();for(let[,t]of this.timeouts)clearTimeout(t);this.timeouts.clear(),this.callbacks.clear()}};var vd=class{uri;diagnostics=[];constructor(e){this.uri=e}set(e){this.diagnostics=e}get(){return this.diagnostics}clear(){this.diagnostics=[]}};var Lo=class{map=new Map;register(e,t){let n=this.map.get(e);n||(n=new Set,this.map.set(e,n)),n.add(t)}unregister(e,t){let n=this.map.get(e);n&&(t!==void 0?n.delete(t):n.clear(),n.size===0&&this.map.delete(e))}invoke(e,...t){let n=this.map.get(e);if(n)for(let i of n)try{i(...t)}catch(o){console.error(`[CallbackRegistry] invoke("${String(e)}") callback error:`,o)}}invokeOnce(e,...t){this.invoke(e,...t),this.unregister(e)}clear(){this.map.clear()}has(e){let t=this.map.get(e);return t!==void 0&&t.size>0}};function M(r){return typeof r=="object"&&r!==null}var HE=20*1e3,t0=30*1e3,UE=300,r0=300;function n0(){let r=process.env.DEVECO_CLI_LSP_STANDARD_EXIT_TIMEOUT_MS;if(r===void 0||r==="")return UE;let e=parseInt(r,10);return Number.isFinite(e)?Math.max(r0,e):UE}var bd=class{client;nextRequestId=1;stopOnce=null;callbacks=new Lo;requestCallbacks=new kn;diagnosticMap=new Map;initProgressReset=null;notificationWaiters=new Map;get lspPid(){return this.client.pid}constructor(e){this.client=new Cn(e),this.client.on("message",t=>this.handleRawMessage(t)),this.client.on("error",t=>this.handleError(t))}async start(e){await this.client.start(e)}stop(){return this.stopOnce||(this.stopOnce=(async()=>{f.info("[ClientMessageHandle] Sending shutdown request"),this.client.sendRequest(b.SHUTDOWN,null,this.nextRequestId++),f.info("[ClientMessageHandle] Sending exit notification"),this.client.sendNotification(b.EXIT,null),f.info("[ClientMessageHandle] Waiting for LSP process to exit"),await this.client.waitForExitOrTimeout(n0()),f.info("[ClientMessageHandle] LSP exit wait completed, calling stop"),this.client.stop()})()),this.stopOnce}setBroadcastToClients(e){this.callbacks.unregister(b.BROADCAST),this.callbacks.register(b.BROADCAST,e)}broadcastToClients(e){this.callbacks.invoke(b.BROADCAST,e)}async sendInitialize(e){let t=this.nextRequestId++,n=this.requestCallbacks.registerPending(t,b.INITIALIZE,it);return this.client.sendRequest(b.INITIALIZE,e,t),n}sendInitializeResettable(e,t){let n=this.nextRequestId++,i=this.requestCallbacks.registerPending(n,b.INITIALIZE,0);return this.client.sendRequest(b.INITIALIZE,e,n),new Promise((o,s)=>{let a,c=()=>{a=setTimeout(()=>{this.initProgressReset=null,s(new Error(`LSP initialization timeout after ${t}ms`))},t)},l=()=>{clearTimeout(a),c()};this.initProgressReset=l,c(),i.then(()=>{clearTimeout(a),this.initProgressReset=null,o()},d=>{clearTimeout(a),this.initProgressReset=null,s(d)})})}sendInitialized(){this.client.sendNotification(b.INITIALIZED,{})}sendInitializeAndWaitForNotification(e,t,n,i,o){return new Promise((s,a)=>{let c={initializeResolved:!1,notificationResolved:!1},l=this.startInitTimer(t,n,a);this.initProgressReset=()=>{l.reset(),o?.()};let d=()=>{c.initializeResolved&&c.notificationResolved&&(l.clear(),s())};this.notificationWaiters.set(t,()=>{c.notificationResolved=!0,d()});let g=this.nextRequestId++;this.client.sendRequest(b.INITIALIZE,e,g),this.requestCallbacks.registerPending(g,b.INITIALIZE,0).then(()=>{c.initializeResolved=!0;try{i()}catch(y){l.clear(),a(y instanceof Error?y:new Error(String(y)));return}d()},y=>{l.clear(),a(y)})})}startInitTimer(e,t,n){let i,o=()=>{clearTimeout(i),this.initProgressReset=null,this.notificationWaiters.delete(e)},s=()=>{i=setTimeout(()=>{o(),n(new Error(`LSP initialization timeout after ${t}ms`))},t)},a=()=>{clearTimeout(i),s()};return s(),{reset:a,clear:o}}sendDidOpen(e){let t=e.textDocument.uri;this.diagnosticMap.has(t)||(this.diagnosticMap.set(t,new vd(t)),this.registerDiagnosticTimeout(t)),this.client.sendNotification(b.DID_OPEN,e)}sendDidChange(e){let t=e.textDocument.uri,n=this.diagnosticMap.get(t);n&&(n.clear(),this.registerDiagnosticTimeout(t)),this.client.sendNotification(b.DID_CHANGE,e)}closeFile(e){this.cleanupDiagnosticState(e.textDocument.uri),this.client.sendNotification(b.DID_CLOSE,e)}sendLspRequest(e,t,n=t0){let i=this.nextRequestId++,o=this.requestCallbacks.registerPending(i,e,n);return this.client.sendRequest(e,t,i),o}registerRequestCallback(e,t){this.requestCallbacks.register(e,t)}onDidChangeWatchedFiles(e){e.length!==0&&this.client.sendNotification(b.WORKSPACE_DID_CHANGE_WATCHED_FILES,{changes:e})}sendDidChangeConfiguration(e){this.client.sendNotification(b.WORKSPACE_DID_CHANGE_CONFIGURATION,{settings:e})}sendNotification(e,t){this.client.sendNotification(e,t)}getDiagnosticMessages(e){let t=this.diagnosticMap.get(e);return t?t.get():[]}clearDiagnostic(e){this.diagnosticMap.get(e)?.clear()}handleRawMessage(e){let t;try{t=JSON.parse(e)}catch(n){let i=n instanceof Error?n.message:String(n);f.error(`[LSP] JSON parse error: ${i}, raw: ${e}`);return}"id"in t&&("result"in t||"error"in t)?this.handleResponse(t):"method"in t?this.handleNotificationOrRequest(t):f.warn(`[LSP] Unrecognized message: ${JSON.stringify(t).slice(0,200)}`)}handleResponse(e){let t=e.id;if(t===void 0)return;let n=t;if(e.error){let i=new Error(`LSP error ${e.error.code}: ${e.error.message}`);this.requestCallbacks.rejectPending(n,i)}else this.requestCallbacks.resolvePending(n,e.result)}handleNotificationOrRequest(e){let t=e.method;if(!t)return;this.initProgressReset?.();let n=this.notificationWaiters.get(t);if(n){this.notificationWaiters.delete(t),n();return}switch(t){case b.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(e.params);break;case b.PROGRESS:this.handleProgress(e.params);break;case b.WINDOW_SHOW_MESSAGE:f.debug(`[LSP] window/showMessage: ${JSON.stringify(e.params)}`);break;case b.WINDOW_LOG_MESSAGE:f.debug(`[LSP] window/logMessage: ${JSON.stringify(e.params)}`);break;default:this.broadcastToClients(e)}}handlePublishDiagnostics(e){if(!e||!e.uri)return;let t=e.uri,n=this.diagnosticMap.get(t);if(!n)return;let i=e.diagnostics||[];this.normalizeDiagnostics(i),n.set(i),this.finalizeDiagnostic(t,i)}normalizeDiagnostics(e){for(let t of e)if(t.severity!==void 0){let n={1:"Error",2:"Warning",3:"Information",4:"Hint"};t.severityStr=n[t.severity]||"Unknown"}}handleProgress(e){M(e)&&this.broadcastToClients({jsonrpc:L,method:b.PROGRESS,params:e})}registerDiagnosticTimeout(e){this.requestCallbacks.registerTimeout(e,b.PUBLISH_DIAGNOSTICS,HE,()=>{let t=this.diagnosticMap.get(e),n=t?t.get():[];this.finalizeDiagnostic(e,n,n.length>0?void 0:`received no diagnostics within ${HE}ms, uri: ${e}`)})}finalizeDiagnostic(e,t,n){let i={uri:e,diagnostics:t,...n?{errorMessage:n}:{}};this.requestCallbacks.emit(e,b.PUBLISH_DIAGNOSTICS,i),this.diagnosticMap.get(e)?.clear()}handleError(e){let t=Array.from(this.diagnosticMap.keys()).filter(n=>this.requestCallbacks.hasCallback(n));if(t.length>0){let n={range:{start:{line:0,character:0},end:{line:0,character:0}},severity:1,message:e.message};for(let i of t)this.finalizeDiagnostic(i,[n]);return}this.broadcastToClients({jsonrpc:L,method:b.ARKTS_ERROR,params:{message:e.message}})}cleanupDiagnosticState(e){this.requestCallbacks.clear(e),this.diagnosticMap.delete(e)}};var Sd=class{uri;messages=[];receivedTypes=new Set;uniqueMessages=new Set;isFromEditor=!1;constructor(e){this.uri=e}setReceivedType(e){this.receivedTypes.add(e)}addMessage(e,t){this.receivedTypes.add(e);let n=`${e}:${t}`;if(this.uniqueMessages.has(n)){f.info(`[LegacyDiagnostic] addMessage: duplicate message=${n}`);return}this.uniqueMessages.add(n),this.messages.push(new Jf(e,t))}clearMessages(){this.messages=[]}clear(){this.receivedTypes.clear(),this.uniqueMessages.clear(),this.messages=[]}hasReceivedAllTypes(e){for(let t of e)if(!this.receivedTypes.has(t))return!1;return!0}getMessages(){return this.messages.map(e=>e.diagnostics)}},Jf=class{version=-1;diagnostics;constructor(e,t){this.version=e,this.diagnostics=t}};var i0={EXIT:"exit",INITIALIZED:"initialized",ON_DID_CHANGE_PACKAGE_DEPENDENCIES:"aceProject/onDidChangePackageDependencies",ON_ASYNC_DID_OPEN:"aceProject/onAsyncDidOpen",ON_ASYNC_DID_CHANGE:"aceProject/onAsyncDidChange",DID_CLOSE:"textDocument/didClose",ON_ASYNC_HOVER:"aceProject/onAsyncHover",ON_ASYNC_DEFINITION:"aceProject/onAsyncDefinition",ON_ASYNC_FIND_USAGES:"aceProject/onAsyncFindUsages"},o0={MODULE_INIT_FINISH:Yi.MODULE_INIT_FINISH,INDEXING_PROGRESS_UPDATE:"aceProject/onIndexingProgressUpdate",ON_FORCE_OPEN_FILE:"aceProject/onForceOpenFile",ON_PACKAGE_CHANGE_FINISH:"aceProject/onPackageChangeFinish",TEXT_DOCUMENT_ON_ASYNC_DEFINITION:"textDocument/onAsyncDefinition",ON_DID_CHANGE_PACKAGE_DEPENDENCIES_CLIENT:"textDocument/onDidChangePackageDependencies",PUBLISH_DIAGNOSTICS:"textDocument/publishDiagnostics",HOVER:"textDocument/hover",DEFINITION:"textDocument/definition",REFERENCES:"textDocument/references",DID_OPEN:"textDocument/didOpen",DID_CHANGE:"textDocument/didChange",WORKSPACE_DID_CHANGE_CONFIGURATION:"workspace/didChangeConfiguration",WORKSPACE_DID_CHANGE_WATCHED_FILES:"workspace/didChangeWatchedFiles",BROADCAST:"lsp/broadcast",ARKTS_ERROR:"arkts/error",ARKTS_INITIALIZED:"arkts/initialized",ARKTS_INITIALIZATION_FAILED:"arkts/initializationFailed",ARKTS_INDEXING_PROGRESS:"arkts/indexingProgress",ARKTS_SYNC_PROJECT:"arkts/syncProject",ARKTS_SYNC_COMPLETED:"arkts/syncCompleted",ARKTS_REINITIALIZING:"arkts/reinitializing"},_={...i0,...o0},Dn={EXIT:"exit",INITIALIZED:"initialized",EMPTY:"empty",ON_DID_CHANGE_PACKAGE_DEPENDENCIES:"onDidChangePackageDependencies",ON_ASYNC_DID_OPEN:"onAsyncDidOpen",ON_ASYNC_DID_CHANGE:"onAsyncDidChange",DID_CLOSE:"didClose",ON_ASYNC_HOVER:"onAsyncHover",ON_ASYNC_DEFINITION:"onAsyncDefinition",ON_ASYNC_FIND_USAGES:"onAsyncFindUsages"},BE=new Set([1e3,2e3,3e3,3001]);function s0(r){if(!M(r))return!1;let e=r.textDocument;return M(e)&&typeof e.uri=="string"}function a0(r){return M(r)?typeof r.uri=="string"&&typeof r.type=="number":!1}function c0(r){return M(r)&&typeof r.moduleName=="string"&&typeof r.current=="number"&&typeof r.total=="number"?`indexing module '${r.moduleName}', ${r.current} of total ${r.total} modules`:`params=${JSON.stringify(r??null)}`}var Ed=class r{client;isInitialized=!1;stopOnce=null;callbacks=new Lo;requestCallbacks=new kn;diagnosticMap=new Map;static DIAGNOSTIC_TIMEOUT_MS=20*1e3;get lspPid(){return this.client.pid}constructor(e){this.client=new Cn(e),this.client.on("message",t=>this.handleRawMessage(t)),this.client.on("error",t=>this.handleError(t))}async start(e){await this.client.start(e)}stop(){return this.stopOnce||(this.stopOnce=(async()=>{f.info("[LegacyClientMessageHandle] Sending exit notification to LSP"),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.EXIT,params:{}}),Dn.EXIT),f.info("[LegacyClientMessageHandle] Waiting for LSP process to exit"),await this.client.waitForExitOrTimeout(300),f.info("[LegacyClientMessageHandle] LSP exit wait completed, calling stop"),this.client.stop()})()),this.stopOnce}setBroadcastToClients(e){this.callbacks.unregister(_.BROADCAST),this.callbacks.register(_.BROADCAST,e)}broadcastToClients(e){this.callbacks.invoke(_.BROADCAST,e)}onInitializationCompleted(e){this.isInitialized?e():this.callbacks.register(_.MODULE_INIT_FINISH,e)}onIndexingProgressUpdate(e){this.callbacks.register(_.INDEXING_PROGRESS_UPDATE,e)}registerRequestCallback(e,t){this.requestCallbacks.register(e,t)}sendInitialize(e,t){this.client.send("initialize",e,t)}sendInitialized(e){this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.INITIALIZED,params:{editors:e}}),Dn.INITIALIZED),this.client.sendRaw(JSON.stringify({jsonrpc:L,id:0,result:{}}),Dn.EMPTY)}sendAsyncRequest(e,t,n,i){if(!M(t)){f.warn(`[LSP] sendAsyncRequest invalid params, method=${e}`);return}if(!s0(t)){f.warn(`[LSP] sendAsyncRequest missing textDocument.uri, method=${e}, params=${JSON.stringify(t)}`);return}if(typeof n!="number"){f.warn(`[LSP] sendAsyncRequest invalid requestId, method=${e}, requestId=${String(n)}`);return}let o=t.textDocument.uri,s=Ht(o);t.textDocument.uri=s,delete t.requestId;let a=i??e;f.info(`[LSP] sendAsyncRequest ${a}, filePath: ${o}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:e,params:{params:t,requestId:n}}),a)}onDidChangeWatchedFiles(e){if(f.info(`[LSP] onDidChangeWatchedFiles, params=${JSON.stringify(e)}`),e.length===0)return;let t=[];for(let n of e){if(!a0(n)){f.warn(`[LSP] onDidChangeWatchedFiles, param is missing 'uri' or 'type': ${JSON.stringify(n)}`);continue}t.push(n)}this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.WORKSPACE_DID_CHANGE_WATCHED_FILES,params:{changes:t}}),_.WORKSPACE_DID_CHANGE_WATCHED_FILES)}sendModuleDependencyUpdate(e){if(!M(e)||!Array.isArray(e.moduleSet)||e.moduleSet.length===0){f.warn("[LSP] sendModuleDependencyUpdate, moduleSet is empty or null");return}let t=e.moduleSet;f.info(`[LSP] sending module dependency updated, count: ${t.length}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.ON_DID_CHANGE_PACKAGE_DEPENDENCIES,params:{params:e}}),Dn.ON_DID_CHANGE_PACKAGE_DEPENDENCIES)}onAsyncOpenFile(e){let t=e.textDocument.uri,n=t.split(".").pop()||"";if(n!=="ets"&&n!=="ts")return;let i=Ht(t);e.textDocument.uri=i,f.info(`[LSP] onAsyncOpenFile, uri: ${i}`);let o=this.diagnosticMap.get(i);o||(o=new Sd(i),this.diagnosticMap.set(i,o),this.registerDiagnosticTimeout(i,_.PUBLISH_DIAGNOSTICS)),e.isFromEditor&&(o.isFromEditor=!0),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.ON_ASYNC_DID_OPEN,params:{params:{editorFiles:e.editorFiles,textDocument:e.textDocument}}}),Dn.ON_ASYNC_DID_OPEN)}onAsyncDidChange(e){let t=Ht(e.uri),n=this.diagnosticMap.get(t);n&&(n.clear(),this.registerDiagnosticTimeout(t,_.PUBLISH_DIAGNOSTICS)),f.info(`[LSP] onAsyncDidChange, uri: ${t}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.ON_ASYNC_DID_CHANGE,params:{editorFiles:[e.uri],params:{textDocument:{uri:t,version:e.version===0?null:e.version},contentChanges:e.contentChanges}}}),Dn.ON_ASYNC_DID_CHANGE)}closeFile(e,t){let n=Ht(e);f.info(`[LSP] didClose, uri: ${n}`);let i=this.diagnosticMap.get(n);if(!t&&(!i||i.isFromEditor)){f.info(`[LSP] closeFile skip, !diagnostic: ${!i}, isFromEditor: ${i?.isFromEditor}`);return}this.cleanupDiagnosticState(n),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:_.DID_CLOSE,params:{textDocument:{uri:n}}}),Dn.DID_CLOSE)}getDiagnosticMessage(e){let t=Ht(e),n=this.diagnosticMap.get(t);return n?n.getMessages():[]}clear(e){this.diagnosticMap.get(e)?.clear()}handleRawMessage(e){try{let t=JSON.parse(e);this.handleLspMessage(t)}catch(t){let n=t instanceof Error?t.message:String(t);f.error(`[LSP] JSON parse error: ${n}, raw: ${e}`)}}handleError(e){let t=this.getPendingDiagnosticUris();if(t.length>0){let n=JSON.stringify({message:e.message,severity:"Error",severityStr:"Error"});for(let i of t)this.finalizeDiagnostic(i,_.PUBLISH_DIAGNOSTICS,[n]);return}this.broadcastToClients({jsonrpc:L,method:_.ARKTS_ERROR,params:{message:e.message}})}handleLspMessage(e){let t=e.method;t!==void 0&&(!this.isInitialized&&this.handlePreInitMessage(t,e)||this.handlePostInitMessage(t,e))}handlePreInitMessage(e,t){switch(e){case _.MODULE_INIT_FINISH:return f.info("[LSP] handleLspMessage, receive onModuleInitFinish"),this.isInitialized=!0,this.callbacks.invokeOnce(_.MODULE_INIT_FINISH),this.callbacks.unregister(_.INDEXING_PROGRESS_UPDATE),this.client.emit("initialized_done"),!0;case _.INDEXING_PROGRESS_UPDATE:return f.info(`[LSP] onIndexingProgressUpdate: ${c0(t.params)}`),this.callbacks.invoke(_.INDEXING_PROGRESS_UPDATE),!0;default:return!1}}handlePostInitMessage(e,t){switch(e){case _.ON_FORCE_OPEN_FILE:this.handleOnForceOpenFile(t);return;case _.ON_PACKAGE_CHANGE_FINISH:f.info("[LSP] handleLspMessage, receive onPackageChangeFinish"),this.handlePackageChangeFinish(t);return;case _.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(t);return;case _.ON_ASYNC_HOVER:this.handleAsyncResponse(t,_.HOVER);return;case _.ON_ASYNC_DEFINITION:this.handleAsyncResponse(t,_.TEXT_DOCUMENT_ON_ASYNC_DEFINITION);return;case _.ON_ASYNC_FIND_USAGES:this.handleAsyncResponse(t,_.REFERENCES);return;default:f.warn(`[LSP] handleLspMessage: no handler for notification, ignoring, method: ${e}, initialized: ${this.isInitialized}`)}}handleOnForceOpenFile(e){f.info("[LSP] handleLspMessage, receive onForceOpenFile");let t=e.params;M(t)&&M(t.result)&&typeof t.result.uri=="string"&&this.handleForceOpenFile(t.result.uri)}handlePublishDiagnostics(e){f.info("[LSP] handleLspMessage, receive publishDiagnostics");let t=e.params;t&&this.parseDiagnostics(t)}handlePackageChangeFinish(e){let t=e.params,n={jsonrpc:L,method:_.ON_PACKAGE_CHANGE_FINISH,params:[!1]};if(!t||!Array.isArray(t)){f.warn("[LSP] aceProject/onPackageChangeFinish params invalid"),this.broadcastToClients(n);return}if(!(t.length>0&&t[0]===!0)){f.warn("[LSP] aceProject/onPackageChangeFinish: package request failed"),this.broadcastToClients(n);return}f.info("[LSP] aceProject/onPackageChangeFinish: success"),this.broadcastToClients(e)}handleAsyncResponse(e,t){f.info(`[LSP] handleAsyncResponse\uFF0C method: ${t}`);let n=e.params;if(!M(n)){f.warn("[LSP] aceProject/onAsyncHover message invalid");return}let i=n.requestId;if(typeof i!="number"){f.warn(`[LSP] ${t} requestId invalid`);return}this.requestCallbacks.emit(i,t,n)}handleForceOpenFile(e){if(!e){f.warn("[LSP] handleForceOpenFile, uri is empty");return}this.requestCallbacks.emit(e,_.DID_OPEN,[]),this.clear(e)}parseDiagnostics(e){let t=e.uri;if(!t){f.info("[LSP] publishDiagnostics uri is null");return}let n=e.version??-1;if(n===-1)return;let i=this.diagnosticMap.get(t);if(!i){f.info(`[LSP] Diagnostic cleared for uri: ${t}`);return}let o=e.diagnostics||[];o.length!==0?o.forEach(s=>{this.normalizeDiagnostic(s),i.addMessage(n,JSON.stringify(s))}):i.setReceivedType(n),i.hasReceivedAllTypes(BE)&&this.finalizeDiagnostic(t,_.PUBLISH_DIAGNOSTICS,i.getMessages())}normalizeDiagnostic(e){let t=e;if(delete t.source,t.severity!==void 0){let n=typeof t.severity=="number"?t.severity:parseInt(t.severity),o={1:"Error",2:"Warning",3:"Information",4:"Hint"}[n]||"Unknown";t.severityStr=o,t.severity=o}e.range&&(this.adjustPositionLine(e.range,"start"),this.adjustPositionLine(e.range,"end"))}adjustPositionLine(e,t){let n=e[t];n&&typeof n.line=="number"&&(n.line=n.line+1)}registerDiagnosticTimeout(e,t){this.requestCallbacks.registerTimeout(e,t,r.DIAGNOSTIC_TIMEOUT_MS,()=>{let n=this.diagnosticMap.get(e),i=n?n.getMessages():[];this.finalizeDiagnostic(e,t,i,i.length>0?void 0:`received no diagnostics within ${r.DIAGNOSTIC_TIMEOUT_MS}ms from LSP, uri: ${e}`)})}finalizeDiagnostic(e,t,n,i){let o={uri:e,diagnostics:n,...i?{errorMessage:i}:{}};this.requestCallbacks.emit(e,t,o),this.diagnosticMap.get(e)?.clear()}getPendingDiagnosticUris(){return Array.from(this.diagnosticMap.keys()).filter(e=>this.requestCallbacks.hasCallback(e))}cleanupDiagnosticState(e){this.requestCallbacks.clear(e),this.diagnosticMap.delete(e)}};import Yf from"path";import*as Ad from"path";var Pd=class{enableRecentlyUsed=!1;enableCompletionSortByType=!0;maxValidCompletionItemsCount=50;enableCompletionFunctionParameter=!1;enableIndexModuleRootDirEtsFile=!1};var Cd=class{overriddenEnable=!0;overridingEnable=!0;implementedEnable=!0;implementingEnable=!0};var kd=class{tsVariablesEnable=!1;tsPropertyEnable=!1;tsParameterEnable=!1;tsReturnEnable=!1;etsVariablesEnable=!1;etsPropertyEnable=!1;etsParameterEnable=!1;etsReturnEnable=!1};var Dd=class{etsParameterNameHintKind=null;tsParameterNameHintKind=null};var Rd=class{typeSetting=new kd;parameterNames=new Dd};var xd=class{constructor(e,t,n,i){this.rootUri=e;this.lspServerWorkspacePath=ge(Ad.dirname(t)),this.indexingDataLocation=ge(i),this.loggerPath=ge(Ad.join(n,"lspLog"))}modules=[];clientType="intellij";indexingDataLocation="";completionSortSetting=new Pd;gutterIconsSetting=new Cd;inlayHintsSetting=new Rd;lspMaxOldSpaceSize="8192";projectType="OHOS";loggerPath="";lspServerWorkspacePath};import*as WE from"path";var Sa=class{productName="default";buildModeName="debug";targetName="default";arkTSVersion="1.1";resourceDirectories=[];targetESVersion="ES2021";maxFlowDepth=2e3;caseSensitiveCheck=!0;tsImportSendable=!1;compatibleSdkVersionStage="";useNormalizedOHMUrl=!0;reExportCheckMode="noCheck";skipOhModulesLint=!1;byteCodeHar=!0;obfuscationRuleOptionsEnable=!1;enableStrictCheckOHModules=!1;sourceRoots=[];constructor(e){e&&this.resourceDirectories.push(ge(WE.join(e,"src","main","resources")))}};var l0="OS",_o=class{deviceType=[5];aceLoaderPath;modulePath;jsComponentType="declarative";sdkJsPath;compatibleSdkVersion;compatibleSdkLevel;compileSdkLevel;compileSdkVersion="6.0.1.112";compileSdkType="Release";syscap={NDeviceSysCaps:[],addedSysCaps:[]};apiType="stageMode";hosSdkPath;runtimeOs=`Harmony${l0}`;moduleName;moduleType;compileMode="jsbundle";crossPlatform=!1;ignoreCrossPlatform=!1;packageManagerType="ohpm";permissions=[];testPermissions=[];buildProfileParam;appParam={bundleType:"app"};packageName;projectType="OHOS";projectName;moduleDependencies;moduleJsonParam=null;globalDeclarationFiles=[];constructor(e){e?(this.modulePath=e,this.buildProfileParam=new Sa(e)):this.buildProfileParam=new Sa}toString(){return JSON.stringify(this)}};var $o=class{constructor(e=[]){this.pages=e}pagesFileName="main_pages.json";metaDataList=[]};import*as Xe from"path";import*as Ho from"fs";var Id=class{modulePath;dependencies={};dynamicDependencies={}};var vi=class{registryType;resolved;name;version;type;constructor(e){let t=typeof e=="object"&&e!==null?e:{};this.name=typeof t.name=="string"?t.name:"",this.version=typeof t.version=="string"?t.version:"",typeof t.registryType=="string"?this.registryType=t.registryType:this.registryType=typeof t.path=="string"?"local":"ohpm",typeof t.resolved=="string"?this.resolved=t.resolved:typeof t.storePath=="string"?this.resolved=t.storePath:this.resolved="",this.type=typeof t.type=="string"?t.type:void 0}};var Fo=class{constructor(e,t,n){this.projectPath=e;this.moduleName=t;this.modulePath=n}dependencies=[];devDependencies=[];dynamicDependencies=[];finalDependencies=[];finalDevDependencies=[];finalDynamicDependencies=[]};import*as Yr from"path";import*as Td from"fs";var jo=class{name="";version="";storePath="";dependencyPath="";path=""};var G={HVIGOR_CACHE:".hvigor",DEPENDENCY:"dependencyMap",JSON5:".json5",KEY_DEPENDENCY:"dependencies",KEY_DYNAMIC_DEPENDENCY:"dynamicDependencies",KEY_DEV_DEPENDENCY:"devDependencies",OH_MODULES_PATH:"oh_modules",OHPM_PATH:".ohpm",LOCK_JSON5_FILE:"lock.json5",OH_PACKAGE_JSON5:Pe.OH_PACKAGE_JSON5},Ea=`${G.HVIGOR_CACHE}/${G.DEPENDENCY}`,bi=`${G.DEPENDENCY}${G.JSON5}`,Xoe=Pe.SYNC_OUTPUT_PATH;var Pa=class r{dependencyPath;modulePath;projectPath;static FILE_DEPENDENCY_PREFIX="file:";static PARAMETER_PREFIX="@param:";fileSpecPattern;fileNameForOhpm=/[.](?:har|tgz|tar.gz|tar)$/;static PACKAGE_JSON_PARSER_MAP=new Map;dependencies=[];devDependencies=[];dynamicDependencies=[];static getInstance(e,t,n){let i=this.PACKAGE_JSON_PARSER_MAP.get(e);return i||(i=new r(e,t,n),this.PACKAGE_JSON_PARSER_MAP.set(e,i)),i}constructor(e,t,n){this.dependencyPath=e,this.modulePath=t,this.projectPath=n,this.fileSpecPattern=r.isWindows()?/^(?:[.]|~[/]|[/\\]|[a-zA-Z]:)/:/^(?:[.]|~[/]|[/]|[a-zA-Z]:)/}static isWindows(){return process.platform==="win32"}parseDependency(e){let t=Yr.join(this.dependencyPath,G.OH_PACKAGE_JSON5),n=ht(t);n&&(this.dependencies=this.getDependencyList(n,G.KEY_DEPENDENCY),this.devDependencies=this.getDependencyList(n,G.KEY_DEV_DEPENDENCY),this.dynamicDependencies=this.getDependencyList(n,G.KEY_DYNAMIC_DEPENDENCY),e.dependencies=this.dependencies,e.dynamicDependencies=this.devDependencies,e.devDependencies=this.dynamicDependencies)}getDependencyList(e,t){let n=[];if(!M(e))return n;let i=e[t];if(!M(i))return n;for(let[o,s]of Object.entries(i)){if(typeof s!="string"){f.error(`${o} package dependency value is not String ${t}`);continue}let a=new jo;a.name=o;let c=s.replace(/\s/g,"");a.version=c,c.startsWith(r.PARAMETER_PREFIX)||this.parseDependencyPath(o,c,a,!1),n.push(a)}return n}parseDependencyPath(e,t,n,i){if(!(!e||!t))try{let o=Yr.normalize(Yr.join(this.modulePath,G.OH_MODULES_PATH,e));if(!(t.startsWith(r.FILE_DEPENDENCY_PREFIX)||this.fileSpecPattern.test(t))){n.dependencyPath=o;return}if(n.path=t,this.fileNameForOhpm.test(t)){n.dependencyPath=o;return}let s=t;if(t.startsWith(r.FILE_DEPENDENCY_PREFIX)&&(s=t.substring(r.FILE_DEPENDENCY_PREFIX.length)),Yr.isAbsolute(s)){n.dependencyPath=o;return}i||(o=Yr.resolve(this.modulePath,s)),Td.existsSync(o)&&Td.statSync(o).isDirectory()&&(n.dependencyPath=o)}catch(o){f.error("parser dependency path is invalid",o)}}};import*as Si from"fs";import*as Rn from"path";import d0 from"json5";var Od=class r{projectPath;static FILE_DEPENDENCY_PREFIX="file:";static MAX_LOCK_FILE_SIZE=20*1024*1024;static MAX_KEYS_PER_OBJECT=5e4;static MAX_JSON_DEPTH=50;fileNameForOhpm=/[.](?:har|tgz|tar.gz|tar)$/;finalDependencies=[];finalDevDependencies=[];finalDynamicDependencies=[];storePathMap=new Map;lockFileCache=null;lockFileParsed=!1;constructor(e=""){this.projectPath=e}parseDependencies(e){if(!this.ensureLockFileParsed())return!1;let t=this.lockFileCache;return this.extractDependencies(t.modules,t.storePathMap,e),!0}ensureLockFileParsed(){if(this.lockFileParsed)return this.lockFileCache!==null;this.lockFileParsed=!0;let e=this.getLockFilePath(),t=this.readLockFile(e);if(!t)return!1;let n=this.validateLockFile(t);return n.valid?(this.lockFileCache={modules:n.modules,storePathMap:this.parseStorePathMap(n.packages)},!0):!1}getLockFilePath(){return Rn.join(this.projectPath,G.OH_MODULES_PATH,G.OHPM_PATH,G.LOCK_JSON5_FILE)}static checkObjectDepth(e,t,n=0){if(n>t)return!1;if(typeof e!="object"||e===null)return!0;if(Array.isArray(e)){for(let i of e)if(!r.checkObjectDepth(i,t,n+1))return!1;return!0}for(let i in e)if(Object.prototype.hasOwnProperty.call(e,i)&&!r.checkObjectDepth(e[i],t,n+1))return!1;return!0}readLockFile(e){if(!Si.existsSync(e))return f.error("lock file does not exist"),this.clearDependencies(),null;try{let t=Si.statSync(e);if(t.size>r.MAX_LOCK_FILE_SIZE)return f.error(`lock file is too large (${t.size} bytes), read aborted`),this.clearDependencies(),null}catch(t){return f.error(`Failed to stat lock file: ${t instanceof Error?t.message:String(t)}`),this.clearDependencies(),null}try{let t=Si.readFileSync(e,"utf8"),n=d0.parse(t);return n?r.checkObjectDepth(n,r.MAX_JSON_DEPTH)?n:(f.error("lock.json5 nesting depth exceeds limit"),this.clearDependencies(),null):(f.error("lockFileJsonObject is null"),this.clearDependencies(),null)}catch(t){return f.error(`Error parsing lock.json5: ${t instanceof Error?t.message:String(t)}`),this.clearDependencies(),null}}validateLockFile(e){if(!M(e))return f.error("lockFileJsonObject is not a valid object"),this.clearDependencies(),{valid:!1};let t=e.modules;if(!t)return f.error("modulesJsonObject is null"),this.clearDependencies(),{valid:!1};let n=e.packages;return n?{valid:!0,modules:t,packages:n}:(f.error("packagesJsonObject is null"),this.clearDependencies(),{valid:!1})}extractDependencies(e,t,n){this.storePathMap=t,this.finalDependencies=this.getDependencyList(e,G.KEY_DEPENDENCY,n),this.finalDevDependencies=this.getDependencyList(e,G.KEY_DEV_DEPENDENCY,n),this.finalDynamicDependencies=this.getDependencyList(e,G.KEY_DYNAMIC_DEPENDENCY,n)}parseStorePathMap(e){let t=new Map;if(!M(e))return t;let n=0;for(let i in e){if(!Object.prototype.hasOwnProperty.call(e,i))continue;let o=e[i];if(!M(o)){f.error(`${i} value is not json object`);continue}if(++n>r.MAX_KEYS_PER_OBJECT){f.warn("lock.json5 packages object exceeds key limit, truncating");break}typeof o.storePath=="string"&&t.set(i,o.storePath)}return t}getDependencyList(e,t,n){if(!M(e))return[];let i=0;for(let o in e){if(!Object.prototype.hasOwnProperty.call(e,o))continue;if(++i>r.MAX_KEYS_PER_OBJECT){f.warn("lock.json5 modules object exceeds key limit, truncating");break}let s=e[o];if(M(s)){let a=typeof s.name=="string"?s.name:"";if(n==="."&&a===""||a===n)return this.getFinalDependencyList(e,t,o)}}return[]}getFinalDependencyList(e,t,n){let i=e[n];if(!M(i))return f.error("moduleJsonObject is null"),[];let o=[],s=i[t];if(!M(s))return[];let a=0;for(let c in s){if(!Object.prototype.hasOwnProperty.call(s,c))continue;if(++a>r.MAX_KEYS_PER_OBJECT){f.warn("lock.json5 dependencies object exceeds key limit, truncating");break}let l=s[c];if(!M(l))continue;let d=typeof l.specifier=="string"?l.specifier:"",g=typeof l.version=="string"?l.version:"",y=new jo;y.name=c,y.version=g.startsWith(r.FILE_DEPENDENCY_PREFIX)?g.substring(r.FILE_DEPENDENCY_PREFIX.length):g,this.parseDependencyPath(y,n,c,d,g);let E=`${c}@${g}`;this.storePathMap.has(E)&&(y.storePath=this.storePathMap.get(E)||""),o.push(y)}return o}parseDependencyPath(e,t,n,i,o){let s=Rn.resolve(this.projectPath,Rn.join(t,G.OH_MODULES_PATH,n));try{let a=o.startsWith(r.FILE_DEPENDENCY_PREFIX)?o.substring(r.FILE_DEPENDENCY_PREFIX.length):o,c=Rn.isAbsolute(a)?a:Rn.resolve(this.projectPath,a);Si.existsSync(c)?(e.path=i,e.dependencyPath=this.fileNameForOhpm.test(o)?s:c):e.dependencyPath=s}catch(a){f.error("Invalid dependency path in lock.json5, msg:",a instanceof Error?a.message:String(a))}}clearDependencies(){this.finalDependencies=[],this.finalDevDependencies=[],this.finalDynamicDependencies=[]}};function VE(r){return M(r)?typeof r.name=="string"&&typeof r.srcPath=="string":!1}var Ei=class{constructor(e,t){this.projectPath=e;this.sdkPath=t;this.moduleInfoParse=new Ir(this.projectPath)}moduleInfoParse;lockJson5Parser=null;sdkPkgCache=void 0;buildProfileCache=void 0;getAllDependencyMap(e,t){let n=this.projectPath,i=Xe.join(n,Ea),o=Xe.join(i,bi);if(!Ho.existsSync(i)||!Ho.existsSync(o)){let l="Dependency map or JSON not found";return f.warn(`[Parser] getAllDependencyMap failed: ${l}.`),{status:"ERROR",message:`${l}, please rebuild project`}}let s=new Fo(this.projectPath,".",this.projectPath);this.parseProjectDependencies(i,s),this.parseLockJson(s);let a=this.moduleInfoParse.getAllModuleInfo();if(a.length===0){let l="No modules found in build-profile.json5";return f.warn(`[Parser] getAllDependencyMap failed: ${l}.`),{status:"ERROR",message:l}}let c=Date.now();for(let l=0;l<a.length;l++){let d=a[l];if(VE(d)){try{P.assertModuleName(d.name)}catch{f.warn(`[Parser] Skipping module with invalid name: ${d.name}`);continue}this.parseSingleModule(d,i,s,e),((l+1)%50===0||l+1===a.length)&&(f.info(`[Parser] getAllDependencyMap progress: ${l+1}/${a.length} (${Date.now()-c}ms)`),t?.(l+1,a.length))}}return f.info(`[Parser] getAllDependencyMap parsed ${e.length} modules in ${Date.now()-c}ms`),{status:"OK"}}getDependenciesOnly(e){let t=[],n=this.projectPath,i=Xe.join(n,Ea),o=Xe.join(i,bi);if(!Ho.existsSync(i)||!Ho.existsSync(o))return f.warn("[Parser] Dependency map or JSON not found."),t;let s=e&&e.length>0?new Set(e.map(l=>l.trim()).filter(Boolean)):null,a=new Fo(this.projectPath,".",this.projectPath);this.parseProjectDependencies(i,a),this.parseLockJson(a);let c=this.moduleInfoParse.getAllModuleInfo();if(c.length===0)return f.warn("[Parser] getAllDependencyMap failed: No modules found in build-profile.json5."),t;for(let l of c){if(!VE(l))continue;let d=l.name;try{P.assertModuleName(d)}catch{f.warn(`[Parser] Skipping module with invalid name: ${d}`);continue}if(s&&!s.has(d))continue;let g=Xe.resolve(this.projectPath,l.srcPath),y=Xe.join(i,d),E=ge(g),j=this.buildModuleDependencies(d,E,y,a);j.moduleName=d,t.push(j)}return t}parseSingleModule(e,t,n,i){let o=e.name,s=Xe.resolve(this.projectPath,e.srcPath),a=Xe.join(t,o),c=ge(s),l=new _o(c),d=this.buildModuleDependencies(o,c,a,n);this.parseModuleJson5(c,l);let g=this.parseMainPages(c);this.parseSdkJson(l),this.parseCompatibleSdkVersion(l),l.moduleName=o,l.moduleType=o,l.packageName=o,l.moduleDependencies=d,l.moduleJsonParam=new $o(g),i.push(l)}buildModuleDependencies(e,t,n,i){let o=new Fo(this.projectPath,e,t);Pa.getInstance(n,t,this.projectPath).parseDependency(o),this.parseLockJson(o),o.finalDependencies.push(...i.finalDependencies),o.finalDevDependencies.push(...i.finalDevDependencies),o.finalDynamicDependencies.push(...i.finalDynamicDependencies),o.finalDependencies.push(...o.finalDevDependencies);let a=new Id;return a.modulePath=t,this.toModuleDependencies(o,a),a}toModuleDependencies(e,t){let n={},i={};for(let o of e.finalDependencies)n[o.name]=new vi(o);for(let o of e.finalDynamicDependencies)i[o.name]=new vi(o);t.dependencies=n,t.dynamicDependencies=i}parseProjectDependencies(e,t){let n=Xe.join(e,G.OH_PACKAGE_JSON5);if(!Ho.existsSync(n))return;Pa.getInstance(e,this.projectPath,this.projectPath).parseDependency(t)}parseLockJson(e){let t=this.getLockJson5Parser();t.parseDependencies(e.moduleName)?(e.finalDependencies=t.finalDependencies,e.finalDevDependencies=t.finalDevDependencies,e.finalDynamicDependencies=t.finalDynamicDependencies):(e.finalDependencies=e.dependencies,e.finalDevDependencies=e.devDependencies,e.finalDynamicDependencies=e.dynamicDependencies)}getLockJson5Parser(){return this.lockJson5Parser||(this.lockJson5Parser=new Od(this.projectPath)),this.lockJson5Parser}parseModuleJson5(e,t){let n=Xe.join(e,"src","main","module.json5"),i=ht(n);if(!M(i)||!M(i.module))return;let o=i.module;t.permissions=this.parseRequestPermissions(o),t.deviceType=this.parseDeviceTypes(o)}parseRequestPermissions(e){let t=[];if(M(e)&&Array.isArray(e.requestPermissions))for(let n of e.requestPermissions)M(n)&&typeof n.name=="string"&&t.push(n.name);return t}parseMainPages(e){let t=Xe.join(e,"src","main","resources","base","profile","main_pages.json"),n=ht(t);return!M(n)||!Array.isArray(n.src)?[]:n.src.filter(i=>typeof i=="string")}parseSdkJson(e){let t=this.getSdkPkg();if(!(!M(t)||!M(t.data))){if(typeof t.data.apiVersion=="string"){let n=parseInt(t.data.apiVersion,10);!Number.isNaN(n)&&n>=26&&typeof t.data.platformVersion=="string"?e.compileSdkLevel=t.data.platformVersion:e.compileSdkLevel=t.data.apiVersion}typeof t.data.releaseType=="string"&&(e.compileSdkType=t.data.releaseType),typeof t.data.version=="string"&&(e.compileSdkVersion=t.data.version)}}getSdkPkg(){if(this.sdkPkgCache===void 0){let e=Xe.join(this.sdkPath,"default","sdk-pkg.json");this.sdkPkgCache=ht(e)}return this.sdkPkgCache}parseCompatibleSdkVersion(e){let t=this.getBuildProfile();if(!M(t)||!M(t.app)||!Array.isArray(t.app.products)||t.app.products.length===0)return;let n=t.app.products[0];if(!M(n)||typeof n.compatibleSdkVersion!="string")return;let[i,o]=this.parseBySplit(n.compatibleSdkVersion);e.compatibleSdkVersion=i,e.compatibleSdkLevel=o}getBuildProfile(){if(this.buildProfileCache===void 0){let e=Xe.join(this.projectPath,"build-profile.json5");this.buildProfileCache=ht(e)}return this.buildProfileCache}parseBySplit(e){let t=e.indexOf("(");if(t===-1||!e.endsWith(")"))return[e,e];let n=e.substring(0,t),i=e.substring(t+1,e.length-1);return[n,i]}parseDeviceTypes(e){return!M(e)||!Array.isArray(e.deviceTypes)?[]:e.deviceTypes.filter(t=>typeof t=="string").map(t=>this.getDeviceType(t))}getDeviceType(e){return{liteWearable:1,wearable:2,tv:3,car:4,phone:5,default:5,smartVision:6,tablet:7,router:8,pc:9,"2in1":10}[e]||0}};var Nd=class{constructor(e=[]){this.valueSet=e}};var Uo=class{refreshSupport=!0;tokenTypes=["namespace","type","class","enum","interface","struct","parameter","variable","property","function","method"];tokenModifiers=["declaration","definition","readonly","static","deprecated"]};var GE=(x=>(x[x.File=1]="File",x[x.Module=2]="Module",x[x.Namespace=3]="Namespace",x[x.Package=4]="Package",x[x.Class=5]="Class",x[x.Method=6]="Method",x[x.Property=7]="Property",x[x.Field=8]="Field",x[x.Constructor=9]="Constructor",x[x.Enum=10]="Enum",x[x.Interface=11]="Interface",x[x.Function=12]="Function",x[x.Variable=13]="Variable",x[x.Constant=14]="Constant",x[x.String=15]="String",x[x.Number=16]="Number",x[x.Boolean=17]="Boolean",x[x.Array=18]="Array",x[x.Object=19]="Object",x[x.Key=20]="Key",x[x.Null=21]="Null",x[x.EnumMember=22]="EnumMember",x[x.Struct=23]="Struct",x[x.Event=24]="Event",x[x.Operator=25]="Operator",x[x.TypeParameter=26]="TypeParameter",x))(GE||{}),qE=()=>Object.values(GE).filter(r=>typeof r=="number");var Md=class{documentChanges=null;resourceOperations=null;failureHanding=null;normalizesLineEndings=null;changeAnnotationSupport=null};var Ld=class{applyEdit=!0;workspaceEdit=new Md;didChangeConfiguration=null;didChangeWatchedFiles={relativePatternSupport:{},dynamicRegistration:{}};symbol=new Nd(qE());executeCommand={dynamicRegistration:{}};workspaceFolders=!1;configuration=!1;semanticTokens=new Uo;codeLens=null;fileOperations=null;inlayHint=null;diagnostics=null};var _d=class{willSave=!0;willSaveWaitUntil=!0;didSave=!0;dynamicRegistration=null};var $d=class{constructor(e=[]){this.valueSet=e}};var Fd=class{snippetSupport=!0;commitCharactersSupport=null;documentationFormat=null;deprecateSupport=null;preselectSupport=null;tagSupport=null;insertReplaceSupport=null;resolveSupport=null;insertTextModeSupport=null;labelDetailsSupport=null};var zE=(I=>(I[I.Text=1]="Text",I[I.Method=2]="Method",I[I.Function=3]="Function",I[I.Constructor=4]="Constructor",I[I.Field=5]="Field",I[I.Variable=6]="Variable",I[I.Class=7]="Class",I[I.Interface=8]="Interface",I[I.Module=9]="Module",I[I.Property=10]="Property",I[I.Unit=11]="Unit",I[I.Value=12]="Value",I[I.Enum=13]="Enum",I[I.Keyword=14]="Keyword",I[I.Snippet=15]="Snippet",I[I.Color=16]="Color",I[I.File=17]="File",I[I.Reference=18]="Reference",I[I.Folder=19]="Folder",I[I.EnumMember=20]="EnumMember",I[I.Constant=21]="Constant",I[I.Struct=22]="Struct",I[I.Event=23]="Event",I[I.Operator=24]="Operator",I[I.TypeParameter=25]="TypeParameter",I))(zE||{}),JE=()=>Object.values(zE).filter(r=>typeof r=="number");var jd=class{completionItemKind=new $d(JE());completionItem=new Fd;contextSupport=null;insertTextSupport=null;completionList=null;dynamicRegistration=null};var Hd=class{synchronization=new _d;completion=new jd;hover={contentFormat:{},dynamicRegistration:{}};signatureHelp={signatureInformation:{},contextSupport:{},dynamicRegistration:{}};references={dynamicRegistration:{}};documentHighlight={dynamicRegistration:!0};documentSymbol=null;formatting={dynamicRegistration:{}};rangeFormatting={dynamicRegistration:{}};onTypeFormatting={dynamicRegistration:{}};declaration={};definition={linkSupport:{},dynamicRegistration:{}};codeLens=null;documentLink={tooltipSupport:{},dynamicRegistration:{}};colorProvider=null;rename={prepareSupport:!0,prepareSupportDefaultBehavior:null,honorsChangeAnnotations:null,dynamicRegistrationSupport:null};publishDiagnostics=null;foldingRage=null;typeHierarchy=null;callHierarchy={dynamicRegistration:{}};selectionRange=null;semanticTokens=new Uo;moniker=null;linkedEditingRange=null;inlayHint=null;inlineValue=null;diagnostic=null};var Ud=class{workspace=new Ld;textDocument=new Hd;notebookDocument=null;window=null;general=null;experimental=null};var Bd=class{constructor(e,t,n){this.rootUri=e;this.initializationOptions=t;this.capabilities=n}};var Wd=class{constructor(e,t,n,i,o,s=!0,a,c=!1){this.sdkPath=e;this.rootUri=n;this.nodeMaxOldSpaceSize=o;this.useStandardProtocol=s;this.nodePath=a;this.useSocket=c;this.serverPath=Oi(t,this.useStandardProtocol),this.logPath=Xy(),this.indexLogPath=i||this.logPath,f.debug(`[LspServerProxy] arktsLangServer=${t}`),f.debug(`[LspServerProxy] useStandardProtocol=${this.useStandardProtocol}, useSocket=${this.useSocket}`),f.debug(`[LspServerProxy] serverPath=${this.serverPath}`);let l={serverPath:this.serverPath,logPath:this.logPath,indexingDataLocation:this.indexLogPath,projectPath:this.rootUri,useSocket:this.useSocket,nodePath:this.nodePath};this.messageHandle=this.useStandardProtocol?new bd(l):new Ed(l),this.messageHandle.setBroadcastToClients(d=>this.onLspMessage(d))}messageHandle;get stdHandle(){return this.messageHandle}get legacyHandle(){return this.messageHandle}get lspPid(){return this.messageHandle.lspPid}onAsyncOpenFile(e){this.legacyHandle.onAsyncOpenFile(e)}closeFileLegacy(e,t){this.legacyHandle.closeFile(e,t)}serverPath;logPath;lastStartErrorMessage=null;currentParams=null;indexLogPath;lastDepsOnlyForDiff=[];get currentModuleModels(){return this.currentParams?.initializationOptions?.modules??[]}async start(e,t,n){let i=!1;try{f.debug(`serverPath: ${this.serverPath}`),f.debug(`rootUri: ${this.rootUri}`),f.debug(`sdkPath: ${this.sdkPath}`),f.debug(`logPath: ${this.logPath}`);let o=Ht(this.rootUri),s=new xd(o,this.serverPath,this.logPath,this.indexLogPath),a=[],l=new Ei(this.rootUri,this.sdkPath).getAllDependencyMap(a,n);if(l.status==="ERROR")throw new Error(`${l.message}`);this.fillModuleModelsPaths(a),s.modules=a;let d=Fc(a.length,this.nodeMaxOldSpaceSize);await this.messageHandle.start(d),this.currentParams=new Bd(o,s,new Ud),this.useStandardProtocol?await this.startStandardProtocol(this.currentParams):await this.startLegacy(this.currentParams,e),i=!0}catch(o){this.lastStartErrorMessage=o instanceof Error?o.message:String(o),f.error(`[LSP] Initialization failed: ${this.lastStartErrorMessage}`),await this.messageHandle.stop()}t?.(i)}async startStandardProtocol(e){let t=this.messageHandle,n=()=>t.broadcastToClients({jsonrpc:L,method:b.ARKTS_INDEXING_PROGRESS,params:{}});this.useSocket?(f.info("[LSP] socket mode: waiting for initialize response + aceProject/onModuleInitFinish"),await t.sendInitializeAndWaitForNotification(e,Yi.MODULE_INIT_FINISH,it,()=>{f.info("[LSP] initialize response received"),n(),t.sendInitialized()},n),f.info("[LSP] initialize response + onModuleInitFinish received, initialization complete")):(await t.sendInitializeResettable(e,it),f.info("[LSP] initialize response received"),n(),t.sendInitialized())}async startLegacy(e,t){let n=this.messageHandle;n.sendInitialize(e,1),n.onIndexingProgressUpdate(()=>{this.onLspMessage({jsonrpc:L,method:b.ARKTS_INDEXING_PROGRESS,params:{}})}),await this.withResettableTimeout((i,o)=>{n.onIndexingProgressUpdate(o),n.onInitializationCompleted(i)},"LSP initialization",it),n.sendInitialized(t)}withResettableTimeout(e,t,n){return new Promise((i,o)=>{let s,a=()=>{s=setTimeout(()=>{o(new Error(`${t} timeout after ${n}ms`))},n)},c=()=>{clearTimeout(s),a()};a(),e(()=>{clearTimeout(s),i()},c)})}consumeStartErrorMessage(){let e=this.lastStartErrorMessage;return this.lastStartErrorMessage=null,e}onLspMessage=()=>{};setOnMessage(e){this.onLspMessage=e}registerDiagnosticCallback(e){f.debug(`[LSP] registerDiagnosticCallback uri='${e}', useStandardProtocol=${this.useStandardProtocol}`),this.messageHandle.registerRequestCallback(e,(t,n)=>{let i=M(n)?n:{};f.debug(`[LSP] onDiagnosticCompleted called, uri: ${e}`);let o={jsonrpc:L,method:t,params:{uri:typeof i.uri=="string"?i.uri:e,diagnostics:Array.isArray(i.diagnostics)?i.diagnostics:[],...typeof i.errorMessage=="string"?{errorMessage:i.errorMessage}:{}}};this.onLspMessage(o)})}async hover(e){let t=e.textDocument.uri;return this.registerDiagnosticCallback(t),this.stdHandle.sendLspRequest(b.HOVER,e)}async definition(e){return this.stdHandle.sendLspRequest(b.DEFINITION,e)}async references(e){return this.stdHandle.sendLspRequest(b.REFERENCES,e)}async completion(e){return this.stdHandle.sendLspRequest(b.COMPLETION,e)}async documentSymbol(e){return this.stdHandle.sendLspRequest(b.DOCUMENT_SYMBOL,e)}async diagnostic(e){return this.stdHandle.sendLspRequest(b.DIAGNOSTIC,e,120*1e3)}async sendFeatureRequest(e,t){return this.stdHandle.sendLspRequest(e,t)}reloadDependenciesOnly(e){let t=e?.fullReload??!1,n=new Ei(this.rootUri,this.sdkPath),i=this.getModuleModelsByName();if(t){f.info("[LspServerProxy] Project-level oh-package changed, parsing all modules' dependencies");let l=n.getDependenciesOnly();this.markDependencyTypesIncremental(l);let d=this.mergeDepsOnlyIntoModuleList(l,i);return this.applyModuleModelsUpdate(d),this.sendDidChangeConfiguration({moduleSet:d}),f.info(`[LspServerProxy] Dependencies only (all) reloaded, count: ${d.length}`),this.lastDepsOnlyForDiff=l,l}let o=e?.changedModules??[],s=new Set(e?.removedModuleNames??[]);if(o.length===0&&s.size===0)return f.info("[LspServerProxy] No changed/removed modules, skip dependency reload"),[];f.info(`[LspServerProxy] Module-level deps changed, parsing: [${o.join(", ")}]`);let a=n.getDependenciesOnly(o);this.markDependencyTypesIncremental(a);let c=this.mergeIncrementalDeps(this.currentModuleModels,s,a);return this.applyModuleModelsUpdate(c),this.sendDidChangeConfiguration({moduleSet:c}),f.info(`[LspServerProxy] Dependencies only (incremental) reloaded, count: ${c.length}`),this.lastDepsOnlyForDiff=a,a}sendDidChangeConfiguration(e){this.stdHandle.sendDidChangeConfiguration(e)}getModuleModelsByName(){return new Map(this.currentModuleModels.map(e=>[e.moduleName??"",e]))}markDependencyTypesIncremental(e){let t=this.getModuleModelsByName(),n=new Map(this.lastDepsOnlyForDiff.map(i=>[i.moduleName??"",i]));for(let i of e){let o=i.moduleName??"",{oldDeps:s,oldDynamic:a}=this.getOldDepsForModule(o,t,n),c=i.dependencies??{},l=i.dynamicDependencies??{};this.markAddAndDeleteInDeps(s,c,(d,g)=>{(i.dependencies??={})[d]=this.makeDeleteEntry(d,g)}),this.markAddAndDeleteInDeps(a,l,(d,g)=>{(i.dynamicDependencies??={})[d]=this.makeDeleteEntry(d,g)})}}getOldDepsForModule(e,t,n){let i=t.get(e),o=i?.moduleDependencies?.dependencies??{},s=i?.moduleDependencies?.dynamicDependencies??{};if(Object.keys(o).length===0&&Object.keys(s).length===0){let a=n.get(e);a&&(o=a.dependencies??{},s=a.dynamicDependencies??{})}return{oldDeps:o,oldDynamic:s}}markAddAndDeleteInDeps(e,t,n){for(let i of Object.keys(t))i in e||(t[i].type="add");for(let i of Object.keys(e))i in t||n(i,e[i])}makeDeleteEntry(e,t){return new vi({name:e,version:t?.version??"",registryType:t?.registryType??"ohpm",resolved:t?.resolved??"",type:"delete"})}createMinimalModelFromDepsItem(e){let t=new _o(e.modulePath);return t.moduleName=e.moduleName,t.moduleType=e.moduleName,t.packageName=e.moduleName,t.moduleJsonParam=new $o([]),t.modulePath=e.modulePath,t.moduleDependencies=e,t}mergeDepsOnlyIntoModuleList(e,t){let n=[];for(let i of e){let o=i.moduleName??"",s=t.get(o);s?(s.modulePath=i.modulePath,s.moduleDependencies=i):s=this.createMinimalModelFromDepsItem(i),n.push(s)}return n}mergeIncrementalDeps(e,t,n){let i=new Map(n.map(s=>[s.moduleName??"",s])),o=[];for(let s of e){let a=s.moduleName??"";if(t.has(a))continue;let c=i.get(a);c&&(s.modulePath=c.modulePath,s.moduleDependencies=c,i.delete(a)),o.push(s)}for(let[,s]of i)o.push(this.createMinimalModelFromDepsItem(s));return o}applyModuleModelsUpdate(e){this.fillModuleModelsPaths(e),this.currentParams&&(this.currentParams.initializationOptions.modules=e)}fillModuleModelsPaths(e){let t=this.sdkPath,n=Xi(Yf.join(t,"default/openharmony/ets/build-tools/ets-loader")),i=Xi(Yf.join(t,"default/openharmony/ets/api")),o=Xi(Yf.join(t,"default/hms"));for(let s of e)s.aceLoaderPath=n,s.sdkJsPath=i,s.hosSdkPath=o}sendRequest(e){switch(e.method){case b.HOVER:this.stdHandle.sendLspRequest(b.HOVER,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;case b.DEFINITION:this.stdHandle.sendLspRequest(b.DEFINITION,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;case b.REFERENCES:this.stdHandle.sendLspRequest(b.REFERENCES,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;default:f.warn(`Unhandled LSP request: ${e.method}`)}}sendNotification(e){if(!_E(e)){f.info("LspServerProxy, msg is not notification request, ignore.");return}switch(e.method){case b.DID_OPEN:this.handleDidOpenNotification(e);break;case b.DID_CHANGE:this.handleDidChangeNotification(e);break;case b.DID_CLOSE:this.handleDidCloseNotification(e);break;case b.WORKSPACE_DID_CHANGE_WATCHED_FILES:this.handleDidChangeWatchedFiles(e);break;case b.DID_CREATE_FILES:this.handleDidCreateFiles(e);break;case b.DID_DELETE_FILES:this.handleDidDeleteFiles(e);break;default:f.warn(`Unhandled LSP notification: ${e.method}`)}}handleDidOpenNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){f.error("Invalid textDocument/didOpen params");return}this.stdHandle.sendDidOpen(t)}handleDidChangeNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){f.error("Invalid textDocument/didChange params");return}this.stdHandle.sendDidChange(t)}handleDidCloseNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){f.error("Invalid textDocument/didClose params");return}this.stdHandle.closeFile(t)}handleDidChangeWatchedFiles(e){let t=e.params;!t||!Array.isArray(t.changes)||this.messageHandle.onDidChangeWatchedFiles(t.changes)}handleDidCreateFiles(e){let t=e.params;!t||!Array.isArray(t.files)||this.stdHandle.sendNotification(b.DID_CREATE_FILES,t)}handleDidDeleteFiles(e){let t=e.params;!t||!Array.isArray(t.files)||this.stdHandle.sendNotification(b.DID_DELETE_FILES,t)}async dispose(){await this.messageHandle.stop()}};import*as Kr from"fs";import*as ct from"path";import{createHash as p0}from"crypto";import{EventEmitter as m0}from"events";var Vd=class extends m0{constructor(t,n=500){super();this.projectRoot=t;this.debounceMs=n}watchers=new Map;debounceTimers=new Map;contentHashes=new Map;buildProfileWatcher=null;lastModulesSnapshot="";lastModules=[];debounceMs;start(){let t=this.parseModulesFromBuildProfile();this.lastModules=t,this.lastModulesSnapshot=this.computeModulesSnapshot(t),this.refreshWatchTargets(),this.watchBuildProfile()}refreshWatchTargets(){let t=new Set(this.collectWatchTargets()),n=new Set(this.watchers.keys());for(let i of t)n.has(i)||this.watchFile(i);for(let i of n)t.has(i)||(this.unwatchFile(i),f.info(`[ConfigFileWatcher] Stopped watching: ${i}`));f.info(`[ConfigFileWatcher] Watching ${this.watchers.size} oh-package.json5 file(s)`)}watchBuildProfile(){let t=this.getBuildProfilePath();if(!Kr.existsSync(t)){f.warn(`[ConfigFileWatcher] build-profile.json5 not found at ${t}, cannot watch for module changes`);return}try{this.buildProfileWatcher=Kr.watch(t,n=>{n==="change"&&this.onBuildProfileChanged()}),this.buildProfileWatcher.on("error",n=>{f.error(`[ConfigFileWatcher] build-profile.json5 watch error: ${n.message}`)}),f.info(`[ConfigFileWatcher] Watching module registry: ${t}`)}catch(n){f.error(`[ConfigFileWatcher] Failed to watch build-profile.json5: ${n instanceof Error?n.message:String(n)}`)}}emitModuleAddedEvents(t,n){for(let i of t){let o=ct.resolve(this.projectRoot,i.srcPath);this.emit("configChanged",{source:"buildProfile",kind:1,filePath:o,relativePath:i.srcPath,timestamp:n,moduleName:i.name})}}emitModuleRemovedEvents(t,n){for(let i of t){let o=ct.resolve(this.projectRoot,i.srcPath);this.emit("configChanged",{source:"buildProfile",kind:2,filePath:o,relativePath:i.srcPath,timestamp:n,removedModuleName:i.name})}}emitModuleRenamedEvents(t,n){for(let i of t){let o=ct.resolve(this.projectRoot,i.after.srcPath);this.emit("configChanged",{source:"buildProfile",kind:3,filePath:o,relativePath:i.after.srcPath,timestamp:n,moduleName:i.after.name,removedModuleName:i.before.name})}}emitModuleMovedEvents(t,n){for(let i of t){let o=ct.resolve(this.projectRoot,i.after.srcPath);this.emit("configChanged",{source:"buildProfile",kind:6,filePath:o,relativePath:i.after.srcPath,timestamp:n,moduleName:i.after.name})}}processBuildProfileDiff(t){this.refreshWatchTargets();let n=Date.now();this.emitModuleAddedEvents(t.added,n),this.emitModuleRemovedEvents(t.removed,n),this.emitModuleRenamedEvents(t.renamed,n),this.emitModuleMovedEvents(t.moved,n)}onBuildProfileChanged(){let t="__build_profile__",n=this.debounceTimers.get(t);n&&clearTimeout(n);let i=setTimeout(()=>{this.debounceTimers.delete(t);let o=this.parseModulesFromBuildProfile(),s=this.computeModulesSnapshot(o);if(s===this.lastModulesSnapshot){f.info("[ConfigFileWatcher] build-profile.json5 changed but modules unchanged, skipping");return}let a=this.diffModules(this.lastModules,o);this.lastModules=o,this.lastModulesSnapshot=s,f.info(`[ConfigFileWatcher] build-profile.json5 modules changed, added=${a.added.length}, removed=${a.removed.length}, renamed=${a.renamed.length}, moved=${a.moved.length}`),this.processBuildProfileDiff(a)},this.debounceMs);this.debounceTimers.set(t,i)}computeModulesSnapshot(t){return t.map(i=>`${i.name}::${i.srcPath}`).sort().join("|")}diffModules(t,n){let i=this.buildModuleMatchState(n),o={added:[],removed:[],renamed:[],moved:[]};return this.matchExactModules(t,i),this.matchRenamedModules(t,i,o),this.matchMovedModules(t,i,o),this.collectRemovedModules(t,i,o),this.collectAddedModules(n,i,o),o}buildModuleMatchState(t){let n=new Map,i=new Map;for(let o of t)n.set(o.srcPath,o),i.set(o.name,o);return{matchedOld:new Set,matchedNew:new Set,newBySrc:n,newByName:i}}matchExactModules(t,n){for(let i of t){let o=n.newBySrc.get(i.srcPath);o&&o.name===i.name&&(n.matchedOld.add(i),n.matchedNew.add(o))}}matchRenamedModules(t,n,i){for(let o of t){if(n.matchedOld.has(o))continue;let s=n.newBySrc.get(o.srcPath);s&&!n.matchedNew.has(s)&&s.name!==o.name&&(i.renamed.push({before:o,after:s}),n.matchedOld.add(o),n.matchedNew.add(s))}}matchMovedModules(t,n,i){for(let o of t){if(n.matchedOld.has(o))continue;let s=n.newByName.get(o.name);s&&!n.matchedNew.has(s)&&s.srcPath!==o.srcPath&&(i.moved.push({before:o,after:s}),n.matchedOld.add(o),n.matchedNew.add(s))}}collectRemovedModules(t,n,i){for(let o of t)n.matchedOld.has(o)||i.removed.push(o)}collectAddedModules(t,n,i){for(let o of t)n.matchedNew.has(o)||i.added.push(o)}parseModulesFromBuildProfile(){let t=this.getBuildProfilePath();try{let n=ht(t);if(typeof n!="object"||n===null)return[];let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):[]}catch(n){return f.warn(`[ConfigFileWatcher] Failed to parse build-profile.json5: ${n instanceof Error?n.message:String(n)}`),[]}}collectWatchTargets(){let t=[],n=ct.join(this.projectRoot,G.OH_PACKAGE_JSON5);Kr.existsSync(n)&&t.push(n);let i=this.parseModulesFromBuildProfile();for(let o of i){let s=ct.resolve(this.projectRoot,o.srcPath),a=ct.join(s,G.OH_PACKAGE_JSON5);Kr.existsSync(a)&&t.push(a)}return t}getBuildProfilePath(){return ct.join(this.projectRoot,"build-profile.json5")}computeFileHash(t){try{let n=Kr.readFileSync(t,"utf-8");return p0("sha256").update(n).digest("hex")}catch{return null}}watchFile(t){if(!this.watchers.has(t))try{let n=this.computeFileHash(t);n&&this.contentHashes.set(t,n);let i=Kr.watch(t,o=>{o==="change"&&this.onFileChanged(t)});i.on("error",o=>{f.error(`[ConfigFileWatcher] Watch error for ${t}: ${o.message}`)}),this.watchers.set(t,i)}catch(n){f.error(`[ConfigFileWatcher] Failed to watch ${t}: ${n instanceof Error?n.message:String(n)}`)}}unwatchFile(t){let n=this.watchers.get(t);n&&(n.close(),this.watchers.delete(t)),this.contentHashes.delete(t);let i=this.debounceTimers.get(t);i&&(clearTimeout(i),this.debounceTimers.delete(t))}onFileChanged(t){let n=this.debounceTimers.get(t);n&&clearTimeout(n);let i=setTimeout(()=>{this.debounceTimers.delete(t);let o=this.computeFileHash(t);if(!o){f.warn(`[ConfigFileWatcher] Could not read file for hash: ${t}`);return}if(this.contentHashes.get(t)===o){f.info(`[ConfigFileWatcher] File touched but content unchanged, skipping: ${t}`);return}this.contentHashes.set(t,o),f.info(`[ConfigFileWatcher] Config file content changed: ${t}`);let a={source:"ohPackage",kind:4,filePath:t,fileName:ct.basename(t),relativePath:ct.relative(this.projectRoot,t),timestamp:Date.now()};this.emit("configChanged",a)},this.debounceMs);this.debounceTimers.set(t,i)}stop(){for(let[,t]of this.watchers)t.close();this.watchers.clear(),this.buildProfileWatcher&&(this.buildProfileWatcher.close(),this.buildProfileWatcher=null);for(let t of this.debounceTimers.values())clearTimeout(t);this.debounceTimers.clear(),this.contentHashes.clear(),f.info("[ConfigFileWatcher] All watchers stopped")}};import*as xn from"fs";import*as Xt from"path";import{createHash as f0}from"crypto";import{EventEmitter as g0}from"events";var Gd=class extends g0{constructor(t,n=500){super();this.projectRoot=t;this.debounceMs=n,this.coalesceMs=n+300,this.depMapDir=Xt.join(t,Ea)}dirWatcher=null;contentHashes=new Map;lastModules=[];debounceMs;depMapDir;pendingTags=[];pendingRenames=[];coalesceTimer=null;coalesceMs;fullScanTimer=null;pollInterval=null;initialScanDone=!1;start(){if(!xn.existsSync(this.depMapDir)){f.warn(`[DependencyMapWatcher] dependencyMap dir not found: ${this.depMapDir}, skip watching`);return}this.lastModules=this.parseModulesFromDepMap();try{this.dirWatcher=xn.watch(this.depMapDir,{recursive:!0},(t,n)=>this.onDirEvent(t,n)),this.dirWatcher.on("error",t=>{f.error(`[DependencyMapWatcher] Directory watch error for ${this.depMapDir}: ${t.message}`)})}catch(t){f.error(`[DependencyMapWatcher] Failed to watch directory ${this.depMapDir}: ${t instanceof Error?t.message:String(t)}`);return}this.pollInterval=setInterval(()=>this.scanAllCacheFiles(),2500),f.info(`[DependencyMapWatcher] Started, watching directory (recursive): ${this.depMapDir}, modules: [${this.lastModules.map(t=>t.name).join(", ")}]`)}canonicalPath(t){return ge(Xt.resolve(t))}onDirEvent(t,n){if(!n||typeof n!="string")return;let i=n.replace(/\\/g,"/"),o;if(i===G.OH_PACKAGE_JSON5)o="root-oh-package";else if(i===bi)o="dep-map-json";else{let a=i.match(/^([^/]+)\/oh-package\.json5$/);o=a?`module:${a[1]}`:""}if(!o)return;let s=Xt.join(this.depMapDir,n);xn.existsSync(s)&&this.scheduleDebouncedFullScan()}stop(){this.dirWatcher&&(this.dirWatcher.close(),this.dirWatcher=null),this.fullScanTimer&&(clearTimeout(this.fullScanTimer),this.fullScanTimer=null),this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=null),this.coalesceTimer&&(clearTimeout(this.coalesceTimer),this.coalesceTimer=null),this.pendingTags=[],this.pendingRenames=[],this.contentHashes.clear(),this.initialScanDone=!1,f.info("[DependencyMapWatcher] All watchers stopped")}scheduleDebouncedFullScan(){this.fullScanTimer&&clearTimeout(this.fullScanTimer),this.fullScanTimer=setTimeout(()=>{this.fullScanTimer=null,this.scanAllCacheFiles()},this.debounceMs)}scanAllCacheFiles(){let t=Xt.join(this.depMapDir,G.OH_PACKAGE_JSON5),n=Xt.join(this.depMapDir,bi),i=this.parseModulesFromDepMap(),o=[{path:t,tag:"root-oh-package"},{path:n,tag:"dep-map-json"},...i.map(s=>({path:(P.assertModuleName(s.name),Xt.join(this.depMapDir,s.name,G.OH_PACKAGE_JSON5)),tag:`module:${s.name}`}))];for(let{path:s,tag:a}of o){if(!xn.existsSync(s))continue;let c=this.canonicalPath(s),l=this.computeFileHash(s);if(!l)continue;let d=this.contentHashes.get(c);if(!this.initialScanDone){this.contentHashes.set(c,l);continue}d!==l&&(this.contentHashes.set(c,l),f.info(`[DependencyMapWatcher] Cache file changed: ${s} (tag=${a})`),this.scheduleCoalescedReload(a))}this.initialScanDone||(this.initialScanDone=!0)}parseModulesFromDepMap(){let t=Xt.join(this.depMapDir,bi);try{let n=ht(t);if(typeof n!="object"||n===null)return[];let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):[]}catch(n){return f.warn(`[DependencyMapWatcher] Failed to parse dependencyMap.json5: ${n instanceof Error?n.message:String(n)}`),[]}}scheduleCoalescedReload(t){this.pendingTags.push(t),t==="dep-map-json"&&this.applyDepMapJsonDiff(),this.coalesceTimer&&clearTimeout(this.coalesceTimer),this.coalesceTimer=setTimeout(()=>{this.coalesceTimer=null,this.flushPendingReload()},this.coalesceMs)}collectPendingState(){let t=this.pendingTags,n=this.pendingRenames;return this.pendingTags=[],this.pendingRenames=[],{tags:t,renameEntries:n}}processTagsIntoSets(t,n,i,o){for(let s of t)s.startsWith("module:")?(i.add(s.substring(7)),n.add("moduleDepsChanged")):s.startsWith("dep-added:")?(i.add(s.substring(10)),n.add("moduleAdded")):s.startsWith("dep-removed:")&&(o.add(s.substring(12)),n.add("moduleRemoved"))}processRenameEntries(t,n,i,o,s){for(let a of t)s.push(a.info),i.add(a.info.newName),o.add(a.info.oldName),n.add(a.kind)}buildAddedNamesSet(t,n){let i=new Set;for(let o of t)o.startsWith("dep-added:")&&i.add(o.substring(10));for(let o of n)i.add(o.info.newName);return i}emitIncrementalReload(t,n,i,o,s){f.info(`[DependencyMapWatcher] Coalesced \u2192 kinds=[${[...t].join(",")}], changed=[${[...n].join(",")}], removed=[${[...i].join(",")}], added=[${[...o].join(",")}], renames=[${s.map(a=>`${a.oldName}\u2192${a.newName}`).join(",")}]`),this.emit("reload",{fullReload:!1,kinds:[...t],changedModules:[...n],removedModuleNames:[...i],addedModuleNames:[...o],renames:s.length>0?s:void 0})}flushPendingReload(){let{tags:t,renameEntries:n}=this.collectPendingState();if(t.length===0&&n.length===0)return;if(f.info(`[DependencyMapWatcher] Flushing coalesced reload, tags=[${t.join(", ")}], renames=${n.length}`),t.includes("root-oh-package")){f.info("[DependencyMapWatcher] Root oh-package.json5 in batch \u2192 full reload"),this.emit("reload",{fullReload:!0,kinds:["projectDepsChanged"]});return}let i=new Set,o=new Set,s=new Set,a=[];this.processTagsIntoSets(t,i,o,s),this.processRenameEntries(n,i,o,s,a);for(let l of o)s.delete(l);if(o.size===0&&s.size===0&&a.length===0){f.info("[DependencyMapWatcher] Coalesced batch has no effective changes, skipping");return}let c=this.buildAddedNamesSet(t,n);this.emitIncrementalReload(i,o,s,c,a)}normalizeSrcPath(t){return ge(t).replace(/^\.\//,"").replace(/\/$/,"")}buildModuleLookupMaps(t){let n=new Map(t.map(o=>[o.name,o])),i=new Map(t.map(o=>[this.normalizeSrcPath(o.srcPath),o]));return{byName:n,bySrcPath:i}}detectModuleRenames(t,n,i,o){for(let[s,a]of t){let c=n.get(s);if(!c||c.name===a.name)continue;this.pendingRenames.push({kind:"moduleRenamed",info:{oldName:a.name,newName:c.name,oldSrcPath:a.srcPath,newSrcPath:c.srcPath,kind:"moduleRenamed"}}),i.add(a.name),o.add(c.name);let l=(P.assertModuleName(a.name),Xt.join(this.depMapDir,a.name,G.OH_PACKAGE_JSON5));this.contentHashes.delete(this.canonicalPath(l)),f.info(`[DependencyMapWatcher] Module renamed: ${a.name} \u2192 ${c.name} (srcPath=${s})`)}}detectModuleMoves(t,n,i,o){for(let[s,a]of t){if(i.has(s))continue;let c=n.get(s);!c||c.srcPath===a.srcPath||(this.pendingRenames.push({kind:"moduleMoved",info:{oldName:a.name,newName:c.name,oldSrcPath:a.srcPath,newSrcPath:c.srcPath,kind:"moduleMoved"}}),i.add(s),o.add(s),f.info(`[DependencyMapWatcher] Module moved: ${s} srcPath ${a.srcPath} \u2192 ${c.srcPath}`))}}detectAddedModules(t,n,i){for(let[o]of t)i.has(o)||n.has(o)||(this.pendingTags.push(`dep-added:${o}`),i.add(o))}detectRemovedModules(t,n,i){for(let[o]of t)if(!i.has(o)&&!n.has(o)){this.pendingTags.push(`dep-removed:${o}`),i.add(o);let s=(P.assertModuleName(o),Xt.join(this.depMapDir,o,G.OH_PACKAGE_JSON5));this.contentHashes.delete(this.canonicalPath(s))}}logDepMapDiffResult(){let t=this.pendingTags.filter(i=>i.startsWith("dep-")),n=this.pendingRenames.map(i=>`${i.kind}(${i.info.oldName}\u2192${i.info.newName})`);f.info(`[DependencyMapWatcher] dependencyMap.json5 diff complete, depTags: [${t.join(", ")}], renames: [${n.join(", ")}]`)}applyDepMapJsonDiff(){let t=this.parseModulesFromDepMap(),{byName:n,bySrcPath:i}=this.buildModuleLookupMaps(this.lastModules),{byName:o,bySrcPath:s}=this.buildModuleLookupMaps(t),a=new Set,c=new Set;this.detectModuleRenames(i,s,a,c),this.detectModuleMoves(n,o,a,c),this.detectAddedModules(o,n,c),this.detectRemovedModules(n,o,a),this.lastModules=t,this.logDepMapDiffResult()}computeFileHash(t){try{let n=xn.readFileSync(t,"utf-8");return f0("sha256").update(n).digest("hex")}catch{return null}}};import*as Sr from"fs";import*as qd from"path";import{EventEmitter as h0}from"events";var Kf={Created:1,Changed:2,Deleted:3},y0=new Set(["oh_modules","node_modules","build",".hvigor",".git",".idea",".cxx",".preview"]);function w0(r){let e=r.replace(/\\/g,"/");return e.endsWith("/ets")&&e.includes("/src/")}var zd=class extends h0{projectRoot;debounceMs;pollMs;sourceDirs=[];watchers=new Map;snapshot=new Map;debounceTimer=null;pollInterval=null;initialScanDone=!1;constructor(e,t=500,n=1e4){super(),this.projectRoot=e,this.debounceMs=t,this.pollMs=n}start(){if(this.sourceDirs=this.discoverSourceDirs(),this.sourceDirs.length===0){f.warn("[SourceFileWatcher] No src/main/ets dir found, skip watching");return}this.refreshSnapshot(),this.initialScanDone=!0;for(let e of this.sourceDirs)this.addSourceDirWatcher(e);this.pollInterval=setInterval(()=>this.scanAndEmit(),this.pollMs),f.info(`[SourceFileWatcher] Started, watching ${this.sourceDirs.length} source dir(s), ${this.snapshot.size} ets file(s)`)}stop(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=null);for(let[,e]of this.watchers)e.close();this.watchers.clear(),this.snapshot.clear(),this.initialScanDone=!1,f.info("[SourceFileWatcher] Stopped")}addSourceDirWatcher(e){if(!this.watchers.has(e))try{let t=Sr.watch(e,{recursive:!0},(n,i)=>this.onFsEvent(i));t.on("error",n=>{f.error(`[SourceFileWatcher] watch error for ${e}: ${n.message}`)}),this.watchers.set(e,t)}catch(t){f.error(`[SourceFileWatcher] Failed to watch ${e}: ${t instanceof Error?t.message:String(t)}`)}}refreshSourceDirs(){if(!this.initialScanDone)return;let e=this.discoverSourceDirs(),t=new Set(this.sourceDirs),n=new Set(e),i=e.filter(s=>!t.has(s)),o=[...t].filter(s=>!n.has(s));if(!(i.length===0&&o.length===0)){for(let s of i)this.addSourceDirWatcher(s);for(let s of o){let a=this.watchers.get(s);a&&(a.close(),this.watchers.delete(s))}this.sourceDirs=e,this.refreshSnapshot(),f.info(`[SourceFileWatcher] Module dirs changed: +${i.length} -${o.length}, now ${this.sourceDirs.length} source dir(s)`)}}discoverSourceDirs(){let e=[];return this.collectSourceDirs(qd.resolve(this.projectRoot),e,new Set,new Set),e}collectSourceDirs(e,t,n,i){let o;try{o=Sr.realpathSync(e)}catch{return}if(i.has(o))return;i.add(o);let s;try{s=Sr.readdirSync(e,{withFileTypes:!0})}catch{return}for(let a of s){if(!a.isDirectory()||y0.has(a.name))continue;let c=qd.resolve(e,a.name);if(!w0(c)){this.collectSourceDirs(c,t,n,i);continue}n.has(c)||(n.add(c),t.push(c))}}onFsEvent(e){!e||typeof e!="string"||e.replace(/\\/g,"/").toLowerCase().endsWith(".ets")&&this.scheduleScan()}scheduleScan(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.scanAndEmit()},this.debounceMs)}scanAndEmit(){if(!this.initialScanDone)return;let e=this.diffScan();e.length>0&&this.emit("sourceChanged",{changes:e})}refreshSnapshot(){let e=new Map;for(let t of this.sourceDirs)this.collectEtsFiles(t,e);this.snapshot=e}diffScan(){let e=new Map;for(let n of this.sourceDirs)this.collectEtsFiles(n,e);let t=[];for(let[n,i]of e){let o=this.snapshot.get(n);o?(o.mtimeMs!==i.mtimeMs||o.size!==i.size)&&t.push({uri:Nt(n),type:Kf.Changed}):t.push({uri:Nt(n),type:Kf.Created})}for(let[n]of this.snapshot)e.has(n)||t.push({uri:Nt(n),type:Kf.Deleted});return this.snapshot=e,t}collectEtsFiles(e,t){this.collectEtsFilesInto(e,t,new Set)}collectEtsFilesInto(e,t,n){let i;try{i=Sr.realpathSync(e)}catch{return}if(n.has(i))return;n.add(i);let o;try{o=Sr.readdirSync(e,{withFileTypes:!0})}catch{return}for(let s of o){let a=qd.resolve(e,s.name);if(s.isDirectory()){this.collectEtsFilesInto(a,t,n);continue}!s.isFile()||!s.name.toLowerCase().endsWith(".ets")||this.recordSnapshot(a,t)}}recordSnapshot(e,t){let n;try{n=Sr.statSync(e)}catch{return}t.set(e,{mtimeMs:n.mtimeMs,size:n.size})}};import{spawn as v0}from"child_process";var YE=["install","--all"];function KE(r,e){let t=r.split(/\r?\n/),n=t.pop()??"";for(let i of t)i&&(f.info("[ohpm] %s",i),e?.(i));return n}async function b0(r,e,t,n,i){return new Promise(o=>{f.info("[ohpm] spawning: %s %s %s, cwd=%s",r,e,YE.join(" "),t);let s=v0(r,[e,...YE],{cwd:t,env:{...process.env,DEVECO_SDK_HOME:n},windowsHide:!0,stdio:["ignore","pipe","pipe"]}),a="",c="";s.stdout?.on("data",l=>{a=KE(a+l.toString(),i)}),s.stderr?.on("data",l=>{c=KE(c+l.toString(),i)}),s.on("close",l=>{a&&(f.info("[ohpm] %s",a),i?.(a)),c&&(f.info("[ohpm] %s",c),i?.(c)),f.info("[ohpm] process exited, code=%s",l),o({exitCode:l??-1})}),s.on("error",l=>{f.error("[ohpm] process error: %s",l.message),o({exitCode:-1})})})}async function XE(r,e,t,n,i){try{if(!t)return f.error("node \u8DEF\u5F84\u4E0D\u5B58\u5728"),!1;if(!n)return f.error("ohpm (pm-cli.js) \u4E0D\u5B58\u5728"),!1;let{exitCode:o}=await b0(t,n,r,e,i);return o===0?(f.info("ohpm \u5B89\u88C5\u6210\u529F"),!0):(f.error("ohpm \u5B89\u88C5\u5931\u8D25\uFF0C\u9000\u51FA\u7801: %s",o),!1)}catch(o){return f.error("ohpm \u5B89\u88C5\u5F02\u5E38",o),!1}}var ZE={UNINITIALIZED:-32099,UNKNOWN:-32e3},Ca=class r extends Error{code;constructor(e,t){super(e),this.name="ArkTsProxyError",this.code=t}static uninitialized(e){return new r(e,ZE.UNINITIALIZED)}static unknown(e="Unknown error"){return new r(e,ZE.UNKNOWN)}toJsonRpcErrorParams(){return{code:this.code,message:this.message}}};var Bo=class{config;lspProxy=null;configWatcher=null;depMapWatcher=null;sourceFileWatcher=null;isInitialized=!1;lastEditorOpenFiles=[];onMessage=()=>{};onConfigChanged=null;disposeOnce=null;get aceServerPid(){return this.lspProxy?.lspPid??null}constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}async start(e=[],t){this.lastEditorOpenFiles=e;try{this.startConfigWatcher(),this.startLspProxy(e,t)}catch(n){throw f.error(`[ArktsLspManager] start() synchronous failure: ${n instanceof Error?n.message:String(n)}`),n}}sendNotification(e){if(!this.lspProxy){f.warn("[ArktsLspManager] sendNotification before LSP ready, dropped");return}this.lspProxy.sendNotification(e)}sendRequest(e){if(!this.lspProxy){f.warn("[ArktsLspManager] sendRequest before LSP ready, dropped");return}this.lspProxy.sendRequest(e)}async diagnostic(e){if(!this.lspProxy)throw new Error("[ArktsLspManager] diagnostic before LSP ready");return this.lspProxy.diagnostic(e)}async sendFeatureRequest(e,t){if(!this.useStandardProtocol)throw new Error(`Language feature '${e}' is not supported on the installed DevEco Studio. The standard LSP protocol entry (plugins/openharmony/ace-server/out/standardIndex/index.js) was not found. Please upgrade DevEco Studio to version 26.0.0.610 or later to use this tool.`);if(!this.lspProxy)throw new Error("LSP not ready");return this.lspProxy.sendFeatureRequest(e,t)}get useStandardProtocol(){return this.config.useStandardProtocol}onAsyncOpenFile(e){this.lspProxy?.onAsyncOpenFile(e)}closeFileLegacy(e,t){this.lspProxy?.closeFileLegacy(e,t)}registerDiagnosticCallback(e){this.lspProxy?.registerDiagnosticCallback(e)}static async handleSyncProject(e,t,n,i,o,s,a,c){if(f.info("[ArktsLspManager] Received arkts/syncProject"),!e||!t)return f.error("[ArktsLspManager] handleSyncProject: workspaceRoot or sdkPath is empty"),{status:"failed",reason:"workspaceRoot or sdkPath is empty"};let l=s?.skipHvigorSync===!0,d=await Mc(e,async()=>await XE(e,t,n??"",i??"",a)?l?(f.info("[ArktsLspManager] hvigor sync skipped (config up-to-date)"),{status:"success"}):await nw(e,t,n??"",o??"",c)?(f.info("[ArktsLspManager] syncProject completed successfully"),{status:"success"}):(f.error("[ArktsLspManager] syncProject failed"),{status:"failed",reason:"hvigor sync failed"}):(f.error("[ArktsLspManager] ohpm install failed"),{status:"failed",reason:"ohpm install failed"}));return d.acquired?d.result:(f.info("[ArktsLspManager] Build lock held by another process, skipping sync"),{status:"skipped",reason:"build lock held by another process"})}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}async performDispose(){try{this.configWatcher?.stop()}catch(e){f.warn(`[ArktsLspManager] configWatcher stop error: ${e}`)}try{this.depMapWatcher?.stop()}catch(e){f.warn(`[ArktsLspManager] depMapWatcher stop error: ${e}`)}try{this.sourceFileWatcher?.stop()}catch(e){f.warn(`[ArktsLspManager] sourceFileWatcher stop error: ${e}`)}if(this.configWatcher=null,this.depMapWatcher=null,this.sourceFileWatcher=null,this.lspProxy){try{await this.lspProxy.dispose()}catch(e){f.warn(`[ArktsLspManager] lspProxy dispose error: ${e}`)}this.lspProxy=null}this.isInitialized=!1}startLspProxy(e,t){let n=new Wd(this.config.sdkPath,this.config.arktsLangServerPath,this.config.workspaceRoot,this.config.indexLogPath,this.config.nodeMaxOldSpaceSize,this.config.useStandardProtocol,this.config.nodePath,this.config.useSocket??!1);n.setOnMessage(i=>this.handleLspMessage(i)),n.start(e,i=>this.handleLspInitialized(i),t),this.lspProxy=n}handleLspInitialized=e=>{if(this.isInitialized=e,e)f.info("[ArktsLspManager] LSP initialized"),this.startDependencyMapWatcher(),this.startSourceFileWatcher(),this.onMessage({jsonrpc:L,method:b.ARKTS_INITIALIZED,params:{}});else{let t=this.lspProxy?.consumeStartErrorMessage();f.error(`[ArktsLspManager] LSP initialization failed: ${t}`);let n=t?Ca.uninitialized(t):Ca.unknown();this.onMessage({jsonrpc:L,method:b.ARKTS_INITIALIZATION_FAILED,params:n.toJsonRpcErrorParams()}),this.lspProxy=null}};handleLspMessage(e){this.onMessage(e)}maybeRetryLspAfterSuccessfulSync(){this.isInitialized||this.lspProxy!==null||(f.info("[ArktsLspManager] Retrying LSP startup after successful sync"),this.onMessage({jsonrpc:L,method:b.ARKTS_REINITIALIZING,params:{}}),this.startLspProxy(this.lastEditorOpenFiles))}startConfigWatcher(){this.configWatcher||(this.configWatcher=new Vd(this.config.workspaceRoot),this.configWatcher.on("configChanged",e=>this.handleConfigChanged(e)),this.configWatcher.start())}startDependencyMapWatcher(){this.depMapWatcher||(this.depMapWatcher=new Gd(this.config.workspaceRoot),this.depMapWatcher.on("reload",e=>{if(!this.lspProxy){f.warn("[ArktsLspManager] LspServerProxy not initialized, skip reload");return}let n=this.lspProxy.reloadDependenciesOnly(e).map(i=>({modulePath:i.modulePath??"",dependencies:i.dependencies??{},dynamicDependencies:i.dynamicDependencies??{}}));this.onMessage({jsonrpc:L,method:b.ARKTS_SYNC_COMPLETED,params:{success:!0,moduleSet:n}})}),this.depMapWatcher.start())}startSourceFileWatcher(){this.sourceFileWatcher||(this.sourceFileWatcher=new zd(this.config.workspaceRoot),this.sourceFileWatcher.on("sourceChanged",e=>{if(!this.lspProxy){f.warn("[ArktsLspManager] LspServerProxy not initialized, skip didChangeWatchedFiles");return}this.sendNotification({jsonrpc:L,method:b.WORKSPACE_DID_CHANGE_WATCHED_FILES,params:{changes:e.changes}}),f.info(`[ArktsLspManager] Notified didChangeWatchedFiles: ${e.changes.length} change(s)`)}),this.sourceFileWatcher.start())}setOnConfigChanged(e){this.onConfigChanged=e}handleConfigChanged(e){f.info(`[ArktsLspManager] Config file changed: ${e.filePath}, notifying server`),e.kind!==4&&this.sourceFileWatcher?.refreshSourceDirs(),this.onConfigChanged?.()}};var S0=10080*60*1e3,E0=7200*60*1e3,P0=120*1e3,Wo=class r{manager=null;get aceServerPid(){return this.manager?.aceServerPid??null}initialized=!1;initializing=!1;initPromise=null;initDeadlineTimer=null;initResolve=null;initReject=null;projectPath;sdkPath;arktsLangServerPath;nodePath;nodeMaxOldSpaceSize;onConfigChangedCallback=null;onInitProgress=null;onDepParseProgress=null;useStandardProtocol=!0;useSocket;diagnosticWaiters=new Map;documentVersion=0;static FEATURE_METHOD_MAP={hover:b.HOVER,definition:b.DEFINITION,declaration:b.DECLARATION,references:b.REFERENCES,implementation:b.IMPLEMENTATION,completion:b.COMPLETION,signatureHelp:b.SIGNATURE_HELP,documentHighlight:b.DOCUMENT_HIGHLIGHT};constructor(e,t,n,i,o,s=!1){this.projectPath=e,this.sdkPath=t,this.arktsLangServerPath=n,this.nodeMaxOldSpaceSize=i,this.nodePath=o,this.useSocket=s}setOnConfigChanged(e){this.onConfigChangedCallback=e}setOnInitProgress(e){this.onInitProgress=e}setOnDepParseProgress(e){this.onDepParseProgress=e}async initialize(){if(!this.initialized){if(this.initPromise){await this.initPromise;return}this.initializing=!0,this.initPromise=this.doInitialize().then(()=>{this.initialized=!0}).finally(()=>{this.initializing=!1}),await this.initPromise}}async doInitialize(){let{harmonyRoot:e,arktsLangServerPath:t,useStandardProtocol:n}=this.resolveProjectAndDeveco();this.useStandardProtocol=n;let i=xe(e),{logPath:o,indexPath:s}=this.getLogAndIndexPath(i);setImmediate(()=>{Uu(s,S0,"[ArkTS-Check]"),Uu(o,E0,"[ArkTS-Check]")}),$c(o);let a=this.nodeMaxOldSpaceSize?parseInt(this.nodeMaxOldSpaceSize,10):NaN,c=Number.isNaN(a)?void 0:a;h.info(`ArktsCheck nodeMaxOldSpaceSize: incoming='${this.nodeMaxOldSpaceSize??"(unset)"}', parsed=${c??"undefined \u2192 dynamic formula applies"}`);let l=this.sdkPath;h.info(`[ArktsCheck] sdkPath=${l}, arktsLangServerPath=${t}, useStandardProtocol=${n}, useSocket=${this.useSocket}`),this.manager=new Bo({sdkPath:l,arktsLangServerPath:t,workspaceRoot:ge(i),indexLogPath:s,nodeMaxOldSpaceSize:c,useStandardProtocol:n,nodePath:this.nodePath,useSocket:this.useSocket}),this.manager.setOnMessage(d=>this.handleLspMessage(d)),this.onConfigChangedCallback&&this.manager.setOnConfigChanged(this.onConfigChangedCallback),await new Promise((d,g)=>{this.initResolve=d,this.initReject=g,this.armInitTimer(it),this.manager.start([],this.onDepParseProgress??void 0).catch(y=>{let E=y instanceof Error?y:new Error(String(y));this.failInit(E)})})}resolveProjectAndDeveco(){let e=Cr(this.projectPath);if(!e)throw new Error(`Failed to find HarmonyOS project from path: ${this.projectPath}`);this.projectPath=e;let t=this.arktsLangServerPath;if(!t)throw new Error("arkts-lang-server path not found");let n=Za(t);return{harmonyRoot:e,arktsLangServerPath:t,useStandardProtocol:n}}armInitTimer(e){this.initDeadlineTimer&&clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=setTimeout(()=>{let t=this.initReject;this.clearInitHandlers(),t?.(new Error("LSP initialize timeout"))},e)}clearInitHandlers(){this.initDeadlineTimer&&(clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=null),this.initResolve=null,this.initReject=null}failInit(e){let t=this.initReject;this.clearInitHandlers(),t?.(e)}async checkFile(e){this.initialized||await this.initialize();let t=this.manager;if(!t)throw new Error("ArktsLspManager not initialized");let n=Nt(e),i=await Tt.promises.readFile(e,"utf8"),s=`deveco.apptool.${He.extname(e).replace(/^\./,"")||"plaintext"}`;return t.useStandardProtocol?this.checkFileStandard(t,n,i,s):this.checkFileLegacy(t,e,n,i,s)}async checkFileStandard(e,t,n,i){h.debug(`textDocument/didOpen uri=${t} content_len=${n.length}`),this.sendNotification("textDocument/didOpen",{textDocument:{uri:t,text:n,languageId:i,version:++this.documentVersion}});try{h.debug(`textDocument/diagnostic uri=${t}`);let o=await e.diagnostic({textDocument:{uri:t}});return C0(o)}finally{this.sendNotification("textDocument/didClose",{textDocument:{uri:t}})}}async checkFileLegacy(e,t,n,i,o){let s=n;e.registerDiagnosticCallback(n);let a=new Promise((c,l)=>{let d=setTimeout(()=>{this.diagnosticWaiters.delete(s)&&l(new Error("Wait for diagnostics timeout"))},P0);this.diagnosticWaiters.set(s,{resolve:c,reject:l,timer:d})});h.debug(`textDocument/didOpen(legacy) uri=${n} content_len=${i.length}`),e.onAsyncOpenFile({textDocument:{uri:n,text:i,languageId:o,version:i.length},editorFiles:[n],isFromEditor:!1});try{return await a}finally{e.closeFileLegacy(n,!1)}}async handleCall(e){if(!this.initialized)return this.buildNotReadyResponse();let t=[],n=[],i=this.collectValidFiles(e.files,t);return i.length===0?{content:[{type:"text",text:t.length>0?t.join(`
1328
- `):"No valid .ets files"}],isError:!0}:(await this.runDiagnosticsForFiles(i,t,n),this.formatCallResult(t,n))}async handleLspFeature(e,t){if(!this.initialized)return this.buildNotReadyResponse();let n=this.resolveSingleFile(t.file);if(!n)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${t.file}`}],isError:!0};let i=r.FEATURE_METHOD_MAP[e];if(!i)return{content:[{type:"text",text:`Unknown feature: ${e}`}],isError:!0};h.info(`handleLspFeature: ${e} file=${n} line=${t.line} char=${t.character}`);try{let o=await this.withOpenFile(n,async a=>{let c={textDocument:{uri:a},position:{line:t.line,character:t.character}};return e==="references"&&(c.context={includeDeclaration:!0}),this.manager.sendFeatureRequest(i,c)});return{content:[{type:"text",text:o==null?`${e}: no result`:`${e}: ${JSON.stringify(o,null,2)}`}]}}catch(o){let s=o instanceof Error?o.message:String(o);return h.error(`handleLspFeature ${e} failed: ${s}`),{content:[{type:"text",text:`${e} failed: ${s}`}],isError:!0}}}async handleWorkspaceSymbol(e){if(!this.initialized)return this.buildNotReadyResponse();h.info(`handleWorkspaceSymbol: query="${e}"`);try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return{content:[{type:"text",text:t==null?"workspaceSymbol: no result":`workspaceSymbol: ${JSON.stringify(t,null,2)}`}]}}catch(t){let n=t instanceof Error?t.message:String(t);return h.error(`handleWorkspaceSymbol failed: ${n}`),{content:[{type:"text",text:`workspaceSymbol failed: ${n}`}],isError:!0}}}async handleWorkspaceSymbolRaw(e){if(!this.initialized)return null;try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return Array.isArray(t)?t:t==null?null:[t]}catch(t){return h.error(`handleWorkspaceSymbolRaw failed: ${t.message}`),null}}async handleDocumentSymbol(e){if(!this.initialized)return this.buildNotReadyResponse();let t=this.resolveSingleFile(e);if(!t)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${e}`}],isError:!0};h.info(`handleDocumentSymbol: file=${t}`);try{let n=await this.withOpenFile(t,async o=>this.manager.sendFeatureRequest(b.DOCUMENT_SYMBOL,{textDocument:{uri:o}}));return{content:[{type:"text",text:n==null?"documentSymbol: no result":`documentSymbol: ${JSON.stringify(n,null,2)}`}]}}catch(n){let i=n instanceof Error?n.message:String(n);return h.error(`handleDocumentSymbol failed: ${i}`),{content:[{type:"text",text:`documentSymbol failed: ${i}`}],isError:!0}}}async handleCallHierarchy(e){if(!this.initialized)return this.buildNotReadyResponse();let t=this.resolveSingleFile(e.file);if(!t)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${e.file}`}],isError:!0};h.info(`handleCallHierarchy: file=${t} line=${e.line} char=${e.character} direction=${e.direction}`);try{let n=await this.withOpenFile(t,async o=>{let s=await this.manager.sendFeatureRequest(b.PREPARE_CALL_HIERARCHY,{textDocument:{uri:o},position:{line:e.line,character:e.character}}),a=Array.isArray(s)?s:s?[s]:[];if(a.length===0)return{items:[],calls:[]};let c=e.direction==="incoming"?b.INCOMING_CALLS:b.OUTGOING_CALLS,l=[];for(let d of a){let g=await this.manager.sendFeatureRequest(c,{item:d});Array.isArray(g)?l.push(...g):g&&l.push(g)}return{items:a,calls:l}});return{content:[{type:"text",text:`callHierarchy (${e.direction}): ${JSON.stringify(n,null,2)}`}]}}catch(n){let i=n instanceof Error?n.message:String(n);return h.error(`handleCallHierarchy failed: ${i}`),{content:[{type:"text",text:`callHierarchy failed: ${i}`}],isError:!0}}}async withOpenFile(e,t){let n=Nt(e),i=await Tt.promises.readFile(e,"utf8"),s=`deveco.apptool.${He.extname(e).replace(/^\./,"")||"plaintext"}`;h.debug(`withOpenFile didOpen uri=${n} len=${i.length}`),this.sendNotification("textDocument/didOpen",{textDocument:{uri:n,text:i,languageId:s,version:++this.documentVersion}});try{return await t(n)}finally{this.sendNotification("textDocument/didClose",{textDocument:{uri:n},isManual:!1})}}resolveSingleFile(e){let t=He.isAbsolute(e)?e:He.join(this.projectPath,e);return!Tt.existsSync(t)||!Tt.statSync(t).isFile()||!t.endsWith(".ets")?null:t}buildNotReadyResponse(){return{content:[{type:"text",text:this.initializing?"LSP is initializing, please retry later":this.projectPath?"LSP not initialized":"No project path configured; set the PROJECT_PATH parameter"}],isError:!0}}collectValidFiles(e,t){let n=He.resolve(this.projectPath),i=[];for(let o of e){let s=He.resolve(He.isAbsolute(o)?o:He.join(n,o));if(!Tt.existsSync(s)){t.push(`File does not exist: ${o}`);continue}if(!Tt.statSync(s).isFile()){t.push(`Not a regular file: ${o}`);continue}if(!s.endsWith(".ets")){t.push(`Not a .ets file: ${o}`);continue}i.push(s)}return i}async runDiagnosticsForFiles(e,t,n){for(let i of e){await Rh(500);try{let o=await this.checkFile(i);n.push(k0(i,o))}catch(o){t.push(`${i} => wait for diagnostics failed: ${o.message}`)}}}formatCallResult(e,t){let n=[];e.length>0&&n.push(e.join(`
1343
+ `);if(n===-1)break;let o=this.buffer.slice(0,n).toString("ascii").match(/Content-Length:\s*(\d+)/i);if(!o){m.warn("[LspClient] Invalid LSP header, drop until next packet"),this.buffer=this.buffer.slice(n+4);continue}let s=parseInt(o[1],10);if(!Number.isFinite(s)||s<0||s>RH){m.warn(`[LspClient] Invalid Content-Length: ${o[1]}, drop until next packet`),this.buffer=this.buffer.slice(n+4);continue}let a=n+4,c=a+s;if(this.buffer.length<c)break;let l=this.buffer.slice(a,c).toString("utf8"),d=this.recoverFramedJson(l);if(d&&d.rest.length>0){m.warn(`[LspClient] recovered mixed LSP frame, bodyLen=${l.length}, restLen=${d.rest.length}`),this.logSocketRecv(d.json),this.emit("message",d.json),this.buffer=Buffer.concat([Buffer.from(d.rest,"utf8"),this.buffer.slice(c)]);continue}this.logSocketRecv(l),this.emit("message",l),this.buffer=this.buffer.slice(c)}}logSocketRecv(t){this.socket&&m.debug(`[LspClient] [SOCKET RECV] ${t.slice(0,200)}`)}waitForExitOrTimeout(t){let n=this.process;return!n||n.exitCode!==null||n.signalCode!==null?Promise.resolve():new Promise(i=>{let o=!1,s=()=>{o||(o=!0,clearTimeout(c),n.off("exit",a),i())},a=()=>s();n.once("exit",a);let c=setTimeout(s,t)})}recoverFramedJson(t){let n=t.search(/\S/);if(n<0||t[n]!=="{"&&t[n]!=="[")return null;let i=0,o=!1,s=!1;for(let a=n;a<t.length;a++){let c=t[a];if(o){if(s){s=!1;continue}if(c==="\\"){s=!0;continue}c==='"'&&(o=!1);continue}if(c==='"'){o=!0;continue}if(c==="{"||c==="["){i++;continue}if((c==="}"||c==="]")&&(i--,i===0)){let l=t.slice(n,a+1),d=t.slice(a+1);return{json:l,rest:d}}}return null}stop(){if(this.isClosing=!0,this.socket){this.socket.destroy(),this.socket=null,this.process=null;return}let t=this.process;if(!t)return;if(this.process=null,t.exitCode===null&&t.signalCode===null)try{t.kill()}catch{}}};var Dn=class{callbacks=new Map;pending=new Map;timeouts=new Map;registerPending(e,t,n){return new Promise((i,o)=>{let s;n>0&&(s=setTimeout(()=>{this.pending.delete(e),this.timeouts.delete(e),o(new Error(`LSP request '${t}' (id=${e}) timeout after ${n}ms`))},n),this.timeouts.set(e,s)),this.pending.set(e,{resolve:i,reject:o,method:t,timer:s})})}resolvePending(e,t){this.clearTimeout(e);let n=this.pending.get(e);return n?(n.resolve(t),this.pending.delete(e),!0):!1}rejectPending(e,t){this.clearTimeout(e);let n=this.pending.get(e);return n?(n.reject(t),this.pending.delete(e),!0):!1}register(e,t){this.callbacks.set(e,t)}emit(e,t,n){m.debug(`[RequestCallbackManager] emit, method: ${t}, key: ${e}`),this.clearTimeout(e);let i=this.callbacks.get(e);if(i)try{i(t,n)}finally{this.callbacks.delete(e)}else{let o=[...this.callbacks.keys()].map(s=>String(s));m.debug(`[RequestCallbackManager] emit: NO callback for key='${e}', registered keys=[${o.join(",")}]`)}}registerTimeout(e,t,n,i){let o=this.timeouts.get(e);o&&clearTimeout(o);let s=setTimeout(()=>{m.debug(`[RequestCallbackManager] timeout, key=${e}, method=${t}`);try{i()}finally{this.timeouts.delete(e)}},n);this.timeouts.set(e,s)}clearTimeout(e){let t=this.timeouts.get(e);t&&(clearTimeout(t),this.timeouts.delete(e))}deleteCallback(e){this.callbacks.delete(e)}hasCallback(e){return this.callbacks.has(e)||this.pending.has(e)}clear(e){this.clearTimeout(e);let t=this.pending.get(e);t&&(t.reject(new Error(`Request '${t.method}' (id=${e}) cancelled`)),this.pending.delete(e)),this.callbacks.delete(e)}rejectAll(e){for(let[,t]of this.pending)t.reject(e);this.pending.clear();for(let[,t]of this.timeouts)clearTimeout(t);this.timeouts.clear(),this.callbacks.clear()}};var Xd=class{uri;diagnostics=[];constructor(e){this.uri=e}set(e){this.diagnostics=e}get(){return this.diagnostics}clear(){this.diagnostics=[]}};var zo=class{map=new Map;register(e,t){let n=this.map.get(e);n||(n=new Set,this.map.set(e,n)),n.add(t)}unregister(e,t){let n=this.map.get(e);n&&(t!==void 0?n.delete(t):n.clear(),n.size===0&&this.map.delete(e))}invoke(e,...t){let n=this.map.get(e);if(n)for(let i of n)try{i(...t)}catch(o){console.error(`[CallbackRegistry] invoke("${String(e)}") callback error:`,o)}}invokeOnce(e,...t){this.invoke(e,...t),this.unregister(e)}clear(){this.map.clear()}has(e){let t=this.map.get(e);return t!==void 0&&t.size>0}};function M(r){return typeof r=="object"&&r!==null}var yC=20*1e3,OH=30*1e3,wC=300,_H=300;function MH(){let r=process.env.DEVECO_CLI_LSP_STANDARD_EXIT_TIMEOUT_MS;if(r===void 0||r==="")return wC;let e=parseInt(r,10);return Number.isFinite(e)?Math.max(_H,e):wC}var Zd=class{client;nextRequestId=1;stopOnce=null;callbacks=new zo;requestCallbacks=new Dn;diagnosticMap=new Map;initProgressReset=null;notificationWaiters=new Map;get lspPid(){return this.client.pid}constructor(e){this.client=new xn(e),this.client.on("message",t=>this.handleRawMessage(t)),this.client.on("error",t=>this.handleError(t))}async start(e){await this.client.start(e)}stop(){return this.stopOnce||(this.stopOnce=(async()=>{m.info("[ClientMessageHandle] Sending shutdown request"),this.client.sendRequest(b.SHUTDOWN,null,this.nextRequestId++),m.info("[ClientMessageHandle] Sending exit notification"),this.client.sendNotification(b.EXIT,null),m.info("[ClientMessageHandle] Waiting for LSP process to exit"),await this.client.waitForExitOrTimeout(MH()),m.info("[ClientMessageHandle] LSP exit wait completed, calling stop"),this.client.stop()})()),this.stopOnce}setBroadcastToClients(e){this.callbacks.unregister(b.BROADCAST),this.callbacks.register(b.BROADCAST,e)}broadcastToClients(e){this.callbacks.invoke(b.BROADCAST,e)}async sendInitialize(e){let t=this.nextRequestId++,n=this.requestCallbacks.registerPending(t,b.INITIALIZE,ot);return this.client.sendRequest(b.INITIALIZE,e,t),n}sendInitializeResettable(e,t){let n=this.nextRequestId++,i=this.requestCallbacks.registerPending(n,b.INITIALIZE,0);return this.client.sendRequest(b.INITIALIZE,e,n),new Promise((o,s)=>{let a,c=()=>{a=setTimeout(()=>{this.initProgressReset=null,s(new Error(`LSP initialization timeout after ${t}ms`))},t)},l=()=>{clearTimeout(a),c()};this.initProgressReset=l,c(),i.then(()=>{clearTimeout(a),this.initProgressReset=null,o()},d=>{clearTimeout(a),this.initProgressReset=null,s(d)})})}sendInitialized(){this.client.sendNotification(b.INITIALIZED,{})}sendInitializeAndWaitForNotification(e,t,n,i,o){return new Promise((s,a)=>{let c={initializeResolved:!1,notificationResolved:!1},l=this.startInitTimer(t,n,a);this.initProgressReset=()=>{l.reset(),o?.()};let d=()=>{c.initializeResolved&&c.notificationResolved&&(l.clear(),s())};this.notificationWaiters.set(t,()=>{c.notificationResolved=!0,d()});let g=this.nextRequestId++;this.client.sendRequest(b.INITIALIZE,e,g),this.requestCallbacks.registerPending(g,b.INITIALIZE,0).then(()=>{c.initializeResolved=!0;try{i()}catch(y){l.clear(),a(y instanceof Error?y:new Error(String(y)));return}d()},y=>{l.clear(),a(y)})})}startInitTimer(e,t,n){let i,o=()=>{clearTimeout(i),this.initProgressReset=null,this.notificationWaiters.delete(e)},s=()=>{i=setTimeout(()=>{o(),n(new Error(`LSP initialization timeout after ${t}ms`))},t)},a=()=>{clearTimeout(i),s()};return s(),{reset:a,clear:o}}sendDidOpen(e){let t=e.textDocument.uri;this.diagnosticMap.has(t)||(this.diagnosticMap.set(t,new Xd(t)),this.registerDiagnosticTimeout(t)),this.client.sendNotification(b.DID_OPEN,e)}sendDidChange(e){let t=e.textDocument.uri,n=this.diagnosticMap.get(t);n&&(n.clear(),this.registerDiagnosticTimeout(t)),this.client.sendNotification(b.DID_CHANGE,e)}closeFile(e){this.cleanupDiagnosticState(e.textDocument.uri),this.client.sendNotification(b.DID_CLOSE,e)}sendLspRequest(e,t,n=OH){let i=this.nextRequestId++,o=this.requestCallbacks.registerPending(i,e,n);return this.client.sendRequest(e,t,i),o}registerRequestCallback(e,t){this.requestCallbacks.register(e,t)}onDidChangeWatchedFiles(e){e.length!==0&&this.client.sendNotification(b.WORKSPACE_DID_CHANGE_WATCHED_FILES,{changes:e})}sendDidChangeConfiguration(e){this.client.sendNotification(b.WORKSPACE_DID_CHANGE_CONFIGURATION,{settings:e})}sendNotification(e,t){this.client.sendNotification(e,t)}getDiagnosticMessages(e){let t=this.diagnosticMap.get(e);return t?t.get():[]}clearDiagnostic(e){this.diagnosticMap.get(e)?.clear()}handleRawMessage(e){let t;try{t=JSON.parse(e)}catch(n){let i=n instanceof Error?n.message:String(n);m.error(`[LSP] JSON parse error: ${i}, raw: ${e}`);return}"id"in t&&("result"in t||"error"in t)?this.handleResponse(t):"method"in t?this.handleNotificationOrRequest(t):m.warn(`[LSP] Unrecognized message: ${JSON.stringify(t).slice(0,200)}`)}handleResponse(e){let t=e.id;if(t===void 0)return;let n=t;if(e.error){let i=new Error(`LSP error ${e.error.code}: ${e.error.message}`);this.requestCallbacks.rejectPending(n,i)}else this.requestCallbacks.resolvePending(n,e.result)}handleNotificationOrRequest(e){let t=e.method;if(!t)return;this.initProgressReset?.();let n=this.notificationWaiters.get(t);if(n){this.notificationWaiters.delete(t),n();return}switch(t){case b.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(e.params);break;case b.PROGRESS:this.handleProgress(e.params);break;case b.WINDOW_SHOW_MESSAGE:m.debug(`[LSP] window/showMessage: ${JSON.stringify(e.params)}`);break;case b.WINDOW_LOG_MESSAGE:m.debug(`[LSP] window/logMessage: ${JSON.stringify(e.params)}`);break;default:this.broadcastToClients(e)}}handlePublishDiagnostics(e){if(!e||!e.uri)return;let t=e.uri,n=this.diagnosticMap.get(t);if(!n)return;let i=e.diagnostics||[];this.normalizeDiagnostics(i),n.set(i),this.finalizeDiagnostic(t,i)}normalizeDiagnostics(e){for(let t of e)if(t.severity!==void 0){let n={1:"Error",2:"Warning",3:"Information",4:"Hint"};t.severityStr=n[t.severity]||"Unknown"}}handleProgress(e){M(e)&&this.broadcastToClients({jsonrpc:L,method:b.PROGRESS,params:e})}registerDiagnosticTimeout(e){this.requestCallbacks.registerTimeout(e,b.PUBLISH_DIAGNOSTICS,yC,()=>{let t=this.diagnosticMap.get(e),n=t?t.get():[];this.finalizeDiagnostic(e,n,n.length>0?void 0:`received no diagnostics within ${yC}ms, uri: ${e}`)})}finalizeDiagnostic(e,t,n){let i={uri:e,diagnostics:t,...n?{errorMessage:n}:{}};this.requestCallbacks.emit(e,b.PUBLISH_DIAGNOSTICS,i),this.diagnosticMap.get(e)?.clear()}handleError(e){let t=Array.from(this.diagnosticMap.keys()).filter(n=>this.requestCallbacks.hasCallback(n));if(t.length>0){let n={range:{start:{line:0,character:0},end:{line:0,character:0}},severity:1,message:e.message};for(let i of t)this.finalizeDiagnostic(i,[n]);return}this.broadcastToClients({jsonrpc:L,method:b.ARKTS_ERROR,params:{message:e.message}})}cleanupDiagnosticState(e){this.requestCallbacks.clear(e),this.diagnosticMap.delete(e)}};var Qd=class{uri;messages=[];receivedTypes=new Set;uniqueMessages=new Set;isFromEditor=!1;constructor(e){this.uri=e}setReceivedType(e){this.receivedTypes.add(e)}addMessage(e,t){this.receivedTypes.add(e);let n=`${e}:${t}`;if(this.uniqueMessages.has(n)){m.info(`[LegacyDiagnostic] addMessage: duplicate message=${n}`);return}this.uniqueMessages.add(n),this.messages.push(new Ug(e,t))}clearMessages(){this.messages=[]}clear(){this.receivedTypes.clear(),this.uniqueMessages.clear(),this.messages=[]}hasReceivedAllTypes(e){for(let t of e)if(!this.receivedTypes.has(t))return!1;return!0}getMessages(){return this.messages.map(e=>e.diagnostics)}},Ug=class{version=-1;diagnostics;constructor(e,t){this.version=e,this.diagnostics=t}};var LH={EXIT:"exit",INITIALIZED:"initialized",ON_DID_CHANGE_PACKAGE_DEPENDENCIES:"aceProject/onDidChangePackageDependencies",ON_ASYNC_DID_OPEN:"aceProject/onAsyncDidOpen",ON_ASYNC_DID_CHANGE:"aceProject/onAsyncDidChange",DID_CLOSE:"textDocument/didClose",ON_ASYNC_HOVER:"aceProject/onAsyncHover",ON_ASYNC_DEFINITION:"aceProject/onAsyncDefinition",ON_ASYNC_FIND_USAGES:"aceProject/onAsyncFindUsages"},FH={MODULE_INIT_FINISH:io.MODULE_INIT_FINISH,INDEXING_PROGRESS_UPDATE:"aceProject/onIndexingProgressUpdate",ON_FORCE_OPEN_FILE:"aceProject/onForceOpenFile",ON_PACKAGE_CHANGE_FINISH:"aceProject/onPackageChangeFinish",TEXT_DOCUMENT_ON_ASYNC_DEFINITION:"textDocument/onAsyncDefinition",ON_DID_CHANGE_PACKAGE_DEPENDENCIES_CLIENT:"textDocument/onDidChangePackageDependencies",PUBLISH_DIAGNOSTICS:"textDocument/publishDiagnostics",HOVER:"textDocument/hover",DEFINITION:"textDocument/definition",REFERENCES:"textDocument/references",DID_OPEN:"textDocument/didOpen",DID_CHANGE:"textDocument/didChange",WORKSPACE_DID_CHANGE_CONFIGURATION:"workspace/didChangeConfiguration",WORKSPACE_DID_CHANGE_WATCHED_FILES:"workspace/didChangeWatchedFiles",BROADCAST:"lsp/broadcast",ARKTS_ERROR:"arkts/error",ARKTS_INITIALIZED:"arkts/initialized",ARKTS_INITIALIZATION_FAILED:"arkts/initializationFailed",ARKTS_INDEXING_PROGRESS:"arkts/indexingProgress",ARKTS_SYNC_PROJECT:"arkts/syncProject",ARKTS_SYNC_COMPLETED:"arkts/syncCompleted",ARKTS_REINITIALIZING:"arkts/reinitializing"},F={...LH,...FH},In={EXIT:"exit",INITIALIZED:"initialized",EMPTY:"empty",ON_DID_CHANGE_PACKAGE_DEPENDENCIES:"onDidChangePackageDependencies",ON_ASYNC_DID_OPEN:"onAsyncDidOpen",ON_ASYNC_DID_CHANGE:"onAsyncDidChange",DID_CLOSE:"didClose",ON_ASYNC_HOVER:"onAsyncHover",ON_ASYNC_DEFINITION:"onAsyncDefinition",ON_ASYNC_FIND_USAGES:"onAsyncFindUsages"},vC=new Set([1e3,2e3,3e3,3001]);function $H(r){if(!M(r))return!1;let e=r.textDocument;return M(e)&&typeof e.uri=="string"}function jH(r){return M(r)?typeof r.uri=="string"&&typeof r.type=="number":!1}function HH(r){return M(r)&&typeof r.moduleName=="string"&&typeof r.current=="number"&&typeof r.total=="number"?`indexing module '${r.moduleName}', ${r.current} of total ${r.total} modules`:`params=${JSON.stringify(r??null)}`}var eu=class r{client;isInitialized=!1;stopOnce=null;callbacks=new zo;requestCallbacks=new Dn;diagnosticMap=new Map;static DIAGNOSTIC_TIMEOUT_MS=20*1e3;get lspPid(){return this.client.pid}constructor(e){this.client=new xn(e),this.client.on("message",t=>this.handleRawMessage(t)),this.client.on("error",t=>this.handleError(t))}async start(e){await this.client.start(e)}stop(){return this.stopOnce||(this.stopOnce=(async()=>{m.info("[LegacyClientMessageHandle] Sending exit notification to LSP"),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.EXIT,params:{}}),In.EXIT),m.info("[LegacyClientMessageHandle] Waiting for LSP process to exit"),await this.client.waitForExitOrTimeout(300),m.info("[LegacyClientMessageHandle] LSP exit wait completed, calling stop"),this.client.stop()})()),this.stopOnce}setBroadcastToClients(e){this.callbacks.unregister(F.BROADCAST),this.callbacks.register(F.BROADCAST,e)}broadcastToClients(e){this.callbacks.invoke(F.BROADCAST,e)}onInitializationCompleted(e){this.isInitialized?e():this.callbacks.register(F.MODULE_INIT_FINISH,e)}onIndexingProgressUpdate(e){this.callbacks.register(F.INDEXING_PROGRESS_UPDATE,e)}registerRequestCallback(e,t){this.requestCallbacks.register(e,t)}sendInitialize(e,t){this.client.send("initialize",e,t)}sendInitialized(e){this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.INITIALIZED,params:{editors:e}}),In.INITIALIZED),this.client.sendRaw(JSON.stringify({jsonrpc:L,id:0,result:{}}),In.EMPTY)}sendAsyncRequest(e,t,n,i){if(!M(t)){m.warn(`[LSP] sendAsyncRequest invalid params, method=${e}`);return}if(!$H(t)){m.warn(`[LSP] sendAsyncRequest missing textDocument.uri, method=${e}, params=${JSON.stringify(t)}`);return}if(typeof n!="number"){m.warn(`[LSP] sendAsyncRequest invalid requestId, method=${e}, requestId=${String(n)}`);return}let o=t.textDocument.uri,s=Wt(o);t.textDocument.uri=s,delete t.requestId;let a=i??e;m.info(`[LSP] sendAsyncRequest ${a}, filePath: ${o}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:e,params:{params:t,requestId:n}}),a)}onDidChangeWatchedFiles(e){if(m.info(`[LSP] onDidChangeWatchedFiles, params=${JSON.stringify(e)}`),e.length===0)return;let t=[];for(let n of e){if(!jH(n)){m.warn(`[LSP] onDidChangeWatchedFiles, param is missing 'uri' or 'type': ${JSON.stringify(n)}`);continue}t.push(n)}this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.WORKSPACE_DID_CHANGE_WATCHED_FILES,params:{changes:t}}),F.WORKSPACE_DID_CHANGE_WATCHED_FILES)}sendModuleDependencyUpdate(e){if(!M(e)||!Array.isArray(e.moduleSet)||e.moduleSet.length===0){m.warn("[LSP] sendModuleDependencyUpdate, moduleSet is empty or null");return}let t=e.moduleSet;m.info(`[LSP] sending module dependency updated, count: ${t.length}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.ON_DID_CHANGE_PACKAGE_DEPENDENCIES,params:{params:e}}),In.ON_DID_CHANGE_PACKAGE_DEPENDENCIES)}onAsyncOpenFile(e){let t=e.textDocument.uri,n=t.split(".").pop()||"";if(n!=="ets"&&n!=="ts")return;let i=Wt(t);e.textDocument.uri=i,m.info(`[LSP] onAsyncOpenFile, uri: ${i}`);let o=this.diagnosticMap.get(i);o||(o=new Qd(i),this.diagnosticMap.set(i,o),this.registerDiagnosticTimeout(i,F.PUBLISH_DIAGNOSTICS)),e.isFromEditor&&(o.isFromEditor=!0),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.ON_ASYNC_DID_OPEN,params:{params:{editorFiles:e.editorFiles,textDocument:e.textDocument}}}),In.ON_ASYNC_DID_OPEN)}onAsyncDidChange(e){let t=Wt(e.uri),n=this.diagnosticMap.get(t);n&&(n.clear(),this.registerDiagnosticTimeout(t,F.PUBLISH_DIAGNOSTICS)),m.info(`[LSP] onAsyncDidChange, uri: ${t}`),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.ON_ASYNC_DID_CHANGE,params:{editorFiles:[e.uri],params:{textDocument:{uri:t,version:e.version===0?null:e.version},contentChanges:e.contentChanges}}}),In.ON_ASYNC_DID_CHANGE)}closeFile(e,t){let n=Wt(e);m.info(`[LSP] didClose, uri: ${n}`);let i=this.diagnosticMap.get(n);if(!t&&(!i||i.isFromEditor)){m.info(`[LSP] closeFile skip, !diagnostic: ${!i}, isFromEditor: ${i?.isFromEditor}`);return}this.cleanupDiagnosticState(n),this.client.sendRaw(JSON.stringify({jsonrpc:L,method:F.DID_CLOSE,params:{textDocument:{uri:n}}}),In.DID_CLOSE)}getDiagnosticMessage(e){let t=Wt(e),n=this.diagnosticMap.get(t);return n?n.getMessages():[]}clear(e){this.diagnosticMap.get(e)?.clear()}handleRawMessage(e){try{let t=JSON.parse(e);this.handleLspMessage(t)}catch(t){let n=t instanceof Error?t.message:String(t);m.error(`[LSP] JSON parse error: ${n}, raw: ${e}`)}}handleError(e){let t=this.getPendingDiagnosticUris();if(t.length>0){let n=JSON.stringify({message:e.message,severity:"Error",severityStr:"Error"});for(let i of t)this.finalizeDiagnostic(i,F.PUBLISH_DIAGNOSTICS,[n]);return}this.broadcastToClients({jsonrpc:L,method:F.ARKTS_ERROR,params:{message:e.message}})}handleLspMessage(e){let t=e.method;t!==void 0&&(!this.isInitialized&&this.handlePreInitMessage(t,e)||this.handlePostInitMessage(t,e))}handlePreInitMessage(e,t){switch(e){case F.MODULE_INIT_FINISH:return m.info("[LSP] handleLspMessage, receive onModuleInitFinish"),this.isInitialized=!0,this.callbacks.invokeOnce(F.MODULE_INIT_FINISH),this.callbacks.unregister(F.INDEXING_PROGRESS_UPDATE),this.client.emit("initialized_done"),!0;case F.INDEXING_PROGRESS_UPDATE:return m.info(`[LSP] onIndexingProgressUpdate: ${HH(t.params)}`),this.callbacks.invoke(F.INDEXING_PROGRESS_UPDATE),!0;default:return!1}}handlePostInitMessage(e,t){switch(e){case F.ON_FORCE_OPEN_FILE:this.handleOnForceOpenFile(t);return;case F.ON_PACKAGE_CHANGE_FINISH:m.info("[LSP] handleLspMessage, receive onPackageChangeFinish"),this.handlePackageChangeFinish(t);return;case F.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(t);return;case F.ON_ASYNC_HOVER:this.handleAsyncResponse(t,F.HOVER);return;case F.ON_ASYNC_DEFINITION:this.handleAsyncResponse(t,F.TEXT_DOCUMENT_ON_ASYNC_DEFINITION);return;case F.ON_ASYNC_FIND_USAGES:this.handleAsyncResponse(t,F.REFERENCES);return;default:m.warn(`[LSP] handleLspMessage: no handler for notification, ignoring, method: ${e}, initialized: ${this.isInitialized}`)}}handleOnForceOpenFile(e){m.info("[LSP] handleLspMessage, receive onForceOpenFile");let t=e.params;M(t)&&M(t.result)&&typeof t.result.uri=="string"&&this.handleForceOpenFile(t.result.uri)}handlePublishDiagnostics(e){m.info("[LSP] handleLspMessage, receive publishDiagnostics");let t=e.params;t&&this.parseDiagnostics(t)}handlePackageChangeFinish(e){let t=e.params,n={jsonrpc:L,method:F.ON_PACKAGE_CHANGE_FINISH,params:[!1]};if(!t||!Array.isArray(t)){m.warn("[LSP] aceProject/onPackageChangeFinish params invalid"),this.broadcastToClients(n);return}if(!(t.length>0&&t[0]===!0)){m.warn("[LSP] aceProject/onPackageChangeFinish: package request failed"),this.broadcastToClients(n);return}m.info("[LSP] aceProject/onPackageChangeFinish: success"),this.broadcastToClients(e)}handleAsyncResponse(e,t){m.info(`[LSP] handleAsyncResponse\uFF0C method: ${t}`);let n=e.params;if(!M(n)){m.warn("[LSP] aceProject/onAsyncHover message invalid");return}let i=n.requestId;if(typeof i!="number"){m.warn(`[LSP] ${t} requestId invalid`);return}this.requestCallbacks.emit(i,t,n)}handleForceOpenFile(e){if(!e){m.warn("[LSP] handleForceOpenFile, uri is empty");return}this.requestCallbacks.emit(e,F.DID_OPEN,[]),this.clear(e)}parseDiagnostics(e){let t=e.uri;if(!t){m.info("[LSP] publishDiagnostics uri is null");return}let n=e.version??-1;if(n===-1)return;let i=this.diagnosticMap.get(t);if(!i){m.info(`[LSP] Diagnostic cleared for uri: ${t}`);return}let o=e.diagnostics||[];o.length!==0?o.forEach(s=>{this.normalizeDiagnostic(s),i.addMessage(n,JSON.stringify(s))}):i.setReceivedType(n),i.hasReceivedAllTypes(vC)&&this.finalizeDiagnostic(t,F.PUBLISH_DIAGNOSTICS,i.getMessages())}normalizeDiagnostic(e){let t=e;if(delete t.source,t.severity!==void 0){let n=typeof t.severity=="number"?t.severity:parseInt(t.severity),o={1:"Error",2:"Warning",3:"Information",4:"Hint"}[n]||"Unknown";t.severityStr=o,t.severity=o}e.range&&(this.adjustPositionLine(e.range,"start"),this.adjustPositionLine(e.range,"end"))}adjustPositionLine(e,t){let n=e[t];n&&typeof n.line=="number"&&(n.line=n.line+1)}registerDiagnosticTimeout(e,t){this.requestCallbacks.registerTimeout(e,t,r.DIAGNOSTIC_TIMEOUT_MS,()=>{let n=this.diagnosticMap.get(e),i=n?n.getMessages():[];this.finalizeDiagnostic(e,t,i,i.length>0?void 0:`received no diagnostics within ${r.DIAGNOSTIC_TIMEOUT_MS}ms from LSP, uri: ${e}`)})}finalizeDiagnostic(e,t,n,i){let o={uri:e,diagnostics:n,...i?{errorMessage:i}:{}};this.requestCallbacks.emit(e,t,o),this.diagnosticMap.get(e)?.clear()}getPendingDiagnosticUris(){return Array.from(this.diagnosticMap.keys()).filter(e=>this.requestCallbacks.hasCallback(e))}cleanupDiagnosticState(e){this.requestCallbacks.clear(e),this.diagnosticMap.delete(e)}};import Bg from"path";import*as au from"path";var tu=class{enableRecentlyUsed=!1;enableCompletionSortByType=!0;maxValidCompletionItemsCount=50;enableCompletionFunctionParameter=!1;enableIndexModuleRootDirEtsFile=!1};var ru=class{overriddenEnable=!0;overridingEnable=!0;implementedEnable=!0;implementingEnable=!0};var nu=class{tsVariablesEnable=!1;tsPropertyEnable=!1;tsParameterEnable=!1;tsReturnEnable=!1;etsVariablesEnable=!1;etsPropertyEnable=!1;etsParameterEnable=!1;etsReturnEnable=!1};var iu=class{etsParameterNameHintKind=null;tsParameterNameHintKind=null};var ou=class{typeSetting=new nu;parameterNames=new iu};var su=class{constructor(e,t,n,i){this.rootUri=e;this.lspServerWorkspacePath=he(au.dirname(t)),this.indexingDataLocation=he(i),this.loggerPath=he(au.join(n,"lspLog"))}modules=[];clientType="intellij";indexingDataLocation="";completionSortSetting=new tu;gutterIconsSetting=new ru;inlayHintsSetting=new ou;lspMaxOldSpaceSize="8192";projectType="OHOS";loggerPath="";lspServerWorkspacePath};import*as bC from"path";var Ha=class{productName="default";buildModeName="debug";targetName="default";arkTSVersion="1.1";resourceDirectories=[];targetESVersion="ES2021";maxFlowDepth=2e3;caseSensitiveCheck=!0;tsImportSendable=!1;compatibleSdkVersionStage="";useNormalizedOHMUrl=!0;reExportCheckMode="noCheck";skipOhModulesLint=!1;byteCodeHar=!0;obfuscationRuleOptionsEnable=!1;enableStrictCheckOHModules=!1;sourceRoots=[];constructor(e){e&&this.resourceDirectories.push(he(bC.join(e,"src","main","resources")))}};var UH="OS",Jo=class{deviceType=[5];aceLoaderPath;modulePath;jsComponentType="declarative";sdkJsPath;compatibleSdkVersion;compatibleSdkLevel;compileSdkLevel;compileSdkVersion="6.0.1.112";compileSdkType="Release";syscap={NDeviceSysCaps:[],addedSysCaps:[]};apiType="stageMode";hosSdkPath;runtimeOs=`Harmony${UH}`;moduleName;moduleType;compileMode="jsbundle";crossPlatform=!1;ignoreCrossPlatform=!1;packageManagerType="ohpm";permissions=[];testPermissions=[];buildProfileParam;appParam={bundleType:"app"};packageName;projectType="OHOS";projectName;moduleDependencies;moduleJsonParam=null;globalDeclarationFiles=[];constructor(e){e?(this.modulePath=e,this.buildProfileParam=new Ha(e)):this.buildProfileParam=new Ha}toString(){return JSON.stringify(this)}};var Ko=class{constructor(e=[]){this.pages=e}pagesFileName="main_pages.json";metaDataList=[]};import*as Ze from"path";import*as Zo from"fs";var cu=class{modulePath;dependencies={};dynamicDependencies={}};var xi=class{registryType;resolved;name;version;type;constructor(e){let t=typeof e=="object"&&e!==null?e:{};this.name=typeof t.name=="string"?t.name:"",this.version=typeof t.version=="string"?t.version:"",typeof t.registryType=="string"?this.registryType=t.registryType:this.registryType=typeof t.path=="string"?"local":"ohpm",typeof t.resolved=="string"?this.resolved=t.resolved:typeof t.storePath=="string"?this.resolved=t.storePath:this.resolved="",this.type=typeof t.type=="string"?t.type:void 0}};var Yo=class{constructor(e,t,n){this.projectPath=e;this.moduleName=t;this.modulePath=n}dependencies=[];devDependencies=[];dynamicDependencies=[];finalDependencies=[];finalDevDependencies=[];finalDynamicDependencies=[]};import*as Zr from"path";import*as lu from"fs";var Xo=class{name="";version="";storePath="";dependencyPath="";path=""};var G={HVIGOR_CACHE:".hvigor",DEPENDENCY:"dependencyMap",JSON5:".json5",KEY_DEPENDENCY:"dependencies",KEY_DYNAMIC_DEPENDENCY:"dynamicDependencies",KEY_DEV_DEPENDENCY:"devDependencies",OH_MODULES_PATH:"oh_modules",OHPM_PATH:".ohpm",LOCK_JSON5_FILE:"lock.json5",OH_PACKAGE_JSON5:Ce.OH_PACKAGE_JSON5},Ua=`${G.HVIGOR_CACHE}/${G.DEPENDENCY}`,Di=`${G.DEPENDENCY}${G.JSON5}`,Jde=Ce.SYNC_OUTPUT_PATH;var Ba=class r{dependencyPath;modulePath;projectPath;static FILE_DEPENDENCY_PREFIX="file:";static PARAMETER_PREFIX="@param:";fileSpecPattern;fileNameForOhpm=/[.](?:har|tgz|tar.gz|tar)$/;static PACKAGE_JSON_PARSER_MAP=new Map;dependencies=[];devDependencies=[];dynamicDependencies=[];static getInstance(e,t,n){let i=this.PACKAGE_JSON_PARSER_MAP.get(e);return i||(i=new r(e,t,n),this.PACKAGE_JSON_PARSER_MAP.set(e,i)),i}constructor(e,t,n){this.dependencyPath=e,this.modulePath=t,this.projectPath=n,this.fileSpecPattern=r.isWindows()?/^(?:[.]|~[/]|[/\\]|[a-zA-Z]:)/:/^(?:[.]|~[/]|[/]|[a-zA-Z]:)/}static isWindows(){return process.platform==="win32"}parseDependency(e){let t=Zr.join(this.dependencyPath,G.OH_PACKAGE_JSON5),n=yt(t);n&&(this.dependencies=this.getDependencyList(n,G.KEY_DEPENDENCY),this.devDependencies=this.getDependencyList(n,G.KEY_DEV_DEPENDENCY),this.dynamicDependencies=this.getDependencyList(n,G.KEY_DYNAMIC_DEPENDENCY),e.dependencies=this.dependencies,e.dynamicDependencies=this.devDependencies,e.devDependencies=this.dynamicDependencies)}getDependencyList(e,t){let n=[];if(!M(e))return n;let i=e[t];if(!M(i))return n;for(let[o,s]of Object.entries(i)){if(typeof s!="string"){m.error(`${o} package dependency value is not String ${t}`);continue}let a=new Xo;a.name=o;let c=s.replace(/\s/g,"");a.version=c,c.startsWith(r.PARAMETER_PREFIX)||this.parseDependencyPath(o,c,a,!1),n.push(a)}return n}parseDependencyPath(e,t,n,i){if(!(!e||!t))try{let o=Zr.normalize(Zr.join(this.modulePath,G.OH_MODULES_PATH,e));if(!(t.startsWith(r.FILE_DEPENDENCY_PREFIX)||this.fileSpecPattern.test(t))){n.dependencyPath=o;return}if(n.path=t,this.fileNameForOhpm.test(t)){n.dependencyPath=o;return}let s=t;if(t.startsWith(r.FILE_DEPENDENCY_PREFIX)&&(s=t.substring(r.FILE_DEPENDENCY_PREFIX.length)),Zr.isAbsolute(s)){n.dependencyPath=o;return}i||(o=Zr.resolve(this.modulePath,s)),lu.existsSync(o)&&lu.statSync(o).isDirectory()&&(n.dependencyPath=o)}catch(o){m.error("parser dependency path is invalid",o)}}};import*as Ii from"fs";import*as An from"path";import BH from"json5";var du=class r{projectPath;static FILE_DEPENDENCY_PREFIX="file:";static MAX_LOCK_FILE_SIZE=20*1024*1024;static MAX_KEYS_PER_OBJECT=5e4;static MAX_JSON_DEPTH=50;fileNameForOhpm=/[.](?:har|tgz|tar.gz|tar)$/;finalDependencies=[];finalDevDependencies=[];finalDynamicDependencies=[];storePathMap=new Map;lockFileCache=null;lockFileParsed=!1;constructor(e=""){this.projectPath=e}parseDependencies(e){if(!this.ensureLockFileParsed())return!1;let t=this.lockFileCache;return this.extractDependencies(t.modules,t.storePathMap,e),!0}ensureLockFileParsed(){if(this.lockFileParsed)return this.lockFileCache!==null;this.lockFileParsed=!0;let e=this.getLockFilePath(),t=this.readLockFile(e);if(!t)return!1;let n=this.validateLockFile(t);return n.valid?(this.lockFileCache={modules:n.modules,storePathMap:this.parseStorePathMap(n.packages)},!0):!1}getLockFilePath(){return An.join(this.projectPath,G.OH_MODULES_PATH,G.OHPM_PATH,G.LOCK_JSON5_FILE)}static checkObjectDepth(e,t,n=0){if(n>t)return!1;if(typeof e!="object"||e===null)return!0;if(Array.isArray(e)){for(let i of e)if(!r.checkObjectDepth(i,t,n+1))return!1;return!0}for(let i in e)if(Object.prototype.hasOwnProperty.call(e,i)&&!r.checkObjectDepth(e[i],t,n+1))return!1;return!0}readLockFile(e){if(!Ii.existsSync(e))return m.error("lock file does not exist"),this.clearDependencies(),null;try{let t=Ii.statSync(e);if(t.size>r.MAX_LOCK_FILE_SIZE)return m.error(`lock file is too large (${t.size} bytes), read aborted`),this.clearDependencies(),null}catch(t){return m.error(`Failed to stat lock file: ${t instanceof Error?t.message:String(t)}`),this.clearDependencies(),null}try{let t=Ii.readFileSync(e,"utf8"),n=BH.parse(t);return n?r.checkObjectDepth(n,r.MAX_JSON_DEPTH)?n:(m.error("lock.json5 nesting depth exceeds limit"),this.clearDependencies(),null):(m.error("lockFileJsonObject is null"),this.clearDependencies(),null)}catch(t){return m.error(`Error parsing lock.json5: ${t instanceof Error?t.message:String(t)}`),this.clearDependencies(),null}}validateLockFile(e){if(!M(e))return m.error("lockFileJsonObject is not a valid object"),this.clearDependencies(),{valid:!1};let t=e.modules;if(!t)return m.error("modulesJsonObject is null"),this.clearDependencies(),{valid:!1};let n=e.packages;return n?{valid:!0,modules:t,packages:n}:(m.error("packagesJsonObject is null"),this.clearDependencies(),{valid:!1})}extractDependencies(e,t,n){this.storePathMap=t,this.finalDependencies=this.getDependencyList(e,G.KEY_DEPENDENCY,n),this.finalDevDependencies=this.getDependencyList(e,G.KEY_DEV_DEPENDENCY,n),this.finalDynamicDependencies=this.getDependencyList(e,G.KEY_DYNAMIC_DEPENDENCY,n)}parseStorePathMap(e){let t=new Map;if(!M(e))return t;let n=0;for(let i in e){if(!Object.prototype.hasOwnProperty.call(e,i))continue;let o=e[i];if(!M(o)){m.error(`${i} value is not json object`);continue}if(++n>r.MAX_KEYS_PER_OBJECT){m.warn("lock.json5 packages object exceeds key limit, truncating");break}typeof o.storePath=="string"&&t.set(i,o.storePath)}return t}getDependencyList(e,t,n){if(!M(e))return[];let i=0;for(let o in e){if(!Object.prototype.hasOwnProperty.call(e,o))continue;if(++i>r.MAX_KEYS_PER_OBJECT){m.warn("lock.json5 modules object exceeds key limit, truncating");break}let s=e[o];if(M(s)){let a=typeof s.name=="string"?s.name:"";if(n==="."&&a===""||a===n)return this.getFinalDependencyList(e,t,o)}}return[]}getFinalDependencyList(e,t,n){let i=e[n];if(!M(i))return m.error("moduleJsonObject is null"),[];let o=[],s=i[t];if(!M(s))return[];let a=0;for(let c in s){if(!Object.prototype.hasOwnProperty.call(s,c))continue;if(++a>r.MAX_KEYS_PER_OBJECT){m.warn("lock.json5 dependencies object exceeds key limit, truncating");break}let l=s[c];if(!M(l))continue;let d=typeof l.specifier=="string"?l.specifier:"",g=typeof l.version=="string"?l.version:"",y=new Xo;y.name=c,y.version=g.startsWith(r.FILE_DEPENDENCY_PREFIX)?g.substring(r.FILE_DEPENDENCY_PREFIX.length):g,this.parseDependencyPath(y,n,c,d,g);let E=`${c}@${g}`;this.storePathMap.has(E)&&(y.storePath=this.storePathMap.get(E)||""),o.push(y)}return o}parseDependencyPath(e,t,n,i,o){let s=An.resolve(this.projectPath,An.join(t,G.OH_MODULES_PATH,n));try{let a=o.startsWith(r.FILE_DEPENDENCY_PREFIX)?o.substring(r.FILE_DEPENDENCY_PREFIX.length):o,c=An.isAbsolute(a)?a:An.resolve(this.projectPath,a);Ii.existsSync(c)?(e.path=i,e.dependencyPath=this.fileNameForOhpm.test(o)?s:c):e.dependencyPath=s}catch(a){m.error("Invalid dependency path in lock.json5, msg:",a instanceof Error?a.message:String(a))}}clearDependencies(){this.finalDependencies=[],this.finalDevDependencies=[],this.finalDynamicDependencies=[]}};function SC(r){return M(r)?typeof r.name=="string"&&typeof r.srcPath=="string":!1}var Ai=class{constructor(e,t){this.projectPath=e;this.sdkPath=t;this.moduleInfoParse=new _r(this.projectPath)}moduleInfoParse;lockJson5Parser=null;sdkPkgCache=void 0;buildProfileCache=void 0;getAllDependencyMap(e,t){let n=this.projectPath,i=Ze.join(n,Ua),o=Ze.join(i,Di);if(!Zo.existsSync(i)||!Zo.existsSync(o)){let l="Dependency map or JSON not found";return m.warn(`[Parser] getAllDependencyMap failed: ${l}.`),{status:"ERROR",message:`${l}, please rebuild project`}}let s=new Yo(this.projectPath,".",this.projectPath);this.parseProjectDependencies(i,s),this.parseLockJson(s);let a=this.moduleInfoParse.getAllModuleInfo();if(a.length===0){let l="No modules found in build-profile.json5";return m.warn(`[Parser] getAllDependencyMap failed: ${l}.`),{status:"ERROR",message:l}}let c=Date.now();for(let l=0;l<a.length;l++){let d=a[l];if(SC(d)){try{P.assertModuleName(d.name)}catch{m.warn(`[Parser] Skipping module with invalid name: ${d.name}`);continue}this.parseSingleModule(d,i,s,e),((l+1)%50===0||l+1===a.length)&&(m.info(`[Parser] getAllDependencyMap progress: ${l+1}/${a.length} (${Date.now()-c}ms)`),t?.(l+1,a.length))}}return m.info(`[Parser] getAllDependencyMap parsed ${e.length} modules in ${Date.now()-c}ms`),{status:"OK"}}getDependenciesOnly(e){let t=[],n=this.projectPath,i=Ze.join(n,Ua),o=Ze.join(i,Di);if(!Zo.existsSync(i)||!Zo.existsSync(o))return m.warn("[Parser] Dependency map or JSON not found."),t;let s=e&&e.length>0?new Set(e.map(l=>l.trim()).filter(Boolean)):null,a=new Yo(this.projectPath,".",this.projectPath);this.parseProjectDependencies(i,a),this.parseLockJson(a);let c=this.moduleInfoParse.getAllModuleInfo();if(c.length===0)return m.warn("[Parser] getAllDependencyMap failed: No modules found in build-profile.json5."),t;for(let l of c){if(!SC(l))continue;let d=l.name;try{P.assertModuleName(d)}catch{m.warn(`[Parser] Skipping module with invalid name: ${d}`);continue}if(s&&!s.has(d))continue;let g=Ze.resolve(this.projectPath,l.srcPath),y=Ze.join(i,d),E=he(g),K=this.buildModuleDependencies(d,E,y,a);K.moduleName=d,t.push(K)}return t}parseSingleModule(e,t,n,i){let o=e.name,s=Ze.resolve(this.projectPath,e.srcPath),a=Ze.join(t,o),c=he(s),l=new Jo(c),d=this.buildModuleDependencies(o,c,a,n);this.parseModuleJson5(c,l);let g=this.parseMainPages(c);this.parseSdkJson(l),this.parseCompatibleSdkVersion(l),l.moduleName=o,l.moduleType=o,l.packageName=o,l.moduleDependencies=d,l.moduleJsonParam=new Ko(g),i.push(l)}buildModuleDependencies(e,t,n,i){let o=new Yo(this.projectPath,e,t);Ba.getInstance(n,t,this.projectPath).parseDependency(o),this.parseLockJson(o),o.finalDependencies.push(...i.finalDependencies),o.finalDevDependencies.push(...i.finalDevDependencies),o.finalDynamicDependencies.push(...i.finalDynamicDependencies),o.finalDependencies.push(...o.finalDevDependencies);let a=new cu;return a.modulePath=t,this.toModuleDependencies(o,a),a}toModuleDependencies(e,t){let n={},i={};for(let o of e.finalDependencies)n[o.name]=new xi(o);for(let o of e.finalDynamicDependencies)i[o.name]=new xi(o);t.dependencies=n,t.dynamicDependencies=i}parseProjectDependencies(e,t){let n=Ze.join(e,G.OH_PACKAGE_JSON5);if(!Zo.existsSync(n))return;Ba.getInstance(e,this.projectPath,this.projectPath).parseDependency(t)}parseLockJson(e){let t=this.getLockJson5Parser();t.parseDependencies(e.moduleName)?(e.finalDependencies=t.finalDependencies,e.finalDevDependencies=t.finalDevDependencies,e.finalDynamicDependencies=t.finalDynamicDependencies):(e.finalDependencies=e.dependencies,e.finalDevDependencies=e.devDependencies,e.finalDynamicDependencies=e.dynamicDependencies)}getLockJson5Parser(){return this.lockJson5Parser||(this.lockJson5Parser=new du(this.projectPath)),this.lockJson5Parser}parseModuleJson5(e,t){let n=Ze.join(e,"src","main","module.json5"),i=yt(n);if(!M(i)||!M(i.module))return;let o=i.module;t.permissions=this.parseRequestPermissions(o),t.deviceType=this.parseDeviceTypes(o)}parseRequestPermissions(e){let t=[];if(M(e)&&Array.isArray(e.requestPermissions))for(let n of e.requestPermissions)M(n)&&typeof n.name=="string"&&t.push(n.name);return t}parseMainPages(e){let t=Ze.join(e,"src","main","resources","base","profile","main_pages.json"),n=yt(t);return!M(n)||!Array.isArray(n.src)?[]:n.src.filter(i=>typeof i=="string")}parseSdkJson(e){let t=this.getSdkPkg();if(!(!M(t)||!M(t.data))){if(typeof t.data.apiVersion=="string"){let n=parseInt(t.data.apiVersion,10);!Number.isNaN(n)&&n>=26&&typeof t.data.platformVersion=="string"?e.compileSdkLevel=t.data.platformVersion:e.compileSdkLevel=t.data.apiVersion}typeof t.data.releaseType=="string"&&(e.compileSdkType=t.data.releaseType),typeof t.data.version=="string"&&(e.compileSdkVersion=t.data.version)}}getSdkPkg(){if(this.sdkPkgCache===void 0){let e=Ze.join(this.sdkPath,"default","sdk-pkg.json");this.sdkPkgCache=yt(e)}return this.sdkPkgCache}parseCompatibleSdkVersion(e){let t=this.getBuildProfile();if(!M(t)||!M(t.app)||!Array.isArray(t.app.products)||t.app.products.length===0)return;let n=t.app.products[0];if(!M(n)||typeof n.compatibleSdkVersion!="string")return;let[i,o]=this.parseBySplit(n.compatibleSdkVersion);e.compatibleSdkVersion=i,e.compatibleSdkLevel=o}getBuildProfile(){if(this.buildProfileCache===void 0){let e=Ze.join(this.projectPath,"build-profile.json5");this.buildProfileCache=yt(e)}return this.buildProfileCache}parseBySplit(e){let t=e.indexOf("(");if(t===-1||!e.endsWith(")"))return[e,e];let n=e.substring(0,t),i=e.substring(t+1,e.length-1);return[n,i]}parseDeviceTypes(e){return!M(e)||!Array.isArray(e.deviceTypes)?[]:e.deviceTypes.filter(t=>typeof t=="string").map(t=>this.getDeviceType(t))}getDeviceType(e){return{liteWearable:1,wearable:2,tv:3,car:4,phone:5,default:5,smartVision:6,tablet:7,router:8,pc:9,"2in1":10}[e]||0}};var uu=class{constructor(e=[]){this.valueSet=e}};var Qo=class{refreshSupport=!0;tokenTypes=["namespace","type","class","enum","interface","struct","parameter","variable","property","function","method"];tokenModifiers=["declaration","definition","readonly","static","deprecated"]};var EC=(D=>(D[D.File=1]="File",D[D.Module=2]="Module",D[D.Namespace=3]="Namespace",D[D.Package=4]="Package",D[D.Class=5]="Class",D[D.Method=6]="Method",D[D.Property=7]="Property",D[D.Field=8]="Field",D[D.Constructor=9]="Constructor",D[D.Enum=10]="Enum",D[D.Interface=11]="Interface",D[D.Function=12]="Function",D[D.Variable=13]="Variable",D[D.Constant=14]="Constant",D[D.String=15]="String",D[D.Number=16]="Number",D[D.Boolean=17]="Boolean",D[D.Array=18]="Array",D[D.Object=19]="Object",D[D.Key=20]="Key",D[D.Null=21]="Null",D[D.EnumMember=22]="EnumMember",D[D.Struct=23]="Struct",D[D.Event=24]="Event",D[D.Operator=25]="Operator",D[D.TypeParameter=26]="TypeParameter",D))(EC||{}),PC=()=>Object.values(EC).filter(r=>typeof r=="number");var pu=class{documentChanges=null;resourceOperations=null;failureHanding=null;normalizesLineEndings=null;changeAnnotationSupport=null};var fu=class{applyEdit=!0;workspaceEdit=new pu;didChangeConfiguration=null;didChangeWatchedFiles={relativePatternSupport:{},dynamicRegistration:{}};symbol=new uu(PC());executeCommand={dynamicRegistration:{}};workspaceFolders=!1;configuration=!1;semanticTokens=new Qo;codeLens=null;fileOperations=null;inlayHint=null;diagnostics=null};var mu=class{willSave=!0;willSaveWaitUntil=!0;didSave=!0;dynamicRegistration=null};var gu=class{constructor(e=[]){this.valueSet=e}};var hu=class{snippetSupport=!0;commitCharactersSupport=null;documentationFormat=null;deprecateSupport=null;preselectSupport=null;tagSupport=null;insertReplaceSupport=null;resolveSupport=null;insertTextModeSupport=null;labelDetailsSupport=null};var CC=(A=>(A[A.Text=1]="Text",A[A.Method=2]="Method",A[A.Function=3]="Function",A[A.Constructor=4]="Constructor",A[A.Field=5]="Field",A[A.Variable=6]="Variable",A[A.Class=7]="Class",A[A.Interface=8]="Interface",A[A.Module=9]="Module",A[A.Property=10]="Property",A[A.Unit=11]="Unit",A[A.Value=12]="Value",A[A.Enum=13]="Enum",A[A.Keyword=14]="Keyword",A[A.Snippet=15]="Snippet",A[A.Color=16]="Color",A[A.File=17]="File",A[A.Reference=18]="Reference",A[A.Folder=19]="Folder",A[A.EnumMember=20]="EnumMember",A[A.Constant=21]="Constant",A[A.Struct=22]="Struct",A[A.Event=23]="Event",A[A.Operator=24]="Operator",A[A.TypeParameter=25]="TypeParameter",A))(CC||{}),kC=()=>Object.values(CC).filter(r=>typeof r=="number");var yu=class{completionItemKind=new gu(kC());completionItem=new hu;contextSupport=null;insertTextSupport=null;completionList=null;dynamicRegistration=null};var wu=class{synchronization=new mu;completion=new yu;hover={contentFormat:{},dynamicRegistration:{}};signatureHelp={signatureInformation:{},contextSupport:{},dynamicRegistration:{}};references={dynamicRegistration:{}};documentHighlight={dynamicRegistration:!0};documentSymbol=null;formatting={dynamicRegistration:{}};rangeFormatting={dynamicRegistration:{}};onTypeFormatting={dynamicRegistration:{}};declaration={};definition={linkSupport:{},dynamicRegistration:{}};codeLens=null;documentLink={tooltipSupport:{},dynamicRegistration:{}};colorProvider=null;rename={prepareSupport:!0,prepareSupportDefaultBehavior:null,honorsChangeAnnotations:null,dynamicRegistrationSupport:null};publishDiagnostics=null;foldingRage=null;typeHierarchy=null;callHierarchy={dynamicRegistration:{}};selectionRange=null;semanticTokens=new Qo;moniker=null;linkedEditingRange=null;inlayHint=null;inlineValue=null;diagnostic=null};var vu=class{workspace=new fu;textDocument=new wu;notebookDocument=null;window=null;general=null;experimental=null};var bu=class{constructor(e,t,n){this.rootUri=e;this.initializationOptions=t;this.capabilities=n}};var Su=class{constructor(e,t,n,i,o,s=!0,a,c=!1){this.sdkPath=e;this.rootUri=n;this.nodeMaxOldSpaceSize=o;this.useStandardProtocol=s;this.nodePath=a;this.useSocket=c;this.serverPath=Hi(t,this.useStandardProtocol),this.logPath=Vw(),this.indexLogPath=i||this.logPath,m.debug(`[LspServerProxy] arktsLangServer=${t}`),m.debug(`[LspServerProxy] useStandardProtocol=${this.useStandardProtocol}, useSocket=${this.useSocket}`),m.debug(`[LspServerProxy] serverPath=${this.serverPath}`);let l={serverPath:this.serverPath,logPath:this.logPath,indexingDataLocation:this.indexLogPath,projectPath:this.rootUri,useSocket:this.useSocket,nodePath:this.nodePath};this.messageHandle=this.useStandardProtocol?new Zd(l):new eu(l),this.messageHandle.setBroadcastToClients(d=>this.onLspMessage(d))}messageHandle;get stdHandle(){return this.messageHandle}get legacyHandle(){return this.messageHandle}get lspPid(){return this.messageHandle.lspPid}onAsyncOpenFile(e){this.legacyHandle.onAsyncOpenFile(e)}closeFileLegacy(e,t){this.legacyHandle.closeFile(e,t)}serverPath;logPath;lastStartErrorMessage=null;currentParams=null;indexLogPath;lastDepsOnlyForDiff=[];get currentModuleModels(){return this.currentParams?.initializationOptions?.modules??[]}async start(e,t,n){let i=!1;try{m.debug(`serverPath: ${this.serverPath}`),m.debug(`rootUri: ${this.rootUri}`),m.debug(`sdkPath: ${this.sdkPath}`),m.debug(`logPath: ${this.logPath}`);let o=Wt(this.rootUri),s=new su(o,this.serverPath,this.logPath,this.indexLogPath),a=[],l=new Ai(this.rootUri,this.sdkPath).getAllDependencyMap(a,n);if(l.status==="ERROR")throw new Error(`${l.message}`);this.fillModuleModelsPaths(a),s.modules=a;let d=rl(a.length,this.nodeMaxOldSpaceSize);await this.messageHandle.start(d),this.currentParams=new bu(o,s,new vu),this.useStandardProtocol?await this.startStandardProtocol(this.currentParams):await this.startLegacy(this.currentParams,e),i=!0}catch(o){this.lastStartErrorMessage=o instanceof Error?o.message:String(o),m.error(`[LSP] Initialization failed: ${this.lastStartErrorMessage}`),await this.messageHandle.stop()}t?.(i)}async startStandardProtocol(e){let t=this.messageHandle,n=()=>t.broadcastToClients({jsonrpc:L,method:b.ARKTS_INDEXING_PROGRESS,params:{}});this.useSocket?(m.info("[LSP] socket mode: waiting for initialize response + aceProject/onModuleInitFinish"),await t.sendInitializeAndWaitForNotification(e,io.MODULE_INIT_FINISH,ot,()=>{m.info("[LSP] initialize response received"),n(),t.sendInitialized()},n),m.info("[LSP] initialize response + onModuleInitFinish received, initialization complete")):(await t.sendInitializeResettable(e,ot),m.info("[LSP] initialize response received"),n(),t.sendInitialized())}async startLegacy(e,t){let n=this.messageHandle;n.sendInitialize(e,1),n.onIndexingProgressUpdate(()=>{this.onLspMessage({jsonrpc:L,method:b.ARKTS_INDEXING_PROGRESS,params:{}})}),await this.withResettableTimeout((i,o)=>{n.onIndexingProgressUpdate(o),n.onInitializationCompleted(i)},"LSP initialization",ot),n.sendInitialized(t)}withResettableTimeout(e,t,n){return new Promise((i,o)=>{let s,a=()=>{s=setTimeout(()=>{o(new Error(`${t} timeout after ${n}ms`))},n)},c=()=>{clearTimeout(s),a()};a(),e(()=>{clearTimeout(s),i()},c)})}consumeStartErrorMessage(){let e=this.lastStartErrorMessage;return this.lastStartErrorMessage=null,e}onLspMessage=()=>{};setOnMessage(e){this.onLspMessage=e}registerDiagnosticCallback(e){m.debug(`[LSP] registerDiagnosticCallback uri='${e}', useStandardProtocol=${this.useStandardProtocol}`),this.messageHandle.registerRequestCallback(e,(t,n)=>{let i=M(n)?n:{};m.debug(`[LSP] onDiagnosticCompleted called, uri: ${e}`);let o={jsonrpc:L,method:t,params:{uri:typeof i.uri=="string"?i.uri:e,diagnostics:Array.isArray(i.diagnostics)?i.diagnostics:[],...typeof i.errorMessage=="string"?{errorMessage:i.errorMessage}:{}}};this.onLspMessage(o)})}async hover(e){let t=e.textDocument.uri;return this.registerDiagnosticCallback(t),this.stdHandle.sendLspRequest(b.HOVER,e)}async definition(e){return this.stdHandle.sendLspRequest(b.DEFINITION,e)}async references(e){return this.stdHandle.sendLspRequest(b.REFERENCES,e)}async completion(e){return this.stdHandle.sendLspRequest(b.COMPLETION,e)}async documentSymbol(e){return this.stdHandle.sendLspRequest(b.DOCUMENT_SYMBOL,e)}async diagnostic(e){return this.stdHandle.sendLspRequest(b.DIAGNOSTIC,e,120*1e3)}async sendFeatureRequest(e,t){return this.stdHandle.sendLspRequest(e,t)}reloadDependenciesOnly(e){let t=e?.fullReload??!1,n=new Ai(this.rootUri,this.sdkPath),i=this.getModuleModelsByName();if(t){m.info("[LspServerProxy] Project-level oh-package changed, parsing all modules' dependencies");let l=n.getDependenciesOnly();this.markDependencyTypesIncremental(l);let d=this.mergeDepsOnlyIntoModuleList(l,i);return this.applyModuleModelsUpdate(d),this.sendDidChangeConfiguration({moduleSet:d}),m.info(`[LspServerProxy] Dependencies only (all) reloaded, count: ${d.length}`),this.lastDepsOnlyForDiff=l,l}let o=e?.changedModules??[],s=new Set(e?.removedModuleNames??[]);if(o.length===0&&s.size===0)return m.info("[LspServerProxy] No changed/removed modules, skip dependency reload"),[];m.info(`[LspServerProxy] Module-level deps changed, parsing: [${o.join(", ")}]`);let a=n.getDependenciesOnly(o);this.markDependencyTypesIncremental(a);let c=this.mergeIncrementalDeps(this.currentModuleModels,s,a);return this.applyModuleModelsUpdate(c),this.sendDidChangeConfiguration({moduleSet:c}),m.info(`[LspServerProxy] Dependencies only (incremental) reloaded, count: ${c.length}`),this.lastDepsOnlyForDiff=a,a}sendDidChangeConfiguration(e){this.stdHandle.sendDidChangeConfiguration(e)}getModuleModelsByName(){return new Map(this.currentModuleModels.map(e=>[e.moduleName??"",e]))}markDependencyTypesIncremental(e){let t=this.getModuleModelsByName(),n=new Map(this.lastDepsOnlyForDiff.map(i=>[i.moduleName??"",i]));for(let i of e){let o=i.moduleName??"",{oldDeps:s,oldDynamic:a}=this.getOldDepsForModule(o,t,n),c=i.dependencies??{},l=i.dynamicDependencies??{};this.markAddAndDeleteInDeps(s,c,(d,g)=>{(i.dependencies??={})[d]=this.makeDeleteEntry(d,g)}),this.markAddAndDeleteInDeps(a,l,(d,g)=>{(i.dynamicDependencies??={})[d]=this.makeDeleteEntry(d,g)})}}getOldDepsForModule(e,t,n){let i=t.get(e),o=i?.moduleDependencies?.dependencies??{},s=i?.moduleDependencies?.dynamicDependencies??{};if(Object.keys(o).length===0&&Object.keys(s).length===0){let a=n.get(e);a&&(o=a.dependencies??{},s=a.dynamicDependencies??{})}return{oldDeps:o,oldDynamic:s}}markAddAndDeleteInDeps(e,t,n){for(let i of Object.keys(t))i in e||(t[i].type="add");for(let i of Object.keys(e))i in t||n(i,e[i])}makeDeleteEntry(e,t){return new xi({name:e,version:t?.version??"",registryType:t?.registryType??"ohpm",resolved:t?.resolved??"",type:"delete"})}createMinimalModelFromDepsItem(e){let t=new Jo(e.modulePath);return t.moduleName=e.moduleName,t.moduleType=e.moduleName,t.packageName=e.moduleName,t.moduleJsonParam=new Ko([]),t.modulePath=e.modulePath,t.moduleDependencies=e,t}mergeDepsOnlyIntoModuleList(e,t){let n=[];for(let i of e){let o=i.moduleName??"",s=t.get(o);s?(s.modulePath=i.modulePath,s.moduleDependencies=i):s=this.createMinimalModelFromDepsItem(i),n.push(s)}return n}mergeIncrementalDeps(e,t,n){let i=new Map(n.map(s=>[s.moduleName??"",s])),o=[];for(let s of e){let a=s.moduleName??"";if(t.has(a))continue;let c=i.get(a);c&&(s.modulePath=c.modulePath,s.moduleDependencies=c,i.delete(a)),o.push(s)}for(let[,s]of i)o.push(this.createMinimalModelFromDepsItem(s));return o}applyModuleModelsUpdate(e){this.fillModuleModelsPaths(e),this.currentParams&&(this.currentParams.initializationOptions.modules=e)}fillModuleModelsPaths(e){let t=this.sdkPath,n=so(Bg.join(t,"default/openharmony/ets/build-tools/ets-loader")),i=so(Bg.join(t,"default/openharmony/ets/api")),o=so(Bg.join(t,"default/hms"));for(let s of e)s.aceLoaderPath=n,s.sdkJsPath=i,s.hosSdkPath=o}sendRequest(e){switch(e.method){case b.HOVER:this.stdHandle.sendLspRequest(b.HOVER,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;case b.DEFINITION:this.stdHandle.sendLspRequest(b.DEFINITION,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;case b.REFERENCES:this.stdHandle.sendLspRequest(b.REFERENCES,e.params).then(t=>this.onLspMessage({jsonrpc:L,id:e.id,result:t}),t=>this.onLspMessage({jsonrpc:L,id:e.id,error:{code:-32603,message:t.message}}));break;default:m.warn(`Unhandled LSP request: ${e.method}`)}}sendNotification(e){if(!fC(e)){m.info("LspServerProxy, msg is not notification request, ignore.");return}switch(e.method){case b.DID_OPEN:this.handleDidOpenNotification(e);break;case b.DID_CHANGE:this.handleDidChangeNotification(e);break;case b.DID_CLOSE:this.handleDidCloseNotification(e);break;case b.WORKSPACE_DID_CHANGE_WATCHED_FILES:this.handleDidChangeWatchedFiles(e);break;case b.DID_CREATE_FILES:this.handleDidCreateFiles(e);break;case b.DID_DELETE_FILES:this.handleDidDeleteFiles(e);break;default:m.warn(`Unhandled LSP notification: ${e.method}`)}}handleDidOpenNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){m.error("Invalid textDocument/didOpen params");return}this.stdHandle.sendDidOpen(t)}handleDidChangeNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){m.error("Invalid textDocument/didChange params");return}this.stdHandle.sendDidChange(t)}handleDidCloseNotification(e){let t=e.params;if(!t||!t.textDocument||typeof t.textDocument.uri!="string"){m.error("Invalid textDocument/didClose params");return}this.stdHandle.closeFile(t)}handleDidChangeWatchedFiles(e){let t=e.params;!t||!Array.isArray(t.changes)||this.messageHandle.onDidChangeWatchedFiles(t.changes)}handleDidCreateFiles(e){let t=e.params;!t||!Array.isArray(t.files)||this.stdHandle.sendNotification(b.DID_CREATE_FILES,t)}handleDidDeleteFiles(e){let t=e.params;!t||!Array.isArray(t.files)||this.stdHandle.sendNotification(b.DID_DELETE_FILES,t)}async dispose(){await this.messageHandle.stop()}};import*as Qr from"fs";import*as lt from"path";import{createHash as VH}from"crypto";import{EventEmitter as GH}from"events";var Eu=class extends GH{constructor(t,n=500){super();this.projectRoot=t;this.debounceMs=n}watchers=new Map;debounceTimers=new Map;contentHashes=new Map;buildProfileWatcher=null;lastModulesSnapshot="";lastModules=[];debounceMs;start(){let t=this.parseModulesFromBuildProfile();this.lastModules=t,this.lastModulesSnapshot=this.computeModulesSnapshot(t),this.refreshWatchTargets(),this.watchBuildProfile()}refreshWatchTargets(){let t=new Set(this.collectWatchTargets()),n=new Set(this.watchers.keys());for(let i of t)n.has(i)||this.watchFile(i);for(let i of n)t.has(i)||(this.unwatchFile(i),m.info(`[ConfigFileWatcher] Stopped watching: ${i}`));m.info(`[ConfigFileWatcher] Watching ${this.watchers.size} oh-package.json5 file(s)`)}watchBuildProfile(){let t=this.getBuildProfilePath();if(!Qr.existsSync(t)){m.warn(`[ConfigFileWatcher] build-profile.json5 not found at ${t}, cannot watch for module changes`);return}try{this.buildProfileWatcher=Qr.watch(t,n=>{n==="change"&&this.onBuildProfileChanged()}),this.buildProfileWatcher.on("error",n=>{m.error(`[ConfigFileWatcher] build-profile.json5 watch error: ${n.message}`)}),m.info(`[ConfigFileWatcher] Watching module registry: ${t}`)}catch(n){m.error(`[ConfigFileWatcher] Failed to watch build-profile.json5: ${n instanceof Error?n.message:String(n)}`)}}emitModuleAddedEvents(t,n){for(let i of t){let o=lt.resolve(this.projectRoot,i.srcPath);this.emit("configChanged",{source:"buildProfile",kind:1,filePath:o,relativePath:i.srcPath,timestamp:n,moduleName:i.name})}}emitModuleRemovedEvents(t,n){for(let i of t){let o=lt.resolve(this.projectRoot,i.srcPath);this.emit("configChanged",{source:"buildProfile",kind:2,filePath:o,relativePath:i.srcPath,timestamp:n,removedModuleName:i.name})}}emitModuleRenamedEvents(t,n){for(let i of t){let o=lt.resolve(this.projectRoot,i.after.srcPath);this.emit("configChanged",{source:"buildProfile",kind:3,filePath:o,relativePath:i.after.srcPath,timestamp:n,moduleName:i.after.name,removedModuleName:i.before.name})}}emitModuleMovedEvents(t,n){for(let i of t){let o=lt.resolve(this.projectRoot,i.after.srcPath);this.emit("configChanged",{source:"buildProfile",kind:6,filePath:o,relativePath:i.after.srcPath,timestamp:n,moduleName:i.after.name})}}processBuildProfileDiff(t){this.refreshWatchTargets();let n=Date.now();this.emitModuleAddedEvents(t.added,n),this.emitModuleRemovedEvents(t.removed,n),this.emitModuleRenamedEvents(t.renamed,n),this.emitModuleMovedEvents(t.moved,n)}onBuildProfileChanged(){let t="__build_profile__",n=this.debounceTimers.get(t);n&&clearTimeout(n);let i=setTimeout(()=>{this.debounceTimers.delete(t);let o=this.parseModulesFromBuildProfile(),s=this.computeModulesSnapshot(o);if(s===this.lastModulesSnapshot){m.info("[ConfigFileWatcher] build-profile.json5 changed but modules unchanged, skipping");return}let a=this.diffModules(this.lastModules,o);this.lastModules=o,this.lastModulesSnapshot=s,m.info(`[ConfigFileWatcher] build-profile.json5 modules changed, added=${a.added.length}, removed=${a.removed.length}, renamed=${a.renamed.length}, moved=${a.moved.length}`),this.processBuildProfileDiff(a)},this.debounceMs);this.debounceTimers.set(t,i)}computeModulesSnapshot(t){return t.map(i=>`${i.name}::${i.srcPath}`).sort().join("|")}diffModules(t,n){let i=this.buildModuleMatchState(n),o={added:[],removed:[],renamed:[],moved:[]};return this.matchExactModules(t,i),this.matchRenamedModules(t,i,o),this.matchMovedModules(t,i,o),this.collectRemovedModules(t,i,o),this.collectAddedModules(n,i,o),o}buildModuleMatchState(t){let n=new Map,i=new Map;for(let o of t)n.set(o.srcPath,o),i.set(o.name,o);return{matchedOld:new Set,matchedNew:new Set,newBySrc:n,newByName:i}}matchExactModules(t,n){for(let i of t){let o=n.newBySrc.get(i.srcPath);o&&o.name===i.name&&(n.matchedOld.add(i),n.matchedNew.add(o))}}matchRenamedModules(t,n,i){for(let o of t){if(n.matchedOld.has(o))continue;let s=n.newBySrc.get(o.srcPath);s&&!n.matchedNew.has(s)&&s.name!==o.name&&(i.renamed.push({before:o,after:s}),n.matchedOld.add(o),n.matchedNew.add(s))}}matchMovedModules(t,n,i){for(let o of t){if(n.matchedOld.has(o))continue;let s=n.newByName.get(o.name);s&&!n.matchedNew.has(s)&&s.srcPath!==o.srcPath&&(i.moved.push({before:o,after:s}),n.matchedOld.add(o),n.matchedNew.add(s))}}collectRemovedModules(t,n,i){for(let o of t)n.matchedOld.has(o)||i.removed.push(o)}collectAddedModules(t,n,i){for(let o of t)n.matchedNew.has(o)||i.added.push(o)}parseModulesFromBuildProfile(){let t=this.getBuildProfilePath();try{let n=yt(t);if(typeof n!="object"||n===null)return[];let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):[]}catch(n){return m.warn(`[ConfigFileWatcher] Failed to parse build-profile.json5: ${n instanceof Error?n.message:String(n)}`),[]}}collectWatchTargets(){let t=[],n=lt.join(this.projectRoot,G.OH_PACKAGE_JSON5);Qr.existsSync(n)&&t.push(n);let i=this.parseModulesFromBuildProfile();for(let o of i){let s=lt.resolve(this.projectRoot,o.srcPath),a=lt.join(s,G.OH_PACKAGE_JSON5);Qr.existsSync(a)&&t.push(a)}return t}getBuildProfilePath(){return lt.join(this.projectRoot,"build-profile.json5")}computeFileHash(t){try{let n=Qr.readFileSync(t,"utf-8");return VH("sha256").update(n).digest("hex")}catch{return null}}watchFile(t){if(!this.watchers.has(t))try{let n=this.computeFileHash(t);n&&this.contentHashes.set(t,n);let i=Qr.watch(t,o=>{o==="change"&&this.onFileChanged(t)});i.on("error",o=>{m.error(`[ConfigFileWatcher] Watch error for ${t}: ${o.message}`)}),this.watchers.set(t,i)}catch(n){m.error(`[ConfigFileWatcher] Failed to watch ${t}: ${n instanceof Error?n.message:String(n)}`)}}unwatchFile(t){let n=this.watchers.get(t);n&&(n.close(),this.watchers.delete(t)),this.contentHashes.delete(t);let i=this.debounceTimers.get(t);i&&(clearTimeout(i),this.debounceTimers.delete(t))}onFileChanged(t){let n=this.debounceTimers.get(t);n&&clearTimeout(n);let i=setTimeout(()=>{this.debounceTimers.delete(t);let o=this.computeFileHash(t);if(!o){m.warn(`[ConfigFileWatcher] Could not read file for hash: ${t}`);return}if(this.contentHashes.get(t)===o){m.info(`[ConfigFileWatcher] File touched but content unchanged, skipping: ${t}`);return}this.contentHashes.set(t,o),m.info(`[ConfigFileWatcher] Config file content changed: ${t}`);let a={source:"ohPackage",kind:4,filePath:t,fileName:lt.basename(t),relativePath:lt.relative(this.projectRoot,t),timestamp:Date.now()};this.emit("configChanged",a)},this.debounceMs);this.debounceTimers.set(t,i)}stop(){for(let[,t]of this.watchers)t.close();this.watchers.clear(),this.buildProfileWatcher&&(this.buildProfileWatcher.close(),this.buildProfileWatcher=null);for(let t of this.debounceTimers.values())clearTimeout(t);this.debounceTimers.clear(),this.contentHashes.clear(),m.info("[ConfigFileWatcher] All watchers stopped")}};import*as Tn from"fs";import*as tr from"path";import{createHash as qH}from"crypto";import{EventEmitter as zH}from"events";var Pu=class extends zH{constructor(t,n=500){super();this.projectRoot=t;this.debounceMs=n,this.coalesceMs=n+300,this.depMapDir=tr.join(t,Ua)}dirWatcher=null;contentHashes=new Map;lastModules=[];debounceMs;depMapDir;pendingTags=[];pendingRenames=[];coalesceTimer=null;coalesceMs;fullScanTimer=null;pollInterval=null;initialScanDone=!1;start(){if(!Tn.existsSync(this.depMapDir)){m.warn(`[DependencyMapWatcher] dependencyMap dir not found: ${this.depMapDir}, skip watching`);return}this.lastModules=this.parseModulesFromDepMap();try{this.dirWatcher=Tn.watch(this.depMapDir,{recursive:!0},(t,n)=>this.onDirEvent(t,n)),this.dirWatcher.on("error",t=>{m.error(`[DependencyMapWatcher] Directory watch error for ${this.depMapDir}: ${t.message}`)})}catch(t){m.error(`[DependencyMapWatcher] Failed to watch directory ${this.depMapDir}: ${t instanceof Error?t.message:String(t)}`);return}this.pollInterval=setInterval(()=>this.scanAllCacheFiles(),2500),m.info(`[DependencyMapWatcher] Started, watching directory (recursive): ${this.depMapDir}, modules: [${this.lastModules.map(t=>t.name).join(", ")}]`)}canonicalPath(t){return he(tr.resolve(t))}onDirEvent(t,n){if(!n||typeof n!="string")return;let i=n.replace(/\\/g,"/"),o;if(i===G.OH_PACKAGE_JSON5)o="root-oh-package";else if(i===Di)o="dep-map-json";else{let a=i.match(/^([^/]+)\/oh-package\.json5$/);o=a?`module:${a[1]}`:""}if(!o)return;let s=tr.join(this.depMapDir,n);Tn.existsSync(s)&&this.scheduleDebouncedFullScan()}stop(){this.dirWatcher&&(this.dirWatcher.close(),this.dirWatcher=null),this.fullScanTimer&&(clearTimeout(this.fullScanTimer),this.fullScanTimer=null),this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=null),this.coalesceTimer&&(clearTimeout(this.coalesceTimer),this.coalesceTimer=null),this.pendingTags=[],this.pendingRenames=[],this.contentHashes.clear(),this.initialScanDone=!1,m.info("[DependencyMapWatcher] All watchers stopped")}scheduleDebouncedFullScan(){this.fullScanTimer&&clearTimeout(this.fullScanTimer),this.fullScanTimer=setTimeout(()=>{this.fullScanTimer=null,this.scanAllCacheFiles()},this.debounceMs)}scanAllCacheFiles(){let t=tr.join(this.depMapDir,G.OH_PACKAGE_JSON5),n=tr.join(this.depMapDir,Di),i=this.parseModulesFromDepMap(),o=[{path:t,tag:"root-oh-package"},{path:n,tag:"dep-map-json"},...i.map(s=>({path:(P.assertModuleName(s.name),tr.join(this.depMapDir,s.name,G.OH_PACKAGE_JSON5)),tag:`module:${s.name}`}))];for(let{path:s,tag:a}of o){if(!Tn.existsSync(s))continue;let c=this.canonicalPath(s),l=this.computeFileHash(s);if(!l)continue;let d=this.contentHashes.get(c);if(!this.initialScanDone){this.contentHashes.set(c,l);continue}d!==l&&(this.contentHashes.set(c,l),m.info(`[DependencyMapWatcher] Cache file changed: ${s} (tag=${a})`),this.scheduleCoalescedReload(a))}this.initialScanDone||(this.initialScanDone=!0)}parseModulesFromDepMap(){let t=tr.join(this.depMapDir,Di);try{let n=yt(t);if(typeof n!="object"||n===null)return[];let i=n.modules;return Array.isArray(i)?i.filter(o=>{if(typeof o!="object"||o===null)return!1;let s=o;return typeof s.name=="string"&&typeof s.srcPath=="string"}):[]}catch(n){return m.warn(`[DependencyMapWatcher] Failed to parse dependencyMap.json5: ${n instanceof Error?n.message:String(n)}`),[]}}scheduleCoalescedReload(t){this.pendingTags.push(t),t==="dep-map-json"&&this.applyDepMapJsonDiff(),this.coalesceTimer&&clearTimeout(this.coalesceTimer),this.coalesceTimer=setTimeout(()=>{this.coalesceTimer=null,this.flushPendingReload()},this.coalesceMs)}collectPendingState(){let t=this.pendingTags,n=this.pendingRenames;return this.pendingTags=[],this.pendingRenames=[],{tags:t,renameEntries:n}}processTagsIntoSets(t,n,i,o){for(let s of t)s.startsWith("module:")?(i.add(s.substring(7)),n.add("moduleDepsChanged")):s.startsWith("dep-added:")?(i.add(s.substring(10)),n.add("moduleAdded")):s.startsWith("dep-removed:")&&(o.add(s.substring(12)),n.add("moduleRemoved"))}processRenameEntries(t,n,i,o,s){for(let a of t)s.push(a.info),i.add(a.info.newName),o.add(a.info.oldName),n.add(a.kind)}buildAddedNamesSet(t,n){let i=new Set;for(let o of t)o.startsWith("dep-added:")&&i.add(o.substring(10));for(let o of n)i.add(o.info.newName);return i}emitIncrementalReload(t,n,i,o,s){m.info(`[DependencyMapWatcher] Coalesced \u2192 kinds=[${[...t].join(",")}], changed=[${[...n].join(",")}], removed=[${[...i].join(",")}], added=[${[...o].join(",")}], renames=[${s.map(a=>`${a.oldName}\u2192${a.newName}`).join(",")}]`),this.emit("reload",{fullReload:!1,kinds:[...t],changedModules:[...n],removedModuleNames:[...i],addedModuleNames:[...o],renames:s.length>0?s:void 0})}flushPendingReload(){let{tags:t,renameEntries:n}=this.collectPendingState();if(t.length===0&&n.length===0)return;if(m.info(`[DependencyMapWatcher] Flushing coalesced reload, tags=[${t.join(", ")}], renames=${n.length}`),t.includes("root-oh-package")){m.info("[DependencyMapWatcher] Root oh-package.json5 in batch \u2192 full reload"),this.emit("reload",{fullReload:!0,kinds:["projectDepsChanged"]});return}let i=new Set,o=new Set,s=new Set,a=[];this.processTagsIntoSets(t,i,o,s),this.processRenameEntries(n,i,o,s,a);for(let l of o)s.delete(l);if(o.size===0&&s.size===0&&a.length===0){m.info("[DependencyMapWatcher] Coalesced batch has no effective changes, skipping");return}let c=this.buildAddedNamesSet(t,n);this.emitIncrementalReload(i,o,s,c,a)}normalizeSrcPath(t){return he(t).replace(/^\.\//,"").replace(/\/$/,"")}buildModuleLookupMaps(t){let n=new Map(t.map(o=>[o.name,o])),i=new Map(t.map(o=>[this.normalizeSrcPath(o.srcPath),o]));return{byName:n,bySrcPath:i}}detectModuleRenames(t,n,i,o){for(let[s,a]of t){let c=n.get(s);if(!c||c.name===a.name)continue;this.pendingRenames.push({kind:"moduleRenamed",info:{oldName:a.name,newName:c.name,oldSrcPath:a.srcPath,newSrcPath:c.srcPath,kind:"moduleRenamed"}}),i.add(a.name),o.add(c.name);let l=(P.assertModuleName(a.name),tr.join(this.depMapDir,a.name,G.OH_PACKAGE_JSON5));this.contentHashes.delete(this.canonicalPath(l)),m.info(`[DependencyMapWatcher] Module renamed: ${a.name} \u2192 ${c.name} (srcPath=${s})`)}}detectModuleMoves(t,n,i,o){for(let[s,a]of t){if(i.has(s))continue;let c=n.get(s);!c||c.srcPath===a.srcPath||(this.pendingRenames.push({kind:"moduleMoved",info:{oldName:a.name,newName:c.name,oldSrcPath:a.srcPath,newSrcPath:c.srcPath,kind:"moduleMoved"}}),i.add(s),o.add(s),m.info(`[DependencyMapWatcher] Module moved: ${s} srcPath ${a.srcPath} \u2192 ${c.srcPath}`))}}detectAddedModules(t,n,i){for(let[o]of t)i.has(o)||n.has(o)||(this.pendingTags.push(`dep-added:${o}`),i.add(o))}detectRemovedModules(t,n,i){for(let[o]of t)if(!i.has(o)&&!n.has(o)){this.pendingTags.push(`dep-removed:${o}`),i.add(o);let s=(P.assertModuleName(o),tr.join(this.depMapDir,o,G.OH_PACKAGE_JSON5));this.contentHashes.delete(this.canonicalPath(s))}}logDepMapDiffResult(){let t=this.pendingTags.filter(i=>i.startsWith("dep-")),n=this.pendingRenames.map(i=>`${i.kind}(${i.info.oldName}\u2192${i.info.newName})`);m.info(`[DependencyMapWatcher] dependencyMap.json5 diff complete, depTags: [${t.join(", ")}], renames: [${n.join(", ")}]`)}applyDepMapJsonDiff(){let t=this.parseModulesFromDepMap(),{byName:n,bySrcPath:i}=this.buildModuleLookupMaps(this.lastModules),{byName:o,bySrcPath:s}=this.buildModuleLookupMaps(t),a=new Set,c=new Set;this.detectModuleRenames(i,s,a,c),this.detectModuleMoves(n,o,a,c),this.detectAddedModules(o,n,c),this.detectRemovedModules(n,o,a),this.lastModules=t,this.logDepMapDiffResult()}computeFileHash(t){try{let n=Tn.readFileSync(t,"utf-8");return qH("sha256").update(n).digest("hex")}catch{return null}}};import*as Rr from"fs";import*as Cu from"path";import{EventEmitter as JH}from"events";var Wg={Created:1,Changed:2,Deleted:3},KH=new Set(["oh_modules","node_modules","build",".hvigor",".git",".idea",".cxx",".preview"]);function YH(r){let e=r.replace(/\\/g,"/");return e.endsWith("/ets")&&e.includes("/src/")}var ku=class extends JH{projectRoot;debounceMs;pollMs;sourceDirs=[];watchers=new Map;snapshot=new Map;debounceTimer=null;pollInterval=null;initialScanDone=!1;constructor(e,t=500,n=1e4){super(),this.projectRoot=e,this.debounceMs=t,this.pollMs=n}start(){if(this.sourceDirs=this.discoverSourceDirs(),this.sourceDirs.length===0){m.warn("[SourceFileWatcher] No src/main/ets dir found, skip watching");return}this.refreshSnapshot(),this.initialScanDone=!0;for(let e of this.sourceDirs)this.addSourceDirWatcher(e);this.pollInterval=setInterval(()=>this.scanAndEmit(),this.pollMs),m.info(`[SourceFileWatcher] Started, watching ${this.sourceDirs.length} source dir(s), ${this.snapshot.size} ets file(s)`)}stop(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.pollInterval&&(clearInterval(this.pollInterval),this.pollInterval=null);for(let[,e]of this.watchers)e.close();this.watchers.clear(),this.snapshot.clear(),this.initialScanDone=!1,m.info("[SourceFileWatcher] Stopped")}addSourceDirWatcher(e){if(!this.watchers.has(e))try{let t=Rr.watch(e,{recursive:!0},(n,i)=>this.onFsEvent(i));t.on("error",n=>{m.error(`[SourceFileWatcher] watch error for ${e}: ${n.message}`)}),this.watchers.set(e,t)}catch(t){m.error(`[SourceFileWatcher] Failed to watch ${e}: ${t instanceof Error?t.message:String(t)}`)}}refreshSourceDirs(){if(!this.initialScanDone)return;let e=this.discoverSourceDirs(),t=new Set(this.sourceDirs),n=new Set(e),i=e.filter(s=>!t.has(s)),o=[...t].filter(s=>!n.has(s));if(!(i.length===0&&o.length===0)){for(let s of i)this.addSourceDirWatcher(s);for(let s of o){let a=this.watchers.get(s);a&&(a.close(),this.watchers.delete(s))}this.sourceDirs=e,this.refreshSnapshot(),m.info(`[SourceFileWatcher] Module dirs changed: +${i.length} -${o.length}, now ${this.sourceDirs.length} source dir(s)`)}}discoverSourceDirs(){let e=[];return this.collectSourceDirs(Cu.resolve(this.projectRoot),e,new Set,new Set),e}collectSourceDirs(e,t,n,i){let o;try{o=Rr.realpathSync(e)}catch{return}if(i.has(o))return;i.add(o);let s;try{s=Rr.readdirSync(e,{withFileTypes:!0})}catch{return}for(let a of s){if(!a.isDirectory()||KH.has(a.name))continue;let c=Cu.resolve(e,a.name);if(!YH(c)){this.collectSourceDirs(c,t,n,i);continue}n.has(c)||(n.add(c),t.push(c))}}onFsEvent(e){!e||typeof e!="string"||e.replace(/\\/g,"/").toLowerCase().endsWith(".ets")&&this.scheduleScan()}scheduleScan(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.scanAndEmit()},this.debounceMs)}scanAndEmit(){if(!this.initialScanDone)return;let e=this.diffScan();e.length>0&&this.emit("sourceChanged",{changes:e})}refreshSnapshot(){let e=new Map;for(let t of this.sourceDirs)this.collectEtsFiles(t,e);this.snapshot=e}diffScan(){let e=new Map;for(let n of this.sourceDirs)this.collectEtsFiles(n,e);let t=[];for(let[n,i]of e){let o=this.snapshot.get(n);o?(o.mtimeMs!==i.mtimeMs||o.size!==i.size)&&t.push({uri:Mt(n),type:Wg.Changed}):t.push({uri:Mt(n),type:Wg.Created})}for(let[n]of this.snapshot)e.has(n)||t.push({uri:Mt(n),type:Wg.Deleted});return this.snapshot=e,t}collectEtsFiles(e,t){this.collectEtsFilesInto(e,t,new Set)}collectEtsFilesInto(e,t,n){let i;try{i=Rr.realpathSync(e)}catch{return}if(n.has(i))return;n.add(i);let o;try{o=Rr.readdirSync(e,{withFileTypes:!0})}catch{return}for(let s of o){let a=Cu.resolve(e,s.name);if(s.isDirectory()){this.collectEtsFilesInto(a,t,n);continue}!s.isFile()||!s.name.toLowerCase().endsWith(".ets")||this.recordSnapshot(a,t)}}recordSnapshot(e,t){let n;try{n=Rr.statSync(e)}catch{return}t.set(e,{mtimeMs:n.mtimeMs,size:n.size})}};import{spawn as XH}from"child_process";var RC=["install","--all"];function xC(r,e){let t=r.split(/\r?\n/),n=t.pop()??"";for(let i of t)i&&(m.info("[ohpm] %s",i),e?.(i));return n}async function ZH(r,e,t,n,i){return new Promise(o=>{m.info("[ohpm] spawning: %s %s %s, cwd=%s",r,e,RC.join(" "),t);let s=XH(r,[e,...RC],{cwd:t,env:{...process.env,DEVECO_SDK_HOME:n},windowsHide:!0,stdio:["ignore","pipe","pipe"]}),a="",c="";s.stdout?.on("data",l=>{a=xC(a+l.toString(),i)}),s.stderr?.on("data",l=>{c=xC(c+l.toString(),i)}),s.on("close",l=>{a&&(m.info("[ohpm] %s",a),i?.(a)),c&&(m.info("[ohpm] %s",c),i?.(c)),m.info("[ohpm] process exited, code=%s",l),o({exitCode:l??-1})}),s.on("error",l=>{m.error("[ohpm] process error: %s",l.message),o({exitCode:-1})})})}async function DC(r,e,t,n,i){try{if(!t)return m.error("node \u8DEF\u5F84\u4E0D\u5B58\u5728"),!1;if(!n)return m.error("ohpm (pm-cli.js) \u4E0D\u5B58\u5728"),!1;let{exitCode:o}=await ZH(t,n,r,e,i);return o===0?(m.info("ohpm \u5B89\u88C5\u6210\u529F"),!0):(m.error("ohpm \u5B89\u88C5\u5931\u8D25\uFF0C\u9000\u51FA\u7801: %s",o),!1)}catch(o){return m.error("ohpm \u5B89\u88C5\u5F02\u5E38",o),!1}}var IC={UNINITIALIZED:-32099,UNKNOWN:-32e3},Wa=class r extends Error{code;constructor(e,t){super(e),this.name="ArkTsProxyError",this.code=t}static uninitialized(e){return new r(e,IC.UNINITIALIZED)}static unknown(e="Unknown error"){return new r(e,IC.UNKNOWN)}toJsonRpcErrorParams(){return{code:this.code,message:this.message}}};var es=class{config;lspProxy=null;configWatcher=null;depMapWatcher=null;sourceFileWatcher=null;isInitialized=!1;lastEditorOpenFiles=[];onMessage=()=>{};onConfigChanged=null;disposeOnce=null;get aceServerPid(){return this.lspProxy?.lspPid??null}constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}async start(e=[],t){this.lastEditorOpenFiles=e;try{this.startConfigWatcher(),this.startLspProxy(e,t)}catch(n){throw m.error(`[ArktsLspManager] start() synchronous failure: ${n instanceof Error?n.message:String(n)}`),n}}sendNotification(e){if(!this.lspProxy){m.warn("[ArktsLspManager] sendNotification before LSP ready, dropped");return}this.lspProxy.sendNotification(e)}sendRequest(e){if(!this.lspProxy){m.warn("[ArktsLspManager] sendRequest before LSP ready, dropped");return}this.lspProxy.sendRequest(e)}async diagnostic(e){if(!this.lspProxy)throw new Error("[ArktsLspManager] diagnostic before LSP ready");return this.lspProxy.diagnostic(e)}async sendFeatureRequest(e,t){if(!this.useStandardProtocol)throw new Error(`Language feature '${e}' is not supported on the installed DevEco Studio. The standard LSP protocol entry (plugins/openharmony/ace-server/out/standardIndex/index.js) was not found. Please upgrade DevEco Studio to version 26.0.0.610 or later to use this tool.`);if(!this.lspProxy)throw new Error("LSP not ready");return this.lspProxy.sendFeatureRequest(e,t)}get useStandardProtocol(){return this.config.useStandardProtocol}onAsyncOpenFile(e){this.lspProxy?.onAsyncOpenFile(e)}closeFileLegacy(e,t){this.lspProxy?.closeFileLegacy(e,t)}registerDiagnosticCallback(e){this.lspProxy?.registerDiagnosticCallback(e)}static async handleSyncProject(e,t,n,i,o,s,a,c){if(m.info("[ArktsLspManager] Received arkts/syncProject"),!e||!t)return m.error("[ArktsLspManager] handleSyncProject: workspaceRoot or sdkPath is empty"),{status:"failed",reason:"workspaceRoot or sdkPath is empty"};let l=s?.skipHvigorSync===!0,d=await Zc(e,async()=>await DC(e,t,n??"",i??"",a)?l?(m.info("[ArktsLspManager] hvigor sync skipped (config up-to-date)"),{status:"success"}):await Yw(e,t,n??"",o??"",c)?(m.info("[ArktsLspManager] syncProject completed successfully"),{status:"success"}):(m.error("[ArktsLspManager] syncProject failed"),{status:"failed",reason:"hvigor sync failed"}):(m.error("[ArktsLspManager] ohpm install failed"),{status:"failed",reason:"ohpm install failed"}));return d.acquired?d.result:(m.info("[ArktsLspManager] Build lock held by another process, skipping sync"),{status:"skipped",reason:"build lock held by another process"})}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}async performDispose(){try{this.configWatcher?.stop()}catch(e){m.warn(`[ArktsLspManager] configWatcher stop error: ${e}`)}try{this.depMapWatcher?.stop()}catch(e){m.warn(`[ArktsLspManager] depMapWatcher stop error: ${e}`)}try{this.sourceFileWatcher?.stop()}catch(e){m.warn(`[ArktsLspManager] sourceFileWatcher stop error: ${e}`)}if(this.configWatcher=null,this.depMapWatcher=null,this.sourceFileWatcher=null,this.lspProxy){try{await this.lspProxy.dispose()}catch(e){m.warn(`[ArktsLspManager] lspProxy dispose error: ${e}`)}this.lspProxy=null}this.isInitialized=!1}startLspProxy(e,t){let n=new Su(this.config.sdkPath,this.config.arktsLangServerPath,this.config.workspaceRoot,this.config.indexLogPath,this.config.nodeMaxOldSpaceSize,this.config.useStandardProtocol,this.config.nodePath,this.config.useSocket??!1);n.setOnMessage(i=>this.handleLspMessage(i)),n.start(e,i=>this.handleLspInitialized(i),t),this.lspProxy=n}handleLspInitialized=e=>{if(this.isInitialized=e,e)m.info("[ArktsLspManager] LSP initialized"),this.startDependencyMapWatcher(),this.startSourceFileWatcher(),this.onMessage({jsonrpc:L,method:b.ARKTS_INITIALIZED,params:{}});else{let t=this.lspProxy?.consumeStartErrorMessage();m.error(`[ArktsLspManager] LSP initialization failed: ${t}`);let n=t?Wa.uninitialized(t):Wa.unknown();this.onMessage({jsonrpc:L,method:b.ARKTS_INITIALIZATION_FAILED,params:n.toJsonRpcErrorParams()}),this.lspProxy=null}};handleLspMessage(e){this.onMessage(e)}maybeRetryLspAfterSuccessfulSync(){this.isInitialized||this.lspProxy!==null||(m.info("[ArktsLspManager] Retrying LSP startup after successful sync"),this.onMessage({jsonrpc:L,method:b.ARKTS_REINITIALIZING,params:{}}),this.startLspProxy(this.lastEditorOpenFiles))}startConfigWatcher(){this.configWatcher||(this.configWatcher=new Eu(this.config.workspaceRoot),this.configWatcher.on("configChanged",e=>this.handleConfigChanged(e)),this.configWatcher.start())}startDependencyMapWatcher(){this.depMapWatcher||(this.depMapWatcher=new Pu(this.config.workspaceRoot),this.depMapWatcher.on("reload",e=>{if(!this.lspProxy){m.warn("[ArktsLspManager] LspServerProxy not initialized, skip reload");return}let n=this.lspProxy.reloadDependenciesOnly(e).map(i=>({modulePath:i.modulePath??"",dependencies:i.dependencies??{},dynamicDependencies:i.dynamicDependencies??{}}));this.onMessage({jsonrpc:L,method:b.ARKTS_SYNC_COMPLETED,params:{success:!0,moduleSet:n}})}),this.depMapWatcher.start())}startSourceFileWatcher(){this.sourceFileWatcher||(this.sourceFileWatcher=new ku(this.config.workspaceRoot),this.sourceFileWatcher.on("sourceChanged",e=>{if(!this.lspProxy){m.warn("[ArktsLspManager] LspServerProxy not initialized, skip didChangeWatchedFiles");return}this.sendNotification({jsonrpc:L,method:b.WORKSPACE_DID_CHANGE_WATCHED_FILES,params:{changes:e.changes}}),m.info(`[ArktsLspManager] Notified didChangeWatchedFiles: ${e.changes.length} change(s)`)}),this.sourceFileWatcher.start())}setOnConfigChanged(e){this.onConfigChanged=e}handleConfigChanged(e){m.info(`[ArktsLspManager] Config file changed: ${e.filePath}, notifying server`),e.kind!==4&&this.sourceFileWatcher?.refreshSourceDirs(),this.onConfigChanged?.()}};var QH=10080*60*1e3,eU=7200*60*1e3,tU=120*1e3,ts=class r{manager=null;get aceServerPid(){return this.manager?.aceServerPid??null}initialized=!1;initializing=!1;initPromise=null;initDeadlineTimer=null;initResolve=null;initReject=null;projectPath;sdkPath;arktsLangServerPath;nodePath;nodeMaxOldSpaceSize;onConfigChangedCallback=null;onInitProgress=null;onDepParseProgress=null;useStandardProtocol=!0;useSocket;diagnosticWaiters=new Map;documentVersion=0;static FEATURE_METHOD_MAP={hover:b.HOVER,definition:b.DEFINITION,declaration:b.DECLARATION,references:b.REFERENCES,implementation:b.IMPLEMENTATION,completion:b.COMPLETION,signatureHelp:b.SIGNATURE_HELP,documentHighlight:b.DOCUMENT_HIGHLIGHT};constructor(e,t,n,i,o,s=!1){this.projectPath=e,this.sdkPath=t,this.arktsLangServerPath=n,this.nodeMaxOldSpaceSize=i,this.nodePath=o,this.useSocket=s}setOnConfigChanged(e){this.onConfigChangedCallback=e}setOnInitProgress(e){this.onInitProgress=e}setOnDepParseProgress(e){this.onDepParseProgress=e}async initialize(){if(!this.initialized){if(this.initPromise){await this.initPromise;return}this.initializing=!0,this.initPromise=this.doInitialize().then(()=>{this.initialized=!0}).finally(()=>{this.initializing=!1}),await this.initPromise}}async doInitialize(){let{harmonyRoot:e,arktsLangServerPath:t,useStandardProtocol:n}=this.resolveProjectAndDeveco();this.useStandardProtocol=n;let i=Ie(e),{logPath:o,indexPath:s}=this.getLogAndIndexPath(i);setImmediate(()=>{vp(s,QH,"[ArkTS-Check]"),vp(o,eU,"[ArkTS-Check]")}),tl(o);let a=this.nodeMaxOldSpaceSize?parseInt(this.nodeMaxOldSpaceSize,10):NaN,c=Number.isNaN(a)?void 0:a;h.info(`ArktsCheck nodeMaxOldSpaceSize: incoming='${this.nodeMaxOldSpaceSize??"(unset)"}', parsed=${c??"undefined \u2192 dynamic formula applies"}`);let l=this.sdkPath;h.info(`[ArktsCheck] sdkPath=${l}, arktsLangServerPath=${t}, useStandardProtocol=${n}, useSocket=${this.useSocket}`),this.manager=new es({sdkPath:l,arktsLangServerPath:t,workspaceRoot:he(i),indexLogPath:s,nodeMaxOldSpaceSize:c,useStandardProtocol:n,nodePath:this.nodePath,useSocket:this.useSocket}),this.manager.setOnMessage(d=>this.handleLspMessage(d)),this.onConfigChangedCallback&&this.manager.setOnConfigChanged(this.onConfigChangedCallback),await new Promise((d,g)=>{this.initResolve=d,this.initReject=g,this.armInitTimer(ot),this.manager.start([],this.onDepParseProgress??void 0).catch(y=>{let E=y instanceof Error?y:new Error(String(y));this.failInit(E)})})}resolveProjectAndDeveco(){let e=Ir(this.projectPath);if(!e)throw new Error(`Failed to find HarmonyOS project from path: ${this.projectPath}`);this.projectPath=e;let t=this.arktsLangServerPath;if(!t)throw new Error("arkts-lang-server path not found");let n=yc(t);return{harmonyRoot:e,arktsLangServerPath:t,useStandardProtocol:n}}armInitTimer(e){this.initDeadlineTimer&&clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=setTimeout(()=>{let t=this.initReject;this.clearInitHandlers(),t?.(new Error("LSP initialize timeout"))},e)}clearInitHandlers(){this.initDeadlineTimer&&(clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=null),this.initResolve=null,this.initReject=null}failInit(e){let t=this.initReject;this.clearInitHandlers(),t?.(e)}async checkFile(e){this.initialized||await this.initialize();let t=this.manager;if(!t)throw new Error("ArktsLspManager not initialized");let n=Mt(e),i=await Ot.promises.readFile(e,"utf8"),s=`deveco.apptool.${Ue.extname(e).replace(/^\./,"")||"plaintext"}`;return t.useStandardProtocol?this.checkFileStandard(t,n,i,s):this.checkFileLegacy(t,e,n,i,s)}async checkFileStandard(e,t,n,i){h.debug(`textDocument/didOpen uri=${t} content_len=${n.length}`),this.sendNotification("textDocument/didOpen",{textDocument:{uri:t,text:n,languageId:i,version:++this.documentVersion}});try{h.debug(`textDocument/diagnostic uri=${t}`);let o=await e.diagnostic({textDocument:{uri:t}});return rU(o)}finally{this.sendNotification("textDocument/didClose",{textDocument:{uri:t}})}}async checkFileLegacy(e,t,n,i,o){let s=n;e.registerDiagnosticCallback(n);let a=new Promise((c,l)=>{let d=setTimeout(()=>{this.diagnosticWaiters.delete(s)&&l(new Error("Wait for diagnostics timeout"))},tU);this.diagnosticWaiters.set(s,{resolve:c,reject:l,timer:d})});h.debug(`textDocument/didOpen(legacy) uri=${n} content_len=${i.length}`),e.onAsyncOpenFile({textDocument:{uri:n,text:i,languageId:o,version:i.length},editorFiles:[n],isFromEditor:!1});try{return await a}finally{e.closeFileLegacy(n,!1)}}async handleCall(e){if(!this.initialized)return this.buildNotReadyResponse();let t=[],n=[],i=this.collectValidFiles(e.files,t);return i.length===0?{content:[{type:"text",text:t.length>0?t.join(`
1344
+ `):"No valid .ets files"}],isError:!0}:(await this.runDiagnosticsForFiles(i,t,n),this.formatCallResult(t,n))}async handleLspFeature(e,t){if(!this.initialized)return this.buildNotReadyResponse();let n=this.resolveSingleFile(t.file);if(!n)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${t.file}`}],isError:!0};let i=r.FEATURE_METHOD_MAP[e];if(!i)return{content:[{type:"text",text:`Unknown feature: ${e}`}],isError:!0};h.info(`handleLspFeature: ${e} file=${n} line=${t.line} char=${t.character}`);try{let o=await this.withOpenFile(n,async a=>{let c={textDocument:{uri:a},position:{line:t.line,character:t.character}};return e==="references"&&(c.context={includeDeclaration:!0}),this.manager.sendFeatureRequest(i,c)});return{content:[{type:"text",text:o==null?`${e}: no result`:`${e}: ${JSON.stringify(o,null,2)}`}]}}catch(o){let s=o instanceof Error?o.message:String(o);return h.error(`handleLspFeature ${e} failed: ${s}`),{content:[{type:"text",text:`${e} failed: ${s}`}],isError:!0}}}async handleWorkspaceSymbol(e){if(!this.initialized)return this.buildNotReadyResponse();h.info(`handleWorkspaceSymbol: query="${e}"`);try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return{content:[{type:"text",text:t==null?"workspaceSymbol: no result":`workspaceSymbol: ${JSON.stringify(t,null,2)}`}]}}catch(t){let n=t instanceof Error?t.message:String(t);return h.error(`handleWorkspaceSymbol failed: ${n}`),{content:[{type:"text",text:`workspaceSymbol failed: ${n}`}],isError:!0}}}async handleWorkspaceSymbolRaw(e){if(!this.initialized)return null;try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return Array.isArray(t)?t:t==null?null:[t]}catch(t){return h.error(`handleWorkspaceSymbolRaw failed: ${t.message}`),null}}async handleDocumentSymbol(e){if(!this.initialized)return this.buildNotReadyResponse();let t=this.resolveSingleFile(e);if(!t)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${e}`}],isError:!0};h.info(`handleDocumentSymbol: file=${t}`);try{let n=await this.withOpenFile(t,async o=>this.manager.sendFeatureRequest(b.DOCUMENT_SYMBOL,{textDocument:{uri:o}}));return{content:[{type:"text",text:n==null?"documentSymbol: no result":`documentSymbol: ${JSON.stringify(n,null,2)}`}]}}catch(n){let i=n instanceof Error?n.message:String(n);return h.error(`handleDocumentSymbol failed: ${i}`),{content:[{type:"text",text:`documentSymbol failed: ${i}`}],isError:!0}}}async handleCallHierarchy(e){if(!this.initialized)return this.buildNotReadyResponse();let t=this.resolveSingleFile(e.file);if(!t)return{content:[{type:"text",text:`File does not exist or is not a .ets file: ${e.file}`}],isError:!0};h.info(`handleCallHierarchy: file=${t} line=${e.line} char=${e.character} direction=${e.direction}`);try{let n=await this.withOpenFile(t,async o=>{let s=await this.manager.sendFeatureRequest(b.PREPARE_CALL_HIERARCHY,{textDocument:{uri:o},position:{line:e.line,character:e.character}}),a=Array.isArray(s)?s:s?[s]:[];if(a.length===0)return{items:[],calls:[]};let c=e.direction==="incoming"?b.INCOMING_CALLS:b.OUTGOING_CALLS,l=[];for(let d of a){let g=await this.manager.sendFeatureRequest(c,{item:d});Array.isArray(g)?l.push(...g):g&&l.push(g)}return{items:a,calls:l}});return{content:[{type:"text",text:`callHierarchy (${e.direction}): ${JSON.stringify(n,null,2)}`}]}}catch(n){let i=n instanceof Error?n.message:String(n);return h.error(`handleCallHierarchy failed: ${i}`),{content:[{type:"text",text:`callHierarchy failed: ${i}`}],isError:!0}}}async withOpenFile(e,t){let n=Mt(e),i=await Ot.promises.readFile(e,"utf8"),s=`deveco.apptool.${Ue.extname(e).replace(/^\./,"")||"plaintext"}`;h.debug(`withOpenFile didOpen uri=${n} len=${i.length}`),this.sendNotification("textDocument/didOpen",{textDocument:{uri:n,text:i,languageId:s,version:++this.documentVersion}});try{return await t(n)}finally{this.sendNotification("textDocument/didClose",{textDocument:{uri:n},isManual:!1})}}resolveSingleFile(e){let t=Ue.isAbsolute(e)?e:Ue.join(this.projectPath,e);return!Ot.existsSync(t)||!Ot.statSync(t).isFile()||!t.endsWith(".ets")?null:t}buildNotReadyResponse(){return{content:[{type:"text",text:this.initializing?"LSP is initializing, please retry later":this.projectPath?"LSP not initialized":"No project path configured; set the PROJECT_PATH parameter"}],isError:!0}}collectValidFiles(e,t){let n=Ue.resolve(this.projectPath),i=[];for(let o of e){let s=Ue.resolve(Ue.isAbsolute(o)?o:Ue.join(n,o));if(!Ot.existsSync(s)){t.push(`File does not exist: ${o}`);continue}if(!Ot.statSync(s).isFile()){t.push(`Not a regular file: ${o}`);continue}if(!s.endsWith(".ets")){t.push(`Not a .ets file: ${o}`);continue}i.push(s)}return i}async runDiagnosticsForFiles(e,t,n){for(let i of e){await by(500);try{let o=await this.checkFile(i);n.push(nU(i,o))}catch(o){t.push(`${i} => wait for diagnostics failed: ${o.message}`)}}}formatCallResult(e,t){let n=[];e.length>0&&n.push(e.join(`
1329
1345
  `)),t.length>0&&n.push(t.join(`
1330
1346
  `));let i=n.join(`
1331
- `).trim(),o=e.length>0;return!o&&t.length===0&&(i="No diagnostics collected"),{content:[{type:"text",text:i}],isError:o}}async shutdown(){let e=this.initReject;if(this.clearInitHandlers(),e?.(new Error("LSP shutting down")),this.manager){try{await this.manager.dispose()}catch(t){h.warn(`Failed to dispose ArktsLspManager: ${t}`)}this.manager=null}this.initialized=!1,this.initializing=!1,this.initPromise=null}sendNotification(e,t){if(!this.manager)throw new Error("ArktsLspManager not initialized");this.manager.sendNotification({jsonrpc:"2.0",method:e,params:t})}handleLspMessage(e){let t=e,n=t.method;if(n)switch(n){case"textDocument/publishDiagnostics":this.handleDiagnosticsNotification(t.params);break;case"arkts/indexingProgress":this.handleIndexingProgress(t.params);break;case Yi.INDEXING_PROGRESS_UPDATE:this.handleIndexingProgress(t.params);break;case b.PROGRESS:this.handleProgressNotification(t.params);break;case"arkts/initialized":{h.info("Received arkts/initialized");let i=this.initResolve;this.clearInitHandlers(),i?.();break}case"arkts/initializationFailed":{let i=t.params?.message??"unknown";h.error(`LSP initialization failed: ${i}`);let o=this.initReject;this.clearInitHandlers(),o?.(new Error(`LSP initialize failed: ${i}`));break}case"workspace/didChangeConfiguration":h.info("Received workspace/didChangeConfiguration, sync deferred to next check");break;default:break}}handleIndexingProgress(e){let t=e;if(t?.current!=null&&t?.total!=null&&t.total>0){let n=Math.round(t.current/t.total*100),i=`indexing ${t.current}/${t.total} modules`+(t.moduleName?` (${t.moduleName})`:"");this.onInitProgress?.(i,n)}this.initResolve&&this.armInitTimer(it)}handleProgressNotification(e){let t=e?.value;if(t&&(t.kind==="report"||t.kind==="begin")){let n=typeof t.percentage=="number"?Math.round(t.percentage):null,i=t.message??(n!==null?`${n}%`:"indexing");this.onInitProgress?.(i,n)}this.initResolve&&this.armInitTimer(it)}handleDiagnosticsNotification(e){if(!e)return;let t=e.uri;if(!t)return;let n=this.popDiagnosticWaiter(t);if(!n&&this.diagnosticWaiters.size===1){let s=this.diagnosticWaiters.keys().next().value;n=this.popDiagnosticWaiter(s)}if(!n)return;if(typeof e.errorMessage=="string"){h.warn(`diagnostics error uri=${t} message=${e.errorMessage}`),n.resolve({errorMessage:e.errorMessage});return}let i=e.diagnostics,o=Array.isArray(i)?i.length:0;h.debug(`diagnostics received uri=${t} count=${o}`),n.resolve(Array.isArray(i)?i:[])}popDiagnosticWaiter(e){let t=this.diagnosticWaiters.get(e);if(t)return this.diagnosticWaiters.delete(e),clearTimeout(t.timer),t}getLogAndIndexPath(e){try{let t=He.join(Qr(),"ArkTSCheck"),n=He.join(t,"mapping-config.properties"),i=xh(e,n),o=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=He.join(t,"lsp-log",String(i),o),a=He.join(t,"lsp-index",String(i));return Tt.mkdirSync(s,{recursive:!0}),Tt.mkdirSync(a,{recursive:!0}),{logPath:xe(s),indexPath:xe(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function C0(r){if(Array.isArray(r))return r;if(r&&typeof r=="object"){let e=r;if(e.kind==="full"&&Array.isArray(e.items))return e.items}return[]}function k0(r,e){if(Array.isArray(e))return e.length===0?`${r} => no diagnostics`:`${r} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${r} diagnostic failed, error_message: ${t}`}return`${r} => diagnostic failed, result: ${JSON.stringify(e)}`}import*as An from"fs";import*as Pi from"path";import{z as Xf}from"zod";function Vo(){return{content:[{type:"text",text:"C++ LSP is not ready, please retry later"}],isError:!0}}function Jd(r,e){let t=e instanceof Error?e.message:String(e);return h.error(`[CppLsp] ${r} failed: ${t}`),{content:[{type:"text",text:`${r} failed: ${t}`}],isError:!0}}var D0=500,Go=class{manager;constructor(e){this.manager=e}static getToolDefinition(){return{name:"check_cpp_files",description:"Perform static syntax checks on the provided C/C++ files and return clangd diagnostics.",inputSchema:Xf.object({files:Xf.array(Xf.string()).describe('List of C/C++ file paths to check, format: ["file1.cpp","file2.hpp",...]')})}}async handleCall(e){if(!this.manager.ready)return Vo();let t=[],n=[],i=this.collectValidFiles(e.files,t);if(i.length===0)return{content:[{type:"text",text:t.length>0?t.join(`
1332
- `):"No valid C/C++ files"}],isError:!0};for(let c of i){await x0(D0);try{let l=await this.checkFile(c);n.push(R0(c,l))}catch(l){t.push(`${c} => wait for diagnostics failed: ${l.message}`)}}let o=t.length>0,s=[];t.length>0&&s.push(t.join(`
1347
+ `).trim(),o=e.length>0;return!o&&t.length===0&&(i="No diagnostics collected"),{content:[{type:"text",text:i}],isError:o}}async shutdown(){let e=this.initReject;if(this.clearInitHandlers(),e?.(new Error("LSP shutting down")),this.manager){try{await this.manager.dispose()}catch(t){h.warn(`Failed to dispose ArktsLspManager: ${t}`)}this.manager=null}this.initialized=!1,this.initializing=!1,this.initPromise=null}sendNotification(e,t){if(!this.manager)throw new Error("ArktsLspManager not initialized");this.manager.sendNotification({jsonrpc:"2.0",method:e,params:t})}handleLspMessage(e){let t=e,n=t.method;if(n)switch(n){case"textDocument/publishDiagnostics":this.handleDiagnosticsNotification(t.params);break;case"arkts/indexingProgress":this.handleIndexingProgress(t.params);break;case io.INDEXING_PROGRESS_UPDATE:this.handleIndexingProgress(t.params);break;case b.PROGRESS:this.handleProgressNotification(t.params);break;case"arkts/initialized":{h.info("Received arkts/initialized");let i=this.initResolve;this.clearInitHandlers(),i?.();break}case"arkts/initializationFailed":{let i=t.params?.message??"unknown";h.error(`LSP initialization failed: ${i}`);let o=this.initReject;this.clearInitHandlers(),o?.(new Error(`LSP initialize failed: ${i}`));break}case"workspace/didChangeConfiguration":h.info("Received workspace/didChangeConfiguration, sync deferred to next check");break;default:break}}handleIndexingProgress(e){let t=e;if(t?.current!=null&&t?.total!=null&&t.total>0){let n=Math.round(t.current/t.total*100),i=`indexing ${t.current}/${t.total} modules`+(t.moduleName?` (${t.moduleName})`:"");this.onInitProgress?.(i,n)}this.initResolve&&this.armInitTimer(ot)}handleProgressNotification(e){let t=e?.value;if(t&&(t.kind==="report"||t.kind==="begin")){let n=typeof t.percentage=="number"?Math.round(t.percentage):null,i=t.message??(n!==null?`${n}%`:"indexing");this.onInitProgress?.(i,n)}this.initResolve&&this.armInitTimer(ot)}handleDiagnosticsNotification(e){if(!e)return;let t=e.uri;if(!t)return;let n=this.popDiagnosticWaiter(t);if(!n&&this.diagnosticWaiters.size===1){let s=this.diagnosticWaiters.keys().next().value;n=this.popDiagnosticWaiter(s)}if(!n)return;if(typeof e.errorMessage=="string"){h.warn(`diagnostics error uri=${t} message=${e.errorMessage}`),n.resolve({errorMessage:e.errorMessage});return}let i=e.diagnostics,o=Array.isArray(i)?i.length:0;h.debug(`diagnostics received uri=${t} count=${o}`),n.resolve(Array.isArray(i)?i:[])}popDiagnosticWaiter(e){let t=this.diagnosticWaiters.get(e);if(t)return this.diagnosticWaiters.delete(e),clearTimeout(t.timer),t}getLogAndIndexPath(e){try{let t=Ue.join(rn(),"ArkTSCheck"),n=Ue.join(t,"mapping-config.properties"),i=Sy(e,n),o=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=Ue.join(t,"lsp-log",String(i),o),a=Ue.join(t,"lsp-index",String(i));return Ot.mkdirSync(s,{recursive:!0}),Ot.mkdirSync(a,{recursive:!0}),{logPath:Ie(s),indexPath:Ie(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function rU(r){if(Array.isArray(r))return r;if(r&&typeof r=="object"){let e=r;if(e.kind==="full"&&Array.isArray(e.items))return e.items}return[]}function nU(r,e){if(Array.isArray(e))return e.length===0?`${r} => no diagnostics`:`${r} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${r} diagnostic failed, error_message: ${t}`}return`${r} => diagnostic failed, result: ${JSON.stringify(e)}`}import*as Nn from"fs";import*as Ti from"path";import{z as Vg}from"zod";function rs(){return{content:[{type:"text",text:"C++ LSP is not ready, please retry later"}],isError:!0}}function Ru(r,e){let t=e instanceof Error?e.message:String(e);return h.error(`[CppLsp] ${r} failed: ${t}`),{content:[{type:"text",text:`${r} failed: ${t}`}],isError:!0}}var iU=500,ns=class{manager;constructor(e){this.manager=e}static getToolDefinition(){return{name:"check_cpp_files",description:"Perform static syntax checks on the provided C/C++ files and return clangd diagnostics.",inputSchema:Vg.object({files:Vg.array(Vg.string()).describe('List of C/C++ file paths to check, format: ["file1.cpp","file2.hpp",...]')})}}async handleCall(e){if(!this.manager.ready)return rs();let t=[],n=[],i=this.collectValidFiles(e.files,t);if(i.length===0)return{content:[{type:"text",text:t.length>0?t.join(`
1348
+ `):"No valid C/C++ files"}],isError:!0};for(let c of i){await sU(iU);try{let l=await this.checkFile(c);n.push(oU(c,l))}catch(l){t.push(`${c} => wait for diagnostics failed: ${l.message}`)}}let o=t.length>0,s=[];t.length>0&&s.push(t.join(`
1333
1349
  `)),n.length>0&&s.push(n.join(`
1334
1350
  `));let a=s.join(`
1335
- `).trim();return!o&&n.length===0&&(a="No diagnostic information collected"),{content:[{type:"text",text:a}],isError:o}}async checkFile(e){let t=Nt(e),n=await An.promises.readFile(e,"utf8"),i=Qa(e),o=this.manager.registerDiagnosticCallback(t);this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didOpen",params:{textDocument:{uri:t,text:n,languageId:i,version:n.length}}});try{return await o}finally{this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didClose",params:{textDocument:{uri:t}}})}}collectValidFiles(e,t){let n=Pi.resolve(this.manager.projectRoot),i=[];for(let o of e){let s=Pi.resolve(Pi.isAbsolute(o)?o:Pi.join(n,o));if(!An.existsSync(s)){t.push(`File does not exist: ${o}`);continue}if(!An.statSync(s).isFile()){t.push(`Not a regular file: ${o}`);continue}if(!qn(s)){t.push(`Not a supported C/C++ file: ${o}`);continue}try{i.push(An.realpathSync(s))}catch{i.push(s)}}return i}};function R0(r,e){if(Array.isArray(e))return e.length===0?`${r} => no diagnostics`:`${r} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${r} diagnostic failed, error_message: ${t}`}return`${r} => diagnostic failed, result: ${JSON.stringify(e)}`}function x0(r){return new Promise(e=>setTimeout(e,r))}import*as zo from"fs";import*as Yd from"path";var qo=class r{manager;static FEATURE_METHOD_MAP={hover:b.HOVER,definition:b.DEFINITION,declaration:b.DECLARATION,references:b.REFERENCES,implementation:b.IMPLEMENTATION};constructor(e){this.manager=e}async handleLspFeature(e,t){if(!this.manager.ready)return Vo();let n=this.resolveSingleFile(t.file);if(!n)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${t.file}`}],isError:!0};let i=r.FEATURE_METHOD_MAP[e];if(!i)return{content:[{type:"text",text:`Unknown feature: ${e}`}],isError:!0};h.info(`[ClangdLspTool] handleLspFeature: ${e} file=${n} line=${t.line} char=${t.character}`);try{let o=await this.withOpenFile(n,async a=>{let c={textDocument:{uri:a},position:{line:t.line,character:t.character}};return e==="references"&&(c.context={includeDeclaration:!0}),this.manager.sendFeatureRequest(i,c)});return{content:[{type:"text",text:o==null?`${e}: no result`:`${e}: ${JSON.stringify(o,null,2)}`}]}}catch(o){return Jd(e,o)}}async handleWorkspaceSymbolRaw(e){if(!this.manager.ready)return null;try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return Array.isArray(t)?t:t==null?null:[t]}catch(t){return h.error(`[ClangdLspTool] handleWorkspaceSymbolRaw failed: ${t.message}`),null}}async handleDocumentSymbol(e){if(!this.manager.ready)return Vo();let t=this.resolveSingleFile(e);if(!t)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${e}`}],isError:!0};h.info(`[ClangdLspTool] handleDocumentSymbol: file=${t}`);try{let n=await this.withOpenFile(t,async o=>this.manager.sendFeatureRequest(b.DOCUMENT_SYMBOL,{textDocument:{uri:o}}));return{content:[{type:"text",text:n==null?"documentSymbol: no result":`documentSymbol: ${JSON.stringify(n,null,2)}`}]}}catch(n){return Jd("documentSymbol",n)}}async handleCallHierarchy(e){if(!this.manager.ready)return Vo();if(e.direction==="outgoing")return{content:[{type:"text",text:"callHierarchy outgoing is not supported by clangd (incoming only)"}],isError:!0};let t=this.resolveSingleFile(e.file);if(!t)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${e.file}`}],isError:!0};h.info(`[ClangdLspTool] handleCallHierarchy: file=${t} line=${e.line} char=${e.character} direction=${e.direction}`);try{let n=await this.withOpenFile(t,o=>this.fetchCallHierarchyResult(o,e));return{content:[{type:"text",text:`callHierarchy (${e.direction}): ${JSON.stringify(n,null,2)}`}]}}catch(n){return Jd("callHierarchy",n)}}async fetchCallHierarchyResult(e,t){let n=await this.manager.sendFeatureRequest(b.PREPARE_CALL_HIERARCHY,{textDocument:{uri:e},position:{line:t.line,character:t.character}}),i=this.normalizeCallHierarchyItems(n);if(i.length===0)return{items:[],calls:[]};let o=await this.collectIncomingCalls(i);return{items:i,calls:o}}normalizeCallHierarchyItems(e){return Array.isArray(e)?e:e?[e]:[]}async collectIncomingCalls(e){let t=[];for(let n of e)t.push(...await this.fetchIncomingCalls(n));return t}async fetchIncomingCalls(e){let t=await this.manager.sendFeatureRequest(b.INCOMING_CALLS,{item:e});return Array.isArray(t)?t:t?[t]:[]}async withOpenFile(e,t){let n=Nt(e),i=await zo.promises.readFile(e,"utf8"),o=Qa(e);h.info(`[ClangdLspTool] withOpenFile didOpen uri=${n} langId=${o} len=${i.length}`),this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didOpen",params:{textDocument:{uri:n,text:i,languageId:o,version:i.length}}});try{return await t(n)}finally{this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didClose",params:{textDocument:{uri:n}}})}}resolveSingleFile(e){let t=Yd.isAbsolute(e)?e:Yd.join(this.manager.projectRoot,e);return!zo.existsSync(t)||!zo.statSync(t).isFile()||!qn(t)?null:t}};import{spawn as A0}from"child_process";import*as Xd from"fs";import*as QE from"path";var I0=30*1e3,T0=30*1e3,Kd=class{config;client=null;clangdProcess=null;nextRequestId=1;requestCallbacks=new kn;diagnosticWaiters=new Map;lastStartErrorMessage=null;onMessage=()=>{};disposeOnce=null;constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}get clangdPid(){return this.clangdProcess?.pid??null}consumeStartErrorMessage(){let e=this.lastStartErrorMessage;return this.lastStartErrorMessage=null,e}async start(e){let t=!1;try{f.info(`[ClangdLspProxy] clangdPath: ${this.config.clangdPath}`),f.info(`[ClangdLspProxy] workspaceRoot: ${this.config.workspaceRoot}`),f.info(`[ClangdLspProxy] compileCommandsDir: ${this.config.compileCommandsDir}`),this.ensureLogDir(),this.clangdProcess=this.spawnClangd();let n={serverPath:"",logPath:this.config.logPath,indexingDataLocation:this.config.logPath,cwd:this.config.workspaceRoot};this.client=new Cn(n),this.client.on("message",o=>this.handleRawMessage(o)),this.client.on("error",o=>this.handleError(o)),this.client.attachProcess(this.clangdProcess,{stderrAsError:!1});let i=this.buildInitializeParams();await this.sendLspRequest(b.INITIALIZE,i,it),f.info("[ClangdLspProxy] initialize response received"),this.sendNotification(b.INITIALIZED,{}),t=!0}catch(n){this.lastStartErrorMessage=n instanceof Error?n.message:String(n),f.error(`[ClangdLspProxy] initialization failed: ${this.lastStartErrorMessage}`),await this.dispose()}e?.(t)}async hover(e){return this.sendLspRequest(b.HOVER,e)}async definition(e){return this.sendLspRequest(b.DEFINITION,e)}async declaration(e){return this.sendLspRequest(b.DECLARATION,e)}async references(e){return this.sendLspRequest(b.REFERENCES,e)}async implementation(e){return this.sendLspRequest(b.IMPLEMENTATION,e)}async documentSymbol(e){return this.sendLspRequest(b.DOCUMENT_SYMBOL,e)}async workspaceSymbol(e){return this.sendLspRequest(b.WORKSPACE_SYMBOL,e)}async prepareCallHierarchy(e){return this.sendLspRequest(b.PREPARE_CALL_HIERARCHY,e)}async incomingCalls(e){return this.sendLspRequest(b.INCOMING_CALLS,e)}async sendFeatureRequest(e,t){return this.sendLspRequest(e,t)}sendDidOpen(e){this.sendNotification(b.DID_OPEN,e)}sendDidChange(e){this.sendNotification(b.DID_CHANGE,e)}sendDidClose(e){this.sendNotification(b.DID_CLOSE,e)}sendNotification(e,t){if(!this.client){f.warn("[ClangdLspProxy] sendNotification before ready, dropped");return}this.client.sendNotification(e,t)}registerDiagnosticCallback(e){let t=this.normalizeClangdUri(e);if(this.diagnosticWaiters.has(t)){f.warn(`[ClangdLspProxy] overwrite existing diagnostic waiter for ${t}`);let n=this.diagnosticWaiters.get(t);clearTimeout(n.timer),this.diagnosticWaiters.delete(t)}return new Promise((n,i)=>{let o=setTimeout(()=>{this.diagnosticWaiters.delete(t)&&i(new Error(`Wait for clangd diagnostics timeout, uri: ${t}`))},T0);this.diagnosticWaiters.set(t,{resolve:n,reject:i,timer:o})})}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}async performDispose(){this.requestCallbacks.rejectAll(new Error("ClangdLspProxy disposing"));for(let[,e]of this.diagnosticWaiters)clearTimeout(e.timer),e.reject(new Error("ClangdLspProxy disposing"));if(this.diagnosticWaiters.clear(),this.client&&this.clangdProcess)try{await this.sendLspRequest(b.SHUTDOWN,null,3e3).catch(e=>{f.warn(`[ClangdLspProxy] shutdown request failed: ${e}`)}),this.sendNotification(b.EXIT,null),await this.client.waitForExitOrTimeout(300)}catch(e){f.warn(`[ClangdLspProxy] dispose error: ${e}`)}if(this.clangdProcess){try{this.clangdProcess.exitCode===null&&this.clangdProcess.signalCode===null&&this.clangdProcess.kill()}catch{}this.clangdProcess=null}this.client=null}spawnClangd(){let e=[`--compile-commands-dir=${ge(this.config.compileCommandsDir)}`,"--log=info","--pch-storage=memory","--limit-results=100"];f.info(`[ClangdLspProxy] spawn: ${this.config.clangdPath} ${e.join(" ")}`);let t=A0(this.config.clangdPath,e,{cwd:this.config.workspaceRoot,stdio:["pipe","pipe","pipe"],windowsHide:!0});if(!t.stdin||!t.stdout||!t.stderr)throw new Error("Failed to spawn clangd: stdio not available");return t}buildInitializeParams(){let e=Xi(this.config.workspaceRoot),t=Ht(e),n=QE.basename(e)||"workspace";return{processId:process.pid,clientInfo:{name:"devecocli-mcp-server",version:"1.3.7"},rootPath:e,rootUri:t,workspaceFolders:[{uri:t,name:n}],capabilities:this.buildClientCapabilities(),initializationOptions:null}}buildClientCapabilities(){return{textDocument:{synchronization:{didOpen:!0,didChange:!0,didClose:!0,willSave:!1,save:!1},publishDiagnostics:{relatedInformation:!0,versionSupport:!1,tagSupport:{valueSet:[1,2]}},hover:{contentFormat:["markdown","plaintext"]},completion:{contextSupport:!1,completionItemKind:{valueSet:[]}},signatureHelp:{signatureInformation:{documentationFormat:["markdown","plaintext"]}},references:{},declaration:{linkSupport:!0},definition:{linkSupport:!0},implementation:{linkSupport:!0},documentSymbol:{hierarchicalDocumentSymbolSupport:!0,symbolKind:{valueSet:[]}},callHierarchy:{dynamicRegistration:!1}},workspace:{symbol:{symbolKind:{valueSet:[]}},configuration:!1,didChangeWatchedFiles:{dynamicRegistration:!1}}}}sendLspRequest(e,t,n=I0){if(!this.client)return Promise.reject(new Error("[ClangdLspProxy] client not ready"));let i=this.nextRequestId++,o=this.requestCallbacks.registerPending(i,e,n);return this.client.sendRequest(e,t,i),o}handleRawMessage(e){let t;try{t=JSON.parse(e)}catch(n){let i=n instanceof Error?n.message:String(n);f.error(`[ClangdLspProxy] JSON parse error: ${i}, raw: ${e.slice(0,200)}`);return}"id"in t&&("result"in t||"error"in t)?this.handleResponse(t):"method"in t?this.handleNotification(t):f.warn(`[ClangdLspProxy] unrecognized message: ${JSON.stringify(t).slice(0,200)}`)}handleResponse(e){let t=e.id;if(t==null||typeof t!="string"&&typeof t!="number")return;let n=t;if(e.error!==void 0&&e.error!==null){let i=e.error;f.warn(`[ClangdLspProxy] LSP error id=${n}: code=${i.code??-1} message=${i.message??"unknown"}`),this.requestCallbacks.rejectPending(n,new Error(`LSP error ${i.code??-1}: ${i.message??"unknown"}`))}else this.requestCallbacks.resolvePending(n,e.result)}handleNotification(e){let t=e.method;if(t)switch(t){case b.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(e.params);break;case b.PROGRESS:this.onMessage({jsonrpc:L,method:b.PROGRESS,params:e.params});break;case b.WINDOW_SHOW_MESSAGE:f.info(`[ClangdLspProxy] window/showMessage: ${JSON.stringify(e.params)}`);break;case b.WINDOW_LOG_MESSAGE:f.info(`[ClangdLspProxy] window/logMessage: ${JSON.stringify(e.params)}`);break;default:this.onMessage({jsonrpc:L,method:t,params:e.params})}}handlePublishDiagnostics(e){if(!e||!e.uri)return;let t=this.normalizeClangdUri(e.uri),n=this.diagnosticWaiters.get(t);if(!n&&this.diagnosticWaiters.size===1){let s=this.diagnosticWaiters.keys().next().value;n=this.diagnosticWaiters.get(s),n&&this.diagnosticWaiters.delete(s)}else n&&this.diagnosticWaiters.delete(t);if(!n)return;clearTimeout(n.timer);let i=Array.isArray(e.diagnostics)?e.diagnostics:[],o=i.length;f.info(`[ClangdLspProxy] diagnostics received uri=${t} count=${o}`),n.resolve(i)}handleError(e){for(let[,t]of this.diagnosticWaiters)clearTimeout(t.timer),t.reject(e);this.diagnosticWaiters.clear(),this.requestCallbacks.rejectAll(e),this.onMessage({jsonrpc:L,method:b.CPP_ERROR,params:{message:e.message}})}ensureLogDir(){if(this.config.logPath)try{Xd.existsSync(this.config.logPath)||Xd.mkdirSync(this.config.logPath,{recursive:!0})}catch{}}normalizeClangdUri(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=decodeURIComponent(t.pathname);return process.platform==="win32"&&/^\/[a-zA-Z]:/.test(n)&&(n=n.slice(1)),Ht(n)}}catch{}return e}};import*as ka from"path";import*as Zf from"fs";var Da=class r{config;proxy=null;isInitialized=!1;onMessage=()=>{};disposeOnce=null;initPromise=null;initDeadlineTimer=null;initResolve=null;initReject=null;resolvedRoot="";constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}get ready(){return this.isInitialized&&this.proxy!==null}get clangdPid(){return this.proxy?.clangdPid??null}get projectRoot(){return this.resolvedRoot}async start(){if(!this.isInitialized){if(this.initPromise){await this.initPromise;return}this.initPromise=this.doStart();try{await this.initPromise}catch(e){throw this.initPromise=null,e}}}sendNotification(e){if(!this.proxy){f.warn("[ClangdLspManager] sendNotification before LSP ready, dropped");return}this.dispatchNotification(e)}async sendFeatureRequest(e,t){if(!this.proxy)throw new Error("[ClangdLspManager] LSP not ready");return this.proxy.sendFeatureRequest(e,t)}registerDiagnosticCallback(e){return this.proxy?this.proxy.registerDiagnosticCallback(e):Promise.reject(new Error("[ClangdLspManager] LSP not ready"))}static async handleSyncCppProject(e,t,n,i,o){if(f.info("[ClangdLspManager] Received cpp/syncProject"),!e||!t)return f.error("[ClangdLspManager] handleSyncCppProject: workspaceRoot or sdkPath is empty"),{status:"failed",reason:"workspaceRoot or sdkPath is empty"};if(an(e).length===0)return f.info("[ClangdLspManager] No C++ modules found, skipping compileNative"),{status:"success"};let a=o?.skipCompileNative===!0,c=await Mc(e,a?async()=>(f.info("[ClangdLspManager] compileNative skipped (C++ project up-to-date)"),{status:"success"}):async()=>r.executeCompileNative(e,t,n,i));return c.acquired?c.result:(f.info("[ClangdLspManager] Build lock held by another process, skipping sync"),{status:"skipped",reason:"build lock held by another process"})}static async executeCompileNative(e,t,n,i){try{return await aw(e,t,n,i),f.info("[ClangdLspManager] compileNative + merge compile_commands completed"),{status:"success"}}catch(o){let s=o instanceof Error?o.message:String(o);return f.error(`[ClangdLspManager] compileNative failed: ${s}`),{status:"failed",reason:s}}}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}doStart(){return new Promise((e,t)=>{this.initResolve=e,this.initReject=t,this.armInitTimer(it);try{this.startProxy()}catch(n){this.failInit(n instanceof Error?n:new Error(String(n)))}})}startProxy(){let e=Cr(this.config.workspaceRoot);this.resolvedRoot=e?xe(e):xe(this.config.workspaceRoot);let t=this.config.logPath??this.getLogPath();$c(t);let n=this.config.clangdPath;if(!n){let s="clangd not found (install DevEco Studio / CLT)";f.error(`[ClangdLspManager] ${s}`),this.failInit(new Error(s));return}let i=this.config.compileCommandsDir??ka.dirname(Gn(this.resolvedRoot));try{Zf.mkdirSync(i,{recursive:!0})}catch(s){f.warn(`[ClangdLspManager] Failed to create compile_commands dir: ${s}`)}f.info(`[ClangdLspManager] clangdPath: ${n}`),f.info(`[ClangdLspManager] workspaceRoot: ${this.resolvedRoot}`),f.info(`[ClangdLspManager] compileCommandsDir: ${i}`);let o=new Kd({clangdPath:n,workspaceRoot:this.resolvedRoot,compileCommandsDir:i,logPath:t});o.setOnMessage(s=>this.handleLspMessage(s)),this.proxy=o,o.start(s=>this.handleProxyInitialized(s)).catch(s=>{let a=s instanceof Error?s:new Error(String(s));this.handleProxyInitialized(!1,a.message)})}handleProxyInitialized=(e,t)=>{if(this.clearInitTimer(),e){this.isInitialized=!0,f.info("[ClangdLspManager] clangd initialized");let n=this.initResolve;this.clearInitHandlers(),n?.()}else{let n=t??this.proxy?.consumeStartErrorMessage()??"unknown error";f.error(`[ClangdLspManager] clangd initialization failed: ${n}`),this.isInitialized=!1,this.proxy=null;let i=this.initReject;this.clearInitHandlers(),i?.(new Error(`C++ LSP initialize failed: ${n}`))}};handleLspMessage(e){this.onMessage(e)}dispatchNotification(e){if(!this.proxy)return;let t=e,n=t.method;if(!n){f.warn("[ClangdLspManager] dispatchNotification: missing method");return}let i=t.params;switch(n){case b.DID_OPEN:this.proxy.sendDidOpen(i);break;case b.DID_CHANGE:this.proxy.sendDidChange(i);break;case b.DID_CLOSE:this.proxy.sendDidClose(i);break;default:this.proxy.sendNotification(n,i)}}armInitTimer(e){this.clearInitTimer(),this.initDeadlineTimer=setTimeout(()=>{this.failInit(new Error("C++ LSP initialize timeout"))},e)}clearInitTimer(){this.initDeadlineTimer&&(clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=null)}clearInitHandlers(){this.clearInitTimer(),this.initResolve=null,this.initReject=null}failInit(e){let t=this.initReject;this.clearInitHandlers(),t?.(e)}async performDispose(){let e=this.initReject;if(this.clearInitHandlers(),e?.(new Error("ClangdLspManager disposing")),this.proxy){try{await this.proxy.dispose()}catch(t){f.warn(`[ClangdLspManager] proxy dispose error: ${t}`)}this.proxy=null}this.isInitialized=!1,this.initPromise=null}getLogPath(){try{let e=ka.join(Qr(),"CppCheck"),t=`${Date.now()}${process.hrtime.bigint()%1000000n}`,n=ka.join(e,"lsp-log",t);return Zf.mkdirSync(n,{recursive:!0}),xe(n)}catch{return"auto"}}};function eP(r){let e=Lc(r);return f.info(`[SyncGuard] ${e.reason}`),e}var rP=(s=>(s[s.IDLE_CPP=0]="IDLE_CPP",s[s.DISCOVERING_CPP=1]="DISCOVERING_CPP",s[s.SYNCING_CPP=2]="SYNCING_CPP",s[s.INITIALIZING_CPP=3]="INITIALIZING_CPP",s[s.READY_CPP=4]="READY_CPP",s[s.ERROR_CPP=5]="ERROR_CPP",s))(rP||{}),Er=3,Qf=600*1e3,eg=100,Zd=["ohpm","hvigor","dep-parse","lsp-init"],tP={ohpm:"ohpm install",hvigor:"hvigor sync","dep-parse":"dependency parse","lsp-init":"LSP init"},Ra=15,Qd=class{server;toolRouter;config={};arktsCheckTool=null;cppCheckTool=null;cppLspTool=null;cppLspManager=null;projectState=0;workspaceRoot="";sdkPath="";arktsLangServerPath=null;nodePath="";ohpmJsPath="";hvigorJsPath="";clangdPath=null;initPromise=null;needsReinit=!1;initRetryCount=0;originalProjectPath="";configChangedTriggeredResync=!1;syncSkippedDueToLock=!1;syncSkipStartedAt=0;arktsInitProgress=null;arktsPipelineStartedAt=0;standardProtocolAvailable=!1;socketAvailable=!1;cppProjectState=0;cppInitPromise=null;cppNeedsReinit=!1;cppInitRetryCount=0;cppSyncSkippedDueToLock=!1;cppSyncSkipStartedAt=0;cppHasNoCppCode=!1;cppEnabled;cppCustomCompileCommandsDir=null;cppCustomDirResolvedFor="";constructor(e={}){this.config=e,zn(e.debug??!1);let t,n=e.projectPath?.trim()??"";this.originalProjectPath=n,n==="."?(t=process.cwd(),h.info(`Constructor: configuredPath is '.', startPath: '${t}'`)):n===""?(t="",h.info("Constructor: configuredPath is empty, startPath remains empty")):(t=n,h.info(`Constructor: using configured path as startPath: '${t}'`));let i=Cr(t);h.info(`Constructor: findHarmonyProject('${t}') => ${i??"null"}`),this.config.projectPath=i??void 0,this.sdkPath=this.config.sdkPath??"",this.arktsLangServerPath=this.config.arktsLangServerPath??null,this.nodePath=this.config.nodePath??"",this.ohpmJsPath=this.config.ohpmJsPath??"",this.hvigorJsPath=this.config.hvigorJsPath??"",this.clangdPath=this.config.clangdPath??null,this.cppEnabled=this.config.cppEnabled??!0,h.info(`Constructor: sdkPath='${this.sdkPath}', arktsLangServerPath='${this.arktsLangServerPath??"(null)"}', cppEnabled=${this.cppEnabled}, cppCompileCommandsPath='${this.config.cppCompileCommandsPath??"(none)"}'`),this.server=new O0({name:"devecocli-mcp-server",version:"0.0.1"}),this.toolRouter=zf(e.telemetry,()=>this.arktsCheckTool?.aceServerPid??null,()=>this.config.projectPath??"",()=>this.sdkPath??""),this.standardProtocolAvailable=this.detectStandardProtocolAvailable()}registerTools(){this.registerCheckTool(),this.registerLspFeatureTools(),this.socketAvailable||this.registerRestartTool()}registerRestartTool(){this.toolRouter.add({name:"restart",description:"Restart the MCP server in-place: re-sync the project and re-initialize the LSP, without dropping the client connection. Use to recover from a stuck/ERROR state after fixing the root cause, instead of exiting and reopening the agent. Use target to restart one side only (arkts/cpp) or both (all, default). Only callable when the project state is ready/idle/error; during discovery/sync/init (large-project init can take minutes) it returns an error\u2014wait for ready and retry tools instead. Caution: if initialization fails again after a restart, the cause is likely a persistent project/SDK configuration issue\u2014do not call restart repeatedly; ask the user to fix the project first.",inputSchema:De.object({target:De.enum(["arkts","cpp","all"]).default("all").describe('Which backend to restart: "arkts" (ArkTS ace-server), "cpp" (C++ clangd), or "all" (both, default).')})},async e=>this.handleRestartCall(e))}registerCheckTool(){this.toolRouter.add({name:"check",description:"Perform static syntax analysis on HarmonyOS project source files and return structured diagnostics. Supported languages: ArkTS and C/C++.",inputSchema:De.object({files:De.array(De.string()).min(1).describe("List of source file paths to check, relative to the project root (absolute paths within the project are also accepted). Supports ArkTS and C/C++ files in the same call.")})},async e=>this.handleCheckCall(e))}registerLspFeatureTools(){if(!this.standardProtocolAvailable){h.info("Skip registering LSP feature tools (hover/definition/declaration/references/implementation, workspaceSymbol, documentSymbol, callHierarchy): standard LSP protocol unavailable (standardIndex/index.js not found). These tools require a DevEco Studio version that ships the standard LSP server entry.");return}let e=De.object({file:De.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets (ArkTS) and C/C++ extensions."),line:De.number().describe("Line number (0-based)"),character:De.number().describe("Character offset in the line (0-based)")});for(let{name:t,description:n,feature:i}of this.getPositionFeatures())this.toolRouter.add({name:t,description:n,inputSchema:e},async o=>this.handleLspFeatureCall(i,o));this.registerSymbolTools(),this.registerCallHierarchyTool()}getPositionFeatures(){return[{name:"hover",description:"Get hover information (type info, documentation) at a specific position in an ArkTS (.ets) or C/C++ file.",feature:"hover"},{name:"definition",description:"Find where the symbol at the given position is defined. Returns file path, line, and character.",feature:"definition"},{name:"declaration",description:"Find the declaration of the symbol at the given position. In ArkTS, this may differ from definition.",feature:"declaration"},{name:"references",description:"Find all references to the symbol at the given position across the HarmonyOS project.",feature:"references"},{name:"implementation",description:"Find implementations of the symbol at the given position (e.g., interface implementations).",feature:"implementation"}]}registerSymbolTools(){this.toolRouter.add({name:"workspaceSymbol",description:"Search for symbols by name across the entire HarmonyOS project.",inputSchema:De.object({query:De.string().describe("Symbol name (or partial) to search for")})},async e=>this.handleWorkspaceSymbolCall(e)),this.toolRouter.add({name:"documentSymbol",description:"Get the symbol tree (functions, classes, variables with ranges) of an ArkTS (.ets) or C/C++ file. Useful for file overview, structured code breakdown, and large file slicing.",inputSchema:De.object({file:De.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets and C/C++ extensions.")})},async e=>this.handleDocumentSymbolCall(e))}registerCallHierarchyTool(){this.toolRouter.add({name:"callHierarchy",description:'Query call hierarchy for a function at the given position. Use direction "incoming" to find callers, "outgoing" to find callees. ArkTS supports both directions; C/C++ (clangd) supports incoming only.',inputSchema:De.object({file:De.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets and C/C++ extensions."),line:De.number().describe("Line number (0-based)"),character:De.number().describe("Character offset in the line (0-based)"),direction:De.enum(["incoming","outgoing"]).describe('"incoming" = who calls this function, "outgoing" = what this function calls')})},async e=>this.handleCallHierarchyCall(e))}detectStandardProtocolAvailable(){try{let e=this.arktsLangServerPath;if(!e)return h.info("Standard LSP protocol unavailable: arkts-lang-server path not found"),!1;let t=Za(e);return h.info(`ArktsCheck protocol: ${t?"standard LSP":"legacy ace-server"} (standardIndex/index.js exists=${t})`),t}catch(e){return h.warn(`Failed to detect standard LSP protocol availability: ${e}`),!1}}async detectSocketAvailable(){try{let e=this.arktsLangServerPath;if(!e){this.socketAvailable=!1;return}this.socketAvailable=await Dh(e,Zn(this.nodePath)),h.info(`Socket transport: ${this.socketAvailable?"enabled":"disabled (stdio mode)"} (--list-protocols probe)`)}catch{this.socketAvailable=!1}}async handleCheckCall(e){let t=Array.isArray(e.files)?e.files.filter(d=>typeof d=="string"):[];if(t.length===0)return h.warn("check tool called with empty files list"),{content:[{type:"text",text:"No files provided"}],isError:!0};if(t.length>eg)return h.warn(`check tool called with ${t.length} files (max: ${eg})`),{content:[{type:"text",text:`Too many files: ${t.length}. Maximum allowed is ${eg}.`}],isError:!0};let{etsFiles:n,cppFiles:i,unsupported:o}=M0(t);o.length>0&&h.warn(`Unsupported file types in check request: ${o.join(", ")}`);let s=o.map(d=>`Unsupported file type: ${d} (only .ets and C/C++ source/header files are supported)`),a=[];n.length>0&&this.mergeCheckResult(await this.callArktsCheck(n),s,a),i.length>0&&this.mergeCheckResult(await this.callCppCheck(i),s,a);let c=s.length>0;return{content:[{type:"text",text:[a.join(`
1351
+ `).trim();return!o&&n.length===0&&(a="No diagnostic information collected"),{content:[{type:"text",text:a}],isError:o}}async checkFile(e){let t=Mt(e),n=await Nn.promises.readFile(e,"utf8"),i=wc(e),o=this.manager.registerDiagnosticCallback(t);this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didOpen",params:{textDocument:{uri:t,text:n,languageId:i,version:n.length}}});try{return await o}finally{this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didClose",params:{textDocument:{uri:t}}})}}collectValidFiles(e,t){let n=Ti.resolve(this.manager.projectRoot),i=[];for(let o of e){let s=Ti.resolve(Ti.isAbsolute(o)?o:Ti.join(n,o));if(!Nn.existsSync(s)){t.push(`File does not exist: ${o}`);continue}if(!Nn.statSync(s).isFile()){t.push(`Not a regular file: ${o}`);continue}if(!Kn(s)){t.push(`Not a supported C/C++ file: ${o}`);continue}try{i.push(Nn.realpathSync(s))}catch{i.push(s)}}return i}};function oU(r,e){if(Array.isArray(e))return e.length===0?`${r} => no diagnostics`:`${r} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${r} diagnostic failed, error_message: ${t}`}return`${r} => diagnostic failed, result: ${JSON.stringify(e)}`}function sU(r){return new Promise(e=>setTimeout(e,r))}import*as os from"fs";import*as xu from"path";var is=class r{manager;static FEATURE_METHOD_MAP={hover:b.HOVER,definition:b.DEFINITION,declaration:b.DECLARATION,references:b.REFERENCES,implementation:b.IMPLEMENTATION};constructor(e){this.manager=e}async handleLspFeature(e,t){if(!this.manager.ready)return rs();let n=this.resolveSingleFile(t.file);if(!n)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${t.file}`}],isError:!0};let i=r.FEATURE_METHOD_MAP[e];if(!i)return{content:[{type:"text",text:`Unknown feature: ${e}`}],isError:!0};h.info(`[ClangdLspTool] handleLspFeature: ${e} file=${n} line=${t.line} char=${t.character}`);try{let o=await this.withOpenFile(n,async a=>{let c={textDocument:{uri:a},position:{line:t.line,character:t.character}};return e==="references"&&(c.context={includeDeclaration:!0}),this.manager.sendFeatureRequest(i,c)});return{content:[{type:"text",text:o==null?`${e}: no result`:`${e}: ${JSON.stringify(o,null,2)}`}]}}catch(o){return Ru(e,o)}}async handleWorkspaceSymbolRaw(e){if(!this.manager.ready)return null;try{let t=await this.manager.sendFeatureRequest(b.WORKSPACE_SYMBOL,{query:e});return Array.isArray(t)?t:t==null?null:[t]}catch(t){return h.error(`[ClangdLspTool] handleWorkspaceSymbolRaw failed: ${t.message}`),null}}async handleDocumentSymbol(e){if(!this.manager.ready)return rs();let t=this.resolveSingleFile(e);if(!t)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${e}`}],isError:!0};h.info(`[ClangdLspTool] handleDocumentSymbol: file=${t}`);try{let n=await this.withOpenFile(t,async o=>this.manager.sendFeatureRequest(b.DOCUMENT_SYMBOL,{textDocument:{uri:o}}));return{content:[{type:"text",text:n==null?"documentSymbol: no result":`documentSymbol: ${JSON.stringify(n,null,2)}`}]}}catch(n){return Ru("documentSymbol",n)}}async handleCallHierarchy(e){if(!this.manager.ready)return rs();if(e.direction==="outgoing")return{content:[{type:"text",text:"callHierarchy outgoing is not supported by clangd (incoming only)"}],isError:!0};let t=this.resolveSingleFile(e.file);if(!t)return{content:[{type:"text",text:`File does not exist or is not a C/C++ file: ${e.file}`}],isError:!0};h.info(`[ClangdLspTool] handleCallHierarchy: file=${t} line=${e.line} char=${e.character} direction=${e.direction}`);try{let n=await this.withOpenFile(t,o=>this.fetchCallHierarchyResult(o,e));return{content:[{type:"text",text:`callHierarchy (${e.direction}): ${JSON.stringify(n,null,2)}`}]}}catch(n){return Ru("callHierarchy",n)}}async fetchCallHierarchyResult(e,t){let n=await this.manager.sendFeatureRequest(b.PREPARE_CALL_HIERARCHY,{textDocument:{uri:e},position:{line:t.line,character:t.character}}),i=this.normalizeCallHierarchyItems(n);if(i.length===0)return{items:[],calls:[]};let o=await this.collectIncomingCalls(i);return{items:i,calls:o}}normalizeCallHierarchyItems(e){return Array.isArray(e)?e:e?[e]:[]}async collectIncomingCalls(e){let t=[];for(let n of e)t.push(...await this.fetchIncomingCalls(n));return t}async fetchIncomingCalls(e){let t=await this.manager.sendFeatureRequest(b.INCOMING_CALLS,{item:e});return Array.isArray(t)?t:t?[t]:[]}async withOpenFile(e,t){let n=Mt(e),i=await os.promises.readFile(e,"utf8"),o=wc(e);h.info(`[ClangdLspTool] withOpenFile didOpen uri=${n} langId=${o} len=${i.length}`),this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didOpen",params:{textDocument:{uri:n,text:i,languageId:o,version:i.length}}});try{return await t(n)}finally{this.manager.sendNotification({jsonrpc:"2.0",method:"textDocument/didClose",params:{textDocument:{uri:n}}})}}resolveSingleFile(e){let t=xu.isAbsolute(e)?e:xu.join(this.manager.projectRoot,e);return!os.existsSync(t)||!os.statSync(t).isFile()||!Kn(t)?null:t}};import{spawn as aU}from"child_process";import*as Iu from"fs";import*as AC from"path";var cU=30*1e3,lU=30*1e3,Du=class{config;client=null;clangdProcess=null;nextRequestId=1;requestCallbacks=new Dn;diagnosticWaiters=new Map;lastStartErrorMessage=null;onMessage=()=>{};disposeOnce=null;constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}get clangdPid(){return this.clangdProcess?.pid??null}consumeStartErrorMessage(){let e=this.lastStartErrorMessage;return this.lastStartErrorMessage=null,e}async start(e){let t=!1;try{m.info(`[ClangdLspProxy] clangdPath: ${this.config.clangdPath}`),m.info(`[ClangdLspProxy] workspaceRoot: ${this.config.workspaceRoot}`),m.info(`[ClangdLspProxy] compileCommandsDir: ${this.config.compileCommandsDir}`),this.ensureLogDir(),this.clangdProcess=this.spawnClangd();let n={serverPath:"",logPath:this.config.logPath,indexingDataLocation:this.config.logPath,cwd:this.config.workspaceRoot};this.client=new xn(n),this.client.on("message",o=>this.handleRawMessage(o)),this.client.on("error",o=>this.handleError(o)),this.client.attachProcess(this.clangdProcess,{stderrAsError:!1});let i=this.buildInitializeParams();await this.sendLspRequest(b.INITIALIZE,i,ot),m.info("[ClangdLspProxy] initialize response received"),this.sendNotification(b.INITIALIZED,{}),t=!0}catch(n){this.lastStartErrorMessage=n instanceof Error?n.message:String(n),m.error(`[ClangdLspProxy] initialization failed: ${this.lastStartErrorMessage}`),await this.dispose()}e?.(t)}async hover(e){return this.sendLspRequest(b.HOVER,e)}async definition(e){return this.sendLspRequest(b.DEFINITION,e)}async declaration(e){return this.sendLspRequest(b.DECLARATION,e)}async references(e){return this.sendLspRequest(b.REFERENCES,e)}async implementation(e){return this.sendLspRequest(b.IMPLEMENTATION,e)}async documentSymbol(e){return this.sendLspRequest(b.DOCUMENT_SYMBOL,e)}async workspaceSymbol(e){return this.sendLspRequest(b.WORKSPACE_SYMBOL,e)}async prepareCallHierarchy(e){return this.sendLspRequest(b.PREPARE_CALL_HIERARCHY,e)}async incomingCalls(e){return this.sendLspRequest(b.INCOMING_CALLS,e)}async sendFeatureRequest(e,t){return this.sendLspRequest(e,t)}sendDidOpen(e){this.sendNotification(b.DID_OPEN,e)}sendDidChange(e){this.sendNotification(b.DID_CHANGE,e)}sendDidClose(e){this.sendNotification(b.DID_CLOSE,e)}sendNotification(e,t){if(!this.client){m.warn("[ClangdLspProxy] sendNotification before ready, dropped");return}this.client.sendNotification(e,t)}registerDiagnosticCallback(e){let t=this.normalizeClangdUri(e);if(this.diagnosticWaiters.has(t)){m.warn(`[ClangdLspProxy] overwrite existing diagnostic waiter for ${t}`);let n=this.diagnosticWaiters.get(t);clearTimeout(n.timer),this.diagnosticWaiters.delete(t)}return new Promise((n,i)=>{let o=setTimeout(()=>{this.diagnosticWaiters.delete(t)&&i(new Error(`Wait for clangd diagnostics timeout, uri: ${t}`))},lU);this.diagnosticWaiters.set(t,{resolve:n,reject:i,timer:o})})}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}async performDispose(){this.requestCallbacks.rejectAll(new Error("ClangdLspProxy disposing"));for(let[,e]of this.diagnosticWaiters)clearTimeout(e.timer),e.reject(new Error("ClangdLspProxy disposing"));if(this.diagnosticWaiters.clear(),this.client&&this.clangdProcess)try{await this.sendLspRequest(b.SHUTDOWN,null,3e3).catch(e=>{m.warn(`[ClangdLspProxy] shutdown request failed: ${e}`)}),this.sendNotification(b.EXIT,null),await this.client.waitForExitOrTimeout(300)}catch(e){m.warn(`[ClangdLspProxy] dispose error: ${e}`)}if(this.clangdProcess){try{this.clangdProcess.exitCode===null&&this.clangdProcess.signalCode===null&&this.clangdProcess.kill()}catch{}this.clangdProcess=null}this.client=null}spawnClangd(){let e=[`--compile-commands-dir=${he(this.config.compileCommandsDir)}`,"--log=info","--pch-storage=memory","--limit-results=100"];m.info(`[ClangdLspProxy] spawn: ${this.config.clangdPath} ${e.join(" ")}`);let t=aU(this.config.clangdPath,e,{cwd:this.config.workspaceRoot,stdio:["pipe","pipe","pipe"],windowsHide:!0});if(!t.stdin||!t.stdout||!t.stderr)throw new Error("Failed to spawn clangd: stdio not available");return t}buildInitializeParams(){let e=so(this.config.workspaceRoot),t=Wt(e),n=AC.basename(e)||"workspace";return{processId:process.pid,clientInfo:{name:"devecocli-mcp-server",version:"1.3.10-Test.1"},rootPath:e,rootUri:t,workspaceFolders:[{uri:t,name:n}],capabilities:this.buildClientCapabilities(),initializationOptions:null}}buildClientCapabilities(){return{textDocument:{synchronization:{didOpen:!0,didChange:!0,didClose:!0,willSave:!1,save:!1},publishDiagnostics:{relatedInformation:!0,versionSupport:!1,tagSupport:{valueSet:[1,2]}},hover:{contentFormat:["markdown","plaintext"]},completion:{contextSupport:!1,completionItemKind:{valueSet:[]}},signatureHelp:{signatureInformation:{documentationFormat:["markdown","plaintext"]}},references:{},declaration:{linkSupport:!0},definition:{linkSupport:!0},implementation:{linkSupport:!0},documentSymbol:{hierarchicalDocumentSymbolSupport:!0,symbolKind:{valueSet:[]}},callHierarchy:{dynamicRegistration:!1}},workspace:{symbol:{symbolKind:{valueSet:[]}},configuration:!1,didChangeWatchedFiles:{dynamicRegistration:!1}}}}sendLspRequest(e,t,n=cU){if(!this.client)return Promise.reject(new Error("[ClangdLspProxy] client not ready"));let i=this.nextRequestId++,o=this.requestCallbacks.registerPending(i,e,n);return this.client.sendRequest(e,t,i),o}handleRawMessage(e){let t;try{t=JSON.parse(e)}catch(n){let i=n instanceof Error?n.message:String(n);m.error(`[ClangdLspProxy] JSON parse error: ${i}, raw: ${e.slice(0,200)}`);return}"id"in t&&("result"in t||"error"in t)?this.handleResponse(t):"method"in t?this.handleNotification(t):m.warn(`[ClangdLspProxy] unrecognized message: ${JSON.stringify(t).slice(0,200)}`)}handleResponse(e){let t=e.id;if(t==null||typeof t!="string"&&typeof t!="number")return;let n=t;if(e.error!==void 0&&e.error!==null){let i=e.error;m.warn(`[ClangdLspProxy] LSP error id=${n}: code=${i.code??-1} message=${i.message??"unknown"}`),this.requestCallbacks.rejectPending(n,new Error(`LSP error ${i.code??-1}: ${i.message??"unknown"}`))}else this.requestCallbacks.resolvePending(n,e.result)}handleNotification(e){let t=e.method;if(t)switch(t){case b.PUBLISH_DIAGNOSTICS:this.handlePublishDiagnostics(e.params);break;case b.PROGRESS:this.onMessage({jsonrpc:L,method:b.PROGRESS,params:e.params});break;case b.WINDOW_SHOW_MESSAGE:m.info(`[ClangdLspProxy] window/showMessage: ${JSON.stringify(e.params)}`);break;case b.WINDOW_LOG_MESSAGE:m.info(`[ClangdLspProxy] window/logMessage: ${JSON.stringify(e.params)}`);break;default:this.onMessage({jsonrpc:L,method:t,params:e.params})}}handlePublishDiagnostics(e){if(!e||!e.uri)return;let t=this.normalizeClangdUri(e.uri),n=this.diagnosticWaiters.get(t);if(!n&&this.diagnosticWaiters.size===1){let s=this.diagnosticWaiters.keys().next().value;n=this.diagnosticWaiters.get(s),n&&this.diagnosticWaiters.delete(s)}else n&&this.diagnosticWaiters.delete(t);if(!n)return;clearTimeout(n.timer);let i=Array.isArray(e.diagnostics)?e.diagnostics:[],o=i.length;m.info(`[ClangdLspProxy] diagnostics received uri=${t} count=${o}`),n.resolve(i)}handleError(e){for(let[,t]of this.diagnosticWaiters)clearTimeout(t.timer),t.reject(e);this.diagnosticWaiters.clear(),this.requestCallbacks.rejectAll(e),this.onMessage({jsonrpc:L,method:b.CPP_ERROR,params:{message:e.message}})}ensureLogDir(){if(this.config.logPath)try{Iu.existsSync(this.config.logPath)||Iu.mkdirSync(this.config.logPath,{recursive:!0})}catch{}}normalizeClangdUri(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=decodeURIComponent(t.pathname);return process.platform==="win32"&&/^\/[a-zA-Z]:/.test(n)&&(n=n.slice(1)),Wt(n)}}catch{}return e}};import*as Va from"path";import*as Gg from"fs";var Ga=class r{config;proxy=null;isInitialized=!1;onMessage=()=>{};disposeOnce=null;initPromise=null;initDeadlineTimer=null;initResolve=null;initReject=null;resolvedRoot="";constructor(e){this.config=e}setOnMessage(e){this.onMessage=e}get ready(){return this.isInitialized&&this.proxy!==null}get clangdPid(){return this.proxy?.clangdPid??null}get projectRoot(){return this.resolvedRoot}async start(){if(!this.isInitialized){if(this.initPromise){await this.initPromise;return}this.initPromise=this.doStart();try{await this.initPromise}catch(e){throw this.initPromise=null,e}}}sendNotification(e){if(!this.proxy){m.warn("[ClangdLspManager] sendNotification before LSP ready, dropped");return}this.dispatchNotification(e)}async sendFeatureRequest(e,t){if(!this.proxy)throw new Error("[ClangdLspManager] LSP not ready");return this.proxy.sendFeatureRequest(e,t)}registerDiagnosticCallback(e){return this.proxy?this.proxy.registerDiagnosticCallback(e):Promise.reject(new Error("[ClangdLspManager] LSP not ready"))}static async handleSyncCppProject(e,t,n,i,o){if(m.info("[ClangdLspManager] Received cpp/syncProject"),!e||!t)return m.error("[ClangdLspManager] handleSyncCppProject: workspaceRoot or sdkPath is empty"),{status:"failed",reason:"workspaceRoot or sdkPath is empty"};if(dn(e).length===0)return m.info("[ClangdLspManager] No C++ modules found, skipping compileNative"),{status:"success"};let a=o?.skipCompileNative===!0,c=await Zc(e,a?async()=>(m.info("[ClangdLspManager] compileNative skipped (C++ project up-to-date)"),{status:"success"}):async()=>r.executeCompileNative(e,t,n,i));return c.acquired?c.result:(m.info("[ClangdLspManager] Build lock held by another process, skipping sync"),{status:"skipped",reason:"build lock held by another process"})}static async executeCompileNative(e,t,n,i){try{return await ev(e,t,n,i),m.info("[ClangdLspManager] compileNative + merge compile_commands completed"),{status:"success"}}catch(o){let s=o instanceof Error?o.message:String(o);return m.error(`[ClangdLspManager] compileNative failed: ${s}`),{status:"failed",reason:s}}}async dispose(){return this.disposeOnce||(this.disposeOnce=this.performDispose()),this.disposeOnce}doStart(){return new Promise((e,t)=>{this.initResolve=e,this.initReject=t,this.armInitTimer(ot);try{this.startProxy()}catch(n){this.failInit(n instanceof Error?n:new Error(String(n)))}})}startProxy(){let e=Ir(this.config.workspaceRoot);this.resolvedRoot=e?Ie(e):Ie(this.config.workspaceRoot);let t=this.config.logPath??this.getLogPath();tl(t);let n=this.config.clangdPath;if(!n){let s="clangd not found (install DevEco Studio / CLT)";m.error(`[ClangdLspManager] ${s}`),this.failInit(new Error(s));return}let i=this.config.compileCommandsDir??Va.dirname(Jn(this.resolvedRoot));try{Gg.mkdirSync(i,{recursive:!0})}catch(s){m.warn(`[ClangdLspManager] Failed to create compile_commands dir: ${s}`)}m.info(`[ClangdLspManager] clangdPath: ${n}`),m.info(`[ClangdLspManager] workspaceRoot: ${this.resolvedRoot}`),m.info(`[ClangdLspManager] compileCommandsDir: ${i}`);let o=new Du({clangdPath:n,workspaceRoot:this.resolvedRoot,compileCommandsDir:i,logPath:t});o.setOnMessage(s=>this.handleLspMessage(s)),this.proxy=o,o.start(s=>this.handleProxyInitialized(s)).catch(s=>{let a=s instanceof Error?s:new Error(String(s));this.handleProxyInitialized(!1,a.message)})}handleProxyInitialized=(e,t)=>{if(this.clearInitTimer(),e){this.isInitialized=!0,m.info("[ClangdLspManager] clangd initialized");let n=this.initResolve;this.clearInitHandlers(),n?.()}else{let n=t??this.proxy?.consumeStartErrorMessage()??"unknown error";m.error(`[ClangdLspManager] clangd initialization failed: ${n}`),this.isInitialized=!1,this.proxy=null;let i=this.initReject;this.clearInitHandlers(),i?.(new Error(`C++ LSP initialize failed: ${n}`))}};handleLspMessage(e){this.onMessage(e)}dispatchNotification(e){if(!this.proxy)return;let t=e,n=t.method;if(!n){m.warn("[ClangdLspManager] dispatchNotification: missing method");return}let i=t.params;switch(n){case b.DID_OPEN:this.proxy.sendDidOpen(i);break;case b.DID_CHANGE:this.proxy.sendDidChange(i);break;case b.DID_CLOSE:this.proxy.sendDidClose(i);break;default:this.proxy.sendNotification(n,i)}}armInitTimer(e){this.clearInitTimer(),this.initDeadlineTimer=setTimeout(()=>{this.failInit(new Error("C++ LSP initialize timeout"))},e)}clearInitTimer(){this.initDeadlineTimer&&(clearTimeout(this.initDeadlineTimer),this.initDeadlineTimer=null)}clearInitHandlers(){this.clearInitTimer(),this.initResolve=null,this.initReject=null}failInit(e){let t=this.initReject;this.clearInitHandlers(),t?.(e)}async performDispose(){let e=this.initReject;if(this.clearInitHandlers(),e?.(new Error("ClangdLspManager disposing")),this.proxy){try{await this.proxy.dispose()}catch(t){m.warn(`[ClangdLspManager] proxy dispose error: ${t}`)}this.proxy=null}this.isInitialized=!1,this.initPromise=null}getLogPath(){try{let e=Va.join(rn(),"CppCheck"),t=`${Date.now()}${process.hrtime.bigint()%1000000n}`,n=Va.join(e,"lsp-log",t);return Gg.mkdirSync(n,{recursive:!0}),Ie(n)}catch{return"auto"}}};function TC(r){let e=Qc(r);return m.info(`[SyncGuard] ${e.reason}`),e}var OC=(s=>(s[s.IDLE_CPP=0]="IDLE_CPP",s[s.DISCOVERING_CPP=1]="DISCOVERING_CPP",s[s.SYNCING_CPP=2]="SYNCING_CPP",s[s.INITIALIZING_CPP=3]="INITIALIZING_CPP",s[s.READY_CPP=4]="READY_CPP",s[s.ERROR_CPP=5]="ERROR_CPP",s))(OC||{}),xr=3,qg=600*1e3,zg=100,Au=["ohpm","hvigor","dep-parse","lsp-init"],NC={ohpm:"ohpm install",hvigor:"hvigor sync","dep-parse":"dependency parse","lsp-init":"LSP init"},qa=15,Tu=class{server;toolRouter;config={};arktsCheckTool=null;cppCheckTool=null;cppLspTool=null;cppLspManager=null;projectState=0;workspaceRoot="";sdkPath="";arktsLangServerPath=null;nodePath="";ohpmJsPath="";hvigorJsPath="";clangdPath=null;initPromise=null;needsReinit=!1;initRetryCount=0;originalProjectPath="";configChangedTriggeredResync=!1;syncSkippedDueToLock=!1;syncSkipStartedAt=0;arktsInitProgress=null;arktsPipelineStartedAt=0;standardProtocolAvailable=!1;socketAvailable=!1;cppProjectState=0;cppInitPromise=null;cppNeedsReinit=!1;cppInitRetryCount=0;cppSyncSkippedDueToLock=!1;cppSyncSkipStartedAt=0;cppHasNoCppCode=!1;cppEnabled;cppCustomCompileCommandsDir=null;cppCustomDirResolvedFor="";constructor(e={}){this.config=e,Yn(e.debug??!1);let t,n=e.projectPath?.trim()??"";this.originalProjectPath=n,n==="."?(t=process.cwd(),h.info(`Constructor: configuredPath is '.', startPath: '${t}'`)):n===""?(t="",h.info("Constructor: configuredPath is empty, startPath remains empty")):(t=n,h.info(`Constructor: using configured path as startPath: '${t}'`));let i=Ir(t);h.info(`Constructor: findHarmonyProject('${t}') => ${i??"null"}`),this.config.projectPath=i??void 0,this.sdkPath=this.config.sdkPath??"",this.arktsLangServerPath=this.config.arktsLangServerPath??null,this.nodePath=this.config.nodePath??"",this.ohpmJsPath=this.config.ohpmJsPath??"",this.hvigorJsPath=this.config.hvigorJsPath??"",this.clangdPath=this.config.clangdPath??null,this.cppEnabled=this.config.cppEnabled??!0,h.info(`Constructor: sdkPath='${this.sdkPath}', arktsLangServerPath='${this.arktsLangServerPath??"(null)"}', cppEnabled=${this.cppEnabled}, cppCompileCommandsPath='${this.config.cppCompileCommandsPath??"(none)"}'`),this.server=new dU({name:"devecocli-mcp-server",version:"0.0.1"}),this.toolRouter=Hg(e.telemetry,()=>this.arktsCheckTool?.aceServerPid??null,()=>this.config.projectPath??"",()=>this.sdkPath??""),this.standardProtocolAvailable=this.detectStandardProtocolAvailable()}registerTools(){this.registerCheckTool(),this.registerLspFeatureTools(),this.socketAvailable||this.registerRestartTool()}registerRestartTool(){this.toolRouter.add({name:"restart",description:"Restart the MCP server in-place: re-sync the project and re-initialize the LSP, without dropping the client connection. Use to recover from a stuck/ERROR state after fixing the root cause, instead of exiting and reopening the agent. Use target to restart one side only (arkts/cpp) or both (all, default). Only callable when the project state is ready/idle/error; during discovery/sync/init (large-project init can take minutes) it returns an error\u2014wait for ready and retry tools instead. Caution: if initialization fails again after a restart, the cause is likely a persistent project/SDK configuration issue\u2014do not call restart repeatedly; ask the user to fix the project first.",inputSchema:xe.object({target:xe.enum(["arkts","cpp","all"]).default("all").describe('Which backend to restart: "arkts" (ArkTS ace-server), "cpp" (C++ clangd), or "all" (both, default).')})},async e=>this.handleRestartCall(e))}registerCheckTool(){this.toolRouter.add({name:"check",description:"Perform static syntax analysis on HarmonyOS project source files and return structured diagnostics. Supported languages: ArkTS and C/C++.",inputSchema:xe.object({files:xe.array(xe.string()).min(1).describe("List of source file paths to check, relative to the project root (absolute paths within the project are also accepted). Supports ArkTS and C/C++ files in the same call.")})},async e=>this.handleCheckCall(e))}registerLspFeatureTools(){if(!this.standardProtocolAvailable){h.info("Skip registering LSP feature tools (hover/definition/declaration/references/implementation, workspaceSymbol, documentSymbol, callHierarchy): standard LSP protocol unavailable (standardIndex/index.js not found). These tools require a DevEco Studio version that ships the standard LSP server entry.");return}let e=xe.object({file:xe.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets (ArkTS) and C/C++ extensions."),line:xe.number().describe("Line number (0-based)"),character:xe.number().describe("Character offset in the line (0-based)")});for(let{name:t,description:n,feature:i}of this.getPositionFeatures())this.toolRouter.add({name:t,description:n,inputSchema:e},async o=>this.handleLspFeatureCall(i,o));this.registerSymbolTools(),this.registerCallHierarchyTool()}getPositionFeatures(){return[{name:"hover",description:"Get hover information (type info, documentation) at a specific position in an ArkTS (.ets) or C/C++ file.",feature:"hover"},{name:"definition",description:"Find where the symbol at the given position is defined. Returns file path, line, and character.",feature:"definition"},{name:"declaration",description:"Find the declaration of the symbol at the given position. In ArkTS, this may differ from definition.",feature:"declaration"},{name:"references",description:"Find all references to the symbol at the given position across the HarmonyOS project.",feature:"references"},{name:"implementation",description:"Find implementations of the symbol at the given position (e.g., interface implementations).",feature:"implementation"}]}registerSymbolTools(){this.toolRouter.add({name:"workspaceSymbol",description:"Search for symbols by name across the entire HarmonyOS project.",inputSchema:xe.object({query:xe.string().describe("Symbol name (or partial) to search for")})},async e=>this.handleWorkspaceSymbolCall(e)),this.toolRouter.add({name:"documentSymbol",description:"Get the symbol tree (functions, classes, variables with ranges) of an ArkTS (.ets) or C/C++ file. Useful for file overview, structured code breakdown, and large file slicing.",inputSchema:xe.object({file:xe.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets and C/C++ extensions.")})},async e=>this.handleDocumentSymbolCall(e))}registerCallHierarchyTool(){this.toolRouter.add({name:"callHierarchy",description:'Query call hierarchy for a function at the given position. Use direction "incoming" to find callers, "outgoing" to find callees. ArkTS supports both directions; C/C++ (clangd) supports incoming only.',inputSchema:xe.object({file:xe.string().describe("Source file path, relative to the project root (absolute paths within the project are also accepted). Supports .ets and C/C++ extensions."),line:xe.number().describe("Line number (0-based)"),character:xe.number().describe("Character offset in the line (0-based)"),direction:xe.enum(["incoming","outgoing"]).describe('"incoming" = who calls this function, "outgoing" = what this function calls')})},async e=>this.handleCallHierarchyCall(e))}detectStandardProtocolAvailable(){try{let e=this.arktsLangServerPath;if(!e)return h.info("Standard LSP protocol unavailable: arkts-lang-server path not found"),!1;let t=yc(e);return h.info(`ArktsCheck protocol: ${t?"standard LSP":"legacy ace-server"} (standardIndex/index.js exists=${t})`),t}catch(e){return h.warn(`Failed to detect standard LSP protocol availability: ${e}`),!1}}async detectSocketAvailable(){try{let e=this.arktsLangServerPath;if(!e){this.socketAvailable=!1;return}this.socketAvailable=await vy(e,ri(this.nodePath)),h.info(`Socket transport: ${this.socketAvailable?"enabled":"disabled (stdio mode)"} (--list-protocols probe)`)}catch{this.socketAvailable=!1}}async handleCheckCall(e){let t=Array.isArray(e.files)?e.files.filter(d=>typeof d=="string"):[];if(t.length===0)return h.warn("check tool called with empty files list"),{content:[{type:"text",text:"No files provided"}],isError:!0};if(t.length>zg)return h.warn(`check tool called with ${t.length} files (max: ${zg})`),{content:[{type:"text",text:`Too many files: ${t.length}. Maximum allowed is ${zg}.`}],isError:!0};let{etsFiles:n,cppFiles:i,unsupported:o}=pU(t);o.length>0&&h.warn(`Unsupported file types in check request: ${o.join(", ")}`);let s=o.map(d=>`Unsupported file type: ${d} (only .ets and C/C++ source/header files are supported)`),a=[];n.length>0&&this.mergeCheckResult(await this.callArktsCheck(n),s,a),i.length>0&&this.mergeCheckResult(await this.callCppCheck(i),s,a);let c=s.length>0;return{content:[{type:"text",text:[a.join(`
1336
1352
  `),s.join(`
1337
1353
  `)].filter(d=>d.trim().length>0).join(`
1338
- `).trim()||"No diagnostics collected"}],isError:c}}async callArktsCheck(e){switch(this.projectState){case 0:return this.handleIdleCheck();case 1:return h.warn(`ArkTS check rejected: project is DISCOVERING, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 2:return h.warn(`ArkTS check rejected: project is SYNCING, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 3:return h.warn(`ArkTS check rejected: LSP is initializing, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 5:return this.handleErrorCheck();case 4:return this.arktsCheckTool.handleCall({files:e});default:return h.error(`ArkTS check: unknown project state ${this.projectState}, files: ${e.join(", ")}`),{content:[{type:"text",text:`Unknown project state: ${this.projectState}`}],isError:!0}}}async handleLspFeatureCall(e,t){let n=t.file,i=t.line,o=t.character;return typeof n!="string"||typeof i!="number"||typeof o!="number"?{content:[{type:"text",text:"Missing or invalid parameters. Required: file (string), line (number), character (number)."}],isError:!0}:this.routeLspRequest(n,e,async()=>{if(n.endsWith(".ets"))return this.arktsCheckTool.handleLspFeature(e,{file:n,line:i,character:o});let s=e;return this.cppLspTool.handleLspFeature(s,{file:n,line:i,character:o})})}async handleWorkspaceSymbolCall(e){let t=e.query;return typeof t!="string"||t.trim().length===0?{content:[{type:"text",text:"Missing or invalid parameter: query (non-empty string required)."}],isError:!0}:this.routeWorkspaceSymbolRequest(t)}async routeWorkspaceSymbolRequest(e){let t=this.projectState===4&&this.arktsCheckTool!==null,n=this.cppProjectState===4&&!this.cppHasNoCppCode&&this.cppLspTool!==null;if(!t&&!n){let a=this.describeArktsState(),c=this.describeCppState();return h.info(`workspaceSymbol rejected: ArkTS ${a}; C++ ${c}`),{content:[{type:"text",text:`workspaceSymbol: ArkTS ${a}; C++ ${c}`}],isError:!0}}let i=[],o=new Set;if(t)try{this.mergeSymbolItems(await this.arktsCheckTool.handleWorkspaceSymbolRaw(e),o,i)}catch(a){h.warn(`workspaceSymbol ArkTS query failed: ${a.message}`)}if(n)try{this.mergeSymbolItems(await this.cppLspTool.handleWorkspaceSymbolRaw(e),o,i)}catch(a){h.warn(`workspaceSymbol C++ query failed: ${a.message}`)}return{content:[{type:"text",text:i.length===0?"workspaceSymbol: no result":`workspaceSymbol: ${JSON.stringify(i,null,2)}`}]}}symbolDedupKey(e){let t=e,n=t?.location?.uri??"",i=t?.location?.range?.start?.line??0,o=t?.location?.range?.start?.character??0;return`${n}:${i}:${o}`}mergeSymbolItems(e,t,n){if(e)for(let i of e){let o=this.symbolDedupKey(i);t.has(o)||(t.add(o),n.push(i))}}describeArktsState(){switch(this.projectState){case 0:return"idle";case 1:return"discovering";case 2:return`syncing (retry ${Ra}s)`;case 3:return`initializing (retry ${Ra}s)`;case 5:return`error (${this.initRetryCount}/${Er})`;case 4:return"ready";default:return"unknown"}}describeCppState(){switch(this.cppProjectState){case 0:return"idle";case 1:return"discovering";case 2:return"syncing (retry 25s)";case 3:return"initializing (retry 10s)";case 5:return`error (${this.cppInitRetryCount}/${Er})`;case 4:return this.cppHasNoCppCode?"ready (no C++ code)":"ready";default:return"unknown"}}async handleDocumentSymbolCall(e){let t=e.file;return typeof t!="string"?{content:[{type:"text",text:"Missing or invalid parameter: file (string required)."}],isError:!0}:this.routeLspRequest(t,"documentSymbol",async()=>t.endsWith(".ets")?this.arktsCheckTool.handleDocumentSymbol(t):this.cppLspTool.handleDocumentSymbol(t))}async handleCallHierarchyCall(e){let t=e.file,n=e.line,i=e.character,o=e.direction;return typeof t!="string"||typeof n!="number"||typeof i!="number"?{content:[{type:"text",text:"Missing or invalid parameters. Required: file (string), line (number), character (number)."}],isError:!0}:o!=="incoming"&&o!=="outgoing"?{content:[{type:"text",text:'Parameter direction must be "incoming" or "outgoing".'}],isError:!0}:this.routeLspRequest(t,`callHierarchy(${o})`,async()=>t.endsWith(".ets")?this.arktsCheckTool.handleCallHierarchy({file:t,line:n,character:i,direction:o}):this.cppLspTool.handleCallHierarchy({file:t,line:n,character:i,direction:o}))}async routeArktsRequest(e,t){switch(this.projectState){case 0:return this.handleIdleCheck();case 1:return h.warn(`ArkTS ${e} rejected: project is DISCOVERING`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 2:return h.warn(`ArkTS ${e} rejected: project is SYNCING`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 3:return h.warn(`ArkTS ${e} rejected: LSP is initializing`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 5:return this.handleErrorCheck();case 4:return t();default:return h.warn(`ArkTS ${e} rejected: unknown project state ${this.projectState}`),{content:[{type:"text",text:"Unknown project state, please retry"}],isError:!0}}}async handleIdleCheck(){if(this.ensureProjectReady(),this.config.projectPath){let e,t;return this.syncSkippedDueToLock?(e=`Another build process is running, sync deferred (waiting ${this.syncSkipStartedAt>0?Math.round((Date.now()-this.syncSkipStartedAt)/1e3):0}s), please retry in 25 seconds`,t="lock contention",this.syncSkippedDueToLock=!1):this.configChangedTriggeredResync?(e=this.arktsInitProgress?this.buildInitRetryMessage():`Config file changed, resyncing project.${this.buildRetrySuffix()}`,t="config changed",this.configChangedTriggeredResync=!1):(e=this.arktsInitProgress?this.buildInitRetryMessage():`ArkTS project detected, syncing.${this.buildRetrySuffix()}`,t="initial"),h.info(`Idle check: project '${this.config.projectPath}' already known, triggering init (${t})`),{content:[{type:"text",text:e}],isError:!0}}return this.workspaceRoot||this.originalProjectPath?(h.info(`Idle check: no project path yet, will try from '${this.workspaceRoot}' or '${this.originalProjectPath}'`),{content:[{type:"text",text:`Initializing.${this.buildRetrySuffix()}`}],isError:!0}):(h.warn("Idle check: no search candidates available"),{content:[{type:"text",text:"No HarmonyOS project detected. Please verify the project directory or create a project first."}],isError:!0})}async handleErrorCheck(){return this.initRetryCount>=Er?(h.error(`Init retry limit reached (${this.initRetryCount}/${Er}), will not auto-retry`),{content:[{type:"text",text:`Project initialization failed repeatedly (auto-retry exhausted: ${this.initRetryCount}/${Er}). Ask the user to investigate and confirm \`ohpm install\` + \`hvigor\` sync succeed manually. Do NOT call the \`restart\` tool repeatedly \u2014 call it at most once after the user fixes the root cause; if it fails again, stop retrying and escalate to the user.`}],isError:!0}):(h.info(`Error check: auto-retrying (${this.initRetryCount}/${Er})`),this.arktsInitProgress=null,this.ensureProjectReady(),{content:[{type:"text",text:`Project initialization failed, auto-retrying.${this.buildRetrySuffix()}`}],isError:!0})}buildRetrySuffix(){return` Retry in ${Ra}s. Expected total: 30s\u201310min (depends on project size).`}buildInitRetryMessage(){let e=this.arktsInitProgress;if(!e)return`ArkTS init in progress.${this.buildRetrySuffix()}`;let t=Zd.indexOf(e.phase)+1,n=Math.round((Date.now()-e.startedAt)/1e3),i=this.arktsPipelineStartedAt?Math.round((Date.now()-this.arktsPipelineStartedAt)/1e3):n,o=e.percent!==null?` (${e.percent}%)`:"";return[`ArkTS init [${t}/4] ${tP[e.phase]}: ${e.detail}${o} [${n}s, total ${i}s]`,this.buildPipelineLine(e.phase),`Retry in ${Ra}s. Expected total: 30s\u201310min (depends on project size).`].join(`
1339
- `)}buildPipelineLine(e){return`Pipeline: ${Zd.map(n=>{let i=Zd.indexOf(n)<Zd.indexOf(e),o=n===e,s=tP[n];return i?`${s} \u2713`:o?`${s}(\u2026)`:s}).join(" \u2192 ")}`}async routeCppRequest(e,t){switch(this.cppProjectState){case 0:return this.handleCppIdleCheck();case 1:case 2:return h.warn(`C++ ${e} rejected: C++ project is ${rP[this.cppProjectState]}`),{content:[{type:"text",text:"C++ project is syncing (compileNative), please retry in 25 seconds"}],isError:!0};case 3:return h.warn(`C++ ${e} rejected: clangd is initializing`),{content:[{type:"text",text:"C++ LSP (clangd) is initializing, please retry in 10 seconds"}],isError:!0};case 5:return this.handleCppErrorCheck();case 4:return this.cppEnabled?this.cppHasNoCppCode?{content:[{type:"text",text:"No C++ code in this project"}],isError:!0}:this.cppLspManager?.ready?t():{content:[{type:"text",text:"C++ LSP is not ready, please retry later"}],isError:!0}:{content:[{type:"text",text:"C++ LSP is disabled. Set DEVECO_CLI_CPP_ENABLED=true to enable."}],isError:!0};default:return h.warn(`C++ ${e} rejected: unknown C++ project state ${this.cppProjectState}`),{content:[{type:"text",text:"Unknown C++ project state, please retry"}],isError:!0}}}async routeLspRequest(e,t,n){return e.endsWith(".ets")?this.routeArktsRequest(t,n):qn(e)?this.routeCppRequest(t,n):{content:[{type:"text",text:`Unsupported file type: ${e} (only .ets and C/C++ source/header files are supported)`}],isError:!0}}async handleCppIdleCheck(){if(this.ensureCppProjectReady(),this.config.projectPath){let e;return this.cppSyncSkippedDueToLock?(e=`Another build process is running, C++ sync deferred (waiting ${this.cppSyncSkipStartedAt>0?Math.round((Date.now()-this.cppSyncSkipStartedAt)/1e3):0}s), please retry in 25 seconds`,this.cppSyncSkippedDueToLock=!1):e="C++ project detected, syncing (compileNative), please retry in 25 seconds",h.info(`C++ idle check: project '${this.config.projectPath}', triggering C++ init`),{content:[{type:"text",text:e}],isError:!0}}return{content:[{type:"text",text:"No HarmonyOS project detected for C++ tools."}],isError:!0}}async handleCppErrorCheck(){return this.cppInitRetryCount>=Er?(h.error(`C++ init retry limit reached (${this.cppInitRetryCount}/${Er}), will not auto-retry`),{content:[{type:"text",text:`C++ project initialization failed repeatedly (auto-retry exhausted: ${this.cppInitRetryCount}/${Er}). Ask the user to investigate and confirm \`hvigor compileNative\` succeeds manually. Do NOT call the \`restart\` tool repeatedly \u2014 call it at most once after the user fixes the root cause; if it fails again, stop retrying and escalate to the user.`}],isError:!0}):(h.info(`C++ error check: auto-retrying (${this.cppInitRetryCount}/${Er})`),this.ensureCppProjectReady(),{content:[{type:"text",text:"C++ project initialization failed, auto-retrying, please retry in 25 seconds"}],isError:!0})}async callCppCheck(e){return this.routeCppRequest("check",async()=>this.cppCheckTool.handleCall({files:e}))}mergeCheckResult(e,t,n){let i=e.content.map(o=>o.text).filter(o=>o&&o.trim().length>0).join(`
1340
- `);i&&(e.isError?t.push(i):n.push(i))}assertRestartAllowed(e){if(e==="arkts"||e==="all"){let t=this.projectState;if(t!==4&&t!==0&&t!==5)return{content:[{type:"text",text:`ArkTS project state: ${this.describeArktsState()}, sync/init in progress, restart unavailable (would interrupt the current flow). Wait for the state to become ready and retry other tools directly\u2014no restart needed. restart is only available in ready/idle/error states.`}],isError:!0}}if(e==="cpp"||e==="all"){let t=this.cppProjectState;if(t!==4&&t!==0&&t!==5)return{content:[{type:"text",text:`C++ project state: ${this.describeCppState()}, sync/init in progress, restart unavailable (would interrupt the current flow). Wait for the state to become ready and retry other tools directly\u2014no restart needed. restart is only available in ready/idle/error states.`}],isError:!0}}return null}async handleRestartCall(e){let t=e.target,n=t==="cpp"?"cpp":t==="arkts"?"arkts":"all";if(n==="cpp"&&!this.cppEnabled)return{content:[{type:"text",text:"C++ LSP is disabled, cannot restart. Set DEVECO_CLI_CPP_ENABLED=true to enable."}],isError:!0};let i=this.assertRestartAllowed(n);return i||(this.restartProject(n),{content:[{type:"text",text:`MCP server is restarting in-place (${n==="all"?"ArkTS + C++":n==="cpp"?"C++":"ArkTS"}): re-sync project + re-initialize LSP. Client connection preserved\u2014no need to exit the agent. Please retry tools in ~${Ra}s.`}]})}restartProject(e){h.info(`[restart] resetting tools + state, re-init (target=${e})`),(e==="arkts"||e==="all")&&this.restartArkts(),(e==="cpp"||e==="all")&&this.cppEnabled&&this.restartCpp()}restartArkts(){this.arktsCheckTool&&(this.arktsCheckTool.shutdown().catch(e=>h.warn("Failed to shutdown ArktsCheckTool during restart:",e)),this.arktsCheckTool=null),this.initRetryCount=0,this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.configChangedTriggeredResync=!1,this.initPromise?(this.needsReinit=!0,h.info("[restart] ArkTS init is running, will reinit after current init completes")):(this.projectState=0,this.ensureProjectReady().catch(e=>h.warn("Failed to re-init ArkTS project during restart:",e)))}restartCpp(){this.cppCheckTool=null,this.cppLspTool=null,this.cppLspManager&&(this.cppLspManager.dispose().catch(e=>h.warn("Failed to dispose ClangdLspManager during restart:",e)),this.cppLspManager=null),this.cppInitRetryCount=0,this.cppHasNoCppCode=!1,this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,this.cppInitPromise?(this.cppNeedsReinit=!0,h.info("[restart] C++ init is running, will reinit after current init completes")):(this.cppProjectState=0,this.ensureCppProjectReady().catch(e=>h.warn("Failed to re-init C++ project during restart:",e)))}async start(){await this.detectSocketAvailable(),this.registerTools(),this.toolRouter.registerToServer(this.server);let e=new N0;if(await this.server.connect(e),h.info("devecocli-mcp-server started"),!this.config.debug){let t=Oh();t&&h.info(`Log file: ${t}`)}if(this.setupStdinCloseHandler(),this.config.projectPath)this.workspaceRoot=this.config.projectPath;else{let t=await this.getProjectRootFromClient();if(t){this.workspaceRoot=t;let n=Cr(t);n?(h.info(`Detected project path from client root: ${n}`),this.config.projectPath=n):h.warn(`Client root '${t}' is not a HarmonyOS project`)}else this.originalProjectPath?h.warn(`PROJECT_PATH '${this.originalProjectPath}' was provided but no HarmonyOS project was found in it`):h.info("project path is empty (no PROJECT_PATH env and client did not provide roots)")}this.ensureProjectReady().catch(t=>{h.warn("Background project init failed:",t)})}async getProjectRootFromClient(){try{let t=(await this.server.server.listRoots()).roots?.[0];if(!t)return h.warn("Client did not provide any roots"),null;let n=t.uri;return this.resolveFileUri(n)}catch(e){return h.warn("Failed to list roots from client:",e),null}}resolveFileUri(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.pathname;return process.platform==="win32"&&/^\/[A-Za-z]:/.test(n)?n.substring(1):n}}catch(t){h.warn("Failed to parse URI with URL API, falling back to manual parsing:",t)}if(e.startsWith("file://")){let t=e.substring(7);return t=decodeURIComponent(t),process.platform==="win32"&&t.startsWith("/")&&/^[A-Za-z]:/.test(t.substring(1))&&(t=t.substring(1)),t}return e}setupStdinCloseHandler(){let e=!1,t=()=>{e||(e=!0,h.info("stdin closed (MCP client disconnected), shutting down..."),this.shutdown().then(()=>{h.info("shutdown completed, exiting process"),process.exit(0)}).catch(n=>{h.error("shutdown failed:",n),process.exit(1)}))};process.stdin.on("end",t),process.stdin.on("close",t)}async ensureProjectReady(){if(!this.initPromise){this.initPromise=this.doEnsureProjectReady();try{await this.initPromise}finally{this.initPromise=null}this.needsReinit&&(this.needsReinit=!1,this.projectState=0,this.ensureProjectReady().catch(e=>{h.warn("Failed to re-init project after needsReinit:",e)}))}}discoverProject(){if(!((this.projectState===0||this.projectState===5)&&!this.config.projectPath))return!0;this.projectState=1;let t=this.workspaceRoot?Cr(this.workspaceRoot):null;return!t&&this.originalProjectPath&&(t=Cr(this.originalProjectPath),t&&h.info(`Phase 1 found HarmonyOS project from original config: ${t}`)),t?(this.config.projectPath=t,this.initRetryCount=0,!0):(this.projectState=0,!1)}async doEnsureProjectReady(){if(!this.discoverProject())return;if(this.arktsPipelineStartedAt=Date.now(),this.arktsInitProgress={phase:"ohpm",detail:"installing dependencies",percent:null,startedAt:Date.now(),updatedAt:Date.now()},!await this.ensureProjectSynced()){this.arktsInitProgress=null;return}this.ensureCppProjectReady().catch(t=>{h.warn("Background C++ project init failed:",t)}),this.projectState=3,this.arktsInitProgress={phase:"dep-parse",detail:"parsing dependency map",percent:null,startedAt:Date.now(),updatedAt:Date.now()},this.arktsCheckTool=this.createArktsCheckTool();let e=Date.now();try{await this.arktsCheckTool.initialize(),this.projectState=4,this.initRetryCount=0,this.arktsInitProgress=null,h.info("Project fully initialized, check tool is available"),await this.trackInit("init_arkts",e,!0,null,this.arktsCheckTool?.aceServerPid??null)}catch(t){h.error("LSP initialization failed:",t);let n=X(t),i=this.arktsCheckTool?.aceServerPid??null;this.arktsCheckTool=null,this.arktsInitProgress=null,this.initRetryCount++,this.projectState=5,await this.trackInit("init_arkts",e,!1,n,i)}}createArktsCheckTool(){let e=new Wo(this.config.projectPath,this.sdkPath,this.arktsLangServerPath,this.config.nodeMaxOldSpaceSize,this.nodePath,this.socketAvailable);return e.setOnConfigChanged(()=>{h.info("Config files changed, resetting to IDLE state for reinit"),this.configChangedTriggeredResync=!0,this.needsReinit=!0,this.projectState=0}),e.setOnInitProgress((t,n)=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="lsp-init",this.arktsInitProgress.detail=t,this.arktsInitProgress.percent=n,this.arktsInitProgress.updatedAt=Date.now())}),e.setOnDepParseProgress((t,n)=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="dep-parse",this.arktsInitProgress.detail=`${t}/${n} modules`,this.arktsInitProgress.percent=n>0?Math.round(t/n*100):null,this.arktsInitProgress.updatedAt=Date.now())}),e}async ensureProjectSynced(){let e=this.config.projectPath,t=eP(e),n=xa.existsSync(Jo.join(e,"oh-package-lock.json5")),i=xa.existsSync(Jo.join(e,"oh_modules"))&&xa.readdirSync(Jo.join(e,"oh_modules")).length>0;if(n&&i)return t.required?(h.info(`Sync required: ${t.reason}`),this.runSync(e,{skipHvigorSync:!1})):(h.info(`Sync skipped: ${t.reason}`),!0);let o=!t.required;return h.info(`Sync check: skipHvigor=${o}, ohpm install forced (lock=${n}, ohModules=${i}), reason=${t.reason}`),this.runSync(e,{skipHvigorSync:o})}async runSync(e,t){this.projectState=2,h.info("Starting project sync...");let n=s=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="ohpm",this.arktsInitProgress.detail=s,this.arktsInitProgress.percent=null,this.arktsInitProgress.updatedAt=Date.now())},i=s=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="hvigor",this.arktsInitProgress.detail=s,this.arktsInitProgress.percent=null,this.arktsInitProgress.updatedAt=Date.now())},o=await Bo.handleSyncProject(e,this.sdkPath,this.nodePath,this.ohpmJsPath,this.hvigorJsPath,t,n,i);return this.handleSyncResult(o)}handleSyncResult(e){switch(e.status){case"success":return this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,!0;case"skipped":{this.syncSkippedDueToLock=!0,this.syncSkipStartedAt===0&&(this.syncSkipStartedAt=Date.now());let t=Date.now()-this.syncSkipStartedAt,n=Math.round(t/1e3);return t>=Qf?(h.error(`Sync skipped for ${n}s due to lock contention, giving up`),this.initRetryCount++,this.syncSkipStartedAt=0,this.projectState=5,!1):(h.warn(`Sync skipped: ${e.reason}, resetting to IDLE for retry (elapsed ${n}s / ${Qf/1e3}s)`),this.projectState=0,!1)}case"failed":return h.error(`Project sync failed: ${e.reason}`),this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.initRetryCount++,this.projectState=5,!1;default:return h.error(`Project sync: unknown status ${e.status}`),this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.initRetryCount++,this.projectState=5,!1}}async ensureCppProjectReady(){if(!this.cppEnabled){h.info("[Cpp] C++ LSP disabled by config, skipping initialization"),this.cppHasNoCppCode=!0,this.cppProjectState=4;return}if(!this.cppInitPromise){this.cppInitPromise=this.doEnsureCppProjectReady();try{await this.cppInitPromise}finally{this.cppInitPromise=null}this.cppNeedsReinit&&(this.cppNeedsReinit=!1,this.cppProjectState=0,this.ensureCppProjectReady().catch(e=>{h.warn("Failed to re-init C++ project after cppNeedsReinit:",e)}))}}resolveCppCustomDir(){let e=`${this.config.cppCompileCommandsPath??""}|${this.config.projectPath??""}`;return e!==this.cppCustomDirResolvedFor&&(this.cppCustomDirResolvedFor=e,this.cppCustomCompileCommandsDir=Uc(this.config.cppCompileCommandsPath,this.config.projectPath),this.cppCustomCompileCommandsDir&&h.info(`[Cpp] Custom compile_commands dir resolved: ${this.cppCustomCompileCommandsDir}`)),this.cppCustomCompileCommandsDir}async doEnsureCppProjectReady(){let e=this.config.projectPath;if(!e){h.info("[Cpp] No project path, skipping C++ init");return}let t=this.resolveCppCustomDir();if(t){h.info(`[Cpp] Custom compile_commands.json configured, skipping compileNative sync (dir: ${t})`),this.cppHasNoCppCode=!1,await this.initCppLsp(e);return}this.cppProjectState=1;let n=an(e);if(n.length===0){h.info('[Cpp] No C++ modules found, C++ tools will return "no C++ code"'),this.cppHasNoCppCode=!0,this.cppProjectState=4,this.cppInitRetryCount=0;return}this.cppHasNoCppCode=!1,h.info(`[Cpp] Found ${n.length} C++ module(s): ${n.map(s=>s.name).join(", ")}`);let i=uw(e),o=!i.required;h.info(`[Cpp] C++ sync check: skipCompileNative=${o}, reason=${i.reason}`),await this.runSyncCpp(e,{skipCompileNative:o})&&await this.initCppLsp(e)}async initCppLsp(e){this.cppProjectState=3,this.cppLspManager=new Da({workspaceRoot:e,clangdPath:this.clangdPath??"",...this.cppCustomCompileCommandsDir?{compileCommandsDir:this.cppCustomCompileCommandsDir}:{}});let t=Date.now();try{await this.cppLspManager.start(),this.cppCheckTool=new Go(this.cppLspManager),this.cppLspTool=new qo(this.cppLspManager),this.cppProjectState=4,this.cppInitRetryCount=0,h.info("[Cpp] C++ project fully initialized, C++ tools are available"),await this.trackInit("init_cpp",t,!0,null,this.cppLspManager?.clangdPid??null)}catch(n){h.error("[Cpp] C++ LSP initialization failed:",n);let i=X(n),o=this.cppLspManager?.clangdPid??null;this.cppLspManager&&this.cppLspManager.dispose().catch(()=>{}),this.cppLspManager=null,this.cppCheckTool=null,this.cppLspTool=null,this.cppInitRetryCount++,this.cppProjectState=5,await this.trackInit("init_cpp",t,!1,i,o)}}async trackInit(e,t,n,i,o){if(!this.config.telemetry)return;let s="unknown";if(o!==null){let l=await ft(o);l!==null&&(s=ae(Number(l)*1024))}let a={event:v.McpToolCall,subAction:e,mcpMemory:ae(process.memoryUsage().rss),lspMemory:s},c={duration_ms:Date.now()-t,success:n,error_code:i};await this.config.telemetry.track(a,c).catch(()=>{})}async runSyncCpp(e,t){this.cppProjectState=2,h.info("[Cpp] Starting C++ project sync (compileNative)...");let n=await Da.handleSyncCppProject(e,this.sdkPath,this.nodePath,this.hvigorJsPath,t);switch(n.status){case"success":return this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,!0;case"skipped":{this.cppSyncSkippedDueToLock=!0,this.cppSyncSkipStartedAt===0&&(this.cppSyncSkipStartedAt=Date.now());let i=Date.now()-this.cppSyncSkipStartedAt,o=Math.round(i/1e3);return i>=Qf?(h.error(`[Cpp] C++ sync skipped for ${o}s due to lock contention, giving up`),this.cppInitRetryCount++,this.cppSyncSkipStartedAt=0,this.cppProjectState=5,!1):(h.warn(`[Cpp] C++ sync skipped: ${n.reason}, resetting to IDLE_CPP for retry (elapsed ${o}s)`),this.cppProjectState=0,!1)}case"failed":return h.error(`[Cpp] C++ project sync failed: ${n.reason}`),this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,this.cppInitRetryCount++,this.cppProjectState=5,!1}return!1}async shutdown(){this.arktsCheckTool&&await this.arktsCheckTool.shutdown(),this.cppLspManager&&await this.cppLspManager.dispose(),this.cppCheckTool=null,this.cppLspTool=null;try{await this.server.close()}catch(e){h.warn("Failed to close MCP server connection:",e)}h.info("devecocli-mcp-server stopped"),Th(),Ih()}getToolRouter(){return this.toolRouter}getServer(){return this.server}};function M0(r){let e=[],t=[],n=[];for(let i of r)Jo.extname(i).toLowerCase()===".ets"?e.push(i):qn(i)?t.push(i):n.push(i);return{etsFiles:e,cppFiles:t,unsupported:n}}function tg(r={}){return new Qd(r)}import*as rg from"fs";import*as Aa from"path";import{spawn as L0}from"child_process";async function nP(r){zn(!1);let{serverPath:e,logPath:t,projectPath:n,sdkPath:i,serverMaxSize:o,nodePath:s}=await _0(r),a=j0(e,t,n,i,o,s);h.info("ace-server started, bridging stdio (initialize is left to the client)"),H0(a),await ig(a.pid,ng("--arkts",r))}function ng(r,e){return[r,...e.projectPath?["--project-path"]:[],...e.autoDetect?["--auto-detect"]:[]]}async function ig(r,e){let t="unknown";if(r!==null){let i=await ft(r);i!==null&&(t=ae(Number(i)*1024))}let n={event:v.ServeLsp,args:e,lspMemory:t};await D.track(n)}async function _0(r){let e=await C.new(),t;if(r.projectPath)t=xe(Aa.resolve(r.projectPath)),h.info(`projectPath=specified ('${t}'), no search`);else if(r.autoDetect){let c=Xa(process.cwd());t=xe(c??process.cwd()),h.info(`findHarmonyProjectInDir('${process.cwd()}') => ${c??"null, fallback to cwd"}`)}else t=xe(process.cwd()),h.info(`projectPath=cwd ('${t}'), no search (pass --auto-detect to search subdirs)`);let n=e.sdkPath,i=e.arktsLangServerPath;i||(h.error("ace-server not found (install DevEco Studio / CLT)."),process.exit(1));let o=Oi(i,!0),s=Aa.join(Qr(),"lsp-server",String(Date.now()));rg.mkdirSync(s,{recursive:!0});let a=$0(t,n);return h.info(`projectPath=${t}, sdkPath=${n}, arktsLangServerPath=${i}, serverPath=${o}, logPath=${s}, serverMaxSize=${a}MB`),{projectPath:t,sdkPath:n,serverPath:o,logPath:s,serverMaxSize:a,nodePath:e.nodePath}}function $0(r,e){let t=process.env.NODE_MAX_OLD_SPACE_SIZE,n=t?parseInt(t,10):NaN,i=Number.isFinite(n)&&n>0?n:void 0,o=F0(r,e),s=Fc(o,i);return h.info(`[serve-lsp] serverMaxSize=${s}MB (moduleCount=${o}, override=${i??"none"})`),s}function F0(r,e){try{let t=[];return new Ei(r,e).getAllDependencyMap(t).status==="OK"?t.length:new Ir(r).getAllModuleInfo().length}catch{return 0}}function j0(r,e,t,n,i,o){let s=Aa.join(e,"lspLog");rg.mkdirSync(s,{recursive:!0});let a=bs({serverPath:r,lspLogPath:s,serverMaxSize:i,projectPath:t,sdkPath:n}),c=Zn(o);return h.info(`[serve-lsp] spawn: ${c} ${a.join(" ")}`),L0(c,a,{cwd:t,stdio:["pipe","pipe","pipe"],windowsHide:!0})}function H0(r){r.on("error",e=>{h.error(`[ace-server] spawn error: ${e.message}`),process.exit(1)}),r.stdout?.on("error",e=>{h.error(`[ace-server] stdout error: ${e.message}`)}),r.stdout?.on("data",e=>process.stdout.write(e)),r.stderr?.on("error",e=>{h.error(`[ace-server] stderr error: ${e.message}`)}),r.stderr?.on("data",e=>{h.error(`[ace-server] ${e.toString("utf8").trim()}`)}),r.stdin?.on("error",e=>{h.error(`[ace-server] stdin error: ${e.message}`)}),process.stdin.on("data",e=>{r.stdin?.write(e)}),process.stdin.on("end",()=>{h.info("Editor disconnected, shutting down"),r.kill(),process.exit(0)}),r.on("exit",e=>{h.info(`ace-server exited with code ${e}`),process.exit(e??0)})}import*as iP from"fs";import*as Ci from"path";import{spawn as U0}from"child_process";async function oP(r){zn(!1);let{clangdPath:e,compileCommandsDir:t,projectPath:n}=await B0(r),i=Ci.join(t,"compile_commands.json");iP.existsSync(i)||h.warn(`compile_commands.json not found at ${i}. Cross-file navigation/completion will be limited. Run \`devecocli build\` first to generate it.`);let o=V0(e,t,n);h.info("clangd started, bridging stdio (initialize is left to the client)"),q0(o),await ig(o.pid,ng("--cpp",r))}async function B0(r){let e=await W0();e?.clangdPath||(h.error("clangd not found. Ensure DevEco Studio / CLT is installed."),process.exit(1));let t;if(r.projectPath)t=xe(Ci.resolve(r.projectPath)),h.info(`projectPath=specified ('${t}'), no search`);else if(r.autoDetect){let c=Xa(process.cwd());t=xe(c??process.cwd()),h.info(`findHarmonyProjectInDir('${process.cwd()}') => ${c??"null, fallback to cwd"}`)}else t=xe(Ci.resolve(process.cwd())),h.info(`projectPath=cwd ('${t}'), no search (pass --auto-detect to search subdirs)`);let n=e.sdkPath,i=e.clangdPath,o=Gn(t),s=Ci.dirname(o),a=Uc(process.env.DEVECO_CLI_CPP_COMPILE_COMMANDS,t);return a&&(h.info(`Using custom compile_commands dir: ${a}`),s=a),h.info(`projectPath=${t}, sdkPath=${n}, clangdPath=${i}, compileCommandsDir=${s}`),{projectPath:t,clangdPath:i,compileCommandsDir:s}}async function W0(){try{return await C.new()}catch{let r=kh();if(!r)return null;try{return C.fromIDE(r)}catch{return null}}}function V0(r,e,t){let n=G0(e);return h.info(`[serve-lsp-cpp] spawn: ${r} ${n.join(" ")}`),U0(r,n,{cwd:t,stdio:["pipe","pipe","pipe"],windowsHide:!0})}function G0(r){return[`--compile-commands-dir=${ge(r)}`,"--log=info","--pch-storage=memory"]}function q0(r){r.on("error",e=>{h.error(`[clangd] spawn error: ${e.message}`),process.exit(1)}),r.stdout?.on("error",e=>{h.error(`[clangd] stdout error: ${e.message}`)}),r.stdout?.on("data",e=>process.stdout.write(e)),r.stderr?.on("error",e=>{h.error(`[clangd] stderr error: ${e.message}`)}),r.stderr?.on("data",e=>{h.error(`[clangd] ${e.toString("utf8").trim()}`)}),r.stdin?.on("error",e=>{h.error(`[clangd] stdin error: ${e.message}`)}),process.stdin.on("data",e=>{r.stdin?.write(e)}),process.stdin.on("end",()=>{h.info("Editor disconnected, shutting down"),r.kill(),process.exit(0)}),r.on("exit",e=>{h.info(`clangd exited with code ${e}`),process.exit(e??0)})}async function J0(){let r=process.env.PROJECT_PATH||"",e=process.env.NODE_MAX_OLD_SPACE_SIZE,t=process.env.DEBUG==="true"||process.env.DEBUG==="1",n=process.env.DEVECO_CLI_CPP_ENABLED!=="false"&&process.env.DEVECO_CLI_CPP_ENABLED!=="0",i=process.env.DEVECO_CLI_CPP_COMPILE_COMMANDS?.trim()||"",o=r,s=await C.new(),a=tg({projectPath:o,sdkPath:s.sdkPath,arktsLangServerPath:s.arktsLangServerPath??void 0,nodePath:s.nodePath,ohpmJsPath:s.ohpmJsPath,hvigorJsPath:s.hvigorJsPath,clangdPath:s.clangdPath??void 0,nodeMaxOldSpaceSize:e,debug:t,cppEnabled:n,cppCompileCommandsPath:i||void 0,telemetry:D}),c,l=new Promise(g=>{c=g}),d=async()=>{await a.shutdown(),c()};process.once("SIGINT",d),process.once("SIGTERM",d),process.platform==="win32"&&process.once("SIGBREAK",d);try{await a.start()}catch(g){console.error("Failed to start MCP server:",g instanceof Error?g.message:String(g)),process.exit(1)}await l}var og=new z0("serve").description("Host bundled auxiliary protocol servers");og.command("mcp").description("Start a local stdio-based MCP server").action(async()=>{await J0()});og.command("lsp").description("Start a bundled LSP language server").option("--arkts","Start the ArkTS language server (ace-server)").option("--cpp","Start the C/C++ language server (clangd)").option("--project-path <path>","project root path (used as-is, no search)").option("--auto-detect","When --project-path is not specified, search the current directory and its subdirectories for the project root (no upward search)").action(async r=>{r.arkts&&r.cpp&&(console.error("--arkts and --cpp are mutually exclusive. Specify only one."),process.exit(1)),r.arkts?await nP({projectPath:r.projectPath,autoDetect:r.autoDetect}):r.cpp?await oP({projectPath:r.projectPath,autoDetect:r.autoDetect}):(console.error("Use --arkts or --cpp to specify which language server to start."),process.exit(1))});var sP=og;import{Command as tF,InvalidArgumentError as dP}from"commander";import{red as rF,dim as nF}from"colorette";import{Command as Y0}from"commander";import{cyan as eu,yellow as tu}from"colorette";import*as aP from"path";function K0(r){return tu(`If you want the latest docs(${r}), please update CLI first: run \`devecocli update\` to update`)}function X0(r){console.log(tu(`Latest docs v${r.version} (apiVersion ${r.apiVersion}) is incompatible with current CLI.`)),console.log(K0(r.version))}function Z0(r,e,t){console.log(t?eu(`New docs version ${r} found (current v${e??"none"})`):eu(`Documentation is already up to date v${r}`))}async function Q0(r){let e=Ft();console.log(eu("Checking for documentation updates..."));let{latest:t,compatible:n}=await lo(e);if(!n){X0(t);return}let i=await Ui(),o=!i||Pt(n.version,i)>0;if(r.check){Z0(n.version,i,o);return}if(!r.force&&!o){console.log(tu(`Docs is already up to date v${n.version}`));return}console.log(eu(`Downloading documentation package v${n.version}...`)),await Pl({version:n.version,apiVersion:n.apiVersion,dist:n.dist},aP.join($(),"doc-data"),"docs-update"),console.log(tu(`Docs successfully upgrade to ${n.version}`))}var eF=new Y0("update").description("Update documentation to the latest compatible version").option("--force","Force re-download even if up to date").option("--check","Check for updates without installing").action(async r=>{await Q0(r)}),cP=eF;async function sg(r,e){let t=Date.now();try{let n=await e();return await lP(r,Date.now()-t,!0,null),n}catch(n){let i=n instanceof Error?n.code??n.name:"UnknownError";throw await lP(r,Date.now()-t,!1,i),n}}async function lP(r,e,t,n){await D.track(r,{duration_ms:e,success:t,error_code:n}).catch(()=>{})}function iF(r){return r instanceof Error&&(r.name==="CacheDirError"||r.name==="DocPathSafetyError")}function ag(r){console.error(rF(oF(r))),process.exitCode=1}function oF(r){let e=r instanceof Error?r.message:String(r);return iF(r)?e:/\b(EACCES|EPERM|ENOSPC|ENOTDIR|ELOOP)\b/.test(e)?"Documentation data directory is unavailable. Check DEVECO_CLI_DATA_DIR and retry.":e}function uP(...r){return e=>{if(!r.includes(e))throw new dP(`Allowed values: ${r.join(", ")}`);return e}}function sF(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new dP("Must be a positive integer.");return e}var aF=uP("json","default"),cF=uP("json","default");function lF(r){let e=r.map(t=>t.trim()).filter(Boolean);if(e.length===0)throw new Error("Keywords cannot be empty.");return e}function dF(r){for(let e=0;e<r.length;e++){let t=r[e];console.log(t.documentId),console.log(` Title: ${t.title}`),t.snippet&&console.log(` Content: ${t.snippet}`),e<r.length-1&&console.log()}}var Ia=new tF("docs").description("HarmonyOS documentation commands (search, read, catalog, update)");Ia.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)","all").option("--format <fmt>","Output format (default, json)",aF,"default").option("--limit <n>","Max number of results",sF,10).action(async(r,e)=>{let t={event:v.DocOperation,subAction:"search",keywords:r,queryLen:r.join(" ").length,catalog:e.catalog??"all"};try{await sg(t,async()=>{let n=lF(r),i=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await vc(),s=o.CATALOG_NAMES;if(i&&s&&!s.includes(i))throw new Error(`Invalid catalog "${e.catalog}". Allowed: all, ${s.join(", ")}`);let a=await o.createDocsEngine({cacheDir:$()});try{let c=await a.search({keywords:n,catalog:i,limit:e.limit});e.format==="json"?console.log(JSON.stringify(c,null,2)):dF(c)}finally{await a.close()}})}catch(n){ag(n)}});Ia.command("read <documentId>").description("Read full content of a document by document ID").action(async r=>{let e=r.trim(),t={event:v.DocOperation,subAction:"read",documentId:e};try{await sg(t,async()=>{if(!e)throw new Error("Document ID cannot be empty.");let i=await(await vc()).createDocsEngine({cacheDir:$()});try{let o=await i.read({relativePath:e});console.log(o)}finally{await i.close()}})}catch(n){ag(n)}});Ia.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",cF,"default").action(async r=>{let e={event:v.DocOperation,subAction:"catalog",fmt:r.format??"default"};try{await sg(e,async()=>{let n=await(await vc()).createDocsEngine({cacheDir:$()});try{let i=await n.catalog();if(r.format==="json")console.log(JSON.stringify(i.map(o=>({name:o.nodeId,title:o.nodeName})),null,2));else for(let o of i)console.log(` ${o.nodeId.padEnd(20)} ${nF(o.nodeName)}`)}finally{await n.close()}})}catch(t){ag(t)}});Ia.addCommand(cP);var pP=Ia;import{Command as tj}from"commander";import{Command as dg,InvalidArgumentError as cg,Option as Ta}from"commander";import ug from"ora";var fP=["Selector DSL (common cases):"," key=value exact text=Login"," key*=value contains text*=Log"," key^=value prefix text^=Log"," key$=value suffix text$=in"," key/=regex[/flags] regex search text/=^Login$ text/=login/i"," a,b AND text=Login,type=Button"," [n] nth match (at end) text=Login[0] [last]/[-1]"," keys: text key desc id type enabled focused checked selected visible clickable scrollable",' value with , [ ] or quotes -> quote it: text="a,b" text="a[b]"'," regex backslashes must be doubled",' xpath= prefix -> use xpath expression: xpath=//Button[@id="login"]'," base64= prefix -> base64-encoded selector for shell-safe special chars"," shell special chars -> wrap whole selector in quotes, or use base64= prefix"].join(`
1341
- `);function uF(r){let e=parseInt(r,10);if(!Number.isInteger(e)||e<0||String(e)!==r.trim())throw new cg("depth must be a non-negative integer");return e}function lg(r){let e=Number(r);if(!Number.isFinite(e)||e<=0)throw new cg("timeout must be a positive number");if(e>36e4)throw new cg("timeout must not exceed 360000ms");return e}function gP(r){let e=[];(r.type||r.id)&&e.push(r.type?r.id?`${r.type}#${r.id}`:r.type:`#${r.id}`),e.push(r.bounds?`[${r.bounds.join(",")}]`:"[]"),r.text&&e.push(`"${JSON.stringify(r.text).slice(1,-1)}"`);let t=[];return r.clickable&&t.push("clickable"),r.longClickable&&t.push("longClickable"),r.scrollable&&t.push("scrollable"),r.checkable&&t.push("checkable"),t.length>0&&e.push(...t),e.join(" ")}function hP(r,e=0){let t=[],n=" ".repeat(e);for(let i of r)t.push(`${n}${gP(i)}`),i.children.length>0&&t.push(...hP(i.children,e+1).split(`
1354
+ `).trim()||"No diagnostics collected"}],isError:c}}async callArktsCheck(e){switch(this.projectState){case 0:return this.handleIdleCheck();case 1:return h.warn(`ArkTS check rejected: project is DISCOVERING, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 2:return h.warn(`ArkTS check rejected: project is SYNCING, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 3:return h.warn(`ArkTS check rejected: LSP is initializing, files: ${e.join(", ")}`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 5:return this.handleErrorCheck();case 4:return this.arktsCheckTool.handleCall({files:e});default:return h.error(`ArkTS check: unknown project state ${this.projectState}, files: ${e.join(", ")}`),{content:[{type:"text",text:`Unknown project state: ${this.projectState}`}],isError:!0}}}async handleLspFeatureCall(e,t){let n=t.file,i=t.line,o=t.character;return typeof n!="string"||typeof i!="number"||typeof o!="number"?{content:[{type:"text",text:"Missing or invalid parameters. Required: file (string), line (number), character (number)."}],isError:!0}:this.routeLspRequest(n,e,async()=>{if(n.endsWith(".ets"))return this.arktsCheckTool.handleLspFeature(e,{file:n,line:i,character:o});let s=e;return this.cppLspTool.handleLspFeature(s,{file:n,line:i,character:o})})}async handleWorkspaceSymbolCall(e){let t=e.query;return typeof t!="string"||t.trim().length===0?{content:[{type:"text",text:"Missing or invalid parameter: query (non-empty string required)."}],isError:!0}:this.routeWorkspaceSymbolRequest(t)}async routeWorkspaceSymbolRequest(e){let t=this.projectState===4&&this.arktsCheckTool!==null,n=this.cppProjectState===4&&!this.cppHasNoCppCode&&this.cppLspTool!==null;if(!t&&!n){let a=this.describeArktsState(),c=this.describeCppState();return h.info(`workspaceSymbol rejected: ArkTS ${a}; C++ ${c}`),{content:[{type:"text",text:`workspaceSymbol: ArkTS ${a}; C++ ${c}`}],isError:!0}}let i=[],o=new Set;if(t)try{this.mergeSymbolItems(await this.arktsCheckTool.handleWorkspaceSymbolRaw(e),o,i)}catch(a){h.warn(`workspaceSymbol ArkTS query failed: ${a.message}`)}if(n)try{this.mergeSymbolItems(await this.cppLspTool.handleWorkspaceSymbolRaw(e),o,i)}catch(a){h.warn(`workspaceSymbol C++ query failed: ${a.message}`)}return{content:[{type:"text",text:i.length===0?"workspaceSymbol: no result":`workspaceSymbol: ${JSON.stringify(i,null,2)}`}]}}symbolDedupKey(e){let t=e,n=t?.location?.uri??"",i=t?.location?.range?.start?.line??0,o=t?.location?.range?.start?.character??0;return`${n}:${i}:${o}`}mergeSymbolItems(e,t,n){if(e)for(let i of e){let o=this.symbolDedupKey(i);t.has(o)||(t.add(o),n.push(i))}}describeArktsState(){switch(this.projectState){case 0:return"idle";case 1:return"discovering";case 2:return`syncing (retry ${qa}s)`;case 3:return`initializing (retry ${qa}s)`;case 5:return`error (${this.initRetryCount}/${xr})`;case 4:return"ready";default:return"unknown"}}describeCppState(){switch(this.cppProjectState){case 0:return"idle";case 1:return"discovering";case 2:return"syncing (retry 25s)";case 3:return"initializing (retry 10s)";case 5:return`error (${this.cppInitRetryCount}/${xr})`;case 4:return this.cppHasNoCppCode?"ready (no C++ code)":"ready";default:return"unknown"}}async handleDocumentSymbolCall(e){let t=e.file;return typeof t!="string"?{content:[{type:"text",text:"Missing or invalid parameter: file (string required)."}],isError:!0}:this.routeLspRequest(t,"documentSymbol",async()=>t.endsWith(".ets")?this.arktsCheckTool.handleDocumentSymbol(t):this.cppLspTool.handleDocumentSymbol(t))}async handleCallHierarchyCall(e){let t=e.file,n=e.line,i=e.character,o=e.direction;return typeof t!="string"||typeof n!="number"||typeof i!="number"?{content:[{type:"text",text:"Missing or invalid parameters. Required: file (string), line (number), character (number)."}],isError:!0}:o!=="incoming"&&o!=="outgoing"?{content:[{type:"text",text:'Parameter direction must be "incoming" or "outgoing".'}],isError:!0}:this.routeLspRequest(t,`callHierarchy(${o})`,async()=>t.endsWith(".ets")?this.arktsCheckTool.handleCallHierarchy({file:t,line:n,character:i,direction:o}):this.cppLspTool.handleCallHierarchy({file:t,line:n,character:i,direction:o}))}async routeArktsRequest(e,t){switch(this.projectState){case 0:return this.handleIdleCheck();case 1:return h.warn(`ArkTS ${e} rejected: project is DISCOVERING`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 2:return h.warn(`ArkTS ${e} rejected: project is SYNCING`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 3:return h.warn(`ArkTS ${e} rejected: LSP is initializing`),{content:[{type:"text",text:this.buildInitRetryMessage()}],isError:!0};case 5:return this.handleErrorCheck();case 4:return t();default:return h.warn(`ArkTS ${e} rejected: unknown project state ${this.projectState}`),{content:[{type:"text",text:"Unknown project state, please retry"}],isError:!0}}}async handleIdleCheck(){if(this.ensureProjectReady(),this.config.projectPath){let e,t;return this.syncSkippedDueToLock?(e=`Another build process is running, sync deferred (waiting ${this.syncSkipStartedAt>0?Math.round((Date.now()-this.syncSkipStartedAt)/1e3):0}s), please retry in 25 seconds`,t="lock contention",this.syncSkippedDueToLock=!1):this.configChangedTriggeredResync?(e=this.arktsInitProgress?this.buildInitRetryMessage():`Config file changed, resyncing project.${this.buildRetrySuffix()}`,t="config changed",this.configChangedTriggeredResync=!1):(e=this.arktsInitProgress?this.buildInitRetryMessage():`ArkTS project detected, syncing.${this.buildRetrySuffix()}`,t="initial"),h.info(`Idle check: project '${this.config.projectPath}' already known, triggering init (${t})`),{content:[{type:"text",text:e}],isError:!0}}return this.workspaceRoot||this.originalProjectPath?(h.info(`Idle check: no project path yet, will try from '${this.workspaceRoot}' or '${this.originalProjectPath}'`),{content:[{type:"text",text:`Initializing.${this.buildRetrySuffix()}`}],isError:!0}):(h.warn("Idle check: no search candidates available"),{content:[{type:"text",text:"No HarmonyOS project detected. Please verify the project directory or create a project first."}],isError:!0})}async handleErrorCheck(){return this.initRetryCount>=xr?(h.error(`Init retry limit reached (${this.initRetryCount}/${xr}), will not auto-retry`),{content:[{type:"text",text:`Project initialization failed repeatedly (auto-retry exhausted: ${this.initRetryCount}/${xr}). Ask the user to investigate and confirm \`ohpm install\` + \`hvigor\` sync succeed manually. Do NOT call the \`restart\` tool repeatedly \u2014 call it at most once after the user fixes the root cause; if it fails again, stop retrying and escalate to the user.`}],isError:!0}):(h.info(`Error check: auto-retrying (${this.initRetryCount}/${xr})`),this.arktsInitProgress=null,this.ensureProjectReady(),{content:[{type:"text",text:`Project initialization failed, auto-retrying.${this.buildRetrySuffix()}`}],isError:!0})}buildRetrySuffix(){return` Retry in ${qa}s. Expected total: 30s\u201310min (depends on project size).`}buildInitRetryMessage(){let e=this.arktsInitProgress;if(!e)return`ArkTS init in progress.${this.buildRetrySuffix()}`;let t=Au.indexOf(e.phase)+1,n=Math.round((Date.now()-e.startedAt)/1e3),i=this.arktsPipelineStartedAt?Math.round((Date.now()-this.arktsPipelineStartedAt)/1e3):n,o=e.percent!==null?` (${e.percent}%)`:"";return[`ArkTS init [${t}/4] ${NC[e.phase]}: ${e.detail}${o} [${n}s, total ${i}s]`,this.buildPipelineLine(e.phase),`Retry in ${qa}s. Expected total: 30s\u201310min (depends on project size).`].join(`
1355
+ `)}buildPipelineLine(e){return`Pipeline: ${Au.map(n=>{let i=Au.indexOf(n)<Au.indexOf(e),o=n===e,s=NC[n];return i?`${s} \u2713`:o?`${s}(\u2026)`:s}).join(" \u2192 ")}`}async routeCppRequest(e,t){switch(this.cppProjectState){case 0:return this.handleCppIdleCheck();case 1:case 2:return h.warn(`C++ ${e} rejected: C++ project is ${OC[this.cppProjectState]}`),{content:[{type:"text",text:"C++ project is syncing (compileNative), please retry in 25 seconds"}],isError:!0};case 3:return h.warn(`C++ ${e} rejected: clangd is initializing`),{content:[{type:"text",text:"C++ LSP (clangd) is initializing, please retry in 10 seconds"}],isError:!0};case 5:return this.handleCppErrorCheck();case 4:return this.cppEnabled?this.cppHasNoCppCode?{content:[{type:"text",text:"No C++ code in this project"}],isError:!0}:this.cppLspManager?.ready?t():{content:[{type:"text",text:"C++ LSP is not ready, please retry later"}],isError:!0}:{content:[{type:"text",text:"C++ LSP is disabled. Set DEVECO_CLI_CPP_ENABLED=true to enable."}],isError:!0};default:return h.warn(`C++ ${e} rejected: unknown C++ project state ${this.cppProjectState}`),{content:[{type:"text",text:"Unknown C++ project state, please retry"}],isError:!0}}}async routeLspRequest(e,t,n){return e.endsWith(".ets")?this.routeArktsRequest(t,n):Kn(e)?this.routeCppRequest(t,n):{content:[{type:"text",text:`Unsupported file type: ${e} (only .ets and C/C++ source/header files are supported)`}],isError:!0}}async handleCppIdleCheck(){if(this.ensureCppProjectReady(),this.config.projectPath){let e;return this.cppSyncSkippedDueToLock?(e=`Another build process is running, C++ sync deferred (waiting ${this.cppSyncSkipStartedAt>0?Math.round((Date.now()-this.cppSyncSkipStartedAt)/1e3):0}s), please retry in 25 seconds`,this.cppSyncSkippedDueToLock=!1):e="C++ project detected, syncing (compileNative), please retry in 25 seconds",h.info(`C++ idle check: project '${this.config.projectPath}', triggering C++ init`),{content:[{type:"text",text:e}],isError:!0}}return{content:[{type:"text",text:"No HarmonyOS project detected for C++ tools."}],isError:!0}}async handleCppErrorCheck(){return this.cppInitRetryCount>=xr?(h.error(`C++ init retry limit reached (${this.cppInitRetryCount}/${xr}), will not auto-retry`),{content:[{type:"text",text:`C++ project initialization failed repeatedly (auto-retry exhausted: ${this.cppInitRetryCount}/${xr}). Ask the user to investigate and confirm \`hvigor compileNative\` succeeds manually. Do NOT call the \`restart\` tool repeatedly \u2014 call it at most once after the user fixes the root cause; if it fails again, stop retrying and escalate to the user.`}],isError:!0}):(h.info(`C++ error check: auto-retrying (${this.cppInitRetryCount}/${xr})`),this.ensureCppProjectReady(),{content:[{type:"text",text:"C++ project initialization failed, auto-retrying, please retry in 25 seconds"}],isError:!0})}async callCppCheck(e){return this.routeCppRequest("check",async()=>this.cppCheckTool.handleCall({files:e}))}mergeCheckResult(e,t,n){let i=e.content.map(o=>o.text).filter(o=>o&&o.trim().length>0).join(`
1356
+ `);i&&(e.isError?t.push(i):n.push(i))}assertRestartAllowed(e){if(e==="arkts"||e==="all"){let t=this.projectState;if(t!==4&&t!==0&&t!==5)return{content:[{type:"text",text:`ArkTS project state: ${this.describeArktsState()}, sync/init in progress, restart unavailable (would interrupt the current flow). Wait for the state to become ready and retry other tools directly\u2014no restart needed. restart is only available in ready/idle/error states.`}],isError:!0}}if(e==="cpp"||e==="all"){let t=this.cppProjectState;if(t!==4&&t!==0&&t!==5)return{content:[{type:"text",text:`C++ project state: ${this.describeCppState()}, sync/init in progress, restart unavailable (would interrupt the current flow). Wait for the state to become ready and retry other tools directly\u2014no restart needed. restart is only available in ready/idle/error states.`}],isError:!0}}return null}async handleRestartCall(e){let t=e.target,n=t==="cpp"?"cpp":t==="arkts"?"arkts":"all";if(n==="cpp"&&!this.cppEnabled)return{content:[{type:"text",text:"C++ LSP is disabled, cannot restart. Set DEVECO_CLI_CPP_ENABLED=true to enable."}],isError:!0};let i=this.assertRestartAllowed(n);return i||(this.restartProject(n),{content:[{type:"text",text:`MCP server is restarting in-place (${n==="all"?"ArkTS + C++":n==="cpp"?"C++":"ArkTS"}): re-sync project + re-initialize LSP. Client connection preserved\u2014no need to exit the agent. Please retry tools in ~${qa}s.`}]})}restartProject(e){h.info(`[restart] resetting tools + state, re-init (target=${e})`),(e==="arkts"||e==="all")&&this.restartArkts(),(e==="cpp"||e==="all")&&this.cppEnabled&&this.restartCpp()}restartArkts(){this.arktsCheckTool&&(this.arktsCheckTool.shutdown().catch(e=>h.warn("Failed to shutdown ArktsCheckTool during restart:",e)),this.arktsCheckTool=null),this.initRetryCount=0,this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.configChangedTriggeredResync=!1,this.initPromise?(this.needsReinit=!0,h.info("[restart] ArkTS init is running, will reinit after current init completes")):(this.projectState=0,this.ensureProjectReady().catch(e=>h.warn("Failed to re-init ArkTS project during restart:",e)))}restartCpp(){this.cppCheckTool=null,this.cppLspTool=null,this.cppLspManager&&(this.cppLspManager.dispose().catch(e=>h.warn("Failed to dispose ClangdLspManager during restart:",e)),this.cppLspManager=null),this.cppInitRetryCount=0,this.cppHasNoCppCode=!1,this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,this.cppInitPromise?(this.cppNeedsReinit=!0,h.info("[restart] C++ init is running, will reinit after current init completes")):(this.cppProjectState=0,this.ensureCppProjectReady().catch(e=>h.warn("Failed to re-init C++ project during restart:",e)))}async start(){await this.detectSocketAvailable(),this.registerTools(),this.toolRouter.registerToServer(this.server);let e=new uU;if(await this.server.connect(e),h.info("devecocli-mcp-server started"),!this.config.debug){let t=ky();t&&h.info(`Log file: ${t}`)}if(this.setupStdinCloseHandler(),this.config.projectPath)this.workspaceRoot=this.config.projectPath;else{let t=await this.getProjectRootFromClient();if(t){this.workspaceRoot=t;let n=Ir(t);n?(h.info(`Detected project path from client root: ${n}`),this.config.projectPath=n):h.warn(`Client root '${t}' is not a HarmonyOS project`)}else this.originalProjectPath?h.warn(`PROJECT_PATH '${this.originalProjectPath}' was provided but no HarmonyOS project was found in it`):h.info("project path is empty (no PROJECT_PATH env and client did not provide roots)")}this.ensureProjectReady().catch(t=>{h.warn("Background project init failed:",t)})}async getProjectRootFromClient(){try{let t=(await this.server.server.listRoots()).roots?.[0];if(!t)return h.warn("Client did not provide any roots"),null;let n=t.uri;return this.resolveFileUri(n)}catch(e){return h.warn("Failed to list roots from client:",e),null}}resolveFileUri(e){try{let t=new URL(e);if(t.protocol==="file:"){let n=t.pathname;return process.platform==="win32"&&/^\/[A-Za-z]:/.test(n)?n.substring(1):n}}catch(t){h.warn("Failed to parse URI with URL API, falling back to manual parsing:",t)}if(e.startsWith("file://")){let t=e.substring(7);return t=decodeURIComponent(t),process.platform==="win32"&&t.startsWith("/")&&/^[A-Za-z]:/.test(t.substring(1))&&(t=t.substring(1)),t}return e}setupStdinCloseHandler(){let e=!1,t=()=>{e||(e=!0,h.info("stdin closed (MCP client disconnected), shutting down..."),this.shutdown().then(()=>{h.info("shutdown completed, exiting process"),process.exit(0)}).catch(n=>{h.error("shutdown failed:",n),process.exit(1)}))};process.stdin.on("end",t),process.stdin.on("close",t)}async ensureProjectReady(){if(!this.initPromise){this.initPromise=this.doEnsureProjectReady();try{await this.initPromise}finally{this.initPromise=null}this.needsReinit&&(this.needsReinit=!1,this.projectState=0,this.ensureProjectReady().catch(e=>{h.warn("Failed to re-init project after needsReinit:",e)}))}}discoverProject(){if(!((this.projectState===0||this.projectState===5)&&!this.config.projectPath))return!0;this.projectState=1;let t=this.workspaceRoot?Ir(this.workspaceRoot):null;return!t&&this.originalProjectPath&&(t=Ir(this.originalProjectPath),t&&h.info(`Phase 1 found HarmonyOS project from original config: ${t}`)),t?(this.config.projectPath=t,this.initRetryCount=0,!0):(this.projectState=0,!1)}async doEnsureProjectReady(){if(!this.discoverProject())return;if(this.arktsPipelineStartedAt=Date.now(),this.arktsInitProgress={phase:"ohpm",detail:"installing dependencies",percent:null,startedAt:Date.now(),updatedAt:Date.now()},!await this.ensureProjectSynced()){this.arktsInitProgress=null;return}this.ensureCppProjectReady().catch(t=>{h.warn("Background C++ project init failed:",t)}),this.projectState=3,this.arktsInitProgress={phase:"dep-parse",detail:"parsing dependency map",percent:null,startedAt:Date.now(),updatedAt:Date.now()},this.arktsCheckTool=this.createArktsCheckTool();let e=Date.now();try{await this.arktsCheckTool.initialize(),this.projectState=4,this.initRetryCount=0,this.arktsInitProgress=null,h.info("Project fully initialized, check tool is available"),await this.trackInit("init_arkts",e,!0,null,this.arktsCheckTool?.aceServerPid??null)}catch(t){h.error("LSP initialization failed:",t);let n=Z(t),i=this.arktsCheckTool?.aceServerPid??null;this.arktsCheckTool=null,this.arktsInitProgress=null,this.initRetryCount++,this.projectState=5,await this.trackInit("init_arkts",e,!1,n,i)}}createArktsCheckTool(){let e=new ts(this.config.projectPath,this.sdkPath,this.arktsLangServerPath,this.config.nodeMaxOldSpaceSize,this.nodePath,this.socketAvailable);return e.setOnConfigChanged(()=>{h.info("Config files changed, resetting to IDLE state for reinit"),this.configChangedTriggeredResync=!0,this.needsReinit=!0,this.projectState=0}),e.setOnInitProgress((t,n)=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="lsp-init",this.arktsInitProgress.detail=t,this.arktsInitProgress.percent=n,this.arktsInitProgress.updatedAt=Date.now())}),e.setOnDepParseProgress((t,n)=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="dep-parse",this.arktsInitProgress.detail=`${t}/${n} modules`,this.arktsInitProgress.percent=n>0?Math.round(t/n*100):null,this.arktsInitProgress.updatedAt=Date.now())}),e}async ensureProjectSynced(){let e=this.config.projectPath,t=TC(e),n=za.existsSync(ss.join(e,"oh-package-lock.json5")),i=za.existsSync(ss.join(e,"oh_modules"))&&za.readdirSync(ss.join(e,"oh_modules")).length>0;if(n&&i)return t.required?(h.info(`Sync required: ${t.reason}`),this.runSync(e,{skipHvigorSync:!1})):(h.info(`Sync skipped: ${t.reason}`),!0);let o=!t.required;return h.info(`Sync check: skipHvigor=${o}, ohpm install forced (lock=${n}, ohModules=${i}), reason=${t.reason}`),this.runSync(e,{skipHvigorSync:o})}async runSync(e,t){this.projectState=2,h.info("Starting project sync...");let n=s=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="ohpm",this.arktsInitProgress.detail=s,this.arktsInitProgress.percent=null,this.arktsInitProgress.updatedAt=Date.now())},i=s=>{this.arktsInitProgress&&(this.arktsInitProgress.phase="hvigor",this.arktsInitProgress.detail=s,this.arktsInitProgress.percent=null,this.arktsInitProgress.updatedAt=Date.now())},o=await es.handleSyncProject(e,this.sdkPath,this.nodePath,this.ohpmJsPath,this.hvigorJsPath,t,n,i);return this.handleSyncResult(o)}handleSyncResult(e){switch(e.status){case"success":return this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,!0;case"skipped":{this.syncSkippedDueToLock=!0,this.syncSkipStartedAt===0&&(this.syncSkipStartedAt=Date.now());let t=Date.now()-this.syncSkipStartedAt,n=Math.round(t/1e3);return t>=qg?(h.error(`Sync skipped for ${n}s due to lock contention, giving up`),this.initRetryCount++,this.syncSkipStartedAt=0,this.projectState=5,!1):(h.warn(`Sync skipped: ${e.reason}, resetting to IDLE for retry (elapsed ${n}s / ${qg/1e3}s)`),this.projectState=0,!1)}case"failed":return h.error(`Project sync failed: ${e.reason}`),this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.initRetryCount++,this.projectState=5,!1;default:return h.error(`Project sync: unknown status ${e.status}`),this.syncSkippedDueToLock=!1,this.syncSkipStartedAt=0,this.initRetryCount++,this.projectState=5,!1}}async ensureCppProjectReady(){if(!this.cppEnabled){h.info("[Cpp] C++ LSP disabled by config, skipping initialization"),this.cppHasNoCppCode=!0,this.cppProjectState=4;return}if(!this.cppInitPromise){this.cppInitPromise=this.doEnsureCppProjectReady();try{await this.cppInitPromise}finally{this.cppInitPromise=null}this.cppNeedsReinit&&(this.cppNeedsReinit=!1,this.cppProjectState=0,this.ensureCppProjectReady().catch(e=>{h.warn("Failed to re-init C++ project after cppNeedsReinit:",e)}))}}resolveCppCustomDir(){let e=`${this.config.cppCompileCommandsPath??""}|${this.config.projectPath??""}`;return e!==this.cppCustomDirResolvedFor&&(this.cppCustomDirResolvedFor=e,this.cppCustomCompileCommandsDir=ol(this.config.cppCompileCommandsPath,this.config.projectPath),this.cppCustomCompileCommandsDir&&h.info(`[Cpp] Custom compile_commands dir resolved: ${this.cppCustomCompileCommandsDir}`)),this.cppCustomCompileCommandsDir}async doEnsureCppProjectReady(){let e=this.config.projectPath;if(!e){h.info("[Cpp] No project path, skipping C++ init");return}let t=this.resolveCppCustomDir();if(t){h.info(`[Cpp] Custom compile_commands.json configured, skipping compileNative sync (dir: ${t})`),this.cppHasNoCppCode=!1,await this.initCppLsp(e);return}this.cppProjectState=1;let n=dn(e);if(n.length===0){h.info('[Cpp] No C++ modules found, C++ tools will return "no C++ code"'),this.cppHasNoCppCode=!0,this.cppProjectState=4,this.cppInitRetryCount=0;return}this.cppHasNoCppCode=!1,h.info(`[Cpp] Found ${n.length} C++ module(s): ${n.map(s=>s.name).join(", ")}`);let i=iv(e),o=!i.required;h.info(`[Cpp] C++ sync check: skipCompileNative=${o}, reason=${i.reason}`),await this.runSyncCpp(e,{skipCompileNative:o})&&await this.initCppLsp(e)}async initCppLsp(e){this.cppProjectState=3,this.cppLspManager=new Ga({workspaceRoot:e,clangdPath:this.clangdPath??"",...this.cppCustomCompileCommandsDir?{compileCommandsDir:this.cppCustomCompileCommandsDir}:{}});let t=Date.now();try{await this.cppLspManager.start(),this.cppCheckTool=new ns(this.cppLspManager),this.cppLspTool=new is(this.cppLspManager),this.cppProjectState=4,this.cppInitRetryCount=0,h.info("[Cpp] C++ project fully initialized, C++ tools are available"),await this.trackInit("init_cpp",t,!0,null,this.cppLspManager?.clangdPid??null)}catch(n){h.error("[Cpp] C++ LSP initialization failed:",n);let i=Z(n),o=this.cppLspManager?.clangdPid??null;this.cppLspManager&&this.cppLspManager.dispose().catch(()=>{}),this.cppLspManager=null,this.cppCheckTool=null,this.cppLspTool=null,this.cppInitRetryCount++,this.cppProjectState=5,await this.trackInit("init_cpp",t,!1,i,o)}}async trackInit(e,t,n,i,o){if(!this.config.telemetry)return;let s="unknown";if(o!==null){let l=await gt(o);l!==null&&(s=ce(Number(l)*1024))}let a={event:v.McpToolCall,subAction:e,mcpMemory:ce(process.memoryUsage().rss),lspMemory:s},c={duration_ms:Date.now()-t,success:n,error_code:i};await this.config.telemetry.track(a,c).catch(()=>{})}async runSyncCpp(e,t){this.cppProjectState=2,h.info("[Cpp] Starting C++ project sync (compileNative)...");let n=await Ga.handleSyncCppProject(e,this.sdkPath,this.nodePath,this.hvigorJsPath,t);switch(n.status){case"success":return this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,!0;case"skipped":{this.cppSyncSkippedDueToLock=!0,this.cppSyncSkipStartedAt===0&&(this.cppSyncSkipStartedAt=Date.now());let i=Date.now()-this.cppSyncSkipStartedAt,o=Math.round(i/1e3);return i>=qg?(h.error(`[Cpp] C++ sync skipped for ${o}s due to lock contention, giving up`),this.cppInitRetryCount++,this.cppSyncSkipStartedAt=0,this.cppProjectState=5,!1):(h.warn(`[Cpp] C++ sync skipped: ${n.reason}, resetting to IDLE_CPP for retry (elapsed ${o}s)`),this.cppProjectState=0,!1)}case"failed":return h.error(`[Cpp] C++ project sync failed: ${n.reason}`),this.cppSyncSkippedDueToLock=!1,this.cppSyncSkipStartedAt=0,this.cppInitRetryCount++,this.cppProjectState=5,!1}return!1}async shutdown(){this.arktsCheckTool&&await this.arktsCheckTool.shutdown(),this.cppLspManager&&await this.cppLspManager.dispose(),this.cppCheckTool=null,this.cppLspTool=null;try{await this.server.close()}catch(e){h.warn("Failed to close MCP server connection:",e)}h.info("devecocli-mcp-server stopped"),Cy(),Py()}getToolRouter(){return this.toolRouter}getServer(){return this.server}};function pU(r){let e=[],t=[],n=[];for(let i of r)ss.extname(i).toLowerCase()===".ets"?e.push(i):Kn(i)?t.push(i):n.push(i);return{etsFiles:e,cppFiles:t,unsupported:n}}function Jg(r={}){return new Tu(r)}import*as Kg from"fs";import*as Ja from"path";import{spawn as fU}from"child_process";async function _C(r){Yn(!1);let{serverPath:e,logPath:t,projectPath:n,sdkPath:i,serverMaxSize:o,nodePath:s}=await mU(r),a=yU(e,t,n,i,o,s);h.info("ace-server started, bridging stdio (initialize is left to the client)"),wU(a),await Xg(a.pid,Yg("--arkts",r))}function Yg(r,e){return[r,...e.projectPath?["--project-path"]:[],...e.autoDetect?["--auto-detect"]:[]]}async function Xg(r,e){let t="unknown";if(r!==null){let i=await gt(r);i!==null&&(t=ce(Number(i)*1024))}let n={event:v.ServeLsp,args:e,lspMemory:t};await R.track(n)}async function mU(r){let e=await C.new(),t;if(r.projectPath)t=Ie(Ja.resolve(r.projectPath)),h.info(`projectPath=specified ('${t}'), no search`);else if(r.autoDetect){let c=hc(process.cwd());t=Ie(c??process.cwd()),h.info(`findHarmonyProjectInDir('${process.cwd()}') => ${c??"null, fallback to cwd"}`)}else t=Ie(process.cwd()),h.info(`projectPath=cwd ('${t}'), no search (pass --auto-detect to search subdirs)`);let n=e.sdkPath,i=e.arktsLangServerPath;i||(h.error("ace-server not found (install DevEco Studio / CLT)."),process.exit(1));let o=Hi(i,!0),s=Ja.join(rn(),"lsp-server",String(Date.now()));Kg.mkdirSync(s,{recursive:!0});let a=gU(t,n);return h.info(`projectPath=${t}, sdkPath=${n}, arktsLangServerPath=${i}, serverPath=${o}, logPath=${s}, serverMaxSize=${a}MB`),{projectPath:t,sdkPath:n,serverPath:o,logPath:s,serverMaxSize:a,nodePath:e.nodePath}}function gU(r,e){let t=process.env.NODE_MAX_OLD_SPACE_SIZE,n=t?parseInt(t,10):NaN,i=Number.isFinite(n)&&n>0?n:void 0,o=hU(r,e),s=rl(o,i);return h.info(`[serve-lsp] serverMaxSize=${s}MB (moduleCount=${o}, override=${i??"none"})`),s}function hU(r,e){try{let t=[];return new Ai(r,e).getAllDependencyMap(t).status==="OK"?t.length:new _r(r).getAllModuleInfo().length}catch{return 0}}function yU(r,e,t,n,i,o){let s=Ja.join(e,"lspLog");Kg.mkdirSync(s,{recursive:!0});let a=Ns({serverPath:r,lspLogPath:s,serverMaxSize:i,projectPath:t,sdkPath:n}),c=ri(o);return h.info(`[serve-lsp] spawn: ${c} ${a.join(" ")}`),fU(c,a,{cwd:t,stdio:["pipe","pipe","pipe"],windowsHide:!0})}function wU(r){r.on("error",e=>{h.error(`[ace-server] spawn error: ${e.message}`),process.exit(1)}),r.stdout?.on("error",e=>{h.error(`[ace-server] stdout error: ${e.message}`)}),r.stdout?.on("data",e=>process.stdout.write(e)),r.stderr?.on("error",e=>{h.error(`[ace-server] stderr error: ${e.message}`)}),r.stderr?.on("data",e=>{h.error(`[ace-server] ${e.toString("utf8").trim()}`)}),r.stdin?.on("error",e=>{h.error(`[ace-server] stdin error: ${e.message}`)}),process.stdin.on("data",e=>{r.stdin?.write(e)}),process.stdin.on("end",()=>{h.info("Editor disconnected, shutting down"),r.kill(),process.exit(0)}),r.on("exit",e=>{h.info(`ace-server exited with code ${e}`),process.exit(e??0)})}import*as MC from"fs";import*as Ni from"path";import{spawn as vU}from"child_process";async function LC(r){Yn(!1);let{clangdPath:e,compileCommandsDir:t,projectPath:n}=await bU(r),i=Ni.join(t,"compile_commands.json");MC.existsSync(i)||h.warn(`compile_commands.json not found at ${i}. Cross-file navigation/completion will be limited. Run \`devecocli build\` first to generate it.`);let o=EU(e,t,n);h.info("clangd started, bridging stdio (initialize is left to the client)"),CU(o),await Xg(o.pid,Yg("--cpp",r))}async function bU(r){let e=await SU();e?.clangdPath||(h.error("clangd not found. Ensure DevEco Studio / CLT is installed."),process.exit(1));let t;if(r.projectPath)t=Ie(Ni.resolve(r.projectPath)),h.info(`projectPath=specified ('${t}'), no search`);else if(r.autoDetect){let c=hc(process.cwd());t=Ie(c??process.cwd()),h.info(`findHarmonyProjectInDir('${process.cwd()}') => ${c??"null, fallback to cwd"}`)}else t=Ie(Ni.resolve(process.cwd())),h.info(`projectPath=cwd ('${t}'), no search (pass --auto-detect to search subdirs)`);let n=e.sdkPath,i=e.clangdPath,o=Jn(t),s=Ni.dirname(o),a=ol(process.env.DEVECO_CLI_CPP_COMPILE_COMMANDS,t);return a&&(h.info(`Using custom compile_commands dir: ${a}`),s=a),h.info(`projectPath=${t}, sdkPath=${n}, clangdPath=${i}, compileCommandsDir=${s}`),{projectPath:t,clangdPath:i,compileCommandsDir:s}}async function SU(){try{return await C.new()}catch{let r=wy();if(!r)return null;try{return C.fromIDE(r)}catch{return null}}}function EU(r,e,t){let n=PU(e);return h.info(`[serve-lsp-cpp] spawn: ${r} ${n.join(" ")}`),vU(r,n,{cwd:t,stdio:["pipe","pipe","pipe"],windowsHide:!0})}function PU(r){return[`--compile-commands-dir=${he(r)}`,"--log=info","--pch-storage=memory"]}function CU(r){r.on("error",e=>{h.error(`[clangd] spawn error: ${e.message}`),process.exit(1)}),r.stdout?.on("error",e=>{h.error(`[clangd] stdout error: ${e.message}`)}),r.stdout?.on("data",e=>process.stdout.write(e)),r.stderr?.on("error",e=>{h.error(`[clangd] stderr error: ${e.message}`)}),r.stderr?.on("data",e=>{h.error(`[clangd] ${e.toString("utf8").trim()}`)}),r.stdin?.on("error",e=>{h.error(`[clangd] stdin error: ${e.message}`)}),process.stdin.on("data",e=>{r.stdin?.write(e)}),process.stdin.on("end",()=>{h.info("Editor disconnected, shutting down"),r.kill(),process.exit(0)}),r.on("exit",e=>{h.info(`clangd exited with code ${e}`),process.exit(e??0)})}async function RU(){let r=process.env.PROJECT_PATH||"",e=process.env.NODE_MAX_OLD_SPACE_SIZE,t=process.env.DEBUG==="true"||process.env.DEBUG==="1",n=process.env.DEVECO_CLI_CPP_ENABLED!=="false"&&process.env.DEVECO_CLI_CPP_ENABLED!=="0",i=process.env.DEVECO_CLI_CPP_COMPILE_COMMANDS?.trim()||"",o=r,s=await C.new(),a=Jg({projectPath:o,sdkPath:s.sdkPath,arktsLangServerPath:s.arktsLangServerPath??void 0,nodePath:s.nodePath,ohpmJsPath:s.ohpmJsPath,hvigorJsPath:s.hvigorJsPath,clangdPath:s.clangdPath??void 0,nodeMaxOldSpaceSize:e,debug:t,cppEnabled:n,cppCompileCommandsPath:i||void 0,telemetry:R}),c,l=new Promise(g=>{c=g}),d=async()=>{await a.shutdown(),c()};process.once("SIGINT",d),process.once("SIGTERM",d),process.platform==="win32"&&process.once("SIGBREAK",d);try{await a.start()}catch(g){console.error("Failed to start MCP server:",g instanceof Error?g.message:String(g)),process.exit(1)}await l}var Zg=new kU("serve").description("Host bundled auxiliary protocol servers");Zg.command("mcp").description("Start a local stdio-based MCP server").action(async()=>{await RU()});Zg.command("lsp").description("Start a bundled LSP language server").option("--arkts","Start the ArkTS language server (ace-server)").option("--cpp","Start the C/C++ language server (clangd)").option("--project-path <path>","project root path (used as-is, no search)").option("--auto-detect","When --project-path is not specified, search the current directory and its subdirectories for the project root (no upward search)").action(async r=>{r.arkts&&r.cpp&&(console.error("--arkts and --cpp are mutually exclusive. Specify only one."),process.exit(1)),r.arkts?await _C({projectPath:r.projectPath,autoDetect:r.autoDetect}):r.cpp?await LC({projectPath:r.projectPath,autoDetect:r.autoDetect}):(console.error("Use --arkts or --cpp to specify which language server to start."),process.exit(1))});var FC=Zg;import{Command as OU,InvalidArgumentError as UC}from"commander";import{red as _U,dim as MU}from"colorette";import{Command as xU}from"commander";import{cyan as Nu,yellow as Ou}from"colorette";import*as $C from"path";function DU(r){return Ou(`If you want the latest docs(${r}), please update CLI first: run \`devecocli update\` to update`)}function IU(r){console.log(Ou(`Latest docs v${r.version} (apiVersion ${r.apiVersion}) is incompatible with current CLI.`)),console.log(DU(r.version))}function AU(r,e,t){console.log(t?Nu(`New docs version ${r} found (current v${e??"none"})`):Nu(`Documentation is already up to date v${r}`))}async function TU(r){let e=Ht();console.log(Nu("Checking for documentation updates..."));let{latest:t,compatible:n}=await vo(e);if(!n){IU(t);return}let i=await Yi(),o=!i||Ct(n.version,i)>0;if(r.check){AU(n.version,i,o);return}if(!r.force&&!o){console.log(Ou(`Docs is already up to date v${n.version}`));return}console.log(Nu(`Downloading documentation package v${n.version}...`)),await Ul({version:n.version,apiVersion:n.apiVersion,dist:n.dist},$C.join($(),"doc-data"),"docs-update"),console.log(Ou(`Docs successfully upgrade to ${n.version}`))}var NU=new xU("update").description("Update documentation to the latest compatible version").option("--force","Force re-download even if up to date").option("--check","Check for updates without installing").action(async r=>{await TU(r)}),jC=NU;async function Qg(r,e){let t=Date.now();try{let n=await e();return await HC(r,Date.now()-t,!0,null),n}catch(n){let i=n instanceof Error?n.code??n.name:"UnknownError";throw await HC(r,Date.now()-t,!1,i),n}}async function HC(r,e,t,n){await R.track(r,{duration_ms:e,success:t,error_code:n}).catch(()=>{})}function LU(r){return r instanceof Error&&(r.name==="CacheDirError"||r.name==="DocPathSafetyError")}function eh(r){console.error(_U(FU(r))),process.exitCode=1}function FU(r){let e=r instanceof Error?r.message:String(r);return LU(r)?e:/\b(EACCES|EPERM|ENOSPC|ENOTDIR|ELOOP)\b/.test(e)?"Documentation data directory is unavailable. Check DEVECO_CLI_DATA_DIR and retry.":e}function BC(...r){return e=>{if(!r.includes(e))throw new UC(`Allowed values: ${r.join(", ")}`);return e}}function $U(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new UC("Must be a positive integer.");return e}var jU=BC("json","default"),HU=BC("json","default");function UU(r){let e=r.map(t=>t.trim()).filter(Boolean);if(e.length===0)throw new Error("Keywords cannot be empty.");return e}function BU(r){for(let e=0;e<r.length;e++){let t=r[e];console.log(t.documentId),console.log(` Title: ${t.title}`),t.snippet&&console.log(` Content: ${t.snippet}`),e<r.length-1&&console.log()}}var Ka=new OU("docs").description("HarmonyOS documentation commands (search, read, catalog, update)");Ka.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)","all").option("--format <fmt>","Output format (default, json)",jU,"default").option("--limit <n>","Max number of results",$U,10).action(async(r,e)=>{let t={event:v.DocOperation,subAction:"search",keywords:r,queryLen:r.join(" ").length,catalog:e.catalog??"all"};try{await Qg(t,async()=>{let n=UU(r),i=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await Fc(),s=o.CATALOG_NAMES;if(i&&s&&!s.includes(i))throw new Error(`Invalid catalog "${e.catalog}". Allowed: all, ${s.join(", ")}`);let a=await o.createDocsEngine({cacheDir:$()});try{let c=await a.search({keywords:n,catalog:i,limit:e.limit});e.format==="json"?console.log(JSON.stringify(c,null,2)):BU(c)}finally{await a.close()}})}catch(n){eh(n)}});Ka.command("read <documentId>").description("Read full content of a document by document ID").action(async r=>{let e=r.trim(),t={event:v.DocOperation,subAction:"read",documentId:e};try{await Qg(t,async()=>{if(!e)throw new Error("Document ID cannot be empty.");let i=await(await Fc()).createDocsEngine({cacheDir:$()});try{let o=await i.read({relativePath:e});console.log(o)}finally{await i.close()}})}catch(n){eh(n)}});Ka.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",HU,"default").action(async r=>{let e={event:v.DocOperation,subAction:"catalog",fmt:r.format??"default"};try{await Qg(e,async()=>{let n=await(await Fc()).createDocsEngine({cacheDir:$()});try{let i=await n.catalog();if(r.format==="json")console.log(JSON.stringify(i.map(o=>({name:o.nodeId,title:o.nodeName})),null,2));else for(let o of i)console.log(` ${o.nodeId.padEnd(20)} ${MU(o.nodeName)}`)}finally{await n.close()}})}catch(t){eh(t)}});Ka.addCommand(jC);var WC=Ka;import{Command as O1}from"commander";import{Command as nh,InvalidArgumentError as th,Option as Ya}from"commander";import ih from"ora";var GC=["Selector DSL (common cases):"," key=value exact text=Login"," key*=value contains text*=Log"," key^=value prefix text^=Log"," key$=value suffix text$=in"," key/=regex[/flags] regex search text/=^Login$ text/=login/i"," a,b AND text=Login,type=Button"," [n] nth match (at end) text=Login[0] [last]/[-1]"," keys: text key desc id type enabled focused checked selected visible clickable scrollable",' value with , [ ] or quotes -> quote it: text="a,b" text="a[b]"'," regex backslashes must be doubled",' xpath= prefix -> use xpath expression: xpath=//Button[@id="login"]'," base64= prefix -> base64-encoded selector for shell-safe special chars"," shell special chars -> wrap whole selector in quotes, or use base64= prefix"].join(`
1357
+ `);function WU(r){let e=parseInt(r,10);if(!Number.isInteger(e)||e<0||String(e)!==r.trim())throw new th("depth must be a non-negative integer");return e}function rh(r){let e=Number(r);if(!Number.isFinite(e)||e<=0)throw new th("timeout must be a positive number");if(e>36e4)throw new th("timeout must not exceed 360000ms");return e}function qC(r){let e=[];(r.type||r.id)&&e.push(r.type?r.id?`${r.type}#${r.id}`:r.type:`#${r.id}`),e.push(r.bounds?`[${r.bounds.join(",")}]`:"[]"),r.text&&e.push(`"${JSON.stringify(r.text).slice(1,-1)}"`);let t=[];return r.clickable&&t.push("clickable"),r.longClickable&&t.push("longClickable"),r.scrollable&&t.push("scrollable"),r.checkable&&t.push("checkable"),t.length>0&&e.push(...t),e.join(" ")}function zC(r,e=0){let t=[],n=" ".repeat(e);for(let i of r)t.push(`${n}${qC(i)}`),i.children.length>0&&t.push(...zC(i.children,e+1).split(`
1342
1358
  `));return t.join(`
1343
- `)}function pF(r){if(r.allWindows&&r.window)throw new Error("--all-windows and --window are mutually exclusive.")}function mF(r,e){let t=ro(r,e);if(t.length===0)throw new Error(`Node '${e}' not found.`);let n=t.map(i=>({...i,children:[]}));return JSON.stringify(n,null,2)}function fF(r,e){return e.id?mF(r,e.id):e.format==="json"?JSON.stringify(r,null,2):hP(r)}async function gF(r){pF(r);let e=ug({text:"Dumping layout\u2026",color:"cyan"}).start(),t;try{let i=await C.new(),o=await T(i,r.device),s=new Nr(i.hdcPath);t=r.mode==="full"?await s.dumpFullTree(o,r.depth,r.window,r.allWindows):await s.dumpCollapsedTree(o,r.depth,r.window,r.allWindows)}catch(i){throw e.stop(),new Error(`Failed to dump layout: ${i.message}`,{cause:i})}e.stop();let n=fF(t,r);return console.log(n),Buffer.byteLength(n,"utf8")}function hF(r){return{event:v.CommandExecuted,args:["ui","layout",...r.device?["--device"]:[]],mode:r.mode,outputSize:0}}async function yF(r){let e=hF(r),t=Date.now(),n=!0,i=null;try{e.outputSize=await gF(r)}catch(o){throw n=!1,i=X(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(e,o)}}var yP=new dg("layout").description("Inspect on-screen node(s) for UI testing").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Layout node id").option("--window <windowId>","Target window id").option("--all-windows","Include all windows (mutually exclusive with --window)").addOption(new Ta("--depth <n>","Tree depth limit (0=unlimited, 1=root only, 2=root+children)").argParser(uF).default(0)).addOption(new Ta("--format <format>","Output format").choices(["default","json"]).default("default")).addOption(new Ta("--mode <mode>","Output mode: full | simplified").choices(["full","simplified"]).default("simplified")).action(async r=>{await yF(r)});function wP(r){let e={id:r.id,type:r.type,text:r.text,bounds:r.bounds,clickable:r.clickable==="true"||void 0,longClickable:r.longClickable==="true"||void 0,scrollable:r.scrollable==="true"||void 0,checkable:r.checkable==="true"||void 0,children:[]};return gP(e)}function mP(r){let e={};return r.id!==void 0&&(e.id=r.id),r.type!==void 0&&(e.type=r.type),r.text!==void 0&&(e.text=r.text),r.bounds!==void 0&&(e.bounds=r.bounds),r.clickable!==void 0&&(e.clickable=r.clickable==="true"),r.longClickable!==void 0&&(e.longClickable=r.longClickable==="true"),r.scrollable!==void 0&&(e.scrollable=r.scrollable==="true"),r.checkable!==void 0&&(e.checkable=r.checkable==="true"),r.checked!==void 0&&(e.checked=r.checked==="true"),e}function Oa(){for(let r of em())console.warn(r)}async function wF(r){if(!r.selector)throw new Error("Provide a selector expression.");let e=ug({text:"Finding element\u2026",color:"cyan"}).start(),t;try{let n=await C.new(),i=await T(n,r.device);t=await new io(n.hdcPath).find(i,r.selector,{window:r.window,all:r.all,timeoutMs:r.timeout})}catch(n){throw e.stop(),Oa(),new Error(`Failed to find element: ${n.message}`,{cause:n})}if(e.stop(),Oa(),r.format==="json"){let n=r.all?t.map(i=>mP(i)):mP(t[0]);console.log(JSON.stringify(n,null,2))}else{let n=r.all===!0;for(let i of t){let o=wP(i);console.log(n?`#${i.index} ${o}`:o)}}}var vP=new dg("find").description('Find on-screen element(s) by a selector (e.g. "text=Login,type=Button")').argument("[selector]","Selector DSL, xpath=, or base64= expression").option("--device <name|serial>","Target device (name or serial)").option("--window <windowId>","Target window id").option("--all","Print all matches instead of the first/indexed one").addOption(new Ta("--timeout <ms>","Max wait time in milliseconds for the element to appear").argParser(lg).default(3e3)).addOption(new Ta("--format <format>","Output format").choices(["default","json"]).default("default")).action(async(r,e)=>{await wF({...e,selector:r})}).addHelpText("after",fP);function vF(r){return wP(r)}async function bF(r){await new Promise(e=>setTimeout(e,r)),console.log(`Waited ${r}ms`)}async function SF(r,e,t,n,i){await r.waitForDisappear(e,t,n,i),console.log(`Element disappeared: ${t}`)}async function EF(r,e,t,n,i){let o=await r.waitForAppearance(e,t,n,i);console.log(vF(o))}async function PF(r,e){if(r.length===0)throw new Error("Usage: ui wait [timeoutMs] | ui wait <selector> [timeoutMs]");let t=r[0];if(/^\d+$/.test(t)){if(e.disappear)throw new Error("--disappear requires a selector.");let a=lg(t);Oa(),await bF(a);return}let i=t,o=r[1]?lg(r[1]):3e3,s=ug({text:"Waiting\u2026",color:"cyan"}).start();try{let a=await C.new(),c=await T(a,e.device),l=new io(a.hdcPath);e.disappear?await SF(l,c,i,o,e.window):await EF(l,c,i,o,e.window),s.stop(),Oa()}catch(a){throw s.stop(),Oa(),new Error(`Failed to wait: ${a.message}`,{cause:a})}}var bP=new dg("wait").description("Wait: sleep [timeoutMs], or wait for element <selector> [timeoutMs] [--disappear]").argument("[args...]","Args: [timeoutMs] for sleep, or <selector> [timeoutMs] for element wait").option("--disappear","Wait for element to disappear (requires selector)").option("--device <name|serial>","Target device (name or serial)").option("--window <windowId>","Target window id").action(async(r,e)=>{await PF(r,e)}).addHelpText("after",fP);import{Command as CF,Option as kF}from"commander";import{yellow as DF}from"colorette";import RF from"ora";var xF=["Id","Name","Pid","DisplayId","Focused"];function AF(r,e){if(e==="json"){let n=r.map(i=>({id:i.id,name:i.name,pid:i.pid,displayId:i.displayId,focused:i.focused}));console.log(JSON.stringify(n,null,2));return}let t=r.map(n=>({cells:[String(n.id),n.name,String(n.pid),String(n.displayId),String(n.focused)],highlight:n.focused}));console.log(jr(xF,t))}async function IF(r){let e=RF({text:"Listing windows\u2026",color:"cyan"}).start(),t;try{let n=await C.new(),i=await T(n,r.device);t=await new Or(n.hdcPath,i).listWindows({all:r.all})}catch(n){throw e.stop(),new Error(`Failed to list windows: ${n.message}`,{cause:n})}if(e.stop(),t.length===0){console.log(DF(" No windows found."));return}AF(t,r.format)}function TF(r){let e=[];return r.device&&e.push("--device"),r.format!=="default"&&e.push("--format"),r.all&&e.push("--all"),{event:v.CommandExecuted,args:["ui","window","list",...e]}}async function OF(r){let e=TF(r),t=Date.now(),n=!0,i=null;try{await IF(r)}catch(o){throw n=!1,i=X(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(e,o)}}var pg=new CF("window").description("Manage device windows");pg.command("list").description("List windows on the device").option("--device <name|serial>","Target device (name or serial)").addOption(new kF("--format <format>","Output format").choices(["default","json"]).default("default")).option("--all","Show all windows including system windows").action(async r=>{await OF(r)});import{Command as NF}from"commander";import{green as MF}from"colorette";function LF(r){return{event:v.CommandExecuted,args:["ui","screenshot",...r.device?["--device"]:[]]}}function _F(r){let e=r.trim();if(!/^\d+$/.test(e))throw new Error("--display must be a non-negative integer.");return e}async function $F(r){let e=LF(r),t=Date.now(),n=!0,i=null;try{if(r.device!==void 0&&!r.device.trim())throw new Error("--device must not be empty.");let o=r.display!==void 0?_F(r.display):void 0,s=await C.new(),a=new ni(s),c=a.resolveDestinationPath(r.path),l=await T(s,r.device);await a.captureToPath(l,c,o),console.log(MF(`Screenshot saved to ${c}`))}catch(o){throw n=!1,i=X(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(e,o)}}var SP=new NF("screenshot").description("Capture a screenshot of the device screen").option("--device <name|serial>","Target device name or serial; required when multiple devices are connected").option("--display <displayId>","Target display id; omit for default screen").option("--path <path>","Required directory or PNG file path; destination must be writable").action($F);import{Command as ru,Option as FF}from"commander";import{green as mg,yellow as jF}from"colorette";import PP from"ora";var nu=["--device <name|serial>","Target physical device name or serial; required when multiple devices are connected"],CP=["--path <dir|file.mp4>","Required writable destination: existing directory or a new .mp4 file"];function iu(r){return new S("INVALID_ARGUMENT",r)}function EP(r){if(r!==void 0&&!r.trim())throw iu("--device must not be empty.")}function ou(r,e){let t=r.parent?.opts()?.device;if(EP(t),EP(e),t&&e&&t!==e)throw iu(`Conflicting --device values: ${JSON.stringify(t)} and ${JSON.stringify(e)}`);return e??t}function kP(r,e){if(r.parent?.opts()?.path!==void 0)throw iu(`--path is not valid for ui screenrecord ${e}.`)}function DP(r,e){let t=r.parent?.opts()?.path;if(t!==void 0&&e!==void 0&&t!==e)throw iu(`Conflicting --path values: ${JSON.stringify(t)} and ${JSON.stringify(e)}`);return e??t}function su(r,e){let t=r.parent?.opts();return e.filter(n=>n.value!==void 0||t?.[n.name.slice(2)]!==void 0).map(n=>n.name)}function HF(r,e){return r.getOptionValueSource(e)==="cli"}async function au(r,e,t){let n={event:v.CommandExecuted,args:["ui","screenrecord",...r,...e]},i=Date.now(),o=!0,s=null;try{await t()}catch(a){throw o=!1,s=X(a),a}finally{let a={duration_ms:Date.now()-i,success:o,error_code:s};await D.track(n,a)}}function RP(r){if(r.kind==="saved"){console.log(mg(`Saved successfully to ${r.localPath}`));for(let e of r.warnings??[])console.error(jF(`Warning: ${e}`))}else r.kind==="external-stopped"&&console.log(mg("Recording stopped. View the file in the device gallery; this CLI cannot retrieve it."))}async function UF(r,e){let t=su(e,[{name:"--device",value:r.device},{name:"--path",value:r.path}]);await au([],t,async()=>{let n=ou(e,r.device),i=DP(e,r.path),o=new dn(await C.new()),s,a;try{a=await o.recordInteractively(n,i,{onStarted:()=>{console.log("Recording... press Ctrl+C to stop and save")},onStopRequested:()=>{s=PP({text:"Stopping and saving the recording\u2026",color:"cyan"}).start()}})}finally{s?.stop()}RP(a)})}async function BF(r,e){let t=su(e,[{name:"--device",value:r.device},{name:"--path",value:r.path}]);await au(["start"],t,async()=>{let n=ou(e,r.device),i=DP(e,r.path);await new dn(await C.new()).startDetached(n,i),console.log(mg("Recording started. Stop with devecocli ui screenrecord stop"))})}async function WF(r,e){let t=[...su(e,[{name:"--device",value:r.device}]),...r.force?["--force"]:[]];await au(["stop"],t,async()=>{let n=ou(e,r.device);kP(e,"stop");let i=new dn(await C.new()),o=PP({text:"Stopping recording\u2026",color:"cyan"}).start(),s;try{s=await i.stopRecording(n,r.force??!1)}finally{o.stop()}RP(s)})}var VF={recording:"Status: recording - a recording started by this CLI is in progress",busy:"Status: busy - a recording started outside this CLI is in progress",idle:"Status: idle - no recording is in progress"};async function GF(r,e){let t=[...su(e,[{name:"--device",value:r.device}]),...HF(e,"format")?["--format"]:[]];await au(["status"],t,async()=>{let n=ou(e,r.device);kP(e,"status");let o=await new dn(await C.new()).getRecordingStatus(n);if(r.format==="json"){console.log(JSON.stringify(o));return}console.log(VF[o.status]),o.status==="idle"&&o.note&&console.log(o.note)})}var Na=new ru("screenrecord").description("Record the screen of a physical device to an MP4 file").option(...nu).option(...CP).action(UF);Na.addCommand(new ru("start").description("Start recording and return immediately (detached)").option(...nu).option(...CP).action(BF));Na.addCommand(new ru("stop").description("Stop the current recording and save the file").option(...nu).option("--force","Stop a recording that was not started by this CLI (no download)").action(WF));Na.addCommand(new ru("status").description("Show the recording status without changing it").option(...nu).addOption(new FF("--format <format>","Output format").choices(["table","json"]).default("table")).action(GF));import{Command as In}from"commander";function Tn(r,e){let t=[];return"device"in e&&e.device&&t.push("--device"),"id"in e&&e.id&&t.push("--id"),"window"in e&&e.window&&t.push("--window"),"speed"in e&&e.speed&&t.push("--speed"),{event:v.CommandExecuted,args:["ui",r,...t]}}function qF(r){let t=`"$(printf '%s' '${Buffer.from(r,"utf8").toString("base64")}' | base64 -d)"`;return m(`escapeShellText: ${r} -> ${t}`),t}async function On(r,e,t,n){let i=new Ie;i.start(r);let o=Date.now(),s=!0,a=null;try{await n(i)}catch(c){throw i.stop(),s=!1,a=X(c),new Error(`${e}: ${c.message}`,{cause:c})}finally{let c={duration_ms:Date.now()-o,success:s,error_code:a};await D.track(t,c)}}async function zF(r,e,t){let n=Tn("click",t);await On("Executing click...","click failed",n,async i=>{ao(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await pr(t.device),{x:a,y:c}=await co(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await Dt(o,s,["uitest","uiInput","click",String(a),String(c)]),i.succeed(`click at (${a}, ${c})`)})}async function JF(r,e,t){let n=Tn("doubleclick",t);await On("Executing doubleclick...","doubleclick failed",n,async i=>{ao(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await pr(t.device),{x:a,y:c}=await co(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await Dt(o,s,["uitest","uiInput","doubleClick",String(a),String(c)]),i.succeed(`doubleclick at (${a}, ${c})`)})}async function YF(r,e,t){let n=Tn("longclick",t);await On("Executing longclick...","longclick failed",n,async i=>{ao(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await pr(t.device),{x:a,y:c}=await co(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await Dt(o,s,["uitest","uiInput","longClick",String(a),String(c)]),i.succeed(`longclick at (${a}, ${c})`)})}async function KF(r,e,t,n,i){let o=Tn("swipe",i);await On("Executing swipe...","swipe failed",o,async s=>{Ve(r,"x1"),Ve(e,"y1"),Ve(t,"x2"),Ve(n,"y2");let a=Ts(i.speed),{hdcPath:c,deviceId:l}=await pr(i.device),d=["uitest","uiInput","swipe",r,e,t,n];a&&d.push(a),await Dt(c,l,d),s.succeed(`swipe from (${r}, ${e}) to (${t}, ${n})`)})}async function XF(r,e,t,n,i){let o=Tn("fling",i);await On("Executing fling...","fling failed",o,async s=>{Ve(r,"x1"),Ve(e,"y1"),Ve(t,"x2"),Ve(n,"y2");let a=Ts(i.speed),{hdcPath:c,deviceId:l}=await pr(i.device),d=["uitest","uiInput","fling",r,e,t,n];a&&d.push(a),await Dt(c,l,d),s.succeed(`fling from (${r}, ${e}) to (${t}, ${n})`)})}async function ZF(r,e,t,n,i){let o=Tn("drag",i);await On("Executing drag...","drag failed",o,async s=>{Ve(r,"x1"),Ve(e,"y1"),Ve(t,"x2"),Ve(n,"y2");let a=Ts(i.speed),{hdcPath:c,deviceId:l}=await pr(i.device),d=["uitest","uiInput","drag",r,e,t,n];a&&d.push(a),await Dt(c,l,d),s.succeed(`drag from (${r}, ${e}) to (${t}, ${n})`)})}async function QF(r,e){let t=Tn("dircfling",e);await On("Executing dircfling...","dircfling failed",t,async n=>{let i=ml[r];if(i===void 0)throw new Error(`Invalid direction "${r}". Valid values: ${Object.keys(ml).join(", ")}`);let{hdcPath:o,deviceId:s}=await pr(e.device);await Dt(o,s,["uitest","uiInput","dircFling",i]),n.succeed(`dircfling ${r}`)})}async function ej(r,e,t,n){let i=Tn("text",n);await On("Executing text input...","input failed",i,async o=>{ao(e,t,n.id,n.window,!1),fl(r,"text");let{hdcPath:s,deviceId:a}=await pr(n.device),c=qF(r);if(e!==void 0)await Dt(s,a,[`uitest uiInput inputText ${e} ${t} ${c}`]),o.succeed(`input ${r} at (${e}, ${t})`);else if(n.id){let{x:l,y:d}=await co(s,a,void 0,void 0,n.id,n.window);await Dt(s,a,[`uitest uiInput inputText ${l} ${d} ${c}`]),o.succeed(`input ${r} at (${l}, ${d})`)}else await Dt(s,a,[`uitest uiInput text ${c}`]),o.succeed(`input ${r}`)})}var xP=new In("click").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Tap at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(zF),AP=new In("doubleclick").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Double-tap at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(JF),IP=new In("longclick").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Long-press at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(YF),TP=new In("swipe").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Swipe from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(KF),OP=new In("fling").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Fling from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(XF),NP=new In("drag").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Drag from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(ZF),MP=new In("dircfling").argument("<direction>","Direction: up, down, left, right").description("Fling in a specified direction").option("--device <name|serial>","Target device (name or serial)").action(QF),LP=new In("text").argument("<text>","Text to input").argument("[x]","Optional X coordinate").argument("[y]","Optional Y coordinate").description("Input text at a target location or the currently focused field").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id to target before input (auto-resolves to center)").option("--window <windowId>","Target window id (used with --id)").action(ej);var Ze=new tj("ui").description("Inspect and interact with UI on a connected device");Ze.addCommand(yP);Ze.addCommand(vP);Ze.addCommand(bP);Ze.addCommand(pg);Ze.addCommand(SP);Ze.addCommand(Na);Ze.addCommand(xP);Ze.addCommand(AP);Ze.addCommand(IP);Ze.addCommand(TP);Ze.addCommand(OP);Ze.addCommand(NP);Ze.addCommand(MP);Ze.addCommand(LP);var _P=Ze;import{Command as yC,InvalidArgumentError as XH}from"commander";import{execa as kj}from"execa";import Pr from"fs";import*as wg from"os";import*as V from"path";var rj=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),nj=/\r/g,ij=/^(Working|Finished)\.\.\.\[[^\]]*\]\d+%$/,oj=/^<+\s*/,sj=/\s*>+$/,aj=[/^The configuration file .+ is in use\.$/,/^The configuration file .+ in the project is in use\.$/,/^Currently active product: ?.+$/,/^Writing the result to .+\.$/,/^Write finished\.$/,/^CodeLinter found some defects in your code\.$/],cj=new Set([1]);function gg(r){if(!r)return"";let e=r.replace(rj,"").replace(nj,`
1359
+ `)}function VU(r){if(r.allWindows&&r.window)throw new Error("--all-windows and --window are mutually exclusive.")}function GU(r,e){let t=po(r,e);if(t.length===0)throw new Error(`Node '${e}' not found.`);let n=t.map(i=>({...i,children:[]}));return JSON.stringify(n,null,2)}function qU(r,e){return e.id?GU(r,e.id):e.format==="json"?JSON.stringify(r,null,2):zC(r)}async function zU(r){VU(r);let e=ih({text:"Dumping layout\u2026",color:"cyan"}).start(),t;try{let i=await C.new(),o=await T(i,r.device),s=new Fr(i.hdcPath);t=r.mode==="full"?await s.dumpFullTree(o,r.depth,r.window,r.allWindows):await s.dumpCollapsedTree(o,r.depth,r.window,r.allWindows)}catch(i){throw e.stop(),new Error(`Failed to dump layout: ${i.message}`,{cause:i})}e.stop();let n=qU(t,r);return console.log(n),Buffer.byteLength(n,"utf8")}function JU(r){return{event:v.CommandExecuted,args:["ui","layout",...r.device?["--device"]:[]],mode:r.mode,outputSize:0}}async function KU(r){let e=JU(r),t=Date.now(),n=!0,i=null;try{e.outputSize=await zU(r)}catch(o){throw n=!1,i=Z(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(e,o)}}var JC=new nh("layout").description("Inspect on-screen node(s) for UI testing").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Layout node id").option("--window <windowId>","Target window id").option("--all-windows","Include all windows (mutually exclusive with --window)").addOption(new Ya("--depth <n>","Tree depth limit (0=unlimited, 1=root only, 2=root+children)").argParser(WU).default(0)).addOption(new Ya("--format <format>","Output format").choices(["default","json"]).default("default")).addOption(new Ya("--mode <mode>","Output mode: full | simplified").choices(["full","simplified"]).default("simplified")).action(async r=>{await KU(r)});function KC(r){let e={id:r.id,type:r.type,text:r.text,bounds:r.bounds,clickable:r.clickable==="true"||void 0,longClickable:r.longClickable==="true"||void 0,scrollable:r.scrollable==="true"||void 0,checkable:r.checkable==="true"||void 0,children:[]};return qC(e)}function VC(r){let e={};return r.id!==void 0&&(e.id=r.id),r.type!==void 0&&(e.type=r.type),r.text!==void 0&&(e.text=r.text),r.bounds!==void 0&&(e.bounds=r.bounds),r.clickable!==void 0&&(e.clickable=r.clickable==="true"),r.longClickable!==void 0&&(e.longClickable=r.longClickable==="true"),r.scrollable!==void 0&&(e.scrollable=r.scrollable==="true"),r.checkable!==void 0&&(e.checkable=r.checkable==="true"),r.checked!==void 0&&(e.checked=r.checked==="true"),e}function Xa(){for(let r of Nf())console.warn(r)}async function YU(r){if(!r.selector)throw new Error("Provide a selector expression.");let e=ih({text:"Finding element\u2026",color:"cyan"}).start(),t;try{let n=await C.new(),i=await T(n,r.device);t=await new mo(n.hdcPath).find(i,r.selector,{window:r.window,all:r.all,timeoutMs:r.timeout})}catch(n){throw e.stop(),Xa(),new Error(`Failed to find element: ${n.message}`,{cause:n})}if(e.stop(),Xa(),r.format==="json"){let n=r.all?t.map(i=>VC(i)):VC(t[0]);console.log(JSON.stringify(n,null,2))}else{let n=r.all===!0;for(let i of t){let o=KC(i);console.log(n?`#${i.index} ${o}`:o)}}}var YC=new nh("find").description('Find on-screen element(s) by a selector (e.g. "text=Login,type=Button")').argument("[selector]","Selector DSL, xpath=, or base64= expression").option("--device <name|serial>","Target device (name or serial)").option("--window <windowId>","Target window id").option("--all","Print all matches instead of the first/indexed one").addOption(new Ya("--timeout <ms>","Max wait time in milliseconds for the element to appear").argParser(rh).default(3e3)).addOption(new Ya("--format <format>","Output format").choices(["default","json"]).default("default")).action(async(r,e)=>{await YU({...e,selector:r})}).addHelpText("after",GC);function XU(r){return KC(r)}async function ZU(r){await new Promise(e=>setTimeout(e,r)),console.log(`Waited ${r}ms`)}async function QU(r,e,t,n,i){await r.waitForDisappear(e,t,n,i),console.log(`Element disappeared: ${t}`)}async function e1(r,e,t,n,i){let o=await r.waitForAppearance(e,t,n,i);console.log(XU(o))}async function t1(r,e){if(r.length===0)throw new Error("Usage: ui wait [timeoutMs] | ui wait <selector> [timeoutMs]");let t=r[0];if(/^\d+$/.test(t)){if(e.disappear)throw new Error("--disappear requires a selector.");let a=rh(t);Xa(),await ZU(a);return}let i=t,o=r[1]?rh(r[1]):3e3,s=ih({text:"Waiting\u2026",color:"cyan"}).start();try{let a=await C.new(),c=await T(a,e.device),l=new mo(a.hdcPath);e.disappear?await QU(l,c,i,o,e.window):await e1(l,c,i,o,e.window),s.stop(),Xa()}catch(a){throw s.stop(),Xa(),new Error(`Failed to wait: ${a.message}`,{cause:a})}}var XC=new nh("wait").description("Wait: sleep [timeoutMs], or wait for element <selector> [timeoutMs] [--disappear]").argument("[args...]","Args: [timeoutMs] for sleep, or <selector> [timeoutMs] for element wait").option("--disappear","Wait for element to disappear (requires selector)").option("--device <name|serial>","Target device (name or serial)").option("--window <windowId>","Target window id").action(async(r,e)=>{await t1(r,e)}).addHelpText("after",GC);import{Command as r1,Option as n1}from"commander";import{yellow as i1}from"colorette";import o1 from"ora";var s1=["Id","Name","Pid","DisplayId","Focused"];function a1(r,e){if(e==="json"){let n=r.map(i=>({id:i.id,name:i.name,pid:i.pid,displayId:i.displayId,focused:i.focused}));console.log(JSON.stringify(n,null,2));return}let t=r.map(n=>({cells:[String(n.id),n.name,String(n.pid),String(n.displayId),String(n.focused)],highlight:n.focused}));console.log(zt(s1,t))}async function c1(r){let e=o1({text:"Listing windows\u2026",color:"cyan"}).start(),t;try{let n=await C.new(),i=await T(n,r.device);t=await new Lr(n.hdcPath,i).listWindows({all:r.all})}catch(n){throw e.stop(),new Error(`Failed to list windows: ${n.message}`,{cause:n})}if(e.stop(),t.length===0){console.log(i1(" No windows found."));return}a1(t,r.format)}function l1(r){let e=[];return r.device&&e.push("--device"),r.format!=="default"&&e.push("--format"),r.all&&e.push("--all"),{event:v.CommandExecuted,args:["ui","window","list",...e]}}async function d1(r){let e=l1(r),t=Date.now(),n=!0,i=null;try{await c1(r)}catch(o){throw n=!1,i=Z(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(e,o)}}var oh=new r1("window").description("Manage device windows");oh.command("list").description("List windows on the device").option("--device <name|serial>","Target device (name or serial)").addOption(new n1("--format <format>","Output format").choices(["default","json"]).default("default")).option("--all","Show all windows including system windows").action(async r=>{await d1(r)});import{Command as u1}from"commander";import{green as p1}from"colorette";function f1(r){return{event:v.CommandExecuted,args:["ui","screenshot",...r.device?["--device"]:[]]}}function m1(r){let e=r.trim();if(!/^\d+$/.test(e))throw new Error("--display must be a non-negative integer.");return e}async function g1(r){let e=f1(r),t=Date.now(),n=!0,i=null;try{if(r.device!==void 0&&!r.device.trim())throw new Error("--device must not be empty.");let o=r.display!==void 0?m1(r.display):void 0,s=await C.new(),a=new ai(s),c=a.resolveDestinationPath(r.path),l=await T(s,r.device);await a.captureToPath(l,c,o),console.log(p1(`Screenshot saved to ${c}`))}catch(o){throw n=!1,i=Z(o),o}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(e,o)}}var ZC=new u1("screenshot").description("Capture a screenshot of the device screen").option("--device <name|serial>","Target device name or serial; required when multiple devices are connected").option("--display <displayId>","Target display id; omit for default screen").option("--path <path>","Required directory or PNG file path; destination must be writable").action(g1);import{Command as _u,Option as h1}from"commander";import{green as sh,yellow as y1}from"colorette";import ek from"ora";var Mu=["--device <name|serial>","Target physical device name or serial; required when multiple devices are connected"],tk=["--path <dir|file.mp4>","Required writable destination: existing directory or a new .mp4 file"];function Lu(r){return new S("INVALID_ARGUMENT",r)}function QC(r){if(r!==void 0&&!r.trim())throw Lu("--device must not be empty.")}function Fu(r,e){let t=r.parent?.opts()?.device;if(QC(t),QC(e),t&&e&&t!==e)throw Lu(`Conflicting --device values: ${JSON.stringify(t)} and ${JSON.stringify(e)}`);return e??t}function rk(r,e){if(r.parent?.opts()?.path!==void 0)throw Lu(`--path is not valid for ui screenrecord ${e}.`)}function nk(r,e){let t=r.parent?.opts()?.path;if(t!==void 0&&e!==void 0&&t!==e)throw Lu(`Conflicting --path values: ${JSON.stringify(t)} and ${JSON.stringify(e)}`);return e??t}function $u(r,e){let t=r.parent?.opts();return e.filter(n=>n.value!==void 0||t?.[n.name.slice(2)]!==void 0).map(n=>n.name)}function w1(r,e){return r.getOptionValueSource(e)==="cli"}async function ju(r,e,t){let n={event:v.CommandExecuted,args:["ui","screenrecord",...r,...e]},i=Date.now(),o=!0,s=null;try{await t()}catch(a){throw o=!1,s=Z(a),a}finally{let a={duration_ms:Date.now()-i,success:o,error_code:s};await R.track(n,a)}}function ik(r){if(r.kind==="saved"){console.log(sh(`Saved successfully to ${r.localPath}`));for(let e of r.warnings??[])console.error(y1(`Warning: ${e}`))}else r.kind==="external-stopped"&&console.log(sh("Recording stopped. View the file in the device gallery; this CLI cannot retrieve it."))}async function v1(r,e){let t=$u(e,[{name:"--device",value:r.device},{name:"--path",value:r.path}]);await ju([],t,async()=>{let n=Fu(e,r.device),i=nk(e,r.path),o=new fn(await C.new()),s,a;try{a=await o.recordInteractively(n,i,{onStarted:()=>{console.log("Recording... press Ctrl+C to stop and save")},onStopRequested:()=>{s=ek({text:"Stopping and saving the recording\u2026",color:"cyan"}).start()}})}finally{s?.stop()}ik(a)})}async function b1(r,e){let t=$u(e,[{name:"--device",value:r.device},{name:"--path",value:r.path}]);await ju(["start"],t,async()=>{let n=Fu(e,r.device),i=nk(e,r.path);await new fn(await C.new()).startDetached(n,i),console.log(sh("Recording started. Stop with devecocli ui screenrecord stop"))})}async function S1(r,e){let t=[...$u(e,[{name:"--device",value:r.device}]),...r.force?["--force"]:[]];await ju(["stop"],t,async()=>{let n=Fu(e,r.device);rk(e,"stop");let i=new fn(await C.new()),o=ek({text:"Stopping recording\u2026",color:"cyan"}).start(),s;try{s=await i.stopRecording(n,r.force??!1)}finally{o.stop()}ik(s)})}var E1={recording:"Status: recording - a recording started by this CLI is in progress",busy:"Status: busy - a recording started outside this CLI is in progress",idle:"Status: idle - no recording is in progress"};async function P1(r,e){let t=[...$u(e,[{name:"--device",value:r.device}]),...w1(e,"format")?["--format"]:[]];await ju(["status"],t,async()=>{let n=Fu(e,r.device);rk(e,"status");let o=await new fn(await C.new()).getRecordingStatus(n);if(r.format==="json"){console.log(JSON.stringify(o));return}console.log(E1[o.status]),o.status==="idle"&&o.note&&console.log(o.note)})}var Za=new _u("screenrecord").description("Record the screen of a physical device to an MP4 file").option(...Mu).option(...tk).action(v1);Za.addCommand(new _u("start").description("Start recording and return immediately (detached)").option(...Mu).option(...tk).action(b1));Za.addCommand(new _u("stop").description("Stop the current recording and save the file").option(...Mu).option("--force","Stop a recording that was not started by this CLI (no download)").action(S1));Za.addCommand(new _u("status").description("Show the recording status without changing it").option(...Mu).addOption(new h1("--format <format>","Output format").choices(["table","json"]).default("table")).action(P1));import{Command as On}from"commander";function _n(r,e){let t=[];return"device"in e&&e.device&&t.push("--device"),"id"in e&&e.id&&t.push("--id"),"window"in e&&e.window&&t.push("--window"),"speed"in e&&e.speed&&t.push("--speed"),{event:v.CommandExecuted,args:["ui",r,...t]}}function C1(r){let t=`"$(printf '%s' '${Buffer.from(r,"utf8").toString("base64")}' | base64 -d)"`;return f(`escapeShellText: ${r} -> ${t}`),t}async function Mn(r,e,t,n){let i=new Te;i.start(r);let o=Date.now(),s=!0,a=null;try{await n(i)}catch(c){throw i.stop(),s=!1,a=Z(c),new Error(`${e}: ${c.message}`,{cause:c})}finally{let c={duration_ms:Date.now()-o,success:s,error_code:a};await R.track(t,c)}}async function k1(r,e,t){let n=_n("click",t);await Mn("Executing click...","click failed",n,async i=>{yo(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await hr(t.device),{x:a,y:c}=await wo(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await xt(o,s,["uitest","uiInput","click",String(a),String(c)]),i.succeed(`click at (${a}, ${c})`)})}async function R1(r,e,t){let n=_n("doubleclick",t);await Mn("Executing doubleclick...","doubleclick failed",n,async i=>{yo(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await hr(t.device),{x:a,y:c}=await wo(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await xt(o,s,["uitest","uiInput","doubleClick",String(a),String(c)]),i.succeed(`doubleclick at (${a}, ${c})`)})}async function x1(r,e,t){let n=_n("longclick",t);await Mn("Executing longclick...","longclick failed",n,async i=>{yo(r,e,t.id,t.window);let{hdcPath:o,deviceId:s}=await hr(t.device),{x:a,y:c}=await wo(o,s,r!==void 0?Number(r):void 0,e!==void 0?Number(e):void 0,t.id,t.window);await xt(o,s,["uitest","uiInput","longClick",String(a),String(c)]),i.succeed(`longclick at (${a}, ${c})`)})}async function D1(r,e,t,n,i){let o=_n("swipe",i);await Mn("Executing swipe...","swipe failed",o,async s=>{Ge(r,"x1"),Ge(e,"y1"),Ge(t,"x2"),Ge(n,"y2");let a=Ws(i.speed),{hdcPath:c,deviceId:l}=await hr(i.device),d=["uitest","uiInput","swipe",r,e,t,n];a&&d.push(a),await xt(c,l,d),s.succeed(`swipe from (${r}, ${e}) to (${t}, ${n})`)})}async function I1(r,e,t,n,i){let o=_n("fling",i);await Mn("Executing fling...","fling failed",o,async s=>{Ge(r,"x1"),Ge(e,"y1"),Ge(t,"x2"),Ge(n,"y2");let a=Ws(i.speed),{hdcPath:c,deviceId:l}=await hr(i.device),d=["uitest","uiInput","fling",r,e,t,n];a&&d.push(a),await xt(c,l,d),s.succeed(`fling from (${r}, ${e}) to (${t}, ${n})`)})}async function A1(r,e,t,n,i){let o=_n("drag",i);await Mn("Executing drag...","drag failed",o,async s=>{Ge(r,"x1"),Ge(e,"y1"),Ge(t,"x2"),Ge(n,"y2");let a=Ws(i.speed),{hdcPath:c,deviceId:l}=await hr(i.device),d=["uitest","uiInput","drag",r,e,t,n];a&&d.push(a),await xt(c,l,d),s.succeed(`drag from (${r}, ${e}) to (${t}, ${n})`)})}async function T1(r,e){let t=_n("dircfling",e);await Mn("Executing dircfling...","dircfling failed",t,async n=>{let i=Tl[r];if(i===void 0)throw new Error(`Invalid direction "${r}". Valid values: ${Object.keys(Tl).join(", ")}`);let{hdcPath:o,deviceId:s}=await hr(e.device);await xt(o,s,["uitest","uiInput","dircFling",i]),n.succeed(`dircfling ${r}`)})}async function N1(r,e,t,n){let i=_n("text",n);await Mn("Executing text input...","input failed",i,async o=>{yo(e,t,n.id,n.window,!1),Nl(r,"text");let{hdcPath:s,deviceId:a}=await hr(n.device),c=C1(r);if(e!==void 0)await xt(s,a,[`uitest uiInput inputText ${e} ${t} ${c}`]),o.succeed(`input ${r} at (${e}, ${t})`);else if(n.id){let{x:l,y:d}=await wo(s,a,void 0,void 0,n.id,n.window);await xt(s,a,[`uitest uiInput inputText ${l} ${d} ${c}`]),o.succeed(`input ${r} at (${l}, ${d})`)}else await xt(s,a,[`uitest uiInput text ${c}`]),o.succeed(`input ${r}`)})}var ok=new On("click").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Tap at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(k1),sk=new On("doubleclick").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Double-tap at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(R1),ak=new On("longclick").argument("[x]","X coordinate").argument("[y]","Y coordinate").description("Long-press at the specified coordinates").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id (auto-resolves to center coordinates)").option("--window <windowId>","Target window id (used with --id)").action(x1),ck=new On("swipe").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Swipe from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(D1),lk=new On("fling").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Fling from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(I1),dk=new On("drag").argument("<x1>","Start X coordinate").argument("<y1>","Start Y coordinate").argument("<x2>","End X coordinate").argument("<y2>","End Y coordinate").description("Drag from one point to another").option("--device <name|serial>","Target device (name or serial)").option("--speed <n>","Swipe speed (pixels per second)").action(A1),uk=new On("dircfling").argument("<direction>","Direction: up, down, left, right").description("Fling in a specified direction").option("--device <name|serial>","Target device (name or serial)").action(T1),pk=new On("text").argument("<text>","Text to input").argument("[x]","Optional X coordinate").argument("[y]","Optional Y coordinate").description("Input text at a target location or the currently focused field").option("--device <name|serial>","Target device (name or serial)").option("--id <id>","Node id to target before input (auto-resolves to center)").option("--window <windowId>","Target window id (used with --id)").action(N1);var Qe=new O1("ui").description("Inspect and interact with UI on a connected device");Qe.addCommand(JC);Qe.addCommand(YC);Qe.addCommand(XC);Qe.addCommand(oh);Qe.addCommand(ZC);Qe.addCommand(Za);Qe.addCommand(ok);Qe.addCommand(sk);Qe.addCommand(ak);Qe.addCommand(ck);Qe.addCommand(lk);Qe.addCommand(dk);Qe.addCommand(uk);Qe.addCommand(pk);var fk=Qe;import{Command as Jk,InvalidArgumentError as IW}from"commander";import{execa as nB}from"execa";import Dr from"fs";import*as uh from"os";import*as V from"path";var _1=new RegExp("\x1B\\[[0-?]*[ -/]*[@-~]","g"),M1=/\r/g,L1=/^(Working|Finished)\.\.\.\[[^\]]*\]\d+%$/,F1=/^<+\s*/,$1=/\s*>+$/,j1=[/^The configuration file .+ is in use\.$/,/^The configuration file .+ in the project is in use\.$/,/^Currently active product: ?.+$/,/^Writing the result to .+\.$/,/^Write finished\.$/,/^CodeLinter found some defects in your code\.$/],H1=new Set([1]);function ch(r){if(!r)return"";let e=r.replace(_1,"").replace(M1,`
1344
1360
  `).split(`
1345
- `).map(lj).map(t=>t.trimEnd()).filter(t=>uj(t));return e.length>0?`${e.join(`
1361
+ `).map(U1).map(t=>t.trimEnd()).filter(t=>W1(t));return e.length>0?`${e.join(`
1346
1362
  `)}
1347
- `:""}function lj(r){let e=r.trim();if(!e.startsWith("{"))return r;try{let t=JSON.parse(e);return typeof t.content!="string"||typeof t.messageType!="number"?r:cj.has(t.messageType)?"":t.content}catch{return r}}var $P=50*1024*1024;function UP(r){let e=gg(r).trim();if(!e)return{jsonText:void 0,diagnostics:""};if(e.length>$P)return{jsonText:void 0,diagnostics:`${e.slice(0,1024)}
1348
- [output truncated: exceeded ${$P} bytes]
1349
- `};if(fg(e))return{jsonText:e,diagnostics:""};let t=e.split(`
1350
- `);if(t.length>1&&t.every(fg))return{jsonText:JSON.stringify(t.map(o=>JSON.parse(o))),diagnostics:""};let n=pj(e);if(!n)return{jsonText:void 0,diagnostics:`${e}
1363
+ `:""}function U1(r){let e=r.trim();if(!e.startsWith("{"))return r;try{let t=JSON.parse(e);return typeof t.content!="string"||typeof t.messageType!="number"?r:H1.has(t.messageType)?"":t.content}catch{return r}}var mk=50*1024*1024;function wk(r){let e=ch(r).trim();if(!e)return{jsonText:void 0,diagnostics:""};if(e.length>mk)return{jsonText:void 0,diagnostics:`${e.slice(0,1024)}
1364
+ [output truncated: exceeded ${mk} bytes]
1365
+ `};if(ah(e))return{jsonText:e,diagnostics:""};let t=e.split(`
1366
+ `);if(t.length>1&&t.every(ah))return{jsonText:JSON.stringify(t.map(o=>JSON.parse(o))),diagnostics:""};let n=V1(e);if(!n)return{jsonText:void 0,diagnostics:`${e}
1351
1367
  `};let i=[e.slice(0,n.start).trim(),e.slice(n.end).trim()].filter(Boolean).join(`
1352
1368
  `);return{jsonText:e.slice(n.start,n.end),diagnostics:i?`${i}
1353
- `:""}}function dj(r){return ij.test(r.trim())}function uj(r){let e=r.trim();return!!e&&!dj(e)&&!aj.some(t=>t.test(e))}function fg(r){try{return JSON.parse(r),!0}catch{return!1}}function pj(r){for(let e=0;e<r.length;e++){let t=r[e];if(t!=="["&&t!=="{")continue;let i=mj(r,e,t,t==="["?"]":"}");if(i!==-1&&fg(r.slice(e,i+1)))return{start:e,end:i+1}}}function mj(r,e,t,n){let i=0,o=!1,s=!1;for(let a=e;a<r.length;a++){let c=r[a];if(s){s=!1;continue}if(c==="\\"&&o){s=!0;continue}if(c==='"'){o=!o;continue}if(!o){if(c===t)i++;else if(c===n&&(i--,i===0))return a}}return-1}var FP=["Error","Warning","Suggestion","Info","Off","Unknown"];function BP(r){let e=hg(r);return{issues:yj(e),summary:fj(r,e)}}function fj(r,e){let t=vj(e);return{filesChecked:bj(r).size,issues:e.length,errors:t.get("Error")??0,warnings:t.get("Warning")??0,suggestions:t.get("Suggestion")??0}}function hg(r,e=""){if(Array.isArray(r))return r.flatMap(o=>hg(o,e));if(!WP(r))return[];let t=Ma(r,["filePath","file","path"])??e,n=gj(r,t);if(n.length>0)return n;let i=hj(r,t);return i?[i]:[]}function gj(r,e){let t=["messages","defects","issues","results","files"];for(let n of t){let i=r[n];if(Array.isArray(i)){let o=i.flatMap(s=>hg(s,e));if(o.length>0)return o}}return[]}function hj(r,e){let t=Ma(r,["message","description","desc","detail"])??"",n=Cj(Ma(r,["rule","ruleId","ruleName"])),i=Ej(r,["severity","level"]),o=Ma(r,["filePath","file","path"])??e;if(!(!t&&!n&&i==="Unknown"))return{file:o,line:HP(r,["line","reportLine"]),column:HP(r,["column","reportColumn"]),severity:i,rule:n,message:t}}function yj(r){return[...r].sort((e,t)=>{let n=jP(e.severity)-jP(t.severity);return n===0?wj(e,t):n})}function wj(r,e){let t=r.file.localeCompare(e.file);if(t!==0)return t;let n=(r.line??Number.MAX_SAFE_INTEGER)-(e.line??Number.MAX_SAFE_INTEGER);return n!==0?n:(r.column??Number.MAX_SAFE_INTEGER)-(e.column??Number.MAX_SAFE_INTEGER)}function vj(r){let e=new Map;for(let t of r){let n=t.severity;e.set(n,(e.get(n)??0)+1)}return e}function bj(r){let e=new Set;return yg(e,r,""),e}function yg(r,e,t){if(Array.isArray(e)){for(let i of e)yg(r,i,t);return}if(!WP(e))return;let n=Ma(e,["filePath","file","path"])??t;n&&r.add(n),Sj(r,e,n)}function Sj(r,e,t){let n=["messages","defects","issues","results","files"];for(let i of n){let o=e[i];if(Array.isArray(o))for(let s of o)yg(r,s,t)}}function Ej(r,e){for(let t of e){let n=r[t];if(typeof n=="string"||typeof n=="number")return Pj(n)}return"Unknown"}function Pj(r){let e=String(r).normalize("NFKC").trim().toLowerCase();return e==="2"||e==="error"||e==="err"?"Error":e==="1"||e==="warn"||e==="warning"?"Warning":e==="3"||e==="suggest"||e==="suggestion"?"Suggestion":e==="info"||e==="information"?"Info":e==="0"||e==="off"?"Off":"Unknown"}function Cj(r){let e=r?.normalize("NFKC").trim();if(e)return e.replace(oj,"").replace(sj,"").toLowerCase()}function jP(r){let e=FP.indexOf(r);return e===-1?FP.length:e}function Ma(r,e){for(let t of e){let n=r[t];if(typeof n=="string")return n}}function HP(r,e){for(let t of e){let n=r[t];if(typeof n=="number")return n}}function WP(r){return typeof r=="object"&&r!==null}var Nn=class extends Error{code;constructor(e,t,n){super(t,n),this.name="ValidationError",this.code=e}},VP="deveco-codelinter-",GP=[".ets",".ts",".js"],La=class r{resolution;cwd;toolProvider;constructor(e,t){this.toolProvider=e,this.resolution=r.resolveWithToolProvider(e),this.cwd=t}get supportsReportOptions(){return!this.resolution.isLegacyStudioArgs}static resolveProjectRoot(e){try{return W.discover(e).rootDir}catch{return e}}async check(e){let t=Pr.mkdtempSync(V.join(wg.tmpdir(),VP)),n=V.join(t,"report.json");try{let i=r.resolveProjectRoot(this.cwd),o=this.resolveLintTarget(e.lintPath,i);await rt.warnInvalidBundledLinks(o.projectRoot??i);let s=this.resolveConfigPath(e.configPath,o),a=this.buildNativeArgs(e,o.path,s,n,t,o.projectRoot??i),c=await this.run(a),l=UP(c.stdout),d=l.diagnostics+gg(c.stderr);try{let g=this.readJsonReport(n,l.jsonText);return{exitCode:c.exitCode,diagnostics:d,report:BP(g)}}catch(g){return{exitCode:c.exitCode,diagnostics:d,reportError:g}}}finally{this.removeTempDir(t)}}resolveLintTarget(e,t){let n=e?V.resolve(this.cwd,e):t,i=this.resolveRealPath(n,"Lint path"),o=Pr.statSync(i);if(!o.isFile()&&!o.isDirectory())throw new Nn("errorCode",`Lint path must be a file or directory: ${n}`);if(o.isFile()){let a=V.extname(i).toLowerCase();if(!GP.some(l=>l===a))throw new Error(`Unsupported lint file extension "${a||"<none>"}": ${i}. Supported extensions: ${GP.join(", ")}.`)}let s=this.discoverProjectRoot(i,o.isDirectory());if(e!==void 0&&s===void 0)throw new Nn("errorCode",`Lint path is not in a valid project directory (project-level build-profile.json5 not found or invalid): ${i}`);return{path:i,projectRoot:s}}resolveConfigPath(e,t){let n=e?V.resolve(this.cwd,e):V.join(t.projectRoot??this.cwd,"code-linter.json5"),i=this.resolveRealPath(n,"`--config-path`");if(!Pr.statSync(i).isFile())throw new Nn("errorCode",`--config-path must point to a file: ${n}`);if(t.projectRoot){let o=this.discoverProjectRoot(i,!1);if(o===void 0||V.relative(t.projectRoot,o)!=="")throw new Nn("errorCode",`\`--config-path\` must belong to the same project as the lint path. Lint project: ${t.projectRoot}; Config project: ${o??"not found"}.`)}return i}discoverProjectRoot(e,t){let n=t?e:V.dirname(e);try{return Pr.realpathSync(W.discover(n).rootDir)}catch{return}}resolveRealPath(e,t){try{return Pr.realpathSync(e)}catch(n){throw new Nn("errorCode",`${t} does not exist or cannot be resolved: ${e}`,{cause:n})}}buildNativeArgs(e,t,n,i,o,s){if(this.resolution.isLegacyStudioArgs)return this.buildLegacyNativeArgs(e,t,n,o,s);let a=["--config",n];return e.fix&&a.push("--fix"),e.incremental&&a.push("--incremental"),a.push("--product",e.product,"--format","json","--output",i,t),a}buildLegacyNativeArgs(e,t,n,i,o){let s=String(this.toolProvider.getMaxApiLevel()),a=this.toolProvider.getSdkPlatformVersion(),c=V.join(i,"check-paths.json");Pr.writeFileSync(c,JSON.stringify([t]),"utf8");let l=["--dir",c,"--isTooManyFiles","true","--config",n,"--product",e.product,"--sdkPath",this.toolProvider.sdkPath,"--sdkNumberVersion",s,"--sdkStringVersion",a,"--project",o,"--logPath",V.join(i,"codelinter.log"),"--workdir",V.dirname(this.toolProvider.codelinterPath),"--inIde","true"];return e.fix&&l.push("--fix","true"),e.incremental&&l.push("--incremental","true"),l}async run(e){let t=this.resolution.isLegacyStudioArgs?[this.resolution.argsPrefix[0],...e]:[...this.resolution.argsPrefix,...e],n=this.resolution.workingDirectory??this.cwd;this.prepareRuntimeDirectories(),m(`Executing: ${this.resolution.command} ${t.join(" ")}`),m(`[CodelinterAdapter] Working directory: ${n}`);let i=await kj(this.resolution.command,t,{cwd:n,env:this.resolution.env,stdout:"pipe",stderr:"pipe",reject:!1});return{exitCode:i.exitCode??1,stdout:i.stdout,stderr:i.stderr}}prepareRuntimeDirectories(){for(let e of this.resolution.runtimeDirectories??[])Pr.mkdirSync(e,{recursive:!0})}readJsonReport(e,t){let i=(Pr.existsSync(e)?Pr.readFileSync(e,"utf-8").trim():void 0)||t?.trim();if(!i)throw new Nn("errorCode","Native JSON report was not generated.");return JSON.parse(i)}removeTempDir(e){let t=V.resolve(e),n=V.resolve(wg.tmpdir());!(t.startsWith(`${n}${V.sep}`)||t===n)||!V.basename(t).startsWith(VP)||Pr.rmSync(t,{recursive:!0,force:!0})}static isModernStudioEntry(e){let t=["plugins","codelinter","run","index.js"],n=V.normalize(e).split(V.sep).slice(-t.length);return t.every((i,o)=>n[o]?.toLowerCase()===i)}static resolveWithToolProvider(e){let t=r.getSource(e),n=e.toolchainRoot,i=e.codelinterPath,o=e.sdkPath,s=r.getPathEntries(e,t),a=t==="ide"?"DevEco Studio":"DevEco Command Line Tools",c=t==="ide"&&!r.isModernStudioEntry(i),l={command:e.nodePath,argsPrefix:[i,o],env:{...process.env,PATH:[...s,process.env.PATH||""].join(V.delimiter),DEVECO_SDK_HOME:o},isLegacyStudioArgs:c};return t==="command-line-tools"&&(l.workingDirectory=n,l.runtimeDirectories=[r.getResultDirectory(i)]),m(`[CodelinterAdapter] Selected ${a} entry: ${i}`),l}static getPathEntries(e,t){let n=[V.dirname(e.nodePath)];return t==="ide"&&e.javaPath&&n.unshift(V.dirname(e.javaPath)),n}static getResultDirectory(e){return V.resolve(e,"..","linter","result")}static getSource(e){return e.sourceType==="studio"?"ide":"command-line-tools"}};import{red as lu,yellow as QP}from"colorette";import{Argument as _j,Command as $j,InvalidArgumentError as Ln}from"commander";import $a from"fs";import*as lt from"path";import*as _a from"path";var qP="n/a",zP=/\\/g,Dj=/\|/g,Rj=/\r?\n/g;function JP(r,e){if(r.issues.length===0)return`No defects found.
1354
- ${vg(r.summary)}
1355
- `;let t=e===void 0?r.issues:r.issues.slice(0,e),n=[Aj(t),vg(r.summary)];return e!==void 0&&t.length<r.issues.length&&n.push(xj(r.issues.length,t.length)),`${n.join(`
1369
+ `:""}}function B1(r){return L1.test(r.trim())}function W1(r){let e=r.trim();return!!e&&!B1(e)&&!j1.some(t=>t.test(e))}function ah(r){try{return JSON.parse(r),!0}catch{return!1}}function V1(r){for(let e=0;e<r.length;e++){let t=r[e];if(t!=="["&&t!=="{")continue;let i=G1(r,e,t,t==="["?"]":"}");if(i!==-1&&ah(r.slice(e,i+1)))return{start:e,end:i+1}}}function G1(r,e,t,n){let i=0,o=!1,s=!1;for(let a=e;a<r.length;a++){let c=r[a];if(s){s=!1;continue}if(c==="\\"&&o){s=!0;continue}if(c==='"'){o=!o;continue}if(!o){if(c===t)i++;else if(c===n&&(i--,i===0))return a}}return-1}var gk=["Error","Warning","Suggestion","Info","Off","Unknown"];function vk(r){let e=lh(r);return{issues:K1(e),summary:q1(r,e)}}function q1(r,e){let t=X1(e);return{filesChecked:Z1(r).size,issues:e.length,errors:t.get("Error")??0,warnings:t.get("Warning")??0,suggestions:t.get("Suggestion")??0}}function lh(r,e=""){if(Array.isArray(r))return r.flatMap(o=>lh(o,e));if(!bk(r))return[];let t=Qa(r,["filePath","file","path"])??e,n=z1(r,t);if(n.length>0)return n;let i=J1(r,t);return i?[i]:[]}function z1(r,e){let t=["messages","defects","issues","results","files"];for(let n of t){let i=r[n];if(Array.isArray(i)){let o=i.flatMap(s=>lh(s,e));if(o.length>0)return o}}return[]}function J1(r,e){let t=Qa(r,["message","description","desc","detail"])??"",n=rB(Qa(r,["rule","ruleId","ruleName"])),i=eB(r,["severity","level"]),o=Qa(r,["filePath","file","path"])??e;if(!(!t&&!n&&i==="Unknown"))return{file:o,line:yk(r,["line","reportLine"]),column:yk(r,["column","reportColumn"]),severity:i,rule:n,message:t}}function K1(r){return[...r].sort((e,t)=>{let n=hk(e.severity)-hk(t.severity);return n===0?Y1(e,t):n})}function Y1(r,e){let t=r.file.localeCompare(e.file);if(t!==0)return t;let n=(r.line??Number.MAX_SAFE_INTEGER)-(e.line??Number.MAX_SAFE_INTEGER);return n!==0?n:(r.column??Number.MAX_SAFE_INTEGER)-(e.column??Number.MAX_SAFE_INTEGER)}function X1(r){let e=new Map;for(let t of r){let n=t.severity;e.set(n,(e.get(n)??0)+1)}return e}function Z1(r){let e=new Set;return dh(e,r,""),e}function dh(r,e,t){if(Array.isArray(e)){for(let i of e)dh(r,i,t);return}if(!bk(e))return;let n=Qa(e,["filePath","file","path"])??t;n&&r.add(n),Q1(r,e,n)}function Q1(r,e,t){let n=["messages","defects","issues","results","files"];for(let i of n){let o=e[i];if(Array.isArray(o))for(let s of o)dh(r,s,t)}}function eB(r,e){for(let t of e){let n=r[t];if(typeof n=="string"||typeof n=="number")return tB(n)}return"Unknown"}function tB(r){let e=String(r).normalize("NFKC").trim().toLowerCase();return e==="2"||e==="error"||e==="err"?"Error":e==="1"||e==="warn"||e==="warning"?"Warning":e==="3"||e==="suggest"||e==="suggestion"?"Suggestion":e==="info"||e==="information"?"Info":e==="0"||e==="off"?"Off":"Unknown"}function rB(r){let e=r?.normalize("NFKC").trim();if(e)return e.replace(F1,"").replace($1,"").toLowerCase()}function hk(r){let e=gk.indexOf(r);return e===-1?gk.length:e}function Qa(r,e){for(let t of e){let n=r[t];if(typeof n=="string")return n}}function yk(r,e){for(let t of e){let n=r[t];if(typeof n=="number")return n}}function bk(r){return typeof r=="object"&&r!==null}var Ln=class extends Error{code;constructor(e,t,n){super(t,n),this.name="ValidationError",this.code=e}},Sk="deveco-codelinter-",Ek=[".ets",".ts",".js"],ec=class r{resolution;cwd;toolProvider;constructor(e,t){this.toolProvider=e,this.resolution=r.resolveWithToolProvider(e),this.cwd=t}get supportsReportOptions(){return!this.resolution.isLegacyStudioArgs}static resolveProjectRoot(e){try{return W.discover(e).rootDir}catch{return e}}async check(e){let t=Dr.mkdtempSync(V.join(uh.tmpdir(),Sk)),n=V.join(t,"report.json");try{let i=r.resolveProjectRoot(this.cwd),o=this.resolveLintTarget(e.lintPath,i);await nt.warnInvalidBundledLinks(o.projectRoot??i);let s=this.resolveConfigPath(e.configPath,o),a=this.buildNativeArgs(e,o.path,s,n,t,o.projectRoot??i),c=await this.run(a),l=wk(c.stdout),d=l.diagnostics+ch(c.stderr);try{let g=this.readJsonReport(n,l.jsonText);return{exitCode:c.exitCode,diagnostics:d,report:vk(g)}}catch(g){return{exitCode:c.exitCode,diagnostics:d,reportError:g}}}finally{this.removeTempDir(t)}}resolveLintTarget(e,t){let n=e?V.resolve(this.cwd,e):t,i=this.resolveRealPath(n,"Lint path"),o=Dr.statSync(i);if(!o.isFile()&&!o.isDirectory())throw new Ln("errorCode",`Lint path must be a file or directory: ${n}`);if(o.isFile()){let a=V.extname(i).toLowerCase();if(!Ek.some(l=>l===a))throw new Error(`Unsupported lint file extension "${a||"<none>"}": ${i}. Supported extensions: ${Ek.join(", ")}.`)}let s=this.discoverProjectRoot(i,o.isDirectory());if(e!==void 0&&s===void 0)throw new Ln("errorCode",`Lint path is not in a valid project directory (project-level build-profile.json5 not found or invalid): ${i}`);return{path:i,projectRoot:s}}resolveConfigPath(e,t){let n=e?V.resolve(this.cwd,e):V.join(t.projectRoot??this.cwd,"code-linter.json5"),i=this.resolveRealPath(n,"`--config-path`");if(!Dr.statSync(i).isFile())throw new Ln("errorCode",`--config-path must point to a file: ${n}`);if(t.projectRoot){let o=this.discoverProjectRoot(i,!1);if(o===void 0||V.relative(t.projectRoot,o)!=="")throw new Ln("errorCode",`\`--config-path\` must belong to the same project as the lint path. Lint project: ${t.projectRoot}; Config project: ${o??"not found"}.`)}return i}discoverProjectRoot(e,t){let n=t?e:V.dirname(e);try{return Dr.realpathSync(W.discover(n).rootDir)}catch{return}}resolveRealPath(e,t){try{return Dr.realpathSync(e)}catch(n){throw new Ln("errorCode",`${t} does not exist or cannot be resolved: ${e}`,{cause:n})}}buildNativeArgs(e,t,n,i,o,s){if(this.resolution.isLegacyStudioArgs)return this.buildLegacyNativeArgs(e,t,n,o,s);let a=["--config",n];return e.fix&&a.push("--fix"),e.incremental&&a.push("--incremental"),a.push("--product",e.product,"--format","json","--output",i,t),a}buildLegacyNativeArgs(e,t,n,i,o){let s=String(this.toolProvider.getMaxApiLevel()),a=this.toolProvider.getSdkPlatformVersion(),c=V.join(i,"check-paths.json");Dr.writeFileSync(c,JSON.stringify([t]),"utf8");let l=["--dir",c,"--isTooManyFiles","true","--config",n,"--product",e.product,"--sdkPath",this.toolProvider.sdkPath,"--sdkNumberVersion",s,"--sdkStringVersion",a,"--project",o,"--logPath",V.join(i,"codelinter.log"),"--workdir",V.dirname(this.toolProvider.codelinterPath),"--inIde","true"];return e.fix&&l.push("--fix","true"),e.incremental&&l.push("--incremental","true"),l}async run(e){let t=this.resolution.isLegacyStudioArgs?[this.resolution.argsPrefix[0],...e]:[...this.resolution.argsPrefix,...e],n=this.resolution.workingDirectory??this.cwd;this.prepareRuntimeDirectories(),f(`Executing: ${this.resolution.command} ${t.join(" ")}`),f(`[CodelinterAdapter] Working directory: ${n}`);let i=await nB(this.resolution.command,t,{cwd:n,env:this.resolution.env,stdout:"pipe",stderr:"pipe",reject:!1});return{exitCode:i.exitCode??1,stdout:i.stdout,stderr:i.stderr}}prepareRuntimeDirectories(){for(let e of this.resolution.runtimeDirectories??[])Dr.mkdirSync(e,{recursive:!0})}readJsonReport(e,t){let i=(Dr.existsSync(e)?Dr.readFileSync(e,"utf-8").trim():void 0)||t?.trim();if(!i)throw new Ln("errorCode","Native JSON report was not generated.");return JSON.parse(i)}removeTempDir(e){let t=V.resolve(e),n=V.resolve(uh.tmpdir());!(t.startsWith(`${n}${V.sep}`)||t===n)||!V.basename(t).startsWith(Sk)||Dr.rmSync(t,{recursive:!0,force:!0})}static isModernStudioEntry(e){let t=["plugins","codelinter","run","index.js"],n=V.normalize(e).split(V.sep).slice(-t.length);return t.every((i,o)=>n[o]?.toLowerCase()===i)}static resolveWithToolProvider(e){let t=r.getSource(e),n=e.toolchainRoot,i=e.codelinterPath,o=e.sdkPath,s=r.getPathEntries(e,t),a=t==="ide"?"DevEco Studio":"DevEco Command Line Tools",c=t==="ide"&&!r.isModernStudioEntry(i),l={command:e.nodePath,argsPrefix:[i,o],env:{...process.env,PATH:[...s,process.env.PATH||""].join(V.delimiter),DEVECO_SDK_HOME:o},isLegacyStudioArgs:c};return t==="command-line-tools"&&(l.workingDirectory=n,l.runtimeDirectories=[r.getResultDirectory(i)]),f(`[CodelinterAdapter] Selected ${a} entry: ${i}`),l}static getPathEntries(e,t){let n=[V.dirname(e.nodePath)];return t==="ide"&&e.javaPath&&n.unshift(V.dirname(e.javaPath)),n}static getResultDirectory(e){return V.resolve(e,"..","linter","result")}static getSource(e){return e.sourceType==="studio"?"ide":"command-line-tools"}};import{red as Uu,yellow as Ak}from"colorette";import{Argument as mB,Command as gB,InvalidArgumentError as $n}from"commander";import rc from"fs";import*as dt from"path";import*as tc from"path";var Pk="n/a",Ck=/\\/g,iB=/\|/g,oB=/\r?\n/g;function kk(r,e){if(r.issues.length===0)return`No defects found.
1370
+ ${ph(r.summary)}
1371
+ `;let t=e===void 0?r.issues:r.issues.slice(0,e),n=[aB(t),ph(r.summary)];return e!==void 0&&t.length<r.issues.length&&n.push(sB(r.issues.length,t.length)),`${n.join(`
1356
1372
  `)}
1357
- `}function YP(r,e){return[vg(r.summary),`Full report: ${bg(e)}`,""].join(`
1358
- `)}function KP(r){let e=["# CodeLinter report",""];return r.issues.length===0?e.push("No defects found.",""):e.push(...Ij(r.issues),""),e.push("## Summary","",...Oj(r.summary),""),e.join(`
1359
- `)}function XP(r){return`${JSON.stringify(r,null,2)}
1360
- `}function vg(r){return`Summary: Issues: ${Ot(r.issues)} | Errors: ${Ot(r.errors)} | Warnings: ${Ot(r.warnings)} | Suggestions: ${Ot(r.suggestions)} | Files checked: ${Ot(r.filesChecked)}`}function xj(r,e){return`Showing ${Ot(e)} of ${Ot(r)} issues. Use --output-path <path> to write all results.`}function Aj(r){let e=["No","File","Line","Column","Severity","Rule","Message"],t=r.map((n,i)=>({cells:Mj(n,i+1)}));return["CodeLinter report","",jr(e,t)].join(`
1361
- `)}function Ij(r){let e=["| No | File | Line | Column | Severity | Rule | Message |","| ---: | --- | ---: | ---: | --- | --- | --- |"];for(let[t,n]of r.entries())e.push(Tj(n,t+1));return e}function Tj(r,e){return`| ${[String(e),bg(Mn(r.file)),cu(r.line),cu(r.column),Mn(r.severity),Mn(r.rule),Mn(r.message)].map(Nj).join(" | ")} |`}function Oj(r){return[`- Issues: ${Ot(r.issues)}`,`- Errors: ${Ot(r.errors)}`,`- Warnings: ${Ot(r.warnings)}`,`- Suggestions: ${Ot(r.suggestions)}`,`- Files checked: ${Ot(r.filesChecked)}`]}function Nj(r){return r.replace(zP,"\\\\").replace(Dj,"\\|").replace(Rj,"<br>")}function Mj(r,e){return[String(e),bg(Mn(Lj(r.file))),cu(r.line),cu(r.column),Mn(r.severity),Mn(r.rule),Mn(r.message)]}function Lj(r){if(!_a.isAbsolute(r))return r;let e=_a.relative(process.cwd(),r);return!e||e.startsWith("..")||_a.isAbsolute(e)?r:e}function bg(r){return r.replace(zP,"/")}function Mn(r){let e=r?.trim();return e||qP}function cu(r){return r===void 0?qP:String(r)}function Ot(r){return r.toLocaleString("en-US")}var Sg=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function Fj(r){let e=r;return r instanceof Sg?r.code:e.code??e.name??"UnknownError"}async function ZP(r,e,t,n){let i=await ft(process.pid),o=i!==null?ae(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(s,a).catch(()=>{})}var jj=/^-?\d+$/;function Eg(){return new $j("lint").description("Run DevEco Code Linter checks for TS/ArkTS code").helpOption("-h, --help","display help for command").addArgument(new _j("[path]","File or directory to lint").argParser(Vj)).option("--fix","Auto-fix fixable code issues").option("--incremental","Only check uncommitted files").option("--config-path <path>","Path to lint configuration file",Uj).option("--product <product>","Product name defined in build-profile.json5",Bj,"default").option("--format <format>","Report format (choices: default, json)",Hj,"default").option("--output-path <path>","Complete report file or directory",Wj).option("--limit <number>","Maximum terminal issues to display when --output-path is omitted",Gj).action(qj)}function Hj(r){if(r==="default"||r==="json")return r;throw new Ln("Invalid --format. Expected one of: default, json.")}function Uj(r){Pg(r,"--config-path");let e=lt.extname(r).toLowerCase();if(e!==".json"&&e!==".json5")throw new Ln("`--config-path` must point to a .json or .json5 file.");return r}function Bj(r){return eC(r,"product"),r}function Wj(r){return Pg(r,"--output-path"),r}function Vj(r){return Pg(r,"path"),r}function Gj(r){if(eC(r,"limit"),!jj.test(r))throw new Ln("`--limit` must be a positive integer.");let e=Number.parseInt(r,10);if(e<=0||!Number.isSafeInteger(e))throw new Ln("`--limit` must be an integer greater than 0.");return e}function eC(r,e){if(r.trim().length===0||nC(r))throw new Ln(`Invalid --${e} value.`)}function Pg(r,e){let t=`\`${e}\``;if(r.length===0||nC(r))throw new Ln(`${t} must be a non-empty path without control characters.`)}async function qj(r,e,t){let n=Date.now(),i=["check","lint"];try{let o=process.cwd(),s=await C.new(),a=new La(s,o),c=Yj(s,a,t,e),l=Qj(c.outputPath,c.format,o);e.fix&&console.warn(QP("Running codelinter with --fix. Ensure your project source is trusted."));let d=await zj(a,r,e);iH(d.diagnostics),process.exitCode=Xj(d,l,c.format,e.limit,o),await ZP(n,!0,null,i)}catch(o){let s=Fj(o);throw await ZP(n,!1,s,i),o}}async function zj(r,e,t){return Kj(r,{lintPath:e,configPath:t.configPath,product:t.product,fix:t.fix,incremental:t.incremental})}function Jj(r){return[["format","--format"],["outputPath","--output-path"]].filter(([e])=>r.getOptionValueSource(e)==="cli").map(([,e])=>e)}function Yj(r,e,t,n){let i=Jj(t);if(i.length===0||e.supportsReportOptions)return n;let o=on(r.toolchainRoot),s=i.length===1?"option":"options";return console.warn(QP(`Warning: The detected DevEco Studio version is: ${o??"unknown"}. The bundled legacy Code Linter does not support ${s}: ${i.join(", ")}. Action: ignore the unsupported ${s} and continue the lint check with default terminal output.`)),{format:i.includes("--format")?"default":n.format,outputPath:i.includes("--output-path")?void 0:n.outputPath}}async function Kj(r,e){let t=new Ie;process.stderr.isTTY&&t.start("Checking code...");try{let n=await r.check(e);return t.stop(),n}catch(n){throw t.fail("Code check failed"),n}}function Xj(r,e,t,n,i){if(!r.report)return console.error(lu("Failed to generate Code Linter report.")),console.error(lu(r.reportError?.message??"Native JSON report was not generated.")),r.exitCode===0?1:r.exitCode;try{if(e){Zj(e,t,r.report);let o=rC(e,i);process.stdout.write(YP(r.report,o))}else process.stdout.write(JP(r.report,n));return r.exitCode}catch(o){return console.error(lu("Failed to generate Code Linter report.")),console.error(lu(o.message)),r.exitCode===0?1:r.exitCode}}function Zj(r,e,t){$a.mkdirSync(lt.dirname(r),{recursive:!0});let n=e==="json"?XP(t):KP(t);try{$a.writeFileSync(r,n,{encoding:"utf-8",flag:"wx"})}catch(i){throw i.code==="EEXIST"?new Error(`Output file already exists: ${r}`,{cause:i}):i}}function Qj(r,e,t){if(!r)return;let n=rH(r,t),i=tH(r,n),o=i?lt.join(n,nH(e)):n;if(i||eH(r,e),$a.existsSync(o))throw new Ln(`Output file already exists: ${rC(o,t)}`);return o}function eH(r,e){let t=tC(e);if(lt.extname(r).toLowerCase()!==t)throw new Ln(`--output-path must use the ${t} extension for --format ${e}.`)}function tH(r,e){return $a.existsSync(e)?$a.statSync(e).isDirectory():r.endsWith("/")||r.endsWith("\\")||lt.extname(r)===""}function rH(r,e){return lt.resolve(e,r)}function nH(r){let e=new Date,t=[e.getFullYear(),e.getMonth()+1,e.getDate()].map((o,s)=>String(o).padStart(s===0?4:2,"0")).join(""),n=[e.getHours(),e.getMinutes(),e.getSeconds()].map(o=>String(o).padStart(2,"0")).join(""),i=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${n}-${i}${tC(r)}`}function tC(r){return r==="json"?".json":".md"}function rC(r,e){let t=lt.relative(e,r);return t&&!t.startsWith("..")&&!lt.isAbsolute(t)?t:r}function iH(r){r&&process.stderr.write(r)}function nC(r){for(let e of r){let t=e.charCodeAt(0);if(t<=31||t===127)return!0}return!1}import{execa as oH}from"execa";import Xr from"fs";import sH from"os";import*as te from"path";import{fileURLToPath as aH}from"url";var iC=te.join("resources","arkts-check.cjs"),Fa=class{toolProvider;cwd;constructor(e,t){this.toolProvider=e,this.cwd=t}async check(e){let t=this.resolveProjectRoot(e.projectRoot,e.files);await rt.warnInvalidBundledLinks(t);let n=this.resolveFiles(t,e.files),i=this.resolveScriptPath(),o=this.buildArgs(i,t,n,e.fix),s=this.buildEnv();m(`Executing: ${this.toolProvider.nodePath} ${o.join(" ")}`);let a=await oH(this.toolProvider.nodePath,o,{cwd:t,env:s,stdout:"pipe",stderr:"pipe",reject:!1});return this.parseResult(a.stdout,a.stderr,a.exitCode??1)}resolveProjectRoot(e,t){if(e){let i=te.resolve(this.cwd,e);if(!Xr.existsSync(i))throw new Error(`Project path not found: ${i}`);if(Xr.statSync(i).isFile()){let s=this.discoverRootFrom(te.dirname(i));if(s)return s;throw new Error(`--project path is a file, not a project root: ${i}
1373
+ `}function Rk(r,e){return[ph(r.summary),`Full report: ${fh(e)}`,""].join(`
1374
+ `)}function xk(r){let e=["# CodeLinter report",""];return r.issues.length===0?e.push("No defects found.",""):e.push(...cB(r.issues),""),e.push("## Summary","",...dB(r.summary),""),e.join(`
1375
+ `)}function Dk(r){return`${JSON.stringify(r,null,2)}
1376
+ `}function ph(r){return`Summary: Issues: ${_t(r.issues)} | Errors: ${_t(r.errors)} | Warnings: ${_t(r.warnings)} | Suggestions: ${_t(r.suggestions)} | Files checked: ${_t(r.filesChecked)}`}function sB(r,e){return`Showing ${_t(e)} of ${_t(r)} issues. Use --output-path <path> to write all results.`}function aB(r){let e=["No","File","Line","Column","Severity","Rule","Message"],t=r.map((n,i)=>({cells:pB(n,i+1)}));return["CodeLinter report","",zt(e,t)].join(`
1377
+ `)}function cB(r){let e=["| No | File | Line | Column | Severity | Rule | Message |","| ---: | --- | ---: | ---: | --- | --- | --- |"];for(let[t,n]of r.entries())e.push(lB(n,t+1));return e}function lB(r,e){return`| ${[String(e),fh(Fn(r.file)),Hu(r.line),Hu(r.column),Fn(r.severity),Fn(r.rule),Fn(r.message)].map(uB).join(" | ")} |`}function dB(r){return[`- Issues: ${_t(r.issues)}`,`- Errors: ${_t(r.errors)}`,`- Warnings: ${_t(r.warnings)}`,`- Suggestions: ${_t(r.suggestions)}`,`- Files checked: ${_t(r.filesChecked)}`]}function uB(r){return r.replace(Ck,"\\\\").replace(iB,"\\|").replace(oB,"<br>")}function pB(r,e){return[String(e),fh(Fn(fB(r.file))),Hu(r.line),Hu(r.column),Fn(r.severity),Fn(r.rule),Fn(r.message)]}function fB(r){if(!tc.isAbsolute(r))return r;let e=tc.relative(process.cwd(),r);return!e||e.startsWith("..")||tc.isAbsolute(e)?r:e}function fh(r){return r.replace(Ck,"/")}function Fn(r){let e=r?.trim();return e||Pk}function Hu(r){return r===void 0?Pk:String(r)}function _t(r){return r.toLocaleString("en-US")}var mh=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function hB(r){let e=r;return r instanceof mh?r.code:e.code??e.name??"UnknownError"}async function Ik(r,e,t,n){let i=await gt(process.pid),o=i!==null?ce(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(s,a).catch(()=>{})}var yB=/^-?\d+$/;function gh(){return new gB("lint").description("Run DevEco Code Linter checks for TS/ArkTS code").helpOption("-h, --help","display help for command").addArgument(new mB("[path]","File or directory to lint").argParser(EB)).option("--fix","Auto-fix fixable code issues").option("--incremental","Only check uncommitted files").option("--config-path <path>","Path to lint configuration file",vB).option("--product <product>","Product name defined in build-profile.json5",bB,"default").option("--format <format>","Report format (choices: default, json)",wB,"default").option("--output-path <path>","Complete report file or directory",SB).option("--limit <number>","Maximum terminal issues to display when --output-path is omitted",PB).action(CB)}function wB(r){if(r==="default"||r==="json")return r;throw new $n("Invalid --format. Expected one of: default, json.")}function vB(r){hh(r,"--config-path");let e=dt.extname(r).toLowerCase();if(e!==".json"&&e!==".json5")throw new $n("`--config-path` must point to a .json or .json5 file.");return r}function bB(r){return Tk(r,"product"),r}function SB(r){return hh(r,"--output-path"),r}function EB(r){return hh(r,"path"),r}function PB(r){if(Tk(r,"limit"),!yB.test(r))throw new $n("`--limit` must be a positive integer.");let e=Number.parseInt(r,10);if(e<=0||!Number.isSafeInteger(e))throw new $n("`--limit` must be an integer greater than 0.");return e}function Tk(r,e){if(r.trim().length===0||_k(r))throw new $n(`Invalid --${e} value.`)}function hh(r,e){let t=`\`${e}\``;if(r.length===0||_k(r))throw new $n(`${t} must be a non-empty path without control characters.`)}async function CB(r,e,t){let n=Date.now(),i=["check","lint"];try{let o=process.cwd(),s=await C.new(),a=new ec(s,o),c=xB(s,a,t,e),l=TB(c.outputPath,c.format,o);e.fix&&console.warn(Ak("Running codelinter with --fix. Ensure your project source is trusted."));let d=await kB(a,r,e);LB(d.diagnostics),process.exitCode=IB(d,l,c.format,e.limit,o),await Ik(n,!0,null,i)}catch(o){let s=hB(o);throw await Ik(n,!1,s,i),o}}async function kB(r,e,t){return DB(r,{lintPath:e,configPath:t.configPath,product:t.product,fix:t.fix,incremental:t.incremental})}function RB(r){return[["format","--format"],["outputPath","--output-path"]].filter(([e])=>r.getOptionValueSource(e)==="cli").map(([,e])=>e)}function xB(r,e,t,n){let i=RB(t);if(i.length===0||e.supportsReportOptions)return n;let o=cn(r.toolchainRoot),s=i.length===1?"option":"options";return console.warn(Ak(`Warning: The detected DevEco Studio version is: ${o??"unknown"}. The bundled legacy Code Linter does not support ${s}: ${i.join(", ")}. Action: ignore the unsupported ${s} and continue the lint check with default terminal output.`)),{format:i.includes("--format")?"default":n.format,outputPath:i.includes("--output-path")?void 0:n.outputPath}}async function DB(r,e){let t=new Te;process.stderr.isTTY&&t.start("Checking code...");try{let n=await r.check(e);return t.stop(),n}catch(n){throw t.fail("Code check failed"),n}}function IB(r,e,t,n,i){if(!r.report)return console.error(Uu("Failed to generate Code Linter report.")),console.error(Uu(r.reportError?.message??"Native JSON report was not generated.")),r.exitCode===0?1:r.exitCode;try{if(e){AB(e,t,r.report);let o=Ok(e,i);process.stdout.write(Rk(r.report,o))}else process.stdout.write(kk(r.report,n));return r.exitCode}catch(o){return console.error(Uu("Failed to generate Code Linter report.")),console.error(Uu(o.message)),r.exitCode===0?1:r.exitCode}}function AB(r,e,t){rc.mkdirSync(dt.dirname(r),{recursive:!0});let n=e==="json"?Dk(t):xk(t);try{rc.writeFileSync(r,n,{encoding:"utf-8",flag:"wx"})}catch(i){throw i.code==="EEXIST"?new Error(`Output file already exists: ${r}`,{cause:i}):i}}function TB(r,e,t){if(!r)return;let n=_B(r,t),i=OB(r,n),o=i?dt.join(n,MB(e)):n;if(i||NB(r,e),rc.existsSync(o))throw new $n(`Output file already exists: ${Ok(o,t)}`);return o}function NB(r,e){let t=Nk(e);if(dt.extname(r).toLowerCase()!==t)throw new $n(`--output-path must use the ${t} extension for --format ${e}.`)}function OB(r,e){return rc.existsSync(e)?rc.statSync(e).isDirectory():r.endsWith("/")||r.endsWith("\\")||dt.extname(r)===""}function _B(r,e){return dt.resolve(e,r)}function MB(r){let e=new Date,t=[e.getFullYear(),e.getMonth()+1,e.getDate()].map((o,s)=>String(o).padStart(s===0?4:2,"0")).join(""),n=[e.getHours(),e.getMinutes(),e.getSeconds()].map(o=>String(o).padStart(2,"0")).join(""),i=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${n}-${i}${Nk(r)}`}function Nk(r){return r==="json"?".json":".md"}function Ok(r,e){let t=dt.relative(e,r);return t&&!t.startsWith("..")&&!dt.isAbsolute(t)?t:r}function LB(r){r&&process.stderr.write(r)}function _k(r){for(let e of r){let t=e.charCodeAt(0);if(t<=31||t===127)return!0}return!1}import{execa as FB}from"execa";import en from"fs";import $B from"os";import*as re from"path";import{fileURLToPath as jB}from"url";var Mk=re.join("resources","arkts-check.cjs"),nc=class{toolProvider;cwd;constructor(e,t){this.toolProvider=e,this.cwd=t}async check(e){let t=this.resolveProjectRoot(e.projectRoot,e.files);await nt.warnInvalidBundledLinks(t);let n=this.resolveFiles(t,e.files),i=this.resolveScriptPath(),o=this.buildArgs(i,t,n,e.fix),s=this.buildEnv();f(`Executing: ${this.toolProvider.nodePath} ${o.join(" ")}`);let a=await FB(this.toolProvider.nodePath,o,{cwd:t,env:s,stdout:"pipe",stderr:"pipe",reject:!1});return this.parseResult(a.stdout,a.stderr,a.exitCode??1)}resolveProjectRoot(e,t){if(e){let i=re.resolve(this.cwd,e);if(!en.existsSync(i))throw new Error(`Project path not found: ${i}`);if(en.statSync(i).isFile()){let s=this.discoverRootFrom(re.dirname(i));if(s)return s;throw new Error(`--project path is a file, not a project root: ${i}
1362
1378
  Could not find a project-level build-profile.json5 above it. Pass the project root directory instead.`)}if(this.discoverRootFrom(i)!==i)throw new Error(`Not a valid Harmony project root: ${i}
1363
- (project-level build-profile.json5 not found).`);return i}if(t&&t.length>0)for(let i of t){let o=te.isAbsolute(i)?i:te.resolve(this.cwd,i),s=this.discoverRootFrom(te.dirname(o));if(s)return s}let n=this.discoverRootFrom(this.cwd);if(n)return n;throw new Error("Not in a valid Harmony project directory (project-level build-profile.json5 not found). Run this command inside a project, or pass --project <path>.")}discoverRootFrom(e){try{return W.discover(e).rootDir}catch{return}}resolveFiles(e,t){if(t.length===0)return[];let n=t.map(a=>{if(te.isAbsolute(a))return a;let c=te.resolve(this.cwd,a);return Xr.existsSync(c)?c:te.resolve(e,a)}),i=n.filter(a=>!Xr.existsSync(a));if(i.length>0)throw new Error(`File(s) not found:
1379
+ (project-level build-profile.json5 not found).`);return i}if(t&&t.length>0)for(let i of t){let o=re.isAbsolute(i)?i:re.resolve(this.cwd,i),s=this.discoverRootFrom(re.dirname(o));if(s)return s}let n=this.discoverRootFrom(this.cwd);if(n)return n;throw new Error("Not in a valid Harmony project directory (project-level build-profile.json5 not found). Run this command inside a project, or pass --project <path>.")}discoverRootFrom(e){try{return W.discover(e).rootDir}catch{return}}resolveFiles(e,t){if(t.length===0)return[];let n=t.map(a=>{if(re.isAbsolute(a))return a;let c=re.resolve(this.cwd,a);return en.existsSync(c)?c:re.resolve(e,a)}),i=n.filter(a=>!en.existsSync(a));if(i.length>0)throw new Error(`File(s) not found:
1364
1380
  `+i.map(a=>` ${a}`).join(`
1365
- `));let o=n.filter(a=>{let c=te.relative(e,a);return c.startsWith("..")||te.isAbsolute(c)});if(o.length>0)throw new Error(`File(s) outside the project root ${e}:
1381
+ `));let o=n.filter(a=>{let c=re.relative(e,a);return c.startsWith("..")||re.isAbsolute(c)});if(o.length>0)throw new Error(`File(s) outside the project root ${e}:
1366
1382
  `+o.map(a=>` ${a}`).join(`
1367
- `));let s=n.filter(a=>Xr.statSync(a).isFile()&&a.endsWith(".ets")&&!a.endsWith(".d.ets"));if(s.length===0)throw new Error(`No .ets files found in the given file(s):
1383
+ `));let s=n.filter(a=>en.statSync(a).isFile()&&a.endsWith(".ets")&&!a.endsWith(".d.ets"));if(s.length===0)throw new Error(`No .ets files found in the given file(s):
1368
1384
  `+n.map(a=>` ${a}`).join(`
1369
- `));return s}buildArgs(e,t,n,i){let o=[e,"--project",t];return o.push(i?"--fix":"--no-fix"),n.length>0&&o.push("--files",...n),o}buildEnv(){return{...process.env,DEVECO_HOME:this.resolveDevecoHome()}}resolveDevecoHome(){let e=this.toolProvider.toolchainRoot;if(sH.platform()==="darwin"&&!Xr.existsSync(te.join(e,"sdk"))){let t=te.join(e,"Contents");if(Xr.existsSync(te.join(t,"sdk")))return t}return e}parseResult(e,t,n){let i=e.trim();if(!i){let o=t.trim();throw new Error(`arkts-check exited with code ${n} but produced no output`+(o?`: ${o}`:""))}try{let o=JSON.parse(i);return{success:o.success??!1,error:o.error,errors:o.errors??[],fixed:o.fixed??[],alsoModified:o.alsoModified??[],summary:{errorCount:o.summary?.errorCount??0,warnCount:o.summary?.warnCount??0,fixedCount:o.summary?.fixedCount??0,checkerDiagCount:o.summary?.checkerDiagCount,fileCount:o.summary?.fileCount??0}}}catch(o){throw new Error(`Failed to parse arkts-check output: ${i.slice(0,500)}`,{cause:o})}}resolveScriptPath(){let e=aH(import.meta.url),t=te.dirname(e);if(e.includes("dist")){let s=te.dirname(t),a=te.join(s,"src",iC);if(Xr.existsSync(a))return a}let n=te.dirname(t),i=te.dirname(n),o=te.join(i,"src",iC);if(Xr.existsSync(o))return o;throw new Error("arkts-check.cjs not found in deveco-cli package resources. Reinstall deveco-cli.")}};import{red as kg,yellow as Dg,green as oC}from"colorette";import{Command as cH}from"commander";function lH(r){let e=r;return e.code??e.name??"UnknownError"}async function Cg(r,e,t,n){let i=await ft(process.pid),o=i!==null?ae(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(s,a).catch(()=>{})}function Rg(){return new cH("arkts").description("Run ArkTS static checks on .ets source files").arguments("[files...]").option("--fix","Auto-fix high-confidence errors before reporting").option("--project <path>","Project root directory (default: auto-detected from cwd)").action(async(r,e)=>{await dH(r,e)})}async function dH(r,e){let t=Date.now(),n=["check","arkts"];try{let i=await C.new(),o=new Fa(i,process.cwd()),s=new Ie;process.stderr.isTTY&&s.start("Checking ArkTS...");let a;try{a=await o.check({files:r,fix:e.fix,projectRoot:e.project})}catch(c){throw s.fail("ArkTS check failed"),c}if(a.error&&a.errors.length===0){s.fail("ArkTS check failed"),console.error(kg(a.error)),process.exitCode=1,await Cg(t,!1,"CheckFailed",n);return}s.stop(),uH(a),await Cg(t,!0,null,n)}catch(i){throw await Cg(t,!1,lH(i),n),i}}function uH(r){let{errorCount:e,warnCount:t,fixedCount:n,fileCount:i}=r.summary;if(pH(r.fixed,n,r.alsoModified),e===0){console.log(oC(`No errors found in ${i} file(s).`)),sC(r.errors);return}mH(r.errors,e,t),process.exitCode=1}function pH(r,e,t){if(r.length!==0){console.log(oC(`\u2713 Auto-fixed ${e} issue(s):`));for(let n of r)console.log(` ${n.file}:${n.line}:${n.column} - ${n.message}`);if(t.length>0){console.log(Dg(`Note: auto-fix also modified ${t.length} file(s) outside the checked list (added missing 'export'):`));for(let n of t)console.log(` ${n}`)}console.log()}}function mH(r,e,t){let n=r.filter(i=>i.severity==="error");console.error(kg(`ArkTS check found ${e} error(s):`));for(let i of n){let o=i.rule?` (${i.rule})`:"";console.error(kg(`${i.file}:${i.line}:${i.column} - ${i.severity}: ${i.message}${o}`))}sC(r,t)}function sC(r,e){let t=r.filter(i=>i.severity!=="error");if(t.length===0)return;let n=e??t.length;console.warn(Dg(`
1370
- Warnings (${n}):`));for(let i of t){let o=i.rule?` (${i.rule})`:"";console.warn(Dg(`${i.file}:${i.line}:${i.column} - ${i.severity}: ${i.message}${o}`))}}import{InvalidArgumentError as fH}from"commander";import*as ne from"path";import*as xg from"os";import{readdirSync as gH,existsSync as du,readFileSync as hH,unlinkSync as yH,copyFileSync as dC,writeFileSync as uC}from"fs";import{execa as wH}from"execa";import{cyan as Te,yellow as pC}from"colorette";import vH from"ora";var pe=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function Ag(r){let e=r;return r instanceof pe?r.code:e.code??e.name??"UnknownError"}async function Yo(r,e,t,n){let i=await ft(process.pid),o=i!==null?ae(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await D.track(s,a).catch(()=>{})}var bH=["default","csv","json"],aC=["default","json"];function SH(r){return[...r].sort((e,t)=>{let n=cC(e),i=cC(t);return n.apiVersion-i.apiVersion||n.suffix.localeCompare(i.suffix)})}function cC(r){let e=r.match(/\((\d+)\)/),t=e?Number(e[1]):0,n=r.lastIndexOf("_"),i=n>=0?r.slice(n+1):r;return{apiVersion:t,suffix:i}}function mC(r){let t=gH(r,{withFileTypes:!0}).filter(n=>n.isFile()&&n.name.toLowerCase().endsWith(".json")).map(n=>n.name.slice(0,-5));return SH(t)}async function fC(r){if(r=r===void 0?"default":r,!aC.includes(r))throw new Error(`--format must be ${aC.join(" or ")}. got "${r}"`);let e=Date.now(),t=["check","compat","versions"];try{let n=await C.new(),{apiChangeDir:i}=n.getApiscanPaths();m(Te(`[compat:versions] apiChangeDir: "${i}"`));let o=mC(i);if(r==="json")console.log(JSON.stringify({versions:o,count:o.length},null,2));else{if(o.length===0){console.log("No SDK versions available."),await Yo(e,!0,null,t);return}console.log(o.join(`
1371
- `))}await Yo(e,!0,null,t)}catch(n){let i=Ag(n);throw await Yo(e,!1,i,t),n}}var lC=new Set([".ets",".c",".cpp"]);function EH(r,e){let t=new Set(r.profile.modules.map(s=>s.name)),n=e.filter(s=>!t.has(s));if(n.length===0)return;let i=r.profile.modules.map(s=>s.name).join(", "),o=n.length>1?"are":"is";throw new pe("errorCode",`Module ${n.map(s=>`"${s}"`).join(", ")} ${o} not defined in build-profile.json5. Available modules: ${i}.`)}function PH(r){for(let e of r){let t=ne.resolve(e);if(!du(t))throw new pe("errorCode",`File "${e}" does not exist.`);let n=ne.extname(t).toLowerCase();if(!lC.has(n)){let i=Array.from(lC).join(", ");throw new pe("errorCode",`Unsupported file extension "${n}" for "${e}". Supported: ${i}.`)}}}function CH(r){let e=[],t=[];for(let n of r)ne.extname(n).toLowerCase()===".ets"?e.push(n):t.push(n);return{arkTs:e,cpp:t}}function kH(r){let e=[],t=[],n="",i=!1,o=0;for(;o<r.length;){let s=r[o];i?{field:n,inQuotes:i,i:o}=DH(r,o,s,n,i):s==='"'?(i=!0,o+=1):s===","?(t.push(n),n="",o+=1):s===`
1372
- `?(t.push(n),e.push(t),t=[],n="",o+=1):(s==="\r"||(n+=s),o+=1)}return(n.length>0||t.length>0)&&(t.push(n),e.push(t)),e}function DH(r,e,t,n,i){return t!=='"'?{field:n+t,inQuotes:i,i:e+1}:r[e+1]==='"'?{field:n+'"',inQuotes:i,i:e+2}:{field:n,inQuotes:!1,i:e+1}}function RH(r,e){return e.map(t=>{let n=i=>{let o=r.indexOf(i);return o>=0&&o<t.length?t[o]:""};return{apiDefinition:n("Api Definition"),language:n("Language"),changeId:n("ChangeId"),changedInSdk:n("Changed in SDK"),affectedVersions:n("Affected Versions"),title:n("Title"),codeLocation:n("Code Location"),changeType:n("Change Type")}})}function xH(r){let e=hH(r,"utf8"),t=e.startsWith("\uFEFF")?e.slice(1):e,n=kH(t);if(n.length<2)return[];let[i,...o]=n;return RH(i,o)}function AH(r,e){let t=r.match(/CSV saved to:\s*([^\r\n]+\.csv)/);if(!t)return null;let n=t[1].trim();if(ne.isAbsolute(n))return n;let i=ne.join(e,n);return P.ensurePathWithinRoot(e,i)}function IH(r,e){let t=new Map;for(let o of r){let s=o.changeType||"(unknown)";t.set(s,(t.get(s)??0)+1)}let n=Array.from(t.entries()).sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])),i=Math.max(5,...n.map(([o])=>o.length));console.log(Te("API change scan summary:")),console.log(` ${"Total".padEnd(i)} ${r.length}`);for(let[o,s]of n)console.log(` ${o.padEnd(i)} ${s}`);e&&console.log(` ${"Report".padEnd(i)} ${e}`)}function TH(r,e){if(console.log(),r.length===0){console.log("No API changes detected.");return}let t=r.slice(0,e),n=r.length-t.length;console.log(Te(`Details (showing ${t.length}${n>0?` of ${r.length}`:""}):`));let i=[["Title","title"],["Language","language"],["ChangeId","changeId"],["Changed in","changedInSdk"],["Affected Versions","affectedVersions"],["Code Location","codeLocation"]],o=Math.max(...i.map(([a])=>a.length)),s=a=>a||"<unknown>";for(let a of t){console.log(` [${s(a.changeType)}] ${s(a.apiDefinition)}`);for(let[c,l]of i)console.log(` ${c.padEnd(o)} ${s(a[l])}`)}n>0&&console.log(pC(` ... and ${n} more. you can re-run with --output-path <dir> to save the full report.`))}function OH(r,e){let t=r.slice(0,e),n=r.length-t.length;console.log(),console.log(JSON.stringify({records:t,count:r.length},null,2)),n>0&&console.log(pC(`... and ${n} more. you can re-run with --output-path <dir> to save the full report.`))}function NH(r,e){let t=[];for(let n of e){let i=r.profile.modules.find(o=>o.name===n);if(!i)throw new pe("errorCode",`Module "${n}" not found in build-profile.json5.`);t.push(ne.resolve(r.rootDir,i.srcPath))}return t}function MH(r,e,t,n){if(!n.sourceVersion||!n.targetVersion)throw new pe("errorCode","source-version and target-version are required.");let i=[r,"--startVersion",n.sourceVersion,"--endVersion",n.targetVersion];if(e.length>0){let{arkTs:o,cpp:s}=CH(e),a=d=>ne.resolve(process.cwd(),d),c=o.map(a),l=s.map(a);c.length>0&&i.push("--arkTsFiles",c.join(",")),l.length>0&&i.push("--cppFiles",l.join(","))}else if(n.modules&&n.modules.length>0){let o=NH(t,n.modules);i.push("--modulePaths",o.join(","))}else i.push("--projectPath",t.rootDir);return i.push("--outputPath",xg.tmpdir()),i}async function LH(r,e){let t=ne.dirname(e[0]);try{let i=(await wH(r.nodePath,e,{cwd:t,stdin:"ignore",stdout:"pipe",stderr:"inherit"})).stdout;return process.env.DEVECO_CLI_DEBUG&&(console.log(Te("[compat:check] === scan stdout ===")),process.stdout.write(i),i.endsWith(`
1385
+ `));return s}buildArgs(e,t,n,i){let o=[e,"--project",t];return o.push(i?"--fix":"--no-fix"),n.length>0&&o.push("--files",...n),o}buildEnv(){return{...process.env,DEVECO_HOME:this.resolveDevecoHome()}}resolveDevecoHome(){let e=this.toolProvider.toolchainRoot;if($B.platform()==="darwin"&&!en.existsSync(re.join(e,"sdk"))){let t=re.join(e,"Contents");if(en.existsSync(re.join(t,"sdk")))return t}return e}parseResult(e,t,n){let i=e.trim();if(!i){let o=t.trim();throw new Error(`arkts-check exited with code ${n} but produced no output`+(o?`: ${o}`:""))}try{let o=JSON.parse(i);return{success:o.success??!1,error:o.error,errors:o.errors??[],fixed:o.fixed??[],alsoModified:o.alsoModified??[],summary:{errorCount:o.summary?.errorCount??0,warnCount:o.summary?.warnCount??0,fixedCount:o.summary?.fixedCount??0,checkerDiagCount:o.summary?.checkerDiagCount,fileCount:o.summary?.fileCount??0}}}catch(o){throw new Error(`Failed to parse arkts-check output: ${i.slice(0,500)}`,{cause:o})}}resolveScriptPath(){let e=jB(import.meta.url),t=re.dirname(e);if(e.includes("dist")){let s=re.dirname(t),a=re.join(s,"src",Mk);if(en.existsSync(a))return a}let n=re.dirname(t),i=re.dirname(n),o=re.join(i,"src",Mk);if(en.existsSync(o))return o;throw new Error("arkts-check.cjs not found in deveco-cli package resources. Reinstall deveco-cli.")}};import{red as wh,yellow as vh,green as Lk}from"colorette";import{Command as HB}from"commander";function UB(r){let e=r;return e.code??e.name??"UnknownError"}async function yh(r,e,t,n){let i=await gt(process.pid),o=i!==null?ce(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(s,a).catch(()=>{})}function bh(){return new HB("arkts").description("Run ArkTS static checks on .ets source files").arguments("[files...]").option("--fix","Auto-fix high-confidence errors before reporting").option("--project <path>","Project root directory (default: auto-detected from cwd)").action(async(r,e)=>{await BB(r,e)})}async function BB(r,e){let t=Date.now(),n=["check","arkts"];try{let i=await C.new(),o=new nc(i,process.cwd()),s=new Te;process.stderr.isTTY&&s.start("Checking ArkTS...");let a;try{a=await o.check({files:r,fix:e.fix,projectRoot:e.project})}catch(c){throw s.fail("ArkTS check failed"),c}if(a.error&&a.errors.length===0){s.fail("ArkTS check failed"),console.error(wh(a.error)),process.exitCode=1,await yh(t,!1,"CheckFailed",n);return}s.stop(),WB(a),await yh(t,!0,null,n)}catch(i){throw await yh(t,!1,UB(i),n),i}}function WB(r){let{errorCount:e,warnCount:t,fixedCount:n,fileCount:i}=r.summary;if(VB(r.fixed,n,r.alsoModified),e===0){console.log(Lk(`No errors found in ${i} file(s).`)),Fk(r.errors);return}GB(r.errors,e,t),process.exitCode=1}function VB(r,e,t){if(r.length!==0){console.log(Lk(`\u2713 Auto-fixed ${e} issue(s):`));for(let n of r)console.log(` ${n.file}:${n.line}:${n.column} - ${n.message}`);if(t.length>0){console.log(vh(`Note: auto-fix also modified ${t.length} file(s) outside the checked list (added missing 'export'):`));for(let n of t)console.log(` ${n}`)}console.log()}}function GB(r,e,t){let n=r.filter(i=>i.severity==="error");console.error(wh(`ArkTS check found ${e} error(s):`));for(let i of n){let o=i.rule?` (${i.rule})`:"";console.error(wh(`${i.file}:${i.line}:${i.column} - ${i.severity}: ${i.message}${o}`))}Fk(r,t)}function Fk(r,e){let t=r.filter(i=>i.severity!=="error");if(t.length===0)return;let n=e??t.length;console.warn(vh(`
1386
+ Warnings (${n}):`));for(let i of t){let o=i.rule?` (${i.rule})`:"";console.warn(vh(`${i.file}:${i.line}:${i.column} - ${i.severity}: ${i.message}${o}`))}}import{InvalidArgumentError as qB}from"commander";import*as ie from"path";import*as Sh from"os";import{readdirSync as zB,existsSync as Bu,readFileSync as JB,unlinkSync as KB,copyFileSync as Uk,writeFileSync as Bk}from"fs";import{execa as YB}from"execa";import{cyan as Ne,yellow as Wk}from"colorette";import XB from"ora";var fe=class extends Error{code;constructor(e,t){super(t),this.name="ValidationError",this.code=e}};function Eh(r){let e=r;return r instanceof fe?r.code:e.code??e.name??"UnknownError"}async function as(r,e,t,n){let i=await gt(process.pid),o=i!==null?ce(Number(i)*1024):"unknown",s={event:v.CheckCommand,args:n,mcpMemory:o,lspMemory:"unknown"},a={duration_ms:Date.now()-r,success:e,error_code:t};await R.track(s,a).catch(()=>{})}var ZB=["default","csv","json"],$k=["default","json"];function QB(r){return[...r].sort((e,t)=>{let n=jk(e),i=jk(t);return n.apiVersion-i.apiVersion||n.suffix.localeCompare(i.suffix)})}function jk(r){let e=r.match(/\((\d+)\)/),t=e?Number(e[1]):0,n=r.lastIndexOf("_"),i=n>=0?r.slice(n+1):r;return{apiVersion:t,suffix:i}}function Vk(r){let t=zB(r,{withFileTypes:!0}).filter(n=>n.isFile()&&n.name.toLowerCase().endsWith(".json")).map(n=>n.name.slice(0,-5));return QB(t)}async function Gk(r){if(r=r===void 0?"default":r,!$k.includes(r))throw new Error(`--format must be ${$k.join(" or ")}. got "${r}"`);let e=Date.now(),t=["check","compat","versions"];try{let n=await C.new(),{apiChangeDir:i}=n.getApiscanPaths();f(Ne(`[compat:versions] apiChangeDir: "${i}"`));let o=Vk(i);if(r==="json")console.log(JSON.stringify({versions:o,count:o.length},null,2));else{if(o.length===0){console.log("No SDK versions available."),await as(e,!0,null,t);return}console.log(o.join(`
1387
+ `))}await as(e,!0,null,t)}catch(n){let i=Eh(n);throw await as(e,!1,i,t),n}}var Hk=new Set([".ets",".c",".cpp"]);function eW(r,e){let t=new Set(r.profile.modules.map(s=>s.name)),n=e.filter(s=>!t.has(s));if(n.length===0)return;let i=r.profile.modules.map(s=>s.name).join(", "),o=n.length>1?"are":"is";throw new fe("errorCode",`Module ${n.map(s=>`"${s}"`).join(", ")} ${o} not defined in build-profile.json5. Available modules: ${i}.`)}function tW(r){for(let e of r){let t=ie.resolve(e);if(!Bu(t))throw new fe("errorCode",`File "${e}" does not exist.`);let n=ie.extname(t).toLowerCase();if(!Hk.has(n)){let i=Array.from(Hk).join(", ");throw new fe("errorCode",`Unsupported file extension "${n}" for "${e}". Supported: ${i}.`)}}}function rW(r){let e=[],t=[];for(let n of r)ie.extname(n).toLowerCase()===".ets"?e.push(n):t.push(n);return{arkTs:e,cpp:t}}function nW(r){let e=[],t=[],n="",i=!1,o=0;for(;o<r.length;){let s=r[o];i?{field:n,inQuotes:i,i:o}=iW(r,o,s,n,i):s==='"'?(i=!0,o+=1):s===","?(t.push(n),n="",o+=1):s===`
1388
+ `?(t.push(n),e.push(t),t=[],n="",o+=1):(s==="\r"||(n+=s),o+=1)}return(n.length>0||t.length>0)&&(t.push(n),e.push(t)),e}function iW(r,e,t,n,i){return t!=='"'?{field:n+t,inQuotes:i,i:e+1}:r[e+1]==='"'?{field:n+'"',inQuotes:i,i:e+2}:{field:n,inQuotes:!1,i:e+1}}function oW(r,e){return e.map(t=>{let n=i=>{let o=r.indexOf(i);return o>=0&&o<t.length?t[o]:""};return{apiDefinition:n("Api Definition"),language:n("Language"),changeId:n("ChangeId"),changedInSdk:n("Changed in SDK"),affectedVersions:n("Affected Versions"),title:n("Title"),codeLocation:n("Code Location"),changeType:n("Change Type")}})}function sW(r){let e=JB(r,"utf8"),t=e.startsWith("\uFEFF")?e.slice(1):e,n=nW(t);if(n.length<2)return[];let[i,...o]=n;return oW(i,o)}function aW(r,e){let t=r.match(/CSV saved to:\s*([^\r\n]+\.csv)/);if(!t)return null;let n=t[1].trim();if(ie.isAbsolute(n))return n;let i=ie.join(e,n);return P.ensurePathWithinRoot(e,i)}function cW(r,e){let t=new Map;for(let o of r){let s=o.changeType||"(unknown)";t.set(s,(t.get(s)??0)+1)}let n=Array.from(t.entries()).sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])),i=Math.max(5,...n.map(([o])=>o.length));console.log(Ne("API change scan summary:")),console.log(` ${"Total".padEnd(i)} ${r.length}`);for(let[o,s]of n)console.log(` ${o.padEnd(i)} ${s}`);e&&console.log(` ${"Report".padEnd(i)} ${e}`)}function lW(r,e){if(console.log(),r.length===0){console.log("No API changes detected.");return}let t=r.slice(0,e),n=r.length-t.length;console.log(Ne(`Details (showing ${t.length}${n>0?` of ${r.length}`:""}):`));let i=[["Title","title"],["Language","language"],["ChangeId","changeId"],["Changed in","changedInSdk"],["Affected Versions","affectedVersions"],["Code Location","codeLocation"]],o=Math.max(...i.map(([a])=>a.length)),s=a=>a||"<unknown>";for(let a of t){console.log(` [${s(a.changeType)}] ${s(a.apiDefinition)}`);for(let[c,l]of i)console.log(` ${c.padEnd(o)} ${s(a[l])}`)}n>0&&console.log(Wk(` ... and ${n} more. you can re-run with --output-path <dir> to save the full report.`))}function dW(r,e){let t=r.slice(0,e),n=r.length-t.length;console.log(),console.log(JSON.stringify({records:t,count:r.length},null,2)),n>0&&console.log(Wk(`... and ${n} more. you can re-run with --output-path <dir> to save the full report.`))}function uW(r,e){let t=[];for(let n of e){let i=r.profile.modules.find(o=>o.name===n);if(!i)throw new fe("errorCode",`Module "${n}" not found in build-profile.json5.`);t.push(ie.resolve(r.rootDir,i.srcPath))}return t}function pW(r,e,t,n){if(!n.sourceVersion||!n.targetVersion)throw new fe("errorCode","source-version and target-version are required.");let i=[r,"--startVersion",n.sourceVersion,"--endVersion",n.targetVersion];if(e.length>0){let{arkTs:o,cpp:s}=rW(e),a=d=>ie.resolve(process.cwd(),d),c=o.map(a),l=s.map(a);c.length>0&&i.push("--arkTsFiles",c.join(",")),l.length>0&&i.push("--cppFiles",l.join(","))}else if(n.modules&&n.modules.length>0){let o=uW(t,n.modules);i.push("--modulePaths",o.join(","))}else i.push("--projectPath",t.rootDir);return i.push("--outputPath",Sh.tmpdir()),i}async function fW(r,e){let t=ie.dirname(e[0]);try{let i=(await YB(r.nodePath,e,{cwd:t,stdin:"ignore",stdout:"pipe",stderr:"inherit"})).stdout;return process.env.DEVECO_CLI_DEBUG&&(console.log(Ne("[compat:check] === scan stdout ===")),process.stdout.write(i),i.endsWith(`
1373
1389
  `)||process.stdout.write(`
1374
- `),console.log(Te("[compat:check] === end stdout ==="))),i}catch(n){let i=n;process.env.DEVECO_CLI_DEBUG&&i.stdout&&(console.log(Te("[compat:check] === scan stdout (on error) ===")),process.stdout.write(i.stdout),i.stdout.endsWith(`
1390
+ `),console.log(Ne("[compat:check] === end stdout ==="))),i}catch(n){let i=n;process.env.DEVECO_CLI_DEBUG&&i.stdout&&(console.log(Ne("[compat:check] === scan stdout (on error) ===")),process.stdout.write(i.stdout),i.stdout.endsWith(`
1375
1391
  `)||process.stdout.write(`
1376
- `),console.log(Te("[compat:check] === end stdout ===")));let o=new pe("errorCode",`Compatibility scan failed: ${i.message}`+(i.stderr?`
1377
- ${i.stderr}`:""));throw i.stdout&&(o.stdout=i.stdout),o}}function _H(r,e){if(!bH.includes(e.format))throw new fH(`--format must be default, csv, or json (console: default|json, file: default|csv|json). got "${e.format}"`);if(r.length>0&&e.modules&&e.modules.length>0)throw new pe("errorCode","Cannot use `--modules` together with file arguments. Use either file-level scanning (with files) or module-level scanning (with --modules).");if(!e.sourceVersion)throw new pe("errorCode","--source-version is required.");if(!e.targetVersion)throw new pe("errorCode","--target-version is required.");if(!e.outputPath&&e.format==="csv")throw new pe("errorCode","--format csv requires --output-path. For console output, use --format json or --format default (or omit the flag).")}function $H(r,e){let t=[];if(r.sourceVersion&&!e.includes(r.sourceVersion)&&t.push(`--source-version "${r.sourceVersion}"`),r.targetVersion&&!e.includes(r.targetVersion)&&t.push(`--target-version "${r.targetVersion}"`),t.length>0){let n=t.length>1?"are":"is";throw new pe("errorCode",`${t.join(" and ")} ${n} not in the available SDK version list.
1378
- Run \`devecocli compat versions\` to see all available versions.`)}if(r.sourceVersion&&r.targetVersion){let n=e.indexOf(r.sourceVersion),i=e.indexOf(r.targetVersion);if(n>=i)throw new pe("errorCode",`--target-version "${r.targetVersion}" must be later than --source-version "${r.sourceVersion}". Run \`devecocli compat versions\` to see the available order.`)}}function FH(r,e,t,n,i){i==="none"&&(t==="json"?OH(r,n):TH(r,n)),IH(r,e)}function jH(r,e){let t=ne.dirname(r),n=ne.basename(r),i=e.slice(1).map(o=>o.startsWith("--")?o:`"${o}"`).join(" ");m(Te(`[compat:check] command: cd "${t}" && node "${n}" ${i}`))}function HH(r){try{yH(r),m(Te(`[compat:check] cleaned up tmp report: "${r}"`))}catch(e){m(Te(`[compat:check] failed to clean up tmp report: ${e.message}`))}}var UH=[".csv",".json"];function BH(r){return UH.includes(r.toLowerCase())}function WH(r,e){if(!r)return{kind:"none"};let t=ne.extname(r).toLowerCase();if(!BH(t))return{kind:"dir",dirPath:ne.resolve(r)};if(t===".csv"&&!(e==="default"||e==="csv")||t===".json"&&e!=="json")throw new pe("errorCode",`The --output-path file extension '${t}' does not match --format ${e}. Use --format ${t===".json"?"json":"default"}, or rename the file.`);return{kind:"file",filePath:ne.resolve(r),ext:t}}function VH(r){if(r.kind==="file"){if(du(r.filePath))throw new pe("errorCode",`Target file "${r.filePath}" already exists. Remove it first, or choose a different --output-path.`);let e=ne.dirname(r.filePath);if(!du(e))throw new pe("errorCode",`Target directory "${e}" does not exist. Create it first, or choose a different --output-path.`)}else if(r.kind==="dir"&&!du(r.dirPath))throw new pe("errorCode",`Target directory "${r.dirPath}" does not exist. Create it first, or choose a different --output-path.`)}function gC(r){return JSON.stringify({records:r,count:r.length},null,2)+`
1379
- `}function GH(r,e,t,n){n===".csv"?dC(r,t):uC(t,gC(e),"utf8"),m(Te(`[compat:check] saved report: "${t}"`))}function qH(r,e,t,n){if(n==="json"){let o=ne.basename(r,".csv"),s=ne.join(t,`${o}.json`);return uC(s,gC(e),"utf8"),m(Te(`[compat:check] saved report: "${s}"`)),s}let i=ne.join(t,ne.basename(r));return dC(r,i),m(Te(`[compat:check] saved report: "${i}"`)),i}async function zH(r,e){let t=new gt(r,process.cwd(),!0),n=e.modules&&e.modules.length>0?e.modules[0]:void 0;try{await t.compileNative("default",n)}catch(i){throw new pe("errorCode",`hvigorw compileNative failed (module=${n??"<project>"}): `+i.message,{cause:i})}}async function JH(r,e){_H(r,e);let t=W.discover(process.cwd());await rt.warnInvalidBundledLinks(t.rootDir),e.modules&&e.modules.length>0&&EH(t,e.modules),r.length>0&&PH(r);let n=await C.new(),{apiChangeDir:i,scriptPath:o}=n.getApiscanPaths();m(Te(`[compat:check] script: "${o}"`));let s=mC(i);$H(e,s),e.outputPath&&m(Te(`[compat:check] outputPath: "${e.outputPath}"`));let a=WH(e.outputPath,e.format);return m(Te(`[compat:check] outputTarget: ${a.kind}`)),VH(a),{project:t,scriptPath:o,target:a,toolProvider:n}}function YH(r,e,t,n){if(t.kind==="file")return GH(r,e,t.filePath,t.ext),t.filePath;if(t.kind==="dir")return qH(r,e,t.dirPath,n);if(t.kind==="none")return null;throw new pe("errorCode",`Unexpected output target kind: ${t.kind}`)}async function KH(r,e,t,n,i){let o=vH({text:"Running compatibility check...",color:"cyan"}).start();try{await zH(r.toolProvider,t);let s=MH(r.scriptPath,e,r.project,t);jH(r.scriptPath,s);let a=await LH(r.toolProvider,s),c=AH(a,xg.tmpdir());if(!c)throw new pe("errorCode","Scanner output format unexpected: missing report path.");m(Te(`[compat:check] tmp csv: "${c}"`));let l=xH(c),d=YH(c,l,r.target,t.format);HH(c),o.stop(),FH(l,d,t.format,t.limit,r.target.kind),await Yo(n,!0,null,i)}catch(s){o.fail("Compatibility check failed");let a=Ag(s);throw await Yo(n,!1,a,i),s}}async function hC(r,e){let t=Date.now(),n=["check","compat"];try{let i=await JH(r,e);await KH(i,r,e,t,n)}catch(i){let o=Ag(i);throw await Yo(t,!1,o,n),i}}function ZH(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new XH(`--limit must be a positive integer (got "${r}")`);return e}var Ig=new yC("compat").description("Compatibility checking utilities.");Ig.description("Check source code compatibility against a target SDK version. By default, performs a project-level scan; pass positional `files...` for file-level scanning; pass `--modules` for module-level scanning.").arguments("[files...]").option("--source-version <version>","Current project SDK version (required; use `compat versions` to list available versions). On zsh, quote the value because version strings contain parentheses; run `compat versions` first to copy a real example.").option("--target-version <version>","Target SDK version (required; use `compat versions` to list available versions). On zsh, quote the value because version strings contain parentheses; run `compat versions` first to copy a real example.").option("--modules <modules...>","Modules to check (default: all modules in the project). Mutually exclusive with positional file arguments.").option("--format <format>",'Output format: "json" or "default" (text) for console; "csv", "json", or "default" for file output (--output-path). "csv" requires --output-path.',"default").option("--output-path <path>","Directory to write the detailed report CSV to (default: ./compat-output)").option("--limit <num>","Maximum number of change records to display (default: 100)",ZH,100).action(async(r,e)=>{await hC(r,e)});Ig.command("versions").description("List all available target SDK versions for compatibility checking").option("--format <format>","Output format: default or json").action(async(r,e)=>{let t=e.optsWithGlobals().format;await fC(t)});var QH=new yC("check").description("Run DevEco project checks").addCommand(Ig).addCommand(Eg()).addCommand(Rg()),wC=QH;import{Command as U1}from"commander";import{green as Qg,red as B1,yellow as rk}from"colorette";import Ii from"fs";import eh from"path";import nk from"json5";import{readFileSync as xU}from"fs";import{join as eU}from"path";var me={BASE_URL:"https://connect-api.cloud.huawei.com",CERT_LIST_PATH:"/api/cps/harmony-cert-manage/v1/cert/list",CERT_DELETE_PATH:"/api/cps/harmony-cert-manage/v1/cert/delete",CERT_ADD_PATH:"/api/cps/harmony-cert-manage/v1/cert/add",CERT_DOWNLOAD_URL_PATH:"/api/amis/app-manage/v1/objects/url/reapply",DEVICE_ADD_PATH:"/api/cps/device-manage/v1/device/add",DEVICE_LIST_PATH:"/api/cps/device-manage/v1/device/list",PROVISION_ADD_REAL_PATH:"/api/cps/provision-manage/v1/ide/real/provision/add",PROVISION_ADD_TEST_PATH:"/api/cps/provision-manage/v1/ide/test/provision/add",PROVISION_DELETE_PATH:"/api/cps/provision-manage/v1/provision/delete"},Re={CERT_NAME_PREFIX:"auto_debug_",CERT_NAME_PREFIX_RELEASE:"auto_release_",CERT_TYPE_DEBUG:"1",CERT_TYPE_RELEASE:"2",TEAM_ID_INVALID_CHARS:/[\\/.:]/g,CERT_PATTERN:/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/,TARGET_FRIENDLY_NAME:"debugKey",CERTIFICATE_PATTERN_GLOBAL:/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g,BUNDLE_NAME_REGEX:/^[a-zA-Z][a-zA-Z0-9._-]*$/,CERT_BEGIN_HEADER:"-----BEGIN CERTIFICATE-----",CERT_SAVE_DIR:eU(".ohos","config"),DOWNLOAD_CONNECT_TIMEOUT_MS:5e3},Oe={SUCCESS_MARKER:'"code":0',SQUARE_BRACKETS:"[]",OPENPROXY_BLOCKED_URL:"Openproxy_Blocked_URL_list",CERT_LIMIT_CODE:"205389872",USER_NOT_HARMONY_CODE:"205389904",DEVICE_EXCEEDS_LIMIT_CODE:"205389859",DEVICE_NAME_REPEAT_CODE:"205389857",PROVISION_EXCEEDS_LIMIT_CODE:"205389938",PROVISION_NAME_REPEAT_CODE:"205389830"},Zt={FORBIDDEN:403,UNAUTHORIZED:401},R={ERR_FORBIDDEN:"You do not have AppGallery Connect permissions for the current team. Request access from the team administrator or switch to a team where you have permissions.",ERR_UNAUTHORIZED:"Invalid AccessToken. Sign in and try again.",ERR_CERT_LIMIT_REACHED:"The number of certificates has reached the limit. Delete some certificates and try again.",ERR_CERT_NETWORK_ERROR:"Ensure the external network connection is available before downloading the certificate.",ERR_CERT_INVALIDATE:"The downloaded .cer file is invalid. Try again.",ERR_DOWNLOAD_CER:"Failed to download the certificate file. Check the following configurations: Network connection, HTTP Proxy, etc.",ERR_USER_NOT_HARMONY:"The user is not in harmony allow list, please grant the permission",ERR_READ_CSR:"Failed to read the .csr file, please try again later",ERROR_WHILE_ADD_DEVICE:"Failed to add the device, please try again.",DEVICE_LIMIT_REACHED:"The number of devices has reached the limit. Delete some unused devices and try again.",DEVICE_NAME_REPEAT:"Duplicate device name, please try again.",DEVICE_LIST_EMPTY:"No devices available.",ADD_PROFILE_FAIL:"Failed to add the profile, please try again.",NO_AGC_PERMISSION:"You do not have the AppGallery Connect permission with the current team. Apply for the permission form the team administrator, or switch to a team with which you already have the permission.",ERROR_WHILE_DOWNLOAD_PROFILE:"Failed to download the profile, please try again.",PROFILE_NAME_REPEAT:"The profile name already exists in the AGC.",ERROR_WHILE_PARSE_PROFILE:"Failed to parse the profile, please try again.",TEST_PROVISION_EXCEEDS_LIMIT:"Provision number exceeds limit.",CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT:"The certificate application file is inconsistent with the file in profile, please try again.",CERTIFICATE_HAS_EXPIRED:"The signature does not take effect or has expired. It may be the current system time is inaccurate, please calibrate the system time and sign again.",ERROR_SIGN_BUNDLE_NAME_VALIDATE:"The bundle name contains 7 to 128 characters, including only letters, digits, and underscores (_). It must be start with a letter and contain at least three segments separated by periods (.), each of the segments ending with a digit or letter."},ve={TOOLCHAIN_INIT_FAILED:"Auto-sign failed: unable to initialize toolchain",LOGIN_REQUIRED:"Failed to automatically generate signatures.Run devecocli auth login to sign in.",TEAM_INFO_FAILED:"Failed to obtain user team information.Check the network connection, HTTP proxy, and other configurations.",REALNAME_REQUIRED:"Users without real-name verification are not supported.Complete real-name verification in AppGallery Connect.",SESSION_EXPIRED:"User session expired or token invalid. Please login again.",REGION_CHINA_ONLY:"This feature is only available for accounts registered in Chinese mainland.",DEVICE_MISSING:"Unable to create the profile file due to missing devices.Connect a device through IP or USB, or manually add a device in AppGallery Connect first.If you are installing the HAP package on an emulator, you can skip the signing step.",DEVICE_DETECT_FAILED:"Unable to detect devices. Please check hdc status. If installing HAP on an emulator, signature step can be skipped.",PROJECT_DIR_MISSING:"Not in a valid project directory (project-level build-profile.json5 not found).",ATOMIC_SERVICE_UNSUPPORTED:"AtomicService projects are not yet supported. Please configure signing manually."};function uu(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}function Tg(r,e=!1){let t=r.replace(Re.TEAM_ID_INVALID_CHARS,"");return`${e?Re.CERT_NAME_PREFIX_RELEASE:Re.CERT_NAME_PREFIX}${t}.cer`}function Ko(r,e,t){if(r===Zt.FORBIDDEN)return e===Oe.OPENPROXY_BLOCKED_URL?new Error(R.ERR_CERT_NETWORK_ERROR):new Error(R.ERR_FORBIDDEN);if(r===Zt.UNAUTHORIZED)return new Error(R.ERR_UNAUTHORIZED);if(t.includes(Oe.USER_NOT_HARMONY_CODE))return new Error(R.ERR_USER_NOT_HARMONY);if(t.includes(Oe.CERT_LIMIT_CODE))return new Error(R.ERR_CERT_LIMIT_REACHED);let n=tU(t);return new Error(n??R.ERR_DOWNLOAD_CER)}function tU(r){let e=vC(r);if(!e||typeof e!="object")return null;let t=e.ret;if(t==null)return null;let n=typeof t=="string"?vC(t):t;if(n&&typeof n=="object"){let i=n.msg;if(typeof i=="string"&&i.trim()!=="")return i}return null}function vC(r){try{return JSON.parse(r)}catch{return null}}function Og(r){return JSON.parse(r)}async function bC(r){let e=`${me.BASE_URL}${me.CERT_LIST_PATH}`,t=await F.postAllowFailure(e,{headers:uu(r)});if(t.statusCode!==200)throw Ko(t.statusCode,t.statusText,t.data);return Og(t.data)?.certList??[]}async function pu(r,e){return(await bC(r)).find(n=>n.certName===e)??null}async function Ng(r,e){let t=`${me.BASE_URL}${me.CERT_DELETE_PATH}`,n=await F.deleteAllowFailure(t,{headers:uu(r),params:{certIds:[e]}});if(n.statusCode!==200)throw Ko(n.statusCode,n.statusText,n.data);return Og(n.data)?.ret?.code===0}async function Mg(r,e,t,n=Re.CERT_TYPE_DEBUG){let i=`${me.BASE_URL}${me.CERT_ADD_PATH}`,o={csr:e,certName:t,certType:n},s=await F.postAllowFailure(i,{headers:uu(r),params:o});if(s.statusCode!==200)throw Ko(s.statusCode,s.statusText,s.data);if(!s.data.includes(Oe.SUCCESS_MARKER))throw Ko(void 0,s.statusText,s.data)}async function Lg(r,e){let t=`${me.BASE_URL}${me.CERT_DOWNLOAD_URL_PATH}`,n=await F.postAllowFailure(t,{headers:uu(r),params:{sourceUrls:e}});if(n.statusCode!==200)throw Ko(n.statusCode,n.statusText,n.data);return Og(n.data)?.urlsInfo?.[0]??null}import{mkdirSync as rU,writeFileSync as nU,existsSync as iU}from"fs";import{dirname as oU}from"path";import{createHash as sU}from"crypto";function aU(r){let e;try{e=new URL(r)}catch{throw new Error(`Invalid download URL: ${JSON.stringify(r)}`)}if(e.protocol!=="https:")throw new Error(`Download URL must use HTTPS: ${e.protocol}`);let t=e.hostname.toLowerCase();if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t.startsWith("169.254.")||t.startsWith("10.")||t.startsWith("192.168.")||/^172\.(1[6-9]|2\d|3[0-1])\./.test(t)||t.endsWith(".internal")||t.endsWith(".local"))throw new Error(`Download URL points to internal/private address: ${t}`)}async function ja(r,e,t){aU(r);let{statusCode:n,statusText:i,buffer:o}=await F.getBinaryAllowFailure(r,{timeout:Re.DOWNLOAD_CONNECT_TIMEOUT_MS});if(n!==200)throw n===Zt.FORBIDDEN&&i===Oe.OPENPROXY_BLOCKED_URL?new Error(R.ERR_CERT_NETWORK_ERROR):new Error(R.ERR_DOWNLOAD_CER);if(t){let a=sU("sha256").update(o).digest("hex");if(a!==t.toLowerCase())throw new Error(`SHA-256 mismatch for ${e}: expected ${t.toLowerCase()}, got ${a}`)}let s=oU(e);iU(s)||rU(s,{recursive:!0}),nU(e,o)}import kU from"fs/promises";import{readFileSync as DU}from"fs";import mu from"path";import PC from"crypto";import cU from"os";import Ha from"fs/promises";var CC={GENERATE_KEYPAIR:"generate-keypair",GENERATE_CSR:"generate-csr"},SC=["ECC","RSA"],EC=["SHA256withECDSA","SHA384withECDSA","SHA256withRSA","SHA384withRSA"],lU={ECC:["NIST-P-256","NIST-P-384"],RSA:["2048","3072","4096"]},dU=8,_g=64,uU=/[\\/:*?"<>|=-]/g,Zr={productName:"default",keyAlias:"debugKey",keyAlg:"ECC",keySize:"NIST-P-256",csrSubject:"CN=DebugKey",signAlg:"SHA256withECDSA"};function pU(r){if(!r.keyAlias.trim())throw new Error("keyAlias cannot be empty");if(!r.keystoreFile.trim())throw new Error("keystoreFile cannot be empty");if(r.keyAlias.length>_g)throw new Error(`The length of keyAlias cannot exceed ${_g}`);if(!SC.includes(r.keyAlg))throw new Error(`Invalid key algorithm ${r.keyAlg}, available: ${SC.join(" / ")}`);let e=lU[r.keyAlg];if(!e.includes(r.keySize))throw new Error(`Key algorithm ${r.keyAlg} does not support size ${r.keySize}, available: ${e.join(", ")}`)}function mU(r){if(!r.keyAlias.trim())throw new Error("keyAlias cannot be empty");if(!r.keystoreFile.trim())throw new Error("keystoreFile cannot be empty");if(!r.subject.trim())throw new Error("subject cannot be empty");if(!EC.includes(r.signAlg))throw new Error(`Invalid sign algorithm ${r.signAlg}, available: ${EC.join(" / ")}`)}function fU(r){return PC.createHash("sha256").update(r,"utf8").digest().toString("base64url").replaceAll(/[-_=]/g,"")}function gU(r){let e=r?.trim()??"";return e&&e.replace(uU,"_").replace(/\.+/g,"_").slice(0,_g)||Zr.productName}async function kC(){let r=await C.new();r.assertJava();let e=r.javaPath,t=r.sdkPath;f.info(`\u8BFB\u53D6SDK\u6839\u76EE\u5F55\uFF1A${t}`);let n=mu.join(t,"default","openharmony","toolchains","lib","hap-sign-tool.jar");try{await Ha.access(n)}catch(i){throw new Error(`Sign tool jar not found: ${n}`,{cause:i})}return{javaPath:e,jarPath:n}}async function hU(r){let{javaPath:e,jarPath:t}=await kC(),n=["-jar",t,CC.GENERATE_KEYPAIR,"-keyAlias",r.keyAlias,"-keyAlg",r.keyAlg,"-keySize",r.keySize,"-keystoreFile",r.keystoreFile,"-keystorePwd",r.keystorePwd];r.keyPwd&&n.push("-keyPwd",r.keyPwd),r.pwdInputMode&&n.push("-pwdInputMode",r.pwdInputMode);let i=n.map((o,s)=>s>0&&["-keyPwd","-keystorePwd"].includes(n[s-1])?"******":o);return f.debug("generate-keypair \u547D\u4EE4\uFF08\u8131\u654F\uFF09\uFF1A",i.join(" ")),[e,...n]}async function yU(r){let{javaPath:e,jarPath:t}=await kC(),n=["-jar",t,CC.GENERATE_CSR,"-keyAlias",r.keyAlias,"-subject",r.subject,"-signAlg",r.signAlg,"-keystoreFile",r.keystoreFile,"-keystorePwd",r.keystorePwd];r.outFile&&n.push("-outFile",r.outFile),r.keyPwd&&n.push("-keyPwd",r.keyPwd),r.pwdInputMode&&n.push("-pwdInputMode",r.pwdInputMode);let i=n.map((o,s)=>s>0&&["-keyPwd","-keystorePwd"].includes(n[s-1])?"******":o);return f.debug("generate-csr \u547D\u4EE4\uFF08\u8131\u654F\uFF09\uFF1A",i.join(" ")),[e,...n]}async function wU(r){f.info("\u5F00\u59CB\u751F\u6210 P12 \u5BC6\u94A5\u5E93"),pU(r);let e=await hU(r),t=await Es(e[0],e.slice(1));if(t.exitCode!==0){let n=t.stderr||t.stdout||"Unknown tool error";throw new Error(`An error occurred while generating the private key P12, exit code${t.exitCode}\uFF1A${n}`)}return f.info("\u751F\u6210P12\u547D\u4EE4\u6267\u884C\u5B8C\u6210"),t}async function vU(r){f.info("\u5F00\u59CB\u751F\u6210 CSR \u8BC1\u4E66\u8BF7\u6C42"),mU(r);let e=await yU(r),t=await Es(e[0],e.slice(1));if(t.exitCode!==0){let n=t.stderr||t.stdout||"Unknown tool error";throw new Error(`An error occurred while generating the CSR, exit code${t.exitCode}\uFF1A${n}`)}return f.info("\u751F\u6210CSR\u547D\u4EE4\u6267\u884C\u5B8C\u6210"),t}function bU(r=dU){return PC.randomBytes(r).toString("base64url").replaceAll(/[-_=]/g,"")}async function SU(){let r=cU.homedir();try{await Ha.access(r)}catch(t){throw new Error("Invalid user path;",{cause:t})}let e=mu.join(r,".ohos","config");try{await Ha.mkdir(e,{recursive:!0,mode:448})}catch(t){throw new Error(`Failed to create directory ${e}`,{cause:t})}return f.info(`\u7B7E\u540D\u914D\u7F6E\u76EE\u5F55\u5C31\u7EEA\uFF1A${e}`),e}async function Ue(r,e,t,n){let i=gU(r),o=mu.basename(e),s=fU(e),c=`${i}_${o}_${s}${n==="release"?"_release":""}=.${t}`,l=await SU();return mu.join(l,c)}function EU(r){let e;try{e=W.discover(r).rootDir}catch(t){throw new Error(`Current directory ${r} is not a valid project root`,{cause:t})}return e}async function PU(r){try{await Ha.access(r)}catch(e){throw new Error(`Project directory ${r} is not accessible, missing read/write permissions`,{cause:e})}}async function CU(r){try{await Ha.access(r)}catch(e){throw new Error(`P12 file ${r} does not exist, terminating CSR generation.`,{cause:e})}}async function $g(r,e,t,n){let i=process.cwd(),o=EU(i);await PU(o),f.info(`\u8BC6\u522B\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${o}`);let s=bU(),a=n==="release",c=a?"releaseKey":Zr.keyAlias,l=a?"CN=ReleaseKey":Zr.csrSubject,d=await Ue(r??"",o,"p12",n),g=await Ue(r??"",o,"csr",n);return console.log("Start generating p12"),await wU({keyAlias:e?.keyAlias??c,keyPwd:s,keyAlg:e?.keyAlg??Zr.keyAlg,keySize:e?.keySize??Zr.keySize,keystoreFile:d,keystorePwd:s}),await CU(d),console.log("Start generating csr"),await vU({subject:t?.subject??l,outFile:g,keyAlias:e?.keyAlias??c,keyPwd:s,signAlg:t?.signAlg??Zr.signAlg,keystoreFile:d,keystorePwd:s}),{p12FilePath:d,csrFilePath:g,keyPwd:s,keyAlias:e?.keyAlias??c}}var RU=["p12","cer","csr","p7b"];async function Fg(r,e,t){for(let n of RU){let i=await Ue(r,e,n,t);await kU.rm(i,{force:!0})}}function jg(r){let e;try{e=DU(r,"utf-8")}catch{throw new Error(R.ERR_CERT_INVALIDATE)}if(!Re.CERT_PATTERN.test(e))throw new Error(R.ERR_CERT_INVALIDATE)}async function fu(r,e,t){return{certPath:await Ue(r,e,"cer",t),csrPath:await Ue(r,e,"csr",t),p12Path:await Ue(r,e,"p12",t),profilePath:await Ue(r,e,"p7b",t)}}async function Hg(r,e,t){let n=e??"",i=W.discover(process.cwd()).rootDir;await Fg(n,i,t);let o=Tg(r.teamId,t==="release"),s=await pu(r,o);if(s&&!await Ng(r,s.id))throw new Error(R.ERR_DOWNLOAD_CER);let a=await $g(e,void 0,void 0,t),c;try{c=xU(a.csrFilePath,"utf-8")}catch{throw new Error(R.ERR_READ_CSR)}console.log("Start generating certificate");let l=t==="release"?Re.CERT_TYPE_RELEASE:Re.CERT_TYPE_DEBUG;await Mg(r,c,o,l);let d=await pu(r,o);if(!d)throw new Error(R.ERR_DOWNLOAD_CER);let g=await Lg(r,d.certObjectId);if(!g)throw new Error(R.ERR_DOWNLOAD_CER);let y=await Ue(n,i,"cer",t);await ja(g.newUrl,y,g.sha256),jg(y);let E=await Ue(n,i,"p7b",t);return{p12FilePath:a.p12FilePath,csrFilePath:a.csrFilePath,cerFilePath:y,profileFilePath:E,certId:d.id,keyAlias:a.keyAlias,keyPwd:a.keyPwd,storePassword:a.keyPwd}}import Cu from"crypto";import jn from"fs";import*as HC from"path";import KU from"json5";import{execa as $C}from"execa";import FC from"node-forge";import{createCipheriv as AU,createDecipheriv as IU,pbkdf2Sync as TU,randomBytes as Vg}from"crypto";import{promises as Di}from"fs";import{dirname as OU,join as Qt}from"path";var gu=3,Ua=16,NU=1e4,DC="material",MU=new Uint8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]),IC="aes-128-gcm",ki=12,hu=16,_n=4;function Ug(r){return new Uint8Array(Vg(r))}function LU(r){return Vg(r).toString("hex")}function _U(...r){if(r.length===0)return new Uint8Array(0);let e=r[0].length,t=new Uint8Array(e);for(let n=0;n<e;n++){let i=0;for(let o of r)i^=o[n];t[n]=i}return t}function RC(r,e,t=NU,n=Ua){let i=[...r,MU],o=_U(...i),s=Buffer.from(o).toString("utf8"),a=Buffer.from(s,"utf8"),c=TU(a,e,t,n,"sha256");return new Uint8Array(c)}function xC(r,e){let t=Vg(ki),n=AU(IC,r,t),i=Buffer.concat([n.update(e),n.final()]),o=n.getAuthTag(),s=Buffer.concat([i,o]),a=s.length,c=Buffer.alloc(_n+ki+s.length);return c.writeUInt32BE(a,0),t.copy(c,_n),s.copy(c,_n+ki),c}function AC(r,e){if(e.length<_n+ki+hu)throw new Error("Ciphertext too short");let t=e.readUInt32BE(0),n=e.subarray(_n,_n+ki),i=e.subarray(_n+ki,_n+ki+t);if(i.length<hu)throw new Error("Ciphertext too short for auth tag");let o=i.subarray(0,i.length-hu),s=i.subarray(i.length-hu),a=IU(IC,r,n);return a.setAuthTag(s),Buffer.concat([a.update(o),a.final()])}async function $U(r){try{await Di.rm(r,{recursive:!0,force:!0})}catch{}}async function Bg(r){let e=await Di.readdir(r),t=e.filter(n=>n!==".DS_Store");if(t.length!==1)throw new Error(`Expected exactly 1 file in ${r}, but found ${t.length} (filtered from ${e.length})`);return Di.readFile(Qt(r,t[0]))}async function Wg(r,e){let t=LU(Ua),n=Qt(r,t);return await Di.writeFile(n,e,{mode:384}),t}var $n=class{static keyChain=Promise.resolve();static async generateMaterial(e){let t=Qt(e,DC);await $U(t);let n=Qt(t,"ac"),i=Qt(t,"ce");await Di.mkdir(n,{recursive:!0,mode:448}),await Di.mkdir(i,{recursive:!0,mode:448});for(let d=0;d<gu;d++)await Di.mkdir(Qt(t,"fd",String(d)),{recursive:!0,mode:448});let o=Ug(Ua),s=[];for(let d=0;d<gu;d++)s.push(Ug(Ua));let a=Ug(Ua),c=RC(s,o),l=xC(c,a);await Wg(n,o),await Wg(i,l);for(let d=0;d<gu;d++){let g=Qt(t,"fd",String(d));await Wg(g,s[d])}return a}static async readMaterial(e){let t=Qt(e,DC),n=Qt(t,"ac"),i=new Uint8Array(await Bg(n)),o=[];for(let d=0;d<gu;d++){let g=Qt(t,"fd",String(d)),y=await Bg(g);o.push(new Uint8Array(y))}let s=Qt(t,"ce"),a=await Bg(s),c=RC(o,i),l=AC(c,a);return new Uint8Array(l)}static async getStoreKey(e){let t,n=this.keyChain;this.keyChain=new Promise(i=>{t=i}),await n;try{let i=OU(e);try{return await this.readMaterial(i)}catch{return await this.generateMaterial(i)}}finally{t()}}static async encryptedPassword(e,t){let n=await this.getStoreKey(t),i=Buffer.from(e,"utf8");return xC(n,i).toString("hex")}static async decryptPassword(e,t){if(!e)return"";let n=await this.getStoreKey(t),i=Buffer.from(e,"hex");return AC(n,i).toString("utf8")}};import LC from"fs";import Eu from"path";import WU from"json5";import*as yu from"fs";import*as TC from"path";function wu(r){let e=TC.resolve(r);if(!yu.existsSync(e))throw new Error(`SDK info file not found: ${e}`);let t;try{t=yu.readFileSync(e,"utf-8")}catch(s){throw new Error(`Failed to read SDK info file: ${e}`,{cause:s})}let n;try{n=JSON.parse(t)}catch(s){throw new Error(`Invalid JSON in SDK info file: ${e}`,{cause:s})}let i=n?.data?.apiVersion;if(i==null||i==="")throw new Error(`Missing data.apiVersion in SDK info file: ${e}`);let o=Number(i);if(!Number.isFinite(o))throw new Error(`Invalid data.apiVersion in SDK info file: ${String(i)}`);return o}import*as Zo from"fs";import*as dt from"path";import{debuglog as Xo}from"util";var OC={"acl.SYSTEM_FLOAT_WINDOW.instead.name":"PiPWindow","acl.READ_CONTACTS.instead.name":"contact.selectContacts","acl.READ_IMAGEVIDEO.instead.name":"PhotoViewPicker","acl.WRITE_IMAGEVIDEO.instead.name":"SaveButton","acl.READ_AUDIO.instead.name":"AudioViewPicker","acl.WRITE_AUDIO.instead.name":"AudioViewPicker","acl.READ_PASTEBOARD.instead.name":"PasteButton"};function FU(r){return Object.prototype.hasOwnProperty.call(OC,r)}function vu(r){if(FU(r))return OC[r]}var NC={DUPLICATE_PERMISSION:"Duplicate permissions detected. Make sure each permission is unique in the same module and try again."};import{fileURLToPath as jU}from"url";var Su=class{permissionName;permissionDisplayName;minSupportApiLevel;permissionInsteadName;permissionHelpUrlKey;constructor(e={}){this.permissionName=e.permissionName??"",this.permissionDisplayName=e.permissionDisplayName??"",this.minSupportApiLevel=e.minSupportApiLevel??"",this.permissionInsteadName=e.permissionInsteadName,this.permissionHelpUrlKey=e.permissionHelpUrlKey}};function bu(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function MC(r){return r==null||r.length===0}function HU(r){return!MC(r)}function Gg(r,e){let t=r[e];return typeof t=="string"?t:t==null?"":String(t)}function UU(r,e){let t=r[e];if(typeof t=="boolean")return t;if(typeof t=="number")return t!==0;if(typeof t=="string"){let n=t.trim().toLowerCase();return n==="true"||n==="1"}return!1}function BU(r,e){let t=r[e];if(typeof t=="number")return Math.trunc(t);if(typeof t=="string"){let n=Number.parseInt(t,10);return Number.isNaN(n)?0:n}return 0}var Fn=class{static MIN_API_TO_FIND_ACL_IN_SDK=23;static ACL_PREFIX="ohos.permission.";static ACL_PERMISSIONS_CONFIG_PATH=dt.join("aclPermission","aclPermissionsInfo.json");static ACL_HAVE_INSTEAD_NAME=new Set(["ohos.permission.SYSTEM_FLOAT_WINDOW","ohos.permission.READ_CONTACTS","ohos.permission.READ_IMAGEVIDEO","ohos.permission.WRITE_IMAGEVIDEO","ohos.permission.READ_AUDIO","ohos.permission.WRITE_AUDIO","ohos.permission.READ_PASTEBOARD"]);static ACL_AVAILABLE_LEVEL_VALUE="system_basic";static ACL_AVAILABLE_TYPE_VALUE="NORMAL";static ACL_AVAILABLE_LEVEL_KEY="availableLevel";static ACL_AVAILABLE_TYPE_KEY="availableType";static ACL_PROVISION_ENABLE_KEY="provisionEnable";static ACL_NAME_KEY="name";static ACL_CONFIG_PREFIX="acl.";static ACL_INSTEAD_NAME_SUFFIX=".instead.name";static ACL_HELP_URL_KEY_SUFFIX=".help.key";static ACL_DEFINE_PERMISSION_KEY="definePermissions";static ACL_SINCE_KEY="since";static PERMISSION_DEFINITIONS_RELATIVE_PATH=dt.join("lib","PermissionDefinitions.json");static INCLUDE_ACL_PERMISSIONS=new Set(["ohos.permission.FILE_ACCESS_PERSIST","ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY","ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY"]);static EXCLUDE_ACL_PERMISSIONS=new Set(["ohos.permission.READ_DOCUMENT","ohos.permission.WRITE_DOCUMENT"]);static handleSpecificAclPermissions(){this.addAclWhiteList(this.INCLUDE_ACL_PERMISSIONS),this.addAclBlackList(this.EXCLUDE_ACL_PERMISSIONS)}static aclPermissionInfoMap=new Map;static aclPermissionNamesMap=new Map;static aclWhiteList=new Set;static aclBlackList=new Set;static builtInConfigTextLoader;static initAclPermission(e,t){let n=e.rootDir,i=this.getOrCreateSet(this.aclPermissionNamesMap,n),o=this.getOrCreateSet(this.aclPermissionInfoMap,n);i.clear(),o.clear();let s=dt.join(t.sdkPath,"default","sdk-pkg.json"),a=wu(s);this.MIN_API_TO_FIND_ACL_IN_SDK-a>0?this.initAclPermissionFromBuiltInConfig(i,o):this.initAclPermissionFromSDK(t,i,o)}static getAclPermissionInfos(e){return this.aclPermissionInfoMap.get(e.rootDir)??new Set}static getAclPermissionNames(e){return this.aclPermissionNamesMap.get(e.rootDir)??new Set}static addAclWhiteList(e){for(let t of e)this.aclWhiteList.add(t)}static addAclBlackList(e){for(let t of e)this.aclBlackList.add(t)}static getOrCreateSet(e,t){let n=e.get(t);return n||(n=new Set,e.set(t,n)),n}static readBuiltInConfigText(){if(this.builtInConfigTextLoader)return this.builtInConfigTextLoader();let e=dt.join(this.getResourcesDir(),this.ACL_PERMISSIONS_CONFIG_PATH);if(Zo.existsSync(e))return Zo.readFileSync(e,"utf-8")}static getResourcesDir(){let e=import.meta.url,t=jU(e);if(t.includes("dist")){let s=dt.dirname(t),a=dt.dirname(s);return dt.join(a,"src","resources")}let n=dt.dirname(t),i=dt.dirname(n),o=dt.dirname(i);return dt.join(o,"src","resources")}static initAclPermissionFromBuiltInConfig(e,t){let n;try{n=this.readBuiltInConfigText()}catch{Xo("read builtin acl permission failed.");return}if(n!==void 0)try{let i=JSON.parse(n),s=(Array.isArray(i)?i:bu(i)?Object.values(i):[]).filter(bu).map(a=>new Su(a));s.forEach(a=>{let c=a.permissionInsteadName;HU(c)&&(a.permissionInsteadName=vu(c)),e.add(a.permissionName)}),s.forEach(a=>{t.add(a)})}catch(i){Xo(`failed to parse aclPermissionsInfo.json: ${i}`)}}static initAclPermissionFromSDK(e,t,n){let i=this.parsePermissionDefinitionFile(e);i&&i.forEach(o=>{if(!bu(o))return;let s=o,a=Gg(s,this.ACL_NAME_KEY);this.isAclPermission(s,a)&&(MC(a)||(this.generateAclInfos(n,a,s),t.add(a)))})}static isAclPermission(e,t){return this.aclWhiteList.has(t)?!0:this.aclBlackList.has(t)||Gg(e,this.ACL_AVAILABLE_LEVEL_KEY)!==this.ACL_AVAILABLE_LEVEL_VALUE||Gg(e,this.ACL_AVAILABLE_TYPE_KEY)!==this.ACL_AVAILABLE_TYPE_VALUE?!1:UU(e,this.ACL_PROVISION_ENABLE_KEY)}static generateAclInfos(e,t,n){let i=new Su;i.permissionName=t;let o=t.startsWith(this.ACL_PREFIX)?t.slice(this.ACL_PREFIX.length):t;i.permissionDisplayName=o;let s=BU(n,this.ACL_SINCE_KEY);i.minSupportApiLevel=String(s),this.handleInsteadName(i,o),e.add(i)}static parsePermissionDefinitionFile(e){let t=dt.join(e.sdkPath,"default","openharmony","toolchains",this.PERMISSION_DEFINITIONS_RELATIVE_PATH);if(!Zo.existsSync(t))return;let n;try{n=Zo.readFileSync(t,"utf-8")}catch(s){Xo(`failed to load permissionDefinitions.json: ${s}`);return}let i;try{let s=JSON.parse(n);if(!bu(s)){Xo("json object is null");return}i=s}catch(s){Xo(`failed to parse permissionDefinitions.json: ${s}`);return}let o=i[this.ACL_DEFINE_PERMISSION_KEY];if(!Array.isArray(o)){Xo("definePermissions is not an array");return}return o}static handleInsteadName(e,t){this.ACL_HAVE_INSTEAD_NAME.has(e.permissionName)&&(e.permissionInsteadName=vu(`${this.ACL_CONFIG_PREFIX}${t}${this.ACL_INSTEAD_NAME_SUFFIX}`),e.permissionHelpUrlKey=vu(`${this.ACL_CONFIG_PREFIX}${t}${this.ACL_HELP_URL_KEY_SUFFIX}`))}};function Pu(r,e){let t=new Set,n=new Set;Fn.handleSpecificAclPermissions(),Fn.initAclPermission(r,e);for(let i of r.profile.modules){let o=_C(i,r,e,n,Eu.join("src","main"));for(let a of o)t.add(a);let s=_C(i,r,e,n,Eu.join("src","ohosTest"));for(let a of s)t.add(a)}return VU(n),t}function VU(r){if(r.size>0)throw new Error(NC.DUPLICATE_PERMISSION)}function _C(r,e,t,n,i){let o=qU(e.rootDir,r,i);if(o==null)return new Set;let s=[];for(let y of o){if(typeof y!="object"||y===null)continue;let E=GU(y,"name");E&&s.push(E)}let a=new Set(s);a.size!==s.length&&n.add(r.name);let c=Eu.join(t.sdkPath,"default","sdk-pkg.json"),l=wu(c),d=Fn.getAclPermissionInfos(e),g=new Set(Array.from(d).filter(y=>{let E=Number(y.minSupportApiLevel);return Number.isFinite(E)&&E<=l}).map(y=>y.permissionName));for(let y of Array.from(a))g.has(y)||a.delete(y);return a}function GU(r,e){let t=r[e];return typeof t=="string"?t:""}function qU(r,e,t){let n=Eu.join(r,e.srcPath,t,"module.json5"),i=zU(n);if(i==null)return null;let o=JU(i,"module");return o==null?null:YU(o,"requestPermissions")}function zU(r){try{if(!LC.existsSync(r))return null;let e=LC.readFileSync(r,"utf-8");return WU.parse(e)}catch{return null}}function JU(r,e){if(r==null||typeof r!="object")return null;let t=r[e];return t!=null&&typeof t=="object"&&!Array.isArray(t)?t:null}function YU(r,e){if(r==null||typeof r!="object")return null;let t=r[e];return Array.isArray(t)?t:null}var zg=class{verifyStorePassword(e,t){try{let n=jn.readFileSync(e),i=FC.asn1.fromDer(n.toString("binary"));return FC.pkcs12.pkcs12FromAsn1(i,t),!0}catch{return!1}}getLocalCerFingerprints(e){let n=jn.readFileSync(e,"utf-8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g);if(n&&n.length>0)return n.map(i=>this.formatFp(new Cu.X509Certificate(i).fingerprint256));try{return[this.formatFp(new Cu.X509Certificate(jn.readFileSync(e)).fingerprint256)]}catch{return[]}}getLocalCerExpiry(e,t){if(!t)return null;let i=jn.readFileSync(e,"utf-8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g)??[];for(let o of i)try{let s=new Cu.X509Certificate(o);if(this.formatFp(s.fingerprint256)===t){let a=new Date(s.validTo);return isNaN(a.getTime())?null:a}}catch{}return null}formatFp(e){let t=e.replace(/:/g,"");return t.match(/.{2}/g)?.join(":")??t}};function XU(r,e){let t=jn.readFileSync(r,"utf-8"),n=ZU(t),i=null;if(n)try{i=JSON.parse(n)}catch{i=null}let o=i?.["bundle-info"]??{},s=e==="release"?"distribution-certificate":"development-certificate";return{rawContent:t,bundleNameInProfile:qg(o["bundle-name"]),expiryDate:QU(i?.validity?.["not-after"]),cerFingerprintInProfile:e1(qg(o[s])),deviceUdidsInProfile:t1(i?.["debug-info"]?.["device-ids"]),aclPermissionsInProfile:r1(i?.acls?.["allowed-acls"]),teamIdInProfile:qg(o["developer-id"])}}function ZU(r){let e=r.indexOf("{");if(e<0)return null;let t=0,n=-1,i=!1,o=!1;for(let s=e;s<r.length;s++){let a=r[s];if(i){o?o=!1:a==="\\"?o=!0:a==='"'&&(i=!1);continue}if(a==='"')i=!0;else if(a==="{")t++;else if(a==="}"&&(t--,t===0)){n=s;break}}return n<0?null:r.slice(e,n+1)}function QU(r){if(typeof r!="number"||!Number.isFinite(r))return null;let e=new Date(r*1e3);return isNaN(e.getTime())?null:e}function e1(r){if(!r)return null;try{let t=new Cu.X509Certificate(r).fingerprint256.replace(/:/g,"");return t.match(/.{2}/g)?.join(":")??t}catch{return null}}function t1(r){if(!Array.isArray(r))return[];let e=[];for(let t of r)if(typeof t=="string"){let n=t.toUpperCase();e.includes(n)||e.push(n)}return e}function r1(r){if(!Array.isArray(r))return[];let e=[];for(let t of r)typeof t=="string"?e.push(t):t&&typeof t=="object"&&typeof t.name=="string"&&e.push(t.name);return[...new Set(e)].sort()}function qg(r){return typeof r=="string"?r:null}var Ba=class r{static async shouldRegenerate(e,t){let n=await r.#e(e,t);return r.#t(n)??r.#r(n)??r.#n(n)??r.#i(n)??r.#o(n)??r.#s(n)??(n.type==="release"?null:r.#a(n))??r.#c(n)??r.#l(n)??r.#d(n)??await r.#u(n)??r.#p()}static async#e(e,t){let n=e.force,i=e.teamId,o=e.productName??"default",s=e.type,a=W.discover(process.cwd()),c=a.rootDir,[l,d]=await Promise.all([n1(o,c,s),s==="release"?Promise.resolve([]):o1(t.hdcPath)]),g=null;if(jC(l).allExist)try{g=XU(l.profileFile,s)}catch{}return{force:n,teamId:i,productName:o,projectPath:c,type:s,materialPaths:l,bundleName:a.getBundleName(o),deviceUdids:d,storePassword:await i1(c,o,l.storeFile,s),localAclPermissions:[...Pu(a,t)].sort(),hapSignTool:new zg,profileInfo:g}}static#t(e){return e.force?(m("[reGenerateSign] --force flag set, skipping all checks"),{shouldRegenerate:!0,reason:"--force flag set",checkDetails:vt({force:!0})}):null}static#r(e){let t=jC(e.materialPaths);return t.allExist?null:(m(`[reGenerateSign] missing files: ${t.missing.join(",")}`),{shouldRegenerate:!0,reason:`Missing files: ${t.missing.join(", ")}`,checkDetails:vt({allFilesExist:!1,missingFiles:t.missing})})}static#n(e){return(e.profileInfo?.rawContent??"").trim().length>0?null:(m("[reGenerateSign] profile content is empty"),{shouldRegenerate:!0,reason:"Profile file content is empty",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!1})})}static#i(e){let t=e.profileInfo?.expiryDate;return!t||t>=new Date?null:(m(`[reGenerateSign] profile expired at ${t.toISOString()}`),{shouldRegenerate:!0,reason:`Profile expired at ${t.toISOString()}`,checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!1})})}static#o(e){let t=e.profileInfo?.bundleNameInProfile;return t&&t===e.bundleName?null:(m(`[reGenerateSign] bundleName mismatch \u2014 current=${e.bundleName}, profile=${t}`),{shouldRegenerate:!0,reason:`bundleName mismatch: current=${e.bundleName}, in profile=${t}`,checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!1})})}static#s(e){let t=e.profileInfo?.teamIdInProfile;return t&&t===e.teamId?null:(m(`[reGenerateSign] teamId mismatch \u2014 current=${e.teamId}, profile=${t}`),{shouldRegenerate:!0,reason:`teamId mismatch: current=${e.teamId}, in profile=${t}`,checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!1})})}static#a(e){let t=a1(e.profileInfo?.deviceUdidsInProfile??[],e.deviceUdids);return t.allPresent?null:(m(`[reGenerateSign] missing device UDIDs: ${t.missing.join(",")}`),{shouldRegenerate:!0,reason:`Device UDID(s) not in profile: ${t.missing.join(", ")}`,checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!1,missingDeviceUdids:t.missing})})}static#c(e){return c1(e.localAclPermissions,e.profileInfo?.aclPermissionsInProfile??[])?null:(m("[reGenerateSign] ACL permissions mismatch"),{shouldRegenerate:!0,reason:"ACL permissions mismatch between project and profile",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!1})})}static#l(e){let t=e.hapSignTool.getLocalCerFingerprints(e.materialPaths.cerFile),n=e.profileInfo?.cerFingerprintInProfile;return n&&t.includes(n)?null:(m("[reGenerateSign] certificate mismatch"),{shouldRegenerate:!0,reason:"Certificate mismatch between profile and local .cer file",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!1})})}static#d(e){let t=e.profileInfo?.cerFingerprintInProfile,n=e.hapSignTool.getLocalCerExpiry(e.materialPaths.cerFile,t);return!n||n>=new Date?null:(m(`[reGenerateSign] local certificate expired at ${n.toISOString()}`),{shouldRegenerate:!0,reason:`Local certificate expired at ${n.toISOString()}`,checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!1})})}static async#u(e){return e.storePassword?e.hapSignTool.verifyStorePassword(e.materialPaths.storeFile,e.storePassword)?null:(m("[reGenerateSign] keystore password verification failed"),{shouldRegenerate:!0,reason:"Keystore password verification failed (storeFile may be corrupted or password changed)",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!1})}):(m("[reGenerateSign] no stored keystore password"),{shouldRegenerate:!0,reason:"No stored keystore password available for verification",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!1})})}static#p(){return m("[reGenerateSign] all checks passed \u2014 skip regeneration"),{shouldRegenerate:!1,reason:"",checkDetails:vt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!0})}}};async function n1(r,e,t){let[n,i,o,s]=await Promise.all([Ue(r,e,"p12",t),Ue(r,e,"csr",t),Ue(r,e,"cer",t),Ue(r,e,"p7b",t)]);return{storeFile:n,csrFile:i,cerFile:o,profileFile:s}}async function i1(r,e,t,n){let i=HC.join(r,"build-profile.json5");if(!jn.existsSync(i))return;let o;try{o=KU.parse(jn.readFileSync(i,"utf-8"))}catch{return}let s=n==="release"?`${e}_release`:e,l=(o?.app?.signingConfigs??[]).find(d=>d.name===s)?.material?.storePassword;if(l)try{return await $n.decryptPassword(l,t)}catch{return}}async function o1(r){m(`Executing: ${r} list targets`);let{stdout:e}=await $C(r,["list","targets"],{stdio:["ignore","pipe","pipe"]}),t=[];for(let i of e.split(`
1380
- `)){let o=i.trim();if(!o||o.startsWith("[Empty]"))continue;let s=o.split(/\s+/),a=s[0],c=s.length>=2?s[1]:"device";a&&!a.startsWith("[Empty]")&&c.toLowerCase()!=="unauthorized"&&t.push(a)}let n=[];for(let i of t)try{m(`Executing: ${r} -t ${i} shell bm get -u`);let{stdout:o}=await $C(r,["-t",i,"shell","bm","get","-u"],{stdio:["ignore","pipe","pipe"]}),s=s1(o);s&&n.push(s)}catch{m(`[reGenerateSign] Failed to get UDID for ${i}, skipping`)}return n}function s1(r){let e=r.trim();if(!e)return null;let t=e.split(`
1381
- `);for(let i=0;i<t.length-1;i++)if(t[i].includes("udid of current device is")){let s=t[i+1].trim().match(/^[A-Fa-f0-9]{64}$/);if(s)return s[0].toUpperCase()}let n=e.match(/[A-Fa-f0-9]{64}/);return n?n[0].toUpperCase():null}function jC(r){let e=[r.storeFile,r.csrFile,r.cerFile,r.profileFile],t=[];for(let n of e)jn.existsSync(n)||t.push(n);return{allExist:t.length===0,missing:t}}function a1(r,e){let t=[];for(let n of e)r.includes(n)||t.push(n);return{allPresent:t.length===0,missing:t}}function c1(r,e){let t=[...r].sort(),n=[...e].sort();return t.length!==n.length?!1:t.every((i,o)=>i===n[o])}function vt(r){let e={force:!1,allFilesExist:!1,missingFiles:[],profileContentNotEmpty:!1,profileNotExpired:!1,bundleNameMatched:!1,teamIdMatched:!1,allDevicesInProfile:!1,missingDeviceUdids:[],aclMatched:!1,cerMatched:!1,cerNotExpired:!1,storePasswordValid:!1};return r.force?{...e,force:!0}:{...e,...r,force:!1}}import{debuglog as Jg}from"util";import{execa as Yg}from"execa";async function BC(r,e){let t=await ku(r);if(!t)throw new Error(R.DEVICE_LIST_EMPTY);let n=await u1(e);if(t.length===0)for(let s of n)await l1(r,s.udid,s.deviceName);else for(let s of n)await d1(r,t,s.udid,s.deviceName);let o=(await ku(r)).map(s=>s.id);if(o.length===0)throw new Error(R.DEVICE_LIST_EMPTY);return o}async function l1(r,e,t){await GC(r,e,WC(t))}async function d1(r,e,t,n){for(let i=0;i<e.length;i++){if(t===e[i].udid)return;if(i===e.length-1){await GC(r,t,WC(n));return}}}function WC(r){switch(r){case"liteWearable":return"1";case"wearable":return"2";case"tv":return"3";default:return"4"}}async function UC(r,e=1,t=100){let n=`${me.BASE_URL}${me.DEVICE_LIST_PATH}?encodeFlag=0&start=${e}&pageSize=${t}`,i=qC(r),o=await F.get(n,{headers:i});if(!o)throw Jg("query devices failed: response is null"),new Error(R.ERROR_WHILE_ADD_DEVICE);if(o.statusCode!==200)throw VC(o.statusCode,o.statusText,o.data);let s=JSON.parse(o.data);if(!s||!s.list)throw Jg("query devices failed: response list is null"),new Error(s.ret?.msg||R.ERROR_WHILE_ADD_DEVICE);return{deviceList:s.list,total:s.totalCount||0}}function VC(r,e,t){return r===Zt.FORBIDDEN?e===Oe.OPENPROXY_BLOCKED_URL?new Error(R.ERR_CERT_NETWORK_ERROR):new Error(R.ERR_FORBIDDEN):r===Zt.UNAUTHORIZED?new Error(R.ERR_UNAUTHORIZED):t.includes(Oe.DEVICE_EXCEEDS_LIMIT_CODE)?new Error(R.DEVICE_LIMIT_REACHED):new Error(R.ERROR_WHILE_ADD_DEVICE)}async function ku(r){let t=await UC(r,1,100);if(!t||!t.deviceList||t.deviceList.length===0)return[];let n=[...t.deviceList],i=t.total,o=Math.floor(i/100)+(i%100===0?0:1);for(let s=2;s<=o;s++){let a=await UC(r,s,100);if(!a||!a.deviceList||a.deviceList.length===0)break;n.push(...a.deviceList)}return n}async function GC(r,e,t){let n=`${me.BASE_URL}${me.DEVICE_ADD_PATH}`,i=qC(r),s={deviceName:`auto_sign_device_No.${Math.floor(Math.random()*3e3)}${Date.now()}`,udid:e,deviceType:t},a=await F.postAllowFailure(n,{headers:i,params:s});if(!a)throw Jg("add device failed: response is null"),new Error(R.ERROR_WHILE_ADD_DEVICE);if(a.statusCode!==200)throw VC(a.statusCode,a.statusText,a.data);let c=a.data,l=JSON.parse(a.data);if(!l||!l.ret||l.ret.code!==0)throw c.includes(Oe.DEVICE_EXCEEDS_LIMIT_CODE)?new Error(R.DEVICE_LIMIT_REACHED):c.includes(Oe.DEVICE_NAME_REPEAT_CODE)?new Error(R.DEVICE_NAME_REPEAT):new Error(R.ERROR_WHILE_ADD_DEVICE)}function qC(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}async function u1(r){let{stdout:e}=await Yg(r,["list","targets"],{stdio:["ignore","pipe","pipe"]}),t=[];for(let i of e.split(`
1382
- `)){let o=i.trim();if(!o||o.startsWith("[Empty]"))continue;let s=o.split(/\s+/),a=s[0],c=s.length>=2?s[1]:"device";a&&!a.startsWith("[Empty]")&&c.toLowerCase()!=="unauthorized"&&t.push(a)}let n=[];for(let i of t)try{let o=await p1(i,r),s=await m1(i,r);o.length>0&&n.push({id:"",udid:o,deviceName:s})}catch{m(`Failed to get device info for ${i}, skipping`)}return n}async function p1(r,e){let{stdout:t}=await Yg(e,["-t",r,"shell","bm","get","-u"],{stdio:["ignore","pipe","pipe"]}),n=t.trim();if(!n)return"";let i=n.split(`
1383
- `);for(let s=0;s<i.length-1;s++)if(i[s].includes("udid of current device is")){let c=i[s+1].trim().match(/^[A-Fa-f0-9]{64}$/);if(c)return c[0].toUpperCase()}let o=n.match(/[A-Fa-f0-9]{64}/);return o?o[0].toUpperCase():""}async function m1(r,e){let{stdout:t}=await Yg(e,["-c","-t",r,"shell","getprop","hw_sc.build.os.deviceType"],{stdio:["ignore","pipe","pipe"]});return f1(t)}function f1(r){let e=r.trim();return!e||e.includes("inaccessible")?"phone":r.includes("liteWearable")?"liteWearable":r.includes("wearable")?"wearable":r.includes("tv")?"tv":"phone"}import Ri from"fs";import{createHash as g1}from"crypto";import{debuglog as Ai}from"util";import{Buffer as JC}from"buffer";import{createPublicKey as h1,X509Certificate as Kg}from"crypto";import{readFileSync as y1}from"fs";import xi from"node-forge";async function YC(r,e){console.log("Start generating profile");let{productName:t,bundleName:n,projectPath:i,aclPermissionList:o,allDeviceIds:s,certIds:a,keyAlias:c,keyPwd:l}=e,d=e.type==="release";if(!d&&(s==null||s.length===0))throw new Error(R.DEVICE_LIST_EMPTY);let g=d?me.PROVISION_ADD_REAL_PATH:me.PROVISION_ADD_TEST_PATH,y=`${me.BASE_URL}${g}`,E=w1(t,n),j=await b1(r,y,a||[],n,s??[],E,o||[]);if(!j||!j.profileInfo||!j.profileInfo.provisionFileUrl)throw Ai("add provision failed, the provision file url is null"),new Error(R.ADD_PROFILE_FAIL);let ye=j.profileInfo,er=(await C1(r,ye.provisionFileUrl)).urlList,Un=j.profileInfo.id;if(er&&er.length>0){let Bn=await fu(t,i,e.type),Wn=Bn.profilePath;if(!await k1(er,Wn))throw await zC(r,Un),new Error(R.ERROR_WHILE_DOWNLOAD_PROFILE);if(await zC(r,Un),Ri.existsSync(Bn.certPath)&&Ri.existsSync(Wn)&&Ri.existsSync(Bn.p12Path)){let fk=Ri.readFileSync(Bn.certPath,"utf8"),gk=Ri.readFileSync(Wn,"utf8");return D1(gk,fk,Bn.p12Path,c,l)||P1(Wn),Wn}}throw new Error(R.ADD_PROFILE_FAIL)}function w1(r,e){let t=r?`${r}_`:"";return`${v1(`${t}${e}_${e}`)}`}function v1(r){return g1("sha256").update(r).digest("hex").substring(0,16)}async function b1(r,e,t,n,i,o,s){S1(n);let a=Zg(r),c={certList:t,packageName:n,provisionName:o};i.length>0&&(c.deviceList=i),s.length&&(c.aclPermissionList=s);let l=await F.postAllowFailure(e,{headers:a,params:c});if(!l)throw m("[generateProfile] add provision failed: response is null"),new Error(R.ADD_PROFILE_FAIL);if(l.statusCode!==200)throw m(`[generateProfile] add provision HTTP ${l.statusCode}: ${l.data}`),Xg(l.statusCode,l.statusText,l.data);let d=JSON.parse(l.data);if(!d||!d.ret||d.ret.code!==0)throw m(`[generateProfile] add provision fail: ${l.data}`),E1(l.data,o),new Error(d.ret?.msg||R.ADD_PROFILE_FAIL);let g=d.provisionFileUrl;return{profileInfo:{id:d.id,name:o,provisionFileUrl:g}}}function Xg(r,e,t){return r===Zt.FORBIDDEN?e===Oe.OPENPROXY_BLOCKED_URL?new Error(R.ERR_CERT_NETWORK_ERROR):new Error(R.ERR_FORBIDDEN):r===Zt.UNAUTHORIZED?new Error(R.ERR_UNAUTHORIZED):t.includes(Oe.PROVISION_EXCEEDS_LIMIT_CODE)?new Error(R.TEST_PROVISION_EXCEEDS_LIMIT):new Error(R.ADD_PROFILE_FAIL)}function S1(r){if(!r||r.trim().length===0)throw new Error(R.ERROR_SIGN_BUNDLE_NAME_VALIDATE);if(!Re.BUNDLE_NAME_REGEX.test(r))throw new Error(R.ERROR_SIGN_BUNDLE_NAME_VALIDATE)}function E1(r,e){if(r.includes(Oe.PROVISION_EXCEEDS_LIMIT_CODE))throw new Error(R.TEST_PROVISION_EXCEEDS_LIMIT);if(r.includes(Oe.PROVISION_NAME_REPEAT_CODE)&&e)throw new Error(R.PROFILE_NAME_REPEAT)}async function zC(r,e){if(!e||e.trim().length===0)return;let t=`${me.BASE_URL}${me.PROVISION_DELETE_PATH}?id=${e}`,n=await F.deleteAllowFailure(t,{headers:Zg(r)});if(n.statusCode!==200)throw Xg(n.statusCode,n.statusText,n.data);let i=JSON.parse(n.data);(!i||!i.ret||i.ret.code!==0)&&Ai(`delete provision failed: ${n.data}`)}function P1(...r){for(let e of r)try{Ri.existsSync(e)&&Ri.unlinkSync(e)}catch(t){Ai(`delete local sign file error: ${t.message}`)}}async function C1(r,e){let t=`${me.BASE_URL}${me.CERT_DOWNLOAD_URL_PATH}`,n=Zg(r),i={sourceUrls:e},o=await F.postAllowFailure(t,{headers:n,params:i});if(!o)throw Ai("get download list failed: response is null"),new Error(R.ADD_PROFILE_FAIL);if(o.statusCode!==200)throw Xg(o.statusCode,o.statusText,o.data);let s=JSON.parse(o.data);if(!s||!s.urlsInfo||s.urlsInfo.length===0)throw Ai("download: The application does not exist"),new Error(s.ret?.msg||R.ADD_PROFILE_FAIL);return{urlList:s.urlsInfo,hasPermission:!0}}async function k1(r,e){if(!r||r.length===0)return!1;let t=r[0];return await ja(t.newUrl,e,t.sha256),!0}function D1(r,e,t,n,i){return R1(r,e),n=n||Re.TARGET_FRIENDLY_NAME,i=i||"",x1(e,t,n,i),!0}function R1(r,e){if(e.lastIndexOf(Re.CERT_BEGIN_HEADER)<0)throw new Error(R.ERROR_WHILE_PARSE_PROFILE);let t=JSON.stringify(e.substring(e.lastIndexOf(Re.CERT_BEGIN_HEADER))).replace(/\\r/g,"");if(!r.includes(t))throw new Error(R.CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT);return!0}function x1(r,e,t,n){let i=r.matchAll(Re.CERTIFICATE_PATTERN_GLOBAL),o=[],s=new Date;for(let c of i)try{let l=c[0],d=A1(l),g=new Date(d.validFrom),y=new Date(d.validTo);if(s<g||s>y){let E=`Certificate is not valid, Valid from ${g} to ${y}`;throw console.warn(`checkCertificateInValidityPeriod: ${E}`),new Error(R.CERTIFICATE_HAS_EXPIRED)}o.push(d)}catch(l){throw console.warn(`checkCertificateInValidityPeriod\uFF1A ${l.message}`),new Error(R.CERTIFICATE_HAS_EXPIRED,{cause:l})}if(!o||o.length===0)throw new Error(R.CERTIFICATE_HAS_EXPIRED);if(!T1(e,t,n,o))throw new Error(R.CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT)}function A1(r){let e="-----BEGIN CERTIFICATE-----",t=r.trim();try{if(t.startsWith(e))return new Kg(t);let n=JC.from(t,"base64");return new Kg(n)}catch(n){throw new Error("decodeBase64ToX509Certificate",{cause:n})}}function I1(r){if(r.cert){let e=xi.pki.publicKeyToPem(r.cert.publicKey);return h1(e).export({type:"spki",format:"der"})}if(r.asn1)try{let e=xi.asn1.toDer(r.asn1).getBytes(),t=JC.from(e,"binary");return new Kg(t).publicKey.export({type:"spki",format:"der"})}catch(e){return Ai(`Failed to parse cert from asn1: ${e}`),null}return null}function T1(r,e,t,n){try{let i=y1(r),o=xi.asn1.fromDer(xi.util.createBuffer(i)),c=xi.pkcs12.pkcs12FromAsn1(o,t).getBags({bagType:xi.pki.oids.certBag})[xi.pki.oids.certBag]||[];for(let l of c){let d=l.attributes?.friendlyName?.[0];if(!d||d.toLowerCase()!==e.toLowerCase())continue;let g=I1(l);if(!g)continue;if(n.some(E=>{let j=E.publicKey.export({type:"spki",format:"der"});return g.equals(j)}))return!0}return!1}catch(i){let o=i instanceof Error?i.message:String(i);return Ai(`Failed to process P12 file: ${r}, error: ${o}`),!1}}function Zg(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}var XC="https://developer.huawei.com",O1={"ohos.permission.SYSTEM_FLOAT_WINDOW":"/consumer/cn/doc/harmonyos-guides/window-pipwindow","ohos.permission.READ_CONTACTS":"/consumer/cn/doc/harmonyos-references/js-apis-contact#contactselectcontacts10","ohos.permission.READ_IMAGEVIDEO":"/consumer/cn/doc/harmonyos-guides/select-user-file#%E9%80%89%E6%8B%A9%E5%9B%BE%E7%89%87%E6%88%96%E8%A7%86%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.WRITE_IMAGEVIDEO":"/consumer/cn/doc/harmonyos-guides/savebutton","ohos.permission.READ_AUDIO":"/consumer/cn/doc/harmonyos-guides/select-user-file#%E9%80%89%E6%8B%A9%E9%9F%B3%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.WRITE_AUDIO":"/consumer/cn/doc/harmonyos-guides/save-user-file#%E4%BF%9D%E5%AD%98%E9%9F%B3%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.READ_PASTEBOARD":"/consumer/cn/doc/harmonyos-guides/pastebutton"},N1="/consumer/cn/doc/harmonyos-guides/restricted-permissions";function M1(r){let e=O1[r];return e?`${XC}${e}`:void 0}function L1(){return`${XC}${N1}`}var _1={"acl.can.apply.text":"Permission Application Scenarios","acl.permissions.warn":"Note: You are applying for restricted ACL permissions: {0} These permissions are subject to review together with your app release. For a faster review process, apply for the following permissions instead, if they are sufficient for your purposes: {1} {2}"};function KC(r,e){return(_1[r]??r).replace(/\{(\d+)\}/g,(n,i)=>String(e[Number(i)]??""))}function $1(r){return Array.from(r).join(", ")}function ZC(r,e){if(r.size===0)return;let t=Fn.getAclPermissionInfos(e),n=new Set;for(let g of t)r.has(g.permissionName)&&n.add(g);for(let g of n){let y=M1(g.permissionName);y!=null&&(g.permissionHelpUrlKey=y)}let i=new Set;for(let g of n)i.add(g.permissionDisplayName);let o=new Set;for(let g of n)if(g.permissionHelpUrlKey!=null){let y=g.permissionInsteadName??g.permissionDisplayName;o.add(`${y} (${g.permissionHelpUrlKey})`)}let s=L1(),a=KC("acl.can.apply.text",[]),c=s?`${a} (${s})`:a,l=o.size>0?Array.from(o).join(", ")+".":"",d=KC("acl.permissions.warn",[$1(i),l,c]);console.log(d)}var Du=class{_project=null;get project(){if(!this._project)throw new Error("Project not initialized. Call checkProjectDir first.");return this._project}checkProjectDir(e){try{return this._project=W.discover(process.cwd()),{passed:!0,message:""}}catch(t){return m(`[EnvCheck] Project.discover() failed: ${t.message}`),e(ve.PROJECT_DIR_MISSING)}}checkProduct(e,t){try{return this._project.validateProduct(e),{passed:!0,message:""}}catch(n){return m(`[EnvCheck] Product validation failed: ${n.message}`),t(`Product "${e}" not found.Check the product property in the build-profile.json5 file.`)}}checkBundleName(e,t){try{return this._project.getBundleName(),{passed:!0,message:""}}catch(n){return m(`[EnvCheck] BundleName check failed: ${n.message}`),t(`bundleName was not found under product "${e}".Check the bundleName configuration.`)}}checkAtomicService(){return this._project.isAtomicService()?{passed:!1,message:ve.ATOMIC_SERVICE_UNSUPPORTED}:{passed:!0,message:""}}};import F1 from"fs";import QC from"path";var Ru=class{constructor(e){this.toolProvider=e}checkJava(e){try{return this.toolProvider.assertJava(),{passed:!0,message:""}}catch(t){return m(`[EnvCheck] Java check failed: ${t.message}`),e(`${t.message}`)}}checkHapSignTools(e){let t=this.toolProvider.sdkPath,n=QC.join(t,"default","openharmony","toolchains","lib","hap-sign-tool.jar");if(!F1.existsSync(n)){let i=QC.join("sdk","default","openharmony","toolchains","lib","hap_sign_tools.jar");return e(`hap_sign_tools.jar not found.Check whether ${i} exists.`)}return{passed:!0,message:""}}};var xu=class{_userInfo=null;async ensureUserInfo(){if(!this._userInfo)try{this._userInfo=await Ke.getUserInfo()}catch(e){return m(`[EnvCheck] Failed to load user info: ${e.message}`),null}return this._userInfo}async checkLogin(e){try{return await Ke.isLoggedIn()?(await this.ensureUserInfo(),{passed:!0,message:""}):e(ve.LOGIN_REQUIRED)}catch(t){return m(`[EnvCheck] Login check failed: ${t.message}`),e(ve.LOGIN_REQUIRED)}}async checkTeamInfo(e){if(!await this.ensureUserInfo())return e(ve.TEAM_INFO_FAILED);try{if((await Sn()).teamList.length>0)return{passed:!0,message:""}}catch(n){return m(`[EnvCheck] Team API error: ${n.message}`),e(ve.TEAM_INFO_FAILED)}return m("[EnvCheck] No teams found for current user"),e(ve.TEAM_INFO_FAILED)}async checkRealname(e){let t=await this.ensureUserInfo();return t?t.isRealName===!1?e(ve.REALNAME_REQUIRED):t.isRealName!==!0?(m("[EnvCheck] Scenario 3 Real-name check: AGC API did not return realName field"),e(ve.REALNAME_REQUIRED)):{passed:!0,message:""}:e(ve.SESSION_EXPIRED)}async checkTeamId(e){let t=await this.ensureUserInfo();if(!t)return{passed:!0,message:""};let n=e??"";try{let i=await Sn();if(n=e??(i.teamList.length>0?i.teamList[0].id:t.userId)??"",!i.teamList.some(s=>s.id===n)){let s=`team-id for ${n} not found.Run devecocli auth team list to view the team to which the logged-in user belongs.`;return m(`[EnvCheck] ${s}`),{passed:!1,message:s}}return{passed:!0,message:""}}catch(i){return m(`[EnvCheck] Team ID check failed: ${i.message}`),{passed:!1,message:`team-id for ${n} not found.Run devecocli auth team list to view the team to which the logged-in user belongs.`}}}async checkRegion(e){let t=await this.ensureUserInfo();return t?t.countryCode?t.countryCode!=="CN"?e(ve.REGION_CHINA_ONLY):{passed:!0,message:""}:(m("[EnvCheck] Scenario 12 Region check: AGC API did not return nationalCode field"),e(ve.REGION_CHINA_ONLY)):e("User session expired or token invalid. Please login again.")}};async function j1(r){try{let{teamList:e}=await Sn();if(e.length>0)return e[0].id}catch(e){m(`[EnvCheck] resolveDefaultTeamId failed: ${e.message}`)}return r??""}async function H1(r){let e=await Ke.getUserInfo(),t=await Ke.refreshToken();if(!e||!t?.accessToken)throw new Error("Not logged in");let n=r||await j1(e.userId);if(!n)throw new Error("No team found");let i={uid:e.userId??"",teamId:n,accessToken:t.accessToken};return(await ku(i)).map(s=>({deviceId:s.udid,deviceName:s.deviceName}))}var Au=class{constructor(e){this.toolProvider=e}async checkDevice(e,t){try{let n=await H1(t);if(n.length>0)return m(`[EnvCheck] Scenario 4 Device check: ${n.length} device(s) found in AGC cloud, skipping local device check`),{passed:!0,message:""};m("[EnvCheck] Scenario 4 Device check: no cloud devices found, falling back to local hdc");let o=await ce.from(this.toolProvider).listDevices();return o.length===0?(m("[EnvCheck] Scenario 4 Device check: no local devices found"),e(ve.DEVICE_MISSING)):o.some(a=>dr(a.serial))?{passed:!0,message:""}:(m("[EnvCheck] Scenario 4 Device check: local device found but not an emulator"),e(ve.DEVICE_MISSING))}catch(n){return m(`[EnvCheck] Scenario 4 Device check failed: ${n.message}`),e(ve.DEVICE_DETECT_FAILED)}}};var Iu=class{projectChecker=new Du;toolchainChecker=null;authChecker=new xu;deviceChecker=null;constructor(){}async preflight(e){let t=n=>this.blockingFail(n);return!(!await this.runAuthChain(e,t)||!await this.initToolchain()||e.type!=="release"&&!await this.runDeviceCheck(e,t)||!await this.runProjectChecks(e,t)||!await this.runAuxChecks(e))}async runAuthChain(e,t){let n=o=>(o.passed||this.fail(o),!0),i=[()=>this.authChecker.checkLogin(t),()=>this.authChecker.checkRealname(t),()=>this.authChecker.checkTeamInfo(t)];for(let o of i)if(!n(await o()))return!1;return!(e.teamId&&!n(await this.authChecker.checkTeamId(e.teamId)))}async initToolchain(){try{let e=await C.new();return this.toolchainChecker=new Ru(e),this.deviceChecker=new Au(e),!0}catch(e){throw m(`[EnvCheck] ToolProvider.new() failed: ${e.message}`),new Error(ve.TOOLCHAIN_INIT_FAILED,{cause:e})}}async runDeviceCheck(e,t){return(i=>i.passed?!0:(this.fail(i),!1))(await this.deviceChecker.checkDevice(t,e.teamId))}async runProjectChecks(e,t){let n=o=>o.passed?!0:(this.fail(o),!1);if(!n(this.projectChecker.checkProjectDir(t))||!n(this.projectChecker.checkAtomicService()))return!1;let i=[()=>this.projectChecker.checkProduct(e.productName,t),()=>this.projectChecker.checkBundleName(e.productName,t),()=>this.toolchainChecker.checkJava(t),()=>this.toolchainChecker.checkHapSignTools(t)];for(let o of i)if(!n(o()))return!1;return!0}async runAuxChecks(e){let t=n=>n.passed?!0:(this.fail(n),!1);return!e.teamId&&!t(await this.authChecker.checkTeamId(e.teamId))?!1:(await this.authChecker.checkRegion(n=>this.blockingFail(n)),!0)}blockingFail(e){return{passed:!1,message:e}}fail(e){throw m(`[EnvCheck] FAIL: ${e.message}`),new Error(e.message)}};var ek=5*1024*1024;function W1(r){try{let e=Ii.statSync(r);if(e.size>ek)throw new Error(`Profile file too large: ${e.size} bytes (max ${ek} bytes): ${r}`);let t=Ii.readFileSync(r,"utf-8");return nk.parse(t)}catch(e){if(e.code==="ENOENT")return{app:{signingConfigs:[],products:[]}};throw new Error(`Failed to read profile: ${r}`,{cause:e})}}function V1(r){r.app||(r.app={signingConfigs:[],products:[]}),r.app.signingConfigs||(r.app.signingConfigs=[]),r.app.products||(r.app.products=[])}async function G1(r){if(r.keyPwd===r.storePassword){let n=await $n.encryptedPassword(r.keyPwd,r.p12FilePath);return{keyPassword:n,storePassword:n}}let e=await $n.encryptedPassword(r.keyPwd,r.p12FilePath),t=await $n.encryptedPassword(r.storePassword,r.p12FilePath);return{keyPassword:e,storePassword:t}}async function ik(r,e,t,n){let i=eh.join(r,"build-profile.json5"),o=W1(i);V1(o);let s=n==="release"?`${t??"default"}_release`:t??"default",{keyPassword:a,storePassword:c}=await G1(e),l={name:s,type:"HarmonyOS",material:{certpath:e.cerFilePath,keyAlias:e.keyAlias,keyPassword:a,profile:e.profileFilePath,signAlg:Zr.signAlg,storeFile:e.p12FilePath,storePassword:c}},d=o.app?.signingConfigs?.findIndex(y=>y.name===s);d!==void 0&&d>=0?o.app.signingConfigs[d]=l:o.app.signingConfigs.push(l);let g=o.app?.products?.findIndex(y=>y.name===t);g!==void 0&&g>=0?o.app.products[g].signingConfig=s:o.app.products.push({name:t,signingConfig:s}),Ii.writeFileSync(i,nk.stringify(o,null,2),"utf-8")}async function q1(r){let e=await Ke.getUserInfo(),t=await Ke.refreshToken();if(!e||!t)throw new Error("Failed to obtain login credentials. Run `devecocli auth login` again.");return{uid:e.userId??"",teamId:r.teamId??e.userId??"",accessToken:t.accessToken??""}}var tk=["debug","release"];async function z1(r){let e=r.product||"default";if(r.type&&!tk.includes(r.type))throw new Error(`Invalid signing type '${r.type}'. Valid types: ${tk.join(", ")}`);await new Iu().preflight({productName:e,teamId:r.teamId,type:r.type}),await rt.warnInvalidBundledLinks(W.discover(process.cwd()).rootDir),console.log("Executing signature generate command");let n=await q1(r),i=await C.new(),{shouldRegenerate:o}=await Ba.shouldRegenerate({force:r.force??!1,teamId:n.teamId,productName:r.product,type:r.type},i);if(!o){console.log(Qg("Signature generation completed successfully."));return}await J1(r,n,i)||(process.exitCode=1)}async function J1(r,e,t){if(r.type==="release"&&await K1(r))return!1;let n=await Hg(e,r.product,r.type),i=X1(r,e,n,t);r.type!=="release"&&(i.allDeviceIds=await BC(e,t.hdcPath));try{await YC(e,i)}catch(s){if(r.type==="release")return Y1(r,n);throw s}let o=W.discover(process.cwd()).rootDir;return await ik(o,n,r.product??"default",r.type),console.log(Qg(`Signing config written to ${eh.join(o,"build-profile.json5")}`)),console.log(Qg("Signature generation completed successfully.")),!0}async function Y1(r,e){let t=r.product||"default",n=W.discover(process.cwd()).rootDir;return await ik(n,e,t,r.type),console.warn(rk(`
1392
+ `),console.log(Ne("[compat:check] === end stdout ===")));let o=new fe("errorCode",`Compatibility scan failed: ${i.message}`+(i.stderr?`
1393
+ ${i.stderr}`:""));throw i.stdout&&(o.stdout=i.stdout),o}}function mW(r,e){if(!ZB.includes(e.format))throw new qB(`--format must be default, csv, or json (console: default|json, file: default|csv|json). got "${e.format}"`);if(r.length>0&&e.modules&&e.modules.length>0)throw new fe("errorCode","Cannot use `--modules` together with file arguments. Use either file-level scanning (with files) or module-level scanning (with --modules).");if(!e.sourceVersion)throw new fe("errorCode","--source-version is required.");if(!e.targetVersion)throw new fe("errorCode","--target-version is required.");if(!e.outputPath&&e.format==="csv")throw new fe("errorCode","--format csv requires --output-path. For console output, use --format json or --format default (or omit the flag).")}function gW(r,e){let t=[];if(r.sourceVersion&&!e.includes(r.sourceVersion)&&t.push(`--source-version "${r.sourceVersion}"`),r.targetVersion&&!e.includes(r.targetVersion)&&t.push(`--target-version "${r.targetVersion}"`),t.length>0){let n=t.length>1?"are":"is";throw new fe("errorCode",`${t.join(" and ")} ${n} not in the available SDK version list.
1394
+ Run \`devecocli compat versions\` to see all available versions.`)}if(r.sourceVersion&&r.targetVersion){let n=e.indexOf(r.sourceVersion),i=e.indexOf(r.targetVersion);if(n>=i)throw new fe("errorCode",`--target-version "${r.targetVersion}" must be later than --source-version "${r.sourceVersion}". Run \`devecocli compat versions\` to see the available order.`)}}function hW(r,e,t,n,i){i==="none"&&(t==="json"?dW(r,n):lW(r,n)),cW(r,e)}function yW(r,e){let t=ie.dirname(r),n=ie.basename(r),i=e.slice(1).map(o=>o.startsWith("--")?o:`"${o}"`).join(" ");f(Ne(`[compat:check] command: cd "${t}" && node "${n}" ${i}`))}function wW(r){try{KB(r),f(Ne(`[compat:check] cleaned up tmp report: "${r}"`))}catch(e){f(Ne(`[compat:check] failed to clean up tmp report: ${e.message}`))}}var vW=[".csv",".json"];function bW(r){return vW.includes(r.toLowerCase())}function SW(r,e){if(!r)return{kind:"none"};let t=ie.extname(r).toLowerCase();if(!bW(t))return{kind:"dir",dirPath:ie.resolve(r)};if(t===".csv"&&!(e==="default"||e==="csv")||t===".json"&&e!=="json")throw new fe("errorCode",`The --output-path file extension '${t}' does not match --format ${e}. Use --format ${t===".json"?"json":"default"}, or rename the file.`);return{kind:"file",filePath:ie.resolve(r),ext:t}}function EW(r){if(r.kind==="file"){if(Bu(r.filePath))throw new fe("errorCode",`Target file "${r.filePath}" already exists. Remove it first, or choose a different --output-path.`);let e=ie.dirname(r.filePath);if(!Bu(e))throw new fe("errorCode",`Target directory "${e}" does not exist. Create it first, or choose a different --output-path.`)}else if(r.kind==="dir"&&!Bu(r.dirPath))throw new fe("errorCode",`Target directory "${r.dirPath}" does not exist. Create it first, or choose a different --output-path.`)}function qk(r){return JSON.stringify({records:r,count:r.length},null,2)+`
1395
+ `}function PW(r,e,t,n){n===".csv"?Uk(r,t):Bk(t,qk(e),"utf8"),f(Ne(`[compat:check] saved report: "${t}"`))}function CW(r,e,t,n){if(n==="json"){let o=ie.basename(r,".csv"),s=ie.join(t,`${o}.json`);return Bk(s,qk(e),"utf8"),f(Ne(`[compat:check] saved report: "${s}"`)),s}let i=ie.join(t,ie.basename(r));return Uk(r,i),f(Ne(`[compat:check] saved report: "${i}"`)),i}async function kW(r,e){let t=new ht(r,process.cwd(),!0),n=e.modules&&e.modules.length>0?e.modules[0]:void 0;try{await t.compileNative("default",n)}catch(i){throw new fe("errorCode",`hvigorw compileNative failed (module=${n??"<project>"}): `+i.message,{cause:i})}}async function RW(r,e){mW(r,e);let t=W.discover(process.cwd());await nt.warnInvalidBundledLinks(t.rootDir),e.modules&&e.modules.length>0&&eW(t,e.modules),r.length>0&&tW(r);let n=await C.new(),{apiChangeDir:i,scriptPath:o}=n.getApiscanPaths();f(Ne(`[compat:check] script: "${o}"`));let s=Vk(i);gW(e,s),e.outputPath&&f(Ne(`[compat:check] outputPath: "${e.outputPath}"`));let a=SW(e.outputPath,e.format);return f(Ne(`[compat:check] outputTarget: ${a.kind}`)),EW(a),{project:t,scriptPath:o,target:a,toolProvider:n}}function xW(r,e,t,n){if(t.kind==="file")return PW(r,e,t.filePath,t.ext),t.filePath;if(t.kind==="dir")return CW(r,e,t.dirPath,n);if(t.kind==="none")return null;throw new fe("errorCode",`Unexpected output target kind: ${t.kind}`)}async function DW(r,e,t,n,i){let o=XB({text:"Running compatibility check...",color:"cyan"}).start();try{await kW(r.toolProvider,t);let s=pW(r.scriptPath,e,r.project,t);yW(r.scriptPath,s);let a=await fW(r.toolProvider,s),c=aW(a,Sh.tmpdir());if(!c)throw new fe("errorCode","Scanner output format unexpected: missing report path.");f(Ne(`[compat:check] tmp csv: "${c}"`));let l=sW(c),d=xW(c,l,r.target,t.format);wW(c),o.stop(),hW(l,d,t.format,t.limit,r.target.kind),await as(n,!0,null,i)}catch(s){o.fail("Compatibility check failed");let a=Eh(s);throw await as(n,!1,a,i),s}}async function zk(r,e){let t=Date.now(),n=["check","compat"];try{let i=await RW(r,e);await DW(i,r,e,t,n)}catch(i){let o=Eh(i);throw await as(t,!1,o,n),i}}function AW(r){let e=Number(r);if(!Number.isInteger(e)||e<=0)throw new IW(`--limit must be a positive integer (got "${r}")`);return e}var Ph=new Jk("compat").description("Compatibility checking utilities.");Ph.description("Check source code compatibility against a target SDK version. By default, performs a project-level scan; pass positional `files...` for file-level scanning; pass `--modules` for module-level scanning.").arguments("[files...]").option("--source-version <version>","Current project SDK version (required; use `compat versions` to list available versions). On zsh, quote the value because version strings contain parentheses; run `compat versions` first to copy a real example.").option("--target-version <version>","Target SDK version (required; use `compat versions` to list available versions). On zsh, quote the value because version strings contain parentheses; run `compat versions` first to copy a real example.").option("--modules <modules...>","Modules to check (default: all modules in the project). Mutually exclusive with positional file arguments.").option("--format <format>",'Output format: "json" or "default" (text) for console; "csv", "json", or "default" for file output (--output-path). "csv" requires --output-path.',"default").option("--output-path <path>","Directory to write the detailed report CSV to (default: ./compat-output)").option("--limit <num>","Maximum number of change records to display (default: 100)",AW,100).action(async(r,e)=>{await zk(r,e)});Ph.command("versions").description("List all available target SDK versions for compatibility checking").option("--format <format>","Output format: default or json").action(async(r,e)=>{let t=e.optsWithGlobals().format;await Gk(t)});var TW=new Jk("check").description("Run DevEco project checks").addCommand(Ph).addCommand(gh()).addCommand(bh()),Kk=TW;import{Command as v2}from"commander";import{green as qh,red as b2,yellow as OR}from"colorette";import $i from"fs";import zh from"path";import _R from"json5";import{readFileSync as sV}from"fs";import{join as NW}from"path";var me={BASE_URL:"https://connect-api.cloud.huawei.com",CERT_LIST_PATH:"/api/cps/harmony-cert-manage/v1/cert/list",CERT_DELETE_PATH:"/api/cps/harmony-cert-manage/v1/cert/delete",CERT_ADD_PATH:"/api/cps/harmony-cert-manage/v1/cert/add",CERT_DOWNLOAD_URL_PATH:"/api/amis/app-manage/v1/objects/url/reapply",DEVICE_ADD_PATH:"/api/cps/device-manage/v1/device/add",DEVICE_LIST_PATH:"/api/cps/device-manage/v1/device/list",PROVISION_ADD_REAL_PATH:"/api/cps/provision-manage/v1/ide/real/provision/add",PROVISION_ADD_TEST_PATH:"/api/cps/provision-manage/v1/ide/test/provision/add",PROVISION_DELETE_PATH:"/api/cps/provision-manage/v1/provision/delete"},De={CERT_NAME_PREFIX:"auto_debug_",CERT_NAME_PREFIX_RELEASE:"auto_release_",CERT_TYPE_DEBUG:"1",CERT_TYPE_RELEASE:"2",TEAM_ID_INVALID_CHARS:/[\\/.:]/g,CERT_PATTERN:/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/,TARGET_FRIENDLY_NAME:"debugKey",CERTIFICATE_PATTERN_GLOBAL:/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g,BUNDLE_NAME_REGEX:/^[a-zA-Z][a-zA-Z0-9._-]*$/,CERT_BEGIN_HEADER:"-----BEGIN CERTIFICATE-----",CERT_SAVE_DIR:NW(".ohos","config"),DOWNLOAD_CONNECT_TIMEOUT_MS:5e3},Oe={SUCCESS_MARKER:'"code":0',SQUARE_BRACKETS:"[]",OPENPROXY_BLOCKED_URL:"Openproxy_Blocked_URL_list",CERT_LIMIT_CODE:"205389872",USER_NOT_HARMONY_CODE:"205389904",DEVICE_EXCEEDS_LIMIT_CODE:"205389859",DEVICE_NAME_REPEAT_CODE:"205389857",PROVISION_EXCEEDS_LIMIT_CODE:"205389938",PROVISION_NAME_REPEAT_CODE:"205389830"},rr={FORBIDDEN:403,UNAUTHORIZED:401},x={ERR_FORBIDDEN:"You do not have AppGallery Connect permissions for the current team. Request access from the team administrator or switch to a team where you have permissions.",ERR_UNAUTHORIZED:"Invalid AccessToken. Sign in and try again.",ERR_CERT_LIMIT_REACHED:"The number of certificates has reached the limit. Delete some certificates and try again.",ERR_CERT_NETWORK_ERROR:"Ensure the external network connection is available before downloading the certificate.",ERR_CERT_INVALIDATE:"The downloaded .cer file is invalid. Try again.",ERR_DOWNLOAD_CER:"Failed to download the certificate file. Check the following configurations: Network connection, HTTP Proxy, etc.",ERR_USER_NOT_HARMONY:"The user is not in harmony allow list, please grant the permission",ERR_READ_CSR:"Failed to read the .csr file, please try again later",ERROR_WHILE_ADD_DEVICE:"Failed to add the device, please try again.",DEVICE_LIMIT_REACHED:"The number of devices has reached the limit. Delete some unused devices and try again.",DEVICE_NAME_REPEAT:"Duplicate device name, please try again.",DEVICE_LIST_EMPTY:"No devices available.",ADD_PROFILE_FAIL:"Failed to add the profile, please try again.",NO_AGC_PERMISSION:"You do not have the AppGallery Connect permission with the current team. Apply for the permission form the team administrator, or switch to a team with which you already have the permission.",ERROR_WHILE_DOWNLOAD_PROFILE:"Failed to download the profile, please try again.",PROFILE_NAME_REPEAT:"The profile name already exists in the AGC.",ERROR_WHILE_PARSE_PROFILE:"Failed to parse the profile, please try again.",TEST_PROVISION_EXCEEDS_LIMIT:"Provision number exceeds limit.",CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT:"The certificate application file is inconsistent with the file in profile, please try again.",CERTIFICATE_HAS_EXPIRED:"The signature does not take effect or has expired. It may be the current system time is inaccurate, please calibrate the system time and sign again.",ERROR_SIGN_BUNDLE_NAME_VALIDATE:"The bundle name contains 7 to 128 characters, including only letters, digits, and underscores (_). It must be start with a letter and contain at least three segments separated by periods (.), each of the segments ending with a digit or letter."},be={TOOLCHAIN_INIT_FAILED:"Auto-sign failed: unable to initialize toolchain",LOGIN_REQUIRED:"Failed to automatically generate signatures.Run devecocli auth login to sign in.",TEAM_INFO_FAILED:"Failed to obtain user team information.Check the network connection, HTTP proxy, and other configurations.",REALNAME_REQUIRED:"Users without real-name verification are not supported.Complete real-name verification in AppGallery Connect.",SESSION_EXPIRED:"User session expired or token invalid. Please login again.",REGION_CHINA_ONLY:"This feature is only available for accounts registered in Chinese mainland.",DEVICE_MISSING:"Unable to create the profile file due to missing devices.Connect a device through IP or USB, or manually add a device in AppGallery Connect first.If you are installing the HAP package on an emulator, you can skip the signing step.",DEVICE_DETECT_FAILED:"Unable to detect devices. Please check hdc status. If installing HAP on an emulator, signature step can be skipped.",PROJECT_DIR_MISSING:"Not in a valid project directory (project-level build-profile.json5 not found).",ATOMIC_SERVICE_UNSUPPORTED:"AtomicService projects are not yet supported. Please configure signing manually."};function Wu(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}function Ch(r,e=!1){let t=r.replace(De.TEAM_ID_INVALID_CHARS,"");return`${e?De.CERT_NAME_PREFIX_RELEASE:De.CERT_NAME_PREFIX}${t}.cer`}function cs(r,e,t){if(r===rr.FORBIDDEN)return e===Oe.OPENPROXY_BLOCKED_URL?new Error(x.ERR_CERT_NETWORK_ERROR):new Error(x.ERR_FORBIDDEN);if(r===rr.UNAUTHORIZED)return new Error(x.ERR_UNAUTHORIZED);if(t.includes(Oe.USER_NOT_HARMONY_CODE))return new Error(x.ERR_USER_NOT_HARMONY);if(t.includes(Oe.CERT_LIMIT_CODE))return new Error(x.ERR_CERT_LIMIT_REACHED);let n=OW(t);return new Error(n??x.ERR_DOWNLOAD_CER)}function OW(r){let e=Yk(r);if(!e||typeof e!="object")return null;let t=e.ret;if(t==null)return null;let n=typeof t=="string"?Yk(t):t;if(n&&typeof n=="object"){let i=n.msg;if(typeof i=="string"&&i.trim()!=="")return i}return null}function Yk(r){try{return JSON.parse(r)}catch{return null}}function kh(r){return JSON.parse(r)}async function Xk(r){let e=`${me.BASE_URL}${me.CERT_LIST_PATH}`,t=await j.postAllowFailure(e,{headers:Wu(r)});if(t.statusCode!==200)throw cs(t.statusCode,t.statusText,t.data);return kh(t.data)?.certList??[]}async function Vu(r,e){return(await Xk(r)).find(n=>n.certName===e)??null}async function Rh(r,e){let t=`${me.BASE_URL}${me.CERT_DELETE_PATH}`,n=await j.deleteAllowFailure(t,{headers:Wu(r),params:{certIds:[e]}});if(n.statusCode!==200)throw cs(n.statusCode,n.statusText,n.data);return kh(n.data)?.ret?.code===0}async function xh(r,e,t,n=De.CERT_TYPE_DEBUG){let i=`${me.BASE_URL}${me.CERT_ADD_PATH}`,o={csr:e,certName:t,certType:n},s=await j.postAllowFailure(i,{headers:Wu(r),params:o});if(s.statusCode!==200)throw cs(s.statusCode,s.statusText,s.data);if(!s.data.includes(Oe.SUCCESS_MARKER))throw cs(void 0,s.statusText,s.data)}async function Dh(r,e){let t=`${me.BASE_URL}${me.CERT_DOWNLOAD_URL_PATH}`,n=await j.postAllowFailure(t,{headers:Wu(r),params:{sourceUrls:e}});if(n.statusCode!==200)throw cs(n.statusCode,n.statusText,n.data);return kh(n.data)?.urlsInfo?.[0]??null}import{mkdirSync as _W,writeFileSync as MW,existsSync as LW}from"fs";import{dirname as FW}from"path";import{createHash as $W}from"crypto";function jW(r){let e;try{e=new URL(r)}catch{throw new Error(`Invalid download URL: ${JSON.stringify(r)}`)}if(e.protocol!=="https:")throw new Error(`Download URL must use HTTPS: ${e.protocol}`);let t=e.hostname.toLowerCase();if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t.startsWith("169.254.")||t.startsWith("10.")||t.startsWith("192.168.")||/^172\.(1[6-9]|2\d|3[0-1])\./.test(t)||t.endsWith(".internal")||t.endsWith(".local"))throw new Error(`Download URL points to internal/private address: ${t}`)}async function ic(r,e,t){jW(r);let{statusCode:n,statusText:i,buffer:o}=await j.getBinaryAllowFailure(r,{timeout:De.DOWNLOAD_CONNECT_TIMEOUT_MS});if(n!==200)throw n===rr.FORBIDDEN&&i===Oe.OPENPROXY_BLOCKED_URL?new Error(x.ERR_CERT_NETWORK_ERROR):new Error(x.ERR_DOWNLOAD_CER);if(t){let a=$W("sha256").update(o).digest("hex");if(a!==t.toLowerCase())throw new Error(`SHA-256 mismatch for ${e}: expected ${t.toLowerCase()}, got ${a}`)}let s=FW(e);LW(s)||_W(s,{recursive:!0}),MW(e,o)}import nV from"fs/promises";import{readFileSync as iV}from"fs";import Gu from"path";import eR from"crypto";import HW from"os";import oc from"fs/promises";var tR={GENERATE_KEYPAIR:"generate-keypair",GENERATE_CSR:"generate-csr"},Zk=["ECC","RSA"],Qk=["SHA256withECDSA","SHA384withECDSA","SHA256withRSA","SHA384withRSA"],UW={ECC:["NIST-P-256","NIST-P-384"],RSA:["2048","3072","4096"]},BW=8,Ih=64,WW=/[\\/:*?"<>|=-]/g,tn={productName:"default",keyAlias:"debugKey",keyAlg:"ECC",keySize:"NIST-P-256",csrSubject:"CN=DebugKey",signAlg:"SHA256withECDSA"};function VW(r){if(!r.keyAlias.trim())throw new Error("keyAlias cannot be empty");if(!r.keystoreFile.trim())throw new Error("keystoreFile cannot be empty");if(r.keyAlias.length>Ih)throw new Error(`The length of keyAlias cannot exceed ${Ih}`);if(!Zk.includes(r.keyAlg))throw new Error(`Invalid key algorithm ${r.keyAlg}, available: ${Zk.join(" / ")}`);let e=UW[r.keyAlg];if(!e.includes(r.keySize))throw new Error(`Key algorithm ${r.keyAlg} does not support size ${r.keySize}, available: ${e.join(", ")}`)}function GW(r){if(!r.keyAlias.trim())throw new Error("keyAlias cannot be empty");if(!r.keystoreFile.trim())throw new Error("keystoreFile cannot be empty");if(!r.subject.trim())throw new Error("subject cannot be empty");if(!Qk.includes(r.signAlg))throw new Error(`Invalid sign algorithm ${r.signAlg}, available: ${Qk.join(" / ")}`)}function qW(r){return eR.createHash("sha256").update(r,"utf8").digest().toString("base64url").replaceAll(/[-_=]/g,"")}function zW(r){let e=r?.trim()??"";return e&&e.replace(WW,"_").replace(/\.+/g,"_").slice(0,Ih)||tn.productName}async function rR(){let r=await C.new();r.assertJava();let e=r.javaPath,t=r.sdkPath;m.info(`\u8BFB\u53D6SDK\u6839\u76EE\u5F55\uFF1A${t}`);let n=Gu.join(t,"default","openharmony","toolchains","lib","hap-sign-tool.jar");try{await oc.access(n)}catch(i){throw new Error(`Sign tool jar not found: ${n}`,{cause:i})}return{javaPath:e,jarPath:n}}async function JW(r){let{javaPath:e,jarPath:t}=await rR(),n=["-jar",t,tR.GENERATE_KEYPAIR,"-keyAlias",r.keyAlias,"-keyAlg",r.keyAlg,"-keySize",r.keySize,"-keystoreFile",r.keystoreFile,"-keystorePwd",r.keystorePwd];r.keyPwd&&n.push("-keyPwd",r.keyPwd),r.pwdInputMode&&n.push("-pwdInputMode",r.pwdInputMode);let i=n.map((o,s)=>s>0&&["-keyPwd","-keystorePwd"].includes(n[s-1])?"******":o);return m.debug("generate-keypair \u547D\u4EE4\uFF08\u8131\u654F\uFF09\uFF1A",i.join(" ")),[e,...n]}async function KW(r){let{javaPath:e,jarPath:t}=await rR(),n=["-jar",t,tR.GENERATE_CSR,"-keyAlias",r.keyAlias,"-subject",r.subject,"-signAlg",r.signAlg,"-keystoreFile",r.keystoreFile,"-keystorePwd",r.keystorePwd];r.outFile&&n.push("-outFile",r.outFile),r.keyPwd&&n.push("-keyPwd",r.keyPwd),r.pwdInputMode&&n.push("-pwdInputMode",r.pwdInputMode);let i=n.map((o,s)=>s>0&&["-keyPwd","-keystorePwd"].includes(n[s-1])?"******":o);return m.debug("generate-csr \u547D\u4EE4\uFF08\u8131\u654F\uFF09\uFF1A",i.join(" ")),[e,...n]}async function YW(r){m.info("\u5F00\u59CB\u751F\u6210 P12 \u5BC6\u94A5\u5E93"),VW(r);let e=await JW(r),t=await _s(e[0],e.slice(1));if(t.exitCode!==0){let n=t.stderr||t.stdout||"Unknown tool error";throw new Error(`An error occurred while generating the private key P12, exit code${t.exitCode}\uFF1A${n}`)}return m.info("\u751F\u6210P12\u547D\u4EE4\u6267\u884C\u5B8C\u6210"),t}async function XW(r){m.info("\u5F00\u59CB\u751F\u6210 CSR \u8BC1\u4E66\u8BF7\u6C42"),GW(r);let e=await KW(r),t=await _s(e[0],e.slice(1));if(t.exitCode!==0){let n=t.stderr||t.stdout||"Unknown tool error";throw new Error(`An error occurred while generating the CSR, exit code${t.exitCode}\uFF1A${n}`)}return m.info("\u751F\u6210CSR\u547D\u4EE4\u6267\u884C\u5B8C\u6210"),t}function ZW(r=BW){return eR.randomBytes(r).toString("base64url").replaceAll(/[-_=]/g,"")}async function QW(){let r=HW.homedir();try{await oc.access(r)}catch(t){throw new Error("Invalid user path;",{cause:t})}let e=Gu.join(r,".ohos","config");try{await oc.mkdir(e,{recursive:!0,mode:448})}catch(t){throw new Error(`Failed to create directory ${e}`,{cause:t})}return m.info(`\u7B7E\u540D\u914D\u7F6E\u76EE\u5F55\u5C31\u7EEA\uFF1A${e}`),e}async function Be(r,e,t,n){let i=zW(r),o=Gu.basename(e),s=qW(e),c=`${i}_${o}_${s}${n==="release"?"_release":""}=.${t}`,l=await QW();return Gu.join(l,c)}function eV(r){let e;try{e=W.discover(r).rootDir}catch(t){throw new Error(`Current directory ${r} is not a valid project root`,{cause:t})}return e}async function tV(r){try{await oc.access(r)}catch(e){throw new Error(`Project directory ${r} is not accessible, missing read/write permissions`,{cause:e})}}async function rV(r){try{await oc.access(r)}catch(e){throw new Error(`P12 file ${r} does not exist, terminating CSR generation.`,{cause:e})}}async function Ah(r,e,t,n){let i=process.cwd(),o=eV(i);await tV(o),m.info(`\u8BC6\u522B\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${o}`);let s=ZW(),a=n==="release",c=a?"releaseKey":tn.keyAlias,l=a?"CN=ReleaseKey":tn.csrSubject,d=await Be(r??"",o,"p12",n),g=await Be(r??"",o,"csr",n);return console.log("Start generating p12"),await YW({keyAlias:e?.keyAlias??c,keyPwd:s,keyAlg:e?.keyAlg??tn.keyAlg,keySize:e?.keySize??tn.keySize,keystoreFile:d,keystorePwd:s}),await rV(d),console.log("Start generating csr"),await XW({subject:t?.subject??l,outFile:g,keyAlias:e?.keyAlias??c,keyPwd:s,signAlg:t?.signAlg??tn.signAlg,keystoreFile:d,keystorePwd:s}),{p12FilePath:d,csrFilePath:g,keyPwd:s,keyAlias:e?.keyAlias??c}}var oV=["p12","cer","csr","p7b"];async function Th(r,e,t){for(let n of oV){let i=await Be(r,e,n,t);await nV.rm(i,{force:!0})}}function Nh(r){let e;try{e=iV(r,"utf-8")}catch{throw new Error(x.ERR_CERT_INVALIDATE)}if(!De.CERT_PATTERN.test(e))throw new Error(x.ERR_CERT_INVALIDATE)}async function qu(r,e,t){return{certPath:await Be(r,e,"cer",t),csrPath:await Be(r,e,"csr",t),p12Path:await Be(r,e,"p12",t),profilePath:await Be(r,e,"p7b",t)}}async function Oh(r,e,t){let n=e??"",i=W.discover(process.cwd()).rootDir;await Th(n,i,t);let o=Ch(r.teamId,t==="release"),s=await Vu(r,o);if(s&&!await Rh(r,s.id))throw new Error(x.ERR_DOWNLOAD_CER);let a=await Ah(e,void 0,void 0,t),c;try{c=sV(a.csrFilePath,"utf-8")}catch{throw new Error(x.ERR_READ_CSR)}console.log("Start generating certificate");let l=t==="release"?De.CERT_TYPE_RELEASE:De.CERT_TYPE_DEBUG;await xh(r,c,o,l);let d=await Vu(r,o);if(!d)throw new Error(x.ERR_DOWNLOAD_CER);let g=await Dh(r,d.certObjectId);if(!g)throw new Error(x.ERR_DOWNLOAD_CER);let y=await Be(n,i,"cer",t);await ic(g.newUrl,y,g.sha256),Nh(y);let E=await Be(n,i,"p7b",t);return{p12FilePath:a.p12FilePath,csrFilePath:a.csrFilePath,cerFilePath:y,profileFilePath:E,certId:d.id,keyAlias:a.keyAlias,keyPwd:a.keyPwd,storePassword:a.keyPwd}}import rp from"crypto";import Bn from"fs";import*as yR from"path";import DV from"json5";import{execa as mR}from"execa";import gR from"node-forge";import{createCipheriv as aV,createDecipheriv as cV,pbkdf2Sync as lV,randomBytes as Fh}from"crypto";import{promises as _i}from"fs";import{dirname as dV,join as nr}from"path";var zu=3,sc=16,uV=1e4,nR="material",pV=new Uint8Array([49,243,9,115,214,175,91,184,211,190,177,88,101,131,192,119]),aR="aes-128-gcm",Oi=12,Ju=16,jn=4;function _h(r){return new Uint8Array(Fh(r))}function fV(r){return Fh(r).toString("hex")}function mV(...r){if(r.length===0)return new Uint8Array(0);let e=r[0].length,t=new Uint8Array(e);for(let n=0;n<e;n++){let i=0;for(let o of r)i^=o[n];t[n]=i}return t}function iR(r,e,t=uV,n=sc){let i=[...r,pV],o=mV(...i),s=Buffer.from(o).toString("utf8"),a=Buffer.from(s,"utf8"),c=lV(a,e,t,n,"sha256");return new Uint8Array(c)}function oR(r,e){let t=Fh(Oi),n=aV(aR,r,t),i=Buffer.concat([n.update(e),n.final()]),o=n.getAuthTag(),s=Buffer.concat([i,o]),a=s.length,c=Buffer.alloc(jn+Oi+s.length);return c.writeUInt32BE(a,0),t.copy(c,jn),s.copy(c,jn+Oi),c}function sR(r,e){if(e.length<jn+Oi+Ju)throw new Error("Ciphertext too short");let t=e.readUInt32BE(0),n=e.subarray(jn,jn+Oi),i=e.subarray(jn+Oi,jn+Oi+t);if(i.length<Ju)throw new Error("Ciphertext too short for auth tag");let o=i.subarray(0,i.length-Ju),s=i.subarray(i.length-Ju),a=cV(aR,r,n);return a.setAuthTag(s),Buffer.concat([a.update(o),a.final()])}async function gV(r){try{await _i.rm(r,{recursive:!0,force:!0})}catch{}}async function Mh(r){let e=await _i.readdir(r),t=e.filter(n=>n!==".DS_Store");if(t.length!==1)throw new Error(`Expected exactly 1 file in ${r}, but found ${t.length} (filtered from ${e.length})`);return _i.readFile(nr(r,t[0]))}async function Lh(r,e){let t=fV(sc),n=nr(r,t);return await _i.writeFile(n,e,{mode:384}),t}var Hn=class{static keyChain=Promise.resolve();static async generateMaterial(e){let t=nr(e,nR);await gV(t);let n=nr(t,"ac"),i=nr(t,"ce");await _i.mkdir(n,{recursive:!0,mode:448}),await _i.mkdir(i,{recursive:!0,mode:448});for(let d=0;d<zu;d++)await _i.mkdir(nr(t,"fd",String(d)),{recursive:!0,mode:448});let o=_h(sc),s=[];for(let d=0;d<zu;d++)s.push(_h(sc));let a=_h(sc),c=iR(s,o),l=oR(c,a);await Lh(n,o),await Lh(i,l);for(let d=0;d<zu;d++){let g=nr(t,"fd",String(d));await Lh(g,s[d])}return a}static async readMaterial(e){let t=nr(e,nR),n=nr(t,"ac"),i=new Uint8Array(await Mh(n)),o=[];for(let d=0;d<zu;d++){let g=nr(t,"fd",String(d)),y=await Mh(g);o.push(new Uint8Array(y))}let s=nr(t,"ce"),a=await Mh(s),c=iR(o,i),l=sR(c,a);return new Uint8Array(l)}static async getStoreKey(e){let t,n=this.keyChain;this.keyChain=new Promise(i=>{t=i}),await n;try{let i=dV(e);try{return await this.readMaterial(i)}catch{return await this.generateMaterial(i)}}finally{t()}}static async encryptedPassword(e,t){let n=await this.getStoreKey(t),i=Buffer.from(e,"utf8");return oR(n,i).toString("hex")}static async decryptPassword(e,t){if(!e)return"";let n=await this.getStoreKey(t),i=Buffer.from(e,"hex");return sR(n,i).toString("utf8")}};import pR from"fs";import ep from"path";import SV from"json5";import*as Ku from"fs";import*as cR from"path";function Yu(r){let e=cR.resolve(r);if(!Ku.existsSync(e))throw new Error(`SDK info file not found: ${e}`);let t;try{t=Ku.readFileSync(e,"utf-8")}catch(s){throw new Error(`Failed to read SDK info file: ${e}`,{cause:s})}let n;try{n=JSON.parse(t)}catch(s){throw new Error(`Invalid JSON in SDK info file: ${e}`,{cause:s})}let i=n?.data?.apiVersion;if(i==null||i==="")throw new Error(`Missing data.apiVersion in SDK info file: ${e}`);let o=Number(i);if(!Number.isFinite(o))throw new Error(`Invalid data.apiVersion in SDK info file: ${String(i)}`);return o}import*as ds from"fs";import*as ut from"path";import{debuglog as ls}from"util";var lR={"acl.SYSTEM_FLOAT_WINDOW.instead.name":"PiPWindow","acl.READ_CONTACTS.instead.name":"contact.selectContacts","acl.READ_IMAGEVIDEO.instead.name":"PhotoViewPicker","acl.WRITE_IMAGEVIDEO.instead.name":"SaveButton","acl.READ_AUDIO.instead.name":"AudioViewPicker","acl.WRITE_AUDIO.instead.name":"AudioViewPicker","acl.READ_PASTEBOARD.instead.name":"PasteButton"};function hV(r){return Object.prototype.hasOwnProperty.call(lR,r)}function Xu(r){if(hV(r))return lR[r]}var dR={DUPLICATE_PERMISSION:"Duplicate permissions detected. Make sure each permission is unique in the same module and try again."};import{fileURLToPath as yV}from"url";var Qu=class{permissionName;permissionDisplayName;minSupportApiLevel;permissionInsteadName;permissionHelpUrlKey;constructor(e={}){this.permissionName=e.permissionName??"",this.permissionDisplayName=e.permissionDisplayName??"",this.minSupportApiLevel=e.minSupportApiLevel??"",this.permissionInsteadName=e.permissionInsteadName,this.permissionHelpUrlKey=e.permissionHelpUrlKey}};function Zu(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function uR(r){return r==null||r.length===0}function wV(r){return!uR(r)}function $h(r,e){let t=r[e];return typeof t=="string"?t:t==null?"":String(t)}function vV(r,e){let t=r[e];if(typeof t=="boolean")return t;if(typeof t=="number")return t!==0;if(typeof t=="string"){let n=t.trim().toLowerCase();return n==="true"||n==="1"}return!1}function bV(r,e){let t=r[e];if(typeof t=="number")return Math.trunc(t);if(typeof t=="string"){let n=Number.parseInt(t,10);return Number.isNaN(n)?0:n}return 0}var Un=class{static MIN_API_TO_FIND_ACL_IN_SDK=23;static ACL_PREFIX="ohos.permission.";static ACL_PERMISSIONS_CONFIG_PATH=ut.join("aclPermission","aclPermissionsInfo.json");static ACL_HAVE_INSTEAD_NAME=new Set(["ohos.permission.SYSTEM_FLOAT_WINDOW","ohos.permission.READ_CONTACTS","ohos.permission.READ_IMAGEVIDEO","ohos.permission.WRITE_IMAGEVIDEO","ohos.permission.READ_AUDIO","ohos.permission.WRITE_AUDIO","ohos.permission.READ_PASTEBOARD"]);static ACL_AVAILABLE_LEVEL_VALUE="system_basic";static ACL_AVAILABLE_TYPE_VALUE="NORMAL";static ACL_AVAILABLE_LEVEL_KEY="availableLevel";static ACL_AVAILABLE_TYPE_KEY="availableType";static ACL_PROVISION_ENABLE_KEY="provisionEnable";static ACL_NAME_KEY="name";static ACL_CONFIG_PREFIX="acl.";static ACL_INSTEAD_NAME_SUFFIX=".instead.name";static ACL_HELP_URL_KEY_SUFFIX=".help.key";static ACL_DEFINE_PERMISSION_KEY="definePermissions";static ACL_SINCE_KEY="since";static PERMISSION_DEFINITIONS_RELATIVE_PATH=ut.join("lib","PermissionDefinitions.json");static INCLUDE_ACL_PERMISSIONS=new Set(["ohos.permission.FILE_ACCESS_PERSIST","ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY","ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY"]);static EXCLUDE_ACL_PERMISSIONS=new Set(["ohos.permission.READ_DOCUMENT","ohos.permission.WRITE_DOCUMENT"]);static handleSpecificAclPermissions(){this.addAclWhiteList(this.INCLUDE_ACL_PERMISSIONS),this.addAclBlackList(this.EXCLUDE_ACL_PERMISSIONS)}static aclPermissionInfoMap=new Map;static aclPermissionNamesMap=new Map;static aclWhiteList=new Set;static aclBlackList=new Set;static builtInConfigTextLoader;static initAclPermission(e,t){let n=e.rootDir,i=this.getOrCreateSet(this.aclPermissionNamesMap,n),o=this.getOrCreateSet(this.aclPermissionInfoMap,n);i.clear(),o.clear();let s=ut.join(t.sdkPath,"default","sdk-pkg.json"),a=Yu(s);this.MIN_API_TO_FIND_ACL_IN_SDK-a>0?this.initAclPermissionFromBuiltInConfig(i,o):this.initAclPermissionFromSDK(t,i,o)}static getAclPermissionInfos(e){return this.aclPermissionInfoMap.get(e.rootDir)??new Set}static getAclPermissionNames(e){return this.aclPermissionNamesMap.get(e.rootDir)??new Set}static addAclWhiteList(e){for(let t of e)this.aclWhiteList.add(t)}static addAclBlackList(e){for(let t of e)this.aclBlackList.add(t)}static getOrCreateSet(e,t){let n=e.get(t);return n||(n=new Set,e.set(t,n)),n}static readBuiltInConfigText(){if(this.builtInConfigTextLoader)return this.builtInConfigTextLoader();let e=ut.join(this.getResourcesDir(),this.ACL_PERMISSIONS_CONFIG_PATH);if(ds.existsSync(e))return ds.readFileSync(e,"utf-8")}static getResourcesDir(){let e=import.meta.url,t=yV(e);if(t.includes("dist")){let s=ut.dirname(t),a=ut.dirname(s);return ut.join(a,"src","resources")}let n=ut.dirname(t),i=ut.dirname(n),o=ut.dirname(i);return ut.join(o,"src","resources")}static initAclPermissionFromBuiltInConfig(e,t){let n;try{n=this.readBuiltInConfigText()}catch{ls("read builtin acl permission failed.");return}if(n!==void 0)try{let i=JSON.parse(n),s=(Array.isArray(i)?i:Zu(i)?Object.values(i):[]).filter(Zu).map(a=>new Qu(a));s.forEach(a=>{let c=a.permissionInsteadName;wV(c)&&(a.permissionInsteadName=Xu(c)),e.add(a.permissionName)}),s.forEach(a=>{t.add(a)})}catch(i){ls(`failed to parse aclPermissionsInfo.json: ${i}`)}}static initAclPermissionFromSDK(e,t,n){let i=this.parsePermissionDefinitionFile(e);i&&i.forEach(o=>{if(!Zu(o))return;let s=o,a=$h(s,this.ACL_NAME_KEY);this.isAclPermission(s,a)&&(uR(a)||(this.generateAclInfos(n,a,s),t.add(a)))})}static isAclPermission(e,t){return this.aclWhiteList.has(t)?!0:this.aclBlackList.has(t)||$h(e,this.ACL_AVAILABLE_LEVEL_KEY)!==this.ACL_AVAILABLE_LEVEL_VALUE||$h(e,this.ACL_AVAILABLE_TYPE_KEY)!==this.ACL_AVAILABLE_TYPE_VALUE?!1:vV(e,this.ACL_PROVISION_ENABLE_KEY)}static generateAclInfos(e,t,n){let i=new Qu;i.permissionName=t;let o=t.startsWith(this.ACL_PREFIX)?t.slice(this.ACL_PREFIX.length):t;i.permissionDisplayName=o;let s=bV(n,this.ACL_SINCE_KEY);i.minSupportApiLevel=String(s),this.handleInsteadName(i,o),e.add(i)}static parsePermissionDefinitionFile(e){let t=ut.join(e.sdkPath,"default","openharmony","toolchains",this.PERMISSION_DEFINITIONS_RELATIVE_PATH);if(!ds.existsSync(t))return;let n;try{n=ds.readFileSync(t,"utf-8")}catch(s){ls(`failed to load permissionDefinitions.json: ${s}`);return}let i;try{let s=JSON.parse(n);if(!Zu(s)){ls("json object is null");return}i=s}catch(s){ls(`failed to parse permissionDefinitions.json: ${s}`);return}let o=i[this.ACL_DEFINE_PERMISSION_KEY];if(!Array.isArray(o)){ls("definePermissions is not an array");return}return o}static handleInsteadName(e,t){this.ACL_HAVE_INSTEAD_NAME.has(e.permissionName)&&(e.permissionInsteadName=Xu(`${this.ACL_CONFIG_PREFIX}${t}${this.ACL_INSTEAD_NAME_SUFFIX}`),e.permissionHelpUrlKey=Xu(`${this.ACL_CONFIG_PREFIX}${t}${this.ACL_HELP_URL_KEY_SUFFIX}`))}};function tp(r,e){let t=new Set,n=new Set;Un.handleSpecificAclPermissions(),Un.initAclPermission(r,e);for(let i of r.profile.modules){let o=fR(i,r,e,n,ep.join("src","main"));for(let a of o)t.add(a);let s=fR(i,r,e,n,ep.join("src","ohosTest"));for(let a of s)t.add(a)}return EV(n),t}function EV(r){if(r.size>0)throw new Error(dR.DUPLICATE_PERMISSION)}function fR(r,e,t,n,i){let o=CV(e.rootDir,r,i);if(o==null)return new Set;let s=[];for(let y of o){if(typeof y!="object"||y===null)continue;let E=PV(y,"name");E&&s.push(E)}let a=new Set(s);a.size!==s.length&&n.add(r.name);let c=ep.join(t.sdkPath,"default","sdk-pkg.json"),l=Yu(c),d=Un.getAclPermissionInfos(e),g=new Set(Array.from(d).filter(y=>{let E=Number(y.minSupportApiLevel);return Number.isFinite(E)&&E<=l}).map(y=>y.permissionName));for(let y of Array.from(a))g.has(y)||a.delete(y);return a}function PV(r,e){let t=r[e];return typeof t=="string"?t:""}function CV(r,e,t){let n=ep.join(r,e.srcPath,t,"module.json5"),i=kV(n);if(i==null)return null;let o=RV(i,"module");return o==null?null:xV(o,"requestPermissions")}function kV(r){try{if(!pR.existsSync(r))return null;let e=pR.readFileSync(r,"utf-8");return SV.parse(e)}catch{return null}}function RV(r,e){if(r==null||typeof r!="object")return null;let t=r[e];return t!=null&&typeof t=="object"&&!Array.isArray(t)?t:null}function xV(r,e){if(r==null||typeof r!="object")return null;let t=r[e];return Array.isArray(t)?t:null}var Hh=class{verifyStorePassword(e,t){try{let n=Bn.readFileSync(e),i=gR.asn1.fromDer(n.toString("binary"));return gR.pkcs12.pkcs12FromAsn1(i,t),!0}catch{return!1}}getLocalCerFingerprints(e){let n=Bn.readFileSync(e,"utf-8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g);if(n&&n.length>0)return n.map(i=>this.formatFp(new rp.X509Certificate(i).fingerprint256));try{return[this.formatFp(new rp.X509Certificate(Bn.readFileSync(e)).fingerprint256)]}catch{return[]}}getLocalCerExpiry(e,t){if(!t)return null;let i=Bn.readFileSync(e,"utf-8").match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g)??[];for(let o of i)try{let s=new rp.X509Certificate(o);if(this.formatFp(s.fingerprint256)===t){let a=new Date(s.validTo);return isNaN(a.getTime())?null:a}}catch{}return null}formatFp(e){let t=e.replace(/:/g,"");return t.match(/.{2}/g)?.join(":")??t}};function IV(r,e){let t=Bn.readFileSync(r,"utf-8"),n=AV(t),i=null;if(n)try{i=JSON.parse(n)}catch{i=null}let o=i?.["bundle-info"]??{},s=e==="release"?"distribution-certificate":"development-certificate";return{rawContent:t,bundleNameInProfile:jh(o["bundle-name"]),expiryDate:TV(i?.validity?.["not-after"]),cerFingerprintInProfile:NV(jh(o[s])),deviceUdidsInProfile:OV(i?.["debug-info"]?.["device-ids"]),aclPermissionsInProfile:_V(i?.acls?.["allowed-acls"]),teamIdInProfile:jh(o["developer-id"])}}function AV(r){let e=r.indexOf("{");if(e<0)return null;let t=0,n=-1,i=!1,o=!1;for(let s=e;s<r.length;s++){let a=r[s];if(i){o?o=!1:a==="\\"?o=!0:a==='"'&&(i=!1);continue}if(a==='"')i=!0;else if(a==="{")t++;else if(a==="}"&&(t--,t===0)){n=s;break}}return n<0?null:r.slice(e,n+1)}function TV(r){if(typeof r!="number"||!Number.isFinite(r))return null;let e=new Date(r*1e3);return isNaN(e.getTime())?null:e}function NV(r){if(!r)return null;try{let t=new rp.X509Certificate(r).fingerprint256.replace(/:/g,"");return t.match(/.{2}/g)?.join(":")??t}catch{return null}}function OV(r){if(!Array.isArray(r))return[];let e=[];for(let t of r)if(typeof t=="string"){let n=t.toUpperCase();e.includes(n)||e.push(n)}return e}function _V(r){if(!Array.isArray(r))return[];let e=[];for(let t of r)typeof t=="string"?e.push(t):t&&typeof t=="object"&&typeof t.name=="string"&&e.push(t.name);return[...new Set(e)].sort()}function jh(r){return typeof r=="string"?r:null}var ac=class r{static async shouldRegenerate(e,t){let n=await r.#e(e,t);return r.#t(n)??r.#r(n)??r.#n(n)??r.#i(n)??r.#o(n)??r.#s(n)??(n.type==="release"?null:r.#a(n))??r.#c(n)??r.#l(n)??r.#d(n)??await r.#u(n)??r.#p()}static async#e(e,t){let n=e.force,i=e.teamId,o=e.productName??"default",s=e.type,a=W.discover(process.cwd()),c=a.rootDir,[l,d]=await Promise.all([MV(o,c,s),s==="release"?Promise.resolve([]):FV(t.hdcPath)]),g=null;if(hR(l).allExist)try{g=IV(l.profileFile,s)}catch{}return{force:n,teamId:i,productName:o,projectPath:c,type:s,materialPaths:l,bundleName:a.getBundleName(o),deviceUdids:d,storePassword:await LV(c,o,l.storeFile,s),localAclPermissions:[...tp(a,t)].sort(),hapSignTool:new Hh,profileInfo:g}}static#t(e){return e.force?(f("[reGenerateSign] --force flag set, skipping all checks"),{shouldRegenerate:!0,reason:"--force flag set",checkDetails:bt({force:!0})}):null}static#r(e){let t=hR(e.materialPaths);return t.allExist?null:(f(`[reGenerateSign] missing files: ${t.missing.join(",")}`),{shouldRegenerate:!0,reason:`Missing files: ${t.missing.join(", ")}`,checkDetails:bt({allFilesExist:!1,missingFiles:t.missing})})}static#n(e){return(e.profileInfo?.rawContent??"").trim().length>0?null:(f("[reGenerateSign] profile content is empty"),{shouldRegenerate:!0,reason:"Profile file content is empty",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!1})})}static#i(e){let t=e.profileInfo?.expiryDate;return!t||t>=new Date?null:(f(`[reGenerateSign] profile expired at ${t.toISOString()}`),{shouldRegenerate:!0,reason:`Profile expired at ${t.toISOString()}`,checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!1})})}static#o(e){let t=e.profileInfo?.bundleNameInProfile;return t&&t===e.bundleName?null:(f(`[reGenerateSign] bundleName mismatch \u2014 current=${e.bundleName}, profile=${t}`),{shouldRegenerate:!0,reason:`bundleName mismatch: current=${e.bundleName}, in profile=${t}`,checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!1})})}static#s(e){let t=e.profileInfo?.teamIdInProfile;return t&&t===e.teamId?null:(f(`[reGenerateSign] teamId mismatch \u2014 current=${e.teamId}, profile=${t}`),{shouldRegenerate:!0,reason:`teamId mismatch: current=${e.teamId}, in profile=${t}`,checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!1})})}static#a(e){let t=jV(e.profileInfo?.deviceUdidsInProfile??[],e.deviceUdids);return t.allPresent?null:(f(`[reGenerateSign] missing device UDIDs: ${t.missing.join(",")}`),{shouldRegenerate:!0,reason:`Device UDID(s) not in profile: ${t.missing.join(", ")}`,checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!1,missingDeviceUdids:t.missing})})}static#c(e){return HV(e.localAclPermissions,e.profileInfo?.aclPermissionsInProfile??[])?null:(f("[reGenerateSign] ACL permissions mismatch"),{shouldRegenerate:!0,reason:"ACL permissions mismatch between project and profile",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!1})})}static#l(e){let t=e.hapSignTool.getLocalCerFingerprints(e.materialPaths.cerFile),n=e.profileInfo?.cerFingerprintInProfile;return n&&t.includes(n)?null:(f("[reGenerateSign] certificate mismatch"),{shouldRegenerate:!0,reason:"Certificate mismatch between profile and local .cer file",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!1})})}static#d(e){let t=e.profileInfo?.cerFingerprintInProfile,n=e.hapSignTool.getLocalCerExpiry(e.materialPaths.cerFile,t);return!n||n>=new Date?null:(f(`[reGenerateSign] local certificate expired at ${n.toISOString()}`),{shouldRegenerate:!0,reason:`Local certificate expired at ${n.toISOString()}`,checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!1})})}static async#u(e){return e.storePassword?e.hapSignTool.verifyStorePassword(e.materialPaths.storeFile,e.storePassword)?null:(f("[reGenerateSign] keystore password verification failed"),{shouldRegenerate:!0,reason:"Keystore password verification failed (storeFile may be corrupted or password changed)",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!1})}):(f("[reGenerateSign] no stored keystore password"),{shouldRegenerate:!0,reason:"No stored keystore password available for verification",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!1})})}static#p(){return f("[reGenerateSign] all checks passed \u2014 skip regeneration"),{shouldRegenerate:!1,reason:"",checkDetails:bt({allFilesExist:!0,profileContentNotEmpty:!0,profileNotExpired:!0,bundleNameMatched:!0,teamIdMatched:!0,allDevicesInProfile:!0,aclMatched:!0,cerMatched:!0,cerNotExpired:!0,storePasswordValid:!0})}}};async function MV(r,e,t){let[n,i,o,s]=await Promise.all([Be(r,e,"p12",t),Be(r,e,"csr",t),Be(r,e,"cer",t),Be(r,e,"p7b",t)]);return{storeFile:n,csrFile:i,cerFile:o,profileFile:s}}async function LV(r,e,t,n){let i=yR.join(r,"build-profile.json5");if(!Bn.existsSync(i))return;let o;try{o=DV.parse(Bn.readFileSync(i,"utf-8"))}catch{return}let s=n==="release"?`${e}_release`:e,l=(o?.app?.signingConfigs??[]).find(d=>d.name===s)?.material?.storePassword;if(l)try{return await Hn.decryptPassword(l,t)}catch{return}}async function FV(r){f(`Executing: ${r} list targets`);let{stdout:e}=await mR(r,["list","targets"],{stdio:["ignore","pipe","pipe"]}),t=[];for(let i of e.split(`
1396
+ `)){let o=i.trim();if(!o||o.startsWith("[Empty]"))continue;let s=o.split(/\s+/),a=s[0],c=s.length>=2?s[1]:"device";a&&!a.startsWith("[Empty]")&&c.toLowerCase()!=="unauthorized"&&t.push(a)}let n=[];for(let i of t)try{f(`Executing: ${r} -t ${i} shell bm get -u`);let{stdout:o}=await mR(r,["-t",i,"shell","bm","get","-u"],{stdio:["ignore","pipe","pipe"]}),s=$V(o);s&&n.push(s)}catch{f(`[reGenerateSign] Failed to get UDID for ${i}, skipping`)}return n}function $V(r){let e=r.trim();if(!e)return null;let t=e.split(`
1397
+ `);for(let i=0;i<t.length-1;i++)if(t[i].includes("udid of current device is")){let s=t[i+1].trim().match(/^[A-Fa-f0-9]{64}$/);if(s)return s[0].toUpperCase()}let n=e.match(/[A-Fa-f0-9]{64}/);return n?n[0].toUpperCase():null}function hR(r){let e=[r.storeFile,r.csrFile,r.cerFile,r.profileFile],t=[];for(let n of e)Bn.existsSync(n)||t.push(n);return{allExist:t.length===0,missing:t}}function jV(r,e){let t=[];for(let n of e)r.includes(n)||t.push(n);return{allPresent:t.length===0,missing:t}}function HV(r,e){let t=[...r].sort(),n=[...e].sort();return t.length!==n.length?!1:t.every((i,o)=>i===n[o])}function bt(r){let e={force:!1,allFilesExist:!1,missingFiles:[],profileContentNotEmpty:!1,profileNotExpired:!1,bundleNameMatched:!1,teamIdMatched:!1,allDevicesInProfile:!1,missingDeviceUdids:[],aclMatched:!1,cerMatched:!1,cerNotExpired:!1,storePasswordValid:!1};return r.force?{...e,force:!0}:{...e,...r,force:!1}}import{debuglog as Uh}from"util";import{execa as Bh}from"execa";async function vR(r,e){let t=await np(r);if(!t)throw new Error(x.DEVICE_LIST_EMPTY);let n=await WV(e);if(t.length===0)for(let s of n)await UV(r,s.udid,s.deviceName);else for(let s of n)await BV(r,t,s.udid,s.deviceName);let o=(await np(r)).map(s=>s.id);if(o.length===0)throw new Error(x.DEVICE_LIST_EMPTY);return o}async function UV(r,e,t){await ER(r,e,bR(t))}async function BV(r,e,t,n){for(let i=0;i<e.length;i++){if(t===e[i].udid)return;if(i===e.length-1){await ER(r,t,bR(n));return}}}function bR(r){switch(r){case"liteWearable":return"1";case"wearable":return"2";case"tv":return"3";default:return"4"}}async function wR(r,e=1,t=100){let n=`${me.BASE_URL}${me.DEVICE_LIST_PATH}?encodeFlag=0&start=${e}&pageSize=${t}`,i=PR(r),o=await j.get(n,{headers:i});if(!o)throw Uh("query devices failed: response is null"),new Error(x.ERROR_WHILE_ADD_DEVICE);if(o.statusCode!==200)throw SR(o.statusCode,o.statusText,o.data);let s=JSON.parse(o.data);if(!s||!s.list)throw Uh("query devices failed: response list is null"),new Error(s.ret?.msg||x.ERROR_WHILE_ADD_DEVICE);return{deviceList:s.list,total:s.totalCount||0}}function SR(r,e,t){return r===rr.FORBIDDEN?e===Oe.OPENPROXY_BLOCKED_URL?new Error(x.ERR_CERT_NETWORK_ERROR):new Error(x.ERR_FORBIDDEN):r===rr.UNAUTHORIZED?new Error(x.ERR_UNAUTHORIZED):t.includes(Oe.DEVICE_EXCEEDS_LIMIT_CODE)?new Error(x.DEVICE_LIMIT_REACHED):new Error(x.ERROR_WHILE_ADD_DEVICE)}async function np(r){let t=await wR(r,1,100);if(!t||!t.deviceList||t.deviceList.length===0)return[];let n=[...t.deviceList],i=t.total,o=Math.floor(i/100)+(i%100===0?0:1);for(let s=2;s<=o;s++){let a=await wR(r,s,100);if(!a||!a.deviceList||a.deviceList.length===0)break;n.push(...a.deviceList)}return n}async function ER(r,e,t){let n=`${me.BASE_URL}${me.DEVICE_ADD_PATH}`,i=PR(r),s={deviceName:`auto_sign_device_No.${Math.floor(Math.random()*3e3)}${Date.now()}`,udid:e,deviceType:t},a=await j.postAllowFailure(n,{headers:i,params:s});if(!a)throw Uh("add device failed: response is null"),new Error(x.ERROR_WHILE_ADD_DEVICE);if(a.statusCode!==200)throw SR(a.statusCode,a.statusText,a.data);let c=a.data,l=JSON.parse(a.data);if(!l||!l.ret||l.ret.code!==0)throw c.includes(Oe.DEVICE_EXCEEDS_LIMIT_CODE)?new Error(x.DEVICE_LIMIT_REACHED):c.includes(Oe.DEVICE_NAME_REPEAT_CODE)?new Error(x.DEVICE_NAME_REPEAT):new Error(x.ERROR_WHILE_ADD_DEVICE)}function PR(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}async function WV(r){let{stdout:e}=await Bh(r,["list","targets"],{stdio:["ignore","pipe","pipe"]}),t=[];for(let i of e.split(`
1398
+ `)){let o=i.trim();if(!o||o.startsWith("[Empty]"))continue;let s=o.split(/\s+/),a=s[0],c=s.length>=2?s[1]:"device";a&&!a.startsWith("[Empty]")&&c.toLowerCase()!=="unauthorized"&&t.push(a)}let n=[];for(let i of t)try{let o=await VV(i,r),s=await GV(i,r);o.length>0&&n.push({id:"",udid:o,deviceName:s})}catch{f(`Failed to get device info for ${i}, skipping`)}return n}async function VV(r,e){let{stdout:t}=await Bh(e,["-t",r,"shell","bm","get","-u"],{stdio:["ignore","pipe","pipe"]}),n=t.trim();if(!n)return"";let i=n.split(`
1399
+ `);for(let s=0;s<i.length-1;s++)if(i[s].includes("udid of current device is")){let c=i[s+1].trim().match(/^[A-Fa-f0-9]{64}$/);if(c)return c[0].toUpperCase()}let o=n.match(/[A-Fa-f0-9]{64}/);return o?o[0].toUpperCase():""}async function GV(r,e){let{stdout:t}=await Bh(e,["-c","-t",r,"shell","getprop","hw_sc.build.os.deviceType"],{stdio:["ignore","pipe","pipe"]});return qV(t)}function qV(r){let e=r.trim();return!e||e.includes("inaccessible")?"phone":r.includes("liteWearable")?"liteWearable":r.includes("wearable")?"wearable":r.includes("tv")?"tv":"phone"}import Mi from"fs";import{createHash as zV}from"crypto";import{debuglog as Fi}from"util";import{Buffer as kR}from"buffer";import{createPublicKey as JV,X509Certificate as Wh}from"crypto";import{readFileSync as KV}from"fs";import Li from"node-forge";async function RR(r,e){console.log("Start generating profile");let{productName:t,bundleName:n,projectPath:i,aclPermissionList:o,allDeviceIds:s,certIds:a,keyAlias:c,keyPwd:l}=e,d=e.type==="release";if(!d&&(s==null||s.length===0))throw new Error(x.DEVICE_LIST_EMPTY);let g=d?me.PROVISION_ADD_REAL_PATH:me.PROVISION_ADD_TEST_PATH,y=`${me.BASE_URL}${g}`,E=YV(t,n),K=await ZV(r,y,a||[],n,s??[],E,o||[]);if(!K||!K.profileInfo||!K.profileInfo.provisionFileUrl)throw Fi("add provision failed, the provision file url is null"),new Error(x.ADD_PROFILE_FAIL);let we=K.profileInfo,ir=(await r2(r,we.provisionFileUrl)).urlList,Vn=K.profileInfo.id;if(ir&&ir.length>0){let Gn=await qu(t,i,e.type),qn=Gn.profilePath;if(!await n2(ir,qn))throw await CR(r,Vn),new Error(x.ERROR_WHILE_DOWNLOAD_PROFILE);if(await CR(r,Vn),Mi.existsSync(Gn.certPath)&&Mi.existsSync(qn)&&Mi.existsSync(Gn.p12Path)){let qR=Mi.readFileSync(Gn.certPath,"utf8"),zR=Mi.readFileSync(qn,"utf8");return i2(zR,qR,Gn.p12Path,c,l)||t2(qn),qn}}throw new Error(x.ADD_PROFILE_FAIL)}function YV(r,e){let t=r?`${r}_`:"";return`${XV(`${t}${e}_${e}`)}`}function XV(r){return zV("sha256").update(r).digest("hex").substring(0,16)}async function ZV(r,e,t,n,i,o,s){QV(n);let a=Gh(r),c={certList:t,packageName:n,provisionName:o};i.length>0&&(c.deviceList=i),s.length&&(c.aclPermissionList=s);let l=await j.postAllowFailure(e,{headers:a,params:c});if(!l)throw f("[generateProfile] add provision failed: response is null"),new Error(x.ADD_PROFILE_FAIL);if(l.statusCode!==200)throw f(`[generateProfile] add provision HTTP ${l.statusCode}: ${l.data}`),Vh(l.statusCode,l.statusText,l.data);let d=JSON.parse(l.data);if(!d||!d.ret||d.ret.code!==0)throw f(`[generateProfile] add provision fail: ${l.data}`),e2(l.data,o),new Error(d.ret?.msg||x.ADD_PROFILE_FAIL);let g=d.provisionFileUrl;return{profileInfo:{id:d.id,name:o,provisionFileUrl:g}}}function Vh(r,e,t){return r===rr.FORBIDDEN?e===Oe.OPENPROXY_BLOCKED_URL?new Error(x.ERR_CERT_NETWORK_ERROR):new Error(x.ERR_FORBIDDEN):r===rr.UNAUTHORIZED?new Error(x.ERR_UNAUTHORIZED):t.includes(Oe.PROVISION_EXCEEDS_LIMIT_CODE)?new Error(x.TEST_PROVISION_EXCEEDS_LIMIT):new Error(x.ADD_PROFILE_FAIL)}function QV(r){if(!r||r.trim().length===0)throw new Error(x.ERROR_SIGN_BUNDLE_NAME_VALIDATE);if(!De.BUNDLE_NAME_REGEX.test(r))throw new Error(x.ERROR_SIGN_BUNDLE_NAME_VALIDATE)}function e2(r,e){if(r.includes(Oe.PROVISION_EXCEEDS_LIMIT_CODE))throw new Error(x.TEST_PROVISION_EXCEEDS_LIMIT);if(r.includes(Oe.PROVISION_NAME_REPEAT_CODE)&&e)throw new Error(x.PROFILE_NAME_REPEAT)}async function CR(r,e){if(!e||e.trim().length===0)return;let t=`${me.BASE_URL}${me.PROVISION_DELETE_PATH}?id=${e}`,n=await j.deleteAllowFailure(t,{headers:Gh(r)});if(n.statusCode!==200)throw Vh(n.statusCode,n.statusText,n.data);let i=JSON.parse(n.data);(!i||!i.ret||i.ret.code!==0)&&Fi(`delete provision failed: ${n.data}`)}function t2(...r){for(let e of r)try{Mi.existsSync(e)&&Mi.unlinkSync(e)}catch(t){Fi(`delete local sign file error: ${t.message}`)}}async function r2(r,e){let t=`${me.BASE_URL}${me.CERT_DOWNLOAD_URL_PATH}`,n=Gh(r),i={sourceUrls:e},o=await j.postAllowFailure(t,{headers:n,params:i});if(!o)throw Fi("get download list failed: response is null"),new Error(x.ADD_PROFILE_FAIL);if(o.statusCode!==200)throw Vh(o.statusCode,o.statusText,o.data);let s=JSON.parse(o.data);if(!s||!s.urlsInfo||s.urlsInfo.length===0)throw Fi("download: The application does not exist"),new Error(s.ret?.msg||x.ADD_PROFILE_FAIL);return{urlList:s.urlsInfo,hasPermission:!0}}async function n2(r,e){if(!r||r.length===0)return!1;let t=r[0];return await ic(t.newUrl,e,t.sha256),!0}function i2(r,e,t,n,i){return o2(r,e),n=n||De.TARGET_FRIENDLY_NAME,i=i||"",s2(e,t,n,i),!0}function o2(r,e){if(e.lastIndexOf(De.CERT_BEGIN_HEADER)<0)throw new Error(x.ERROR_WHILE_PARSE_PROFILE);let t=JSON.stringify(e.substring(e.lastIndexOf(De.CERT_BEGIN_HEADER))).replace(/\\r/g,"");if(!r.includes(t))throw new Error(x.CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT);return!0}function s2(r,e,t,n){let i=r.matchAll(De.CERTIFICATE_PATTERN_GLOBAL),o=[],s=new Date;for(let c of i)try{let l=c[0],d=a2(l),g=new Date(d.validFrom),y=new Date(d.validTo);if(s<g||s>y){let E=`Certificate is not valid, Valid from ${g} to ${y}`;throw console.warn(`checkCertificateInValidityPeriod: ${E}`),new Error(x.CERTIFICATE_HAS_EXPIRED)}o.push(d)}catch(l){throw console.warn(`checkCertificateInValidityPeriod\uFF1A ${l.message}`),new Error(x.CERTIFICATE_HAS_EXPIRED,{cause:l})}if(!o||o.length===0)throw new Error(x.CERTIFICATE_HAS_EXPIRED);if(!l2(e,t,n,o))throw new Error(x.CERTIFICATION_AND_PROFILE_NOT_INCONSISTENT)}function a2(r){let e="-----BEGIN CERTIFICATE-----",t=r.trim();try{if(t.startsWith(e))return new Wh(t);let n=kR.from(t,"base64");return new Wh(n)}catch(n){throw new Error("decodeBase64ToX509Certificate",{cause:n})}}function c2(r){if(r.cert){let e=Li.pki.publicKeyToPem(r.cert.publicKey);return JV(e).export({type:"spki",format:"der"})}if(r.asn1)try{let e=Li.asn1.toDer(r.asn1).getBytes(),t=kR.from(e,"binary");return new Wh(t).publicKey.export({type:"spki",format:"der"})}catch(e){return Fi(`Failed to parse cert from asn1: ${e}`),null}return null}function l2(r,e,t,n){try{let i=KV(r),o=Li.asn1.fromDer(Li.util.createBuffer(i)),c=Li.pkcs12.pkcs12FromAsn1(o,t).getBags({bagType:Li.pki.oids.certBag})[Li.pki.oids.certBag]||[];for(let l of c){let d=l.attributes?.friendlyName?.[0];if(!d||d.toLowerCase()!==e.toLowerCase())continue;let g=c2(l);if(!g)continue;if(n.some(E=>{let K=E.publicKey.export({type:"spki",format:"der"});return g.equals(K)}))return!0}return!1}catch(i){let o=i instanceof Error?i.message:String(i);return Fi(`Failed to process P12 file: ${r}, error: ${o}`),!1}}function Gh(r){return{uid:r.uid,teamId:r.teamId,oauth2Token:r.accessToken}}var DR="https://developer.huawei.com",d2={"ohos.permission.SYSTEM_FLOAT_WINDOW":"/consumer/cn/doc/harmonyos-guides/window-pipwindow","ohos.permission.READ_CONTACTS":"/consumer/cn/doc/harmonyos-references/js-apis-contact#contactselectcontacts10","ohos.permission.READ_IMAGEVIDEO":"/consumer/cn/doc/harmonyos-guides/select-user-file#%E9%80%89%E6%8B%A9%E5%9B%BE%E7%89%87%E6%88%96%E8%A7%86%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.WRITE_IMAGEVIDEO":"/consumer/cn/doc/harmonyos-guides/savebutton","ohos.permission.READ_AUDIO":"/consumer/cn/doc/harmonyos-guides/select-user-file#%E9%80%89%E6%8B%A9%E9%9F%B3%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.WRITE_AUDIO":"/consumer/cn/doc/harmonyos-guides/save-user-file#%E4%BF%9D%E5%AD%98%E9%9F%B3%E9%A2%91%E7%B1%BB%E6%96%87%E4%BB%B6","ohos.permission.READ_PASTEBOARD":"/consumer/cn/doc/harmonyos-guides/pastebutton"},u2="/consumer/cn/doc/harmonyos-guides/restricted-permissions";function p2(r){let e=d2[r];return e?`${DR}${e}`:void 0}function f2(){return`${DR}${u2}`}var m2={"acl.can.apply.text":"Permission Application Scenarios","acl.permissions.warn":"Note: You are applying for restricted ACL permissions: {0} These permissions are subject to review together with your app release. For a faster review process, apply for the following permissions instead, if they are sufficient for your purposes: {1} {2}"};function xR(r,e){return(m2[r]??r).replace(/\{(\d+)\}/g,(n,i)=>String(e[Number(i)]??""))}function g2(r){return Array.from(r).join(", ")}function IR(r,e){if(r.size===0)return;let t=Un.getAclPermissionInfos(e),n=new Set;for(let g of t)r.has(g.permissionName)&&n.add(g);for(let g of n){let y=p2(g.permissionName);y!=null&&(g.permissionHelpUrlKey=y)}let i=new Set;for(let g of n)i.add(g.permissionDisplayName);let o=new Set;for(let g of n)if(g.permissionHelpUrlKey!=null){let y=g.permissionInsteadName??g.permissionDisplayName;o.add(`${y} (${g.permissionHelpUrlKey})`)}let s=f2(),a=xR("acl.can.apply.text",[]),c=s?`${a} (${s})`:a,l=o.size>0?Array.from(o).join(", ")+".":"",d=xR("acl.permissions.warn",[g2(i),l,c]);console.log(d)}var ip=class{_project=null;get project(){if(!this._project)throw new Error("Project not initialized. Call checkProjectDir first.");return this._project}checkProjectDir(e){try{return this._project=W.discover(process.cwd()),{passed:!0,message:""}}catch(t){return f(`[EnvCheck] Project.discover() failed: ${t.message}`),e(be.PROJECT_DIR_MISSING)}}checkProduct(e,t){try{return this._project.validateProduct(e),{passed:!0,message:""}}catch(n){return f(`[EnvCheck] Product validation failed: ${n.message}`),t(`Product "${e}" not found.Check the product property in the build-profile.json5 file.`)}}checkBundleName(e,t){try{return this._project.getBundleName(),{passed:!0,message:""}}catch(n){return f(`[EnvCheck] BundleName check failed: ${n.message}`),t(`bundleName was not found under product "${e}".Check the bundleName configuration.`)}}checkAtomicService(){return this._project.isAtomicService()?{passed:!1,message:be.ATOMIC_SERVICE_UNSUPPORTED}:{passed:!0,message:""}}};import h2 from"fs";import AR from"path";var op=class{constructor(e){this.toolProvider=e}checkJava(e){try{return this.toolProvider.assertJava(),{passed:!0,message:""}}catch(t){return f(`[EnvCheck] Java check failed: ${t.message}`),e(`${t.message}`)}}checkHapSignTools(e){let t=this.toolProvider.sdkPath,n=AR.join(t,"default","openharmony","toolchains","lib","hap-sign-tool.jar");if(!h2.existsSync(n)){let i=AR.join("sdk","default","openharmony","toolchains","lib","hap_sign_tools.jar");return e(`hap_sign_tools.jar not found.Check whether ${i} exists.`)}return{passed:!0,message:""}}};var sp=class{_userInfo=null;async ensureUserInfo(){if(!this._userInfo)try{this._userInfo=await Xe.getUserInfo()}catch(e){return f(`[EnvCheck] Failed to load user info: ${e.message}`),null}return this._userInfo}async checkLogin(e){try{return await Xe.isLoggedIn()?(await this.ensureUserInfo(),{passed:!0,message:""}):e(be.LOGIN_REQUIRED)}catch(t){return f(`[EnvCheck] Login check failed: ${t.message}`),e(be.LOGIN_REQUIRED)}}async checkTeamInfo(e){if(!await this.ensureUserInfo())return e(be.TEAM_INFO_FAILED);try{if((await Cn()).teamList.length>0)return{passed:!0,message:""}}catch(n){return f(`[EnvCheck] Team API error: ${n.message}`),e(be.TEAM_INFO_FAILED)}return f("[EnvCheck] No teams found for current user"),e(be.TEAM_INFO_FAILED)}async checkRealname(e){let t=await this.ensureUserInfo();return t?t.isRealName===!1?e(be.REALNAME_REQUIRED):t.isRealName!==!0?(f("[EnvCheck] Scenario 3 Real-name check: AGC API did not return realName field"),e(be.REALNAME_REQUIRED)):{passed:!0,message:""}:e(be.SESSION_EXPIRED)}async checkTeamId(e){let t=await this.ensureUserInfo();if(!t)return{passed:!0,message:""};let n=e??"";try{let i=await Cn();if(n=e??(i.teamList.length>0?i.teamList[0].id:t.userId)??"",!i.teamList.some(s=>s.id===n)){let s=`team-id for ${n} not found.Run devecocli auth team list to view the team to which the logged-in user belongs.`;return f(`[EnvCheck] ${s}`),{passed:!1,message:s}}return{passed:!0,message:""}}catch(i){return f(`[EnvCheck] Team ID check failed: ${i.message}`),{passed:!1,message:`team-id for ${n} not found.Run devecocli auth team list to view the team to which the logged-in user belongs.`}}}async checkRegion(e){let t=await this.ensureUserInfo();return t?t.countryCode?t.countryCode!=="CN"?e(be.REGION_CHINA_ONLY):{passed:!0,message:""}:(f("[EnvCheck] Scenario 12 Region check: AGC API did not return nationalCode field"),e(be.REGION_CHINA_ONLY)):e("User session expired or token invalid. Please login again.")}};async function y2(r){try{let{teamList:e}=await Cn();if(e.length>0)return e[0].id}catch(e){f(`[EnvCheck] resolveDefaultTeamId failed: ${e.message}`)}return r??""}async function w2(r){let e=await Xe.getUserInfo(),t=await Xe.refreshToken();if(!e||!t?.accessToken)throw new Error("Not logged in");let n=r||await y2(e.userId);if(!n)throw new Error("No team found");let i={uid:e.userId??"",teamId:n,accessToken:t.accessToken};return(await np(i)).map(s=>({deviceId:s.udid,deviceName:s.deviceName}))}var ap=class{constructor(e){this.toolProvider=e}async checkDevice(e,t){try{let n=await w2(t);if(n.length>0)return f(`[EnvCheck] Scenario 4 Device check: ${n.length} device(s) found in AGC cloud, skipping local device check`),{passed:!0,message:""};f("[EnvCheck] Scenario 4 Device check: no cloud devices found, falling back to local hdc");let o=await le.from(this.toolProvider).listDevices();return o.length===0?(f("[EnvCheck] Scenario 4 Device check: no local devices found"),e(be.DEVICE_MISSING)):o.some(a=>mr(a.serial))?{passed:!0,message:""}:(f("[EnvCheck] Scenario 4 Device check: local device found but not an emulator"),e(be.DEVICE_MISSING))}catch(n){return f(`[EnvCheck] Scenario 4 Device check failed: ${n.message}`),e(be.DEVICE_DETECT_FAILED)}}};var cp=class{projectChecker=new ip;toolchainChecker=null;authChecker=new sp;deviceChecker=null;constructor(){}async preflight(e){let t=n=>this.blockingFail(n);return!(!await this.runAuthChain(e,t)||!await this.initToolchain()||e.type!=="release"&&!await this.runDeviceCheck(e,t)||!await this.runProjectChecks(e,t)||!await this.runAuxChecks(e))}async runAuthChain(e,t){let n=o=>(o.passed||this.fail(o),!0),i=[()=>this.authChecker.checkLogin(t),()=>this.authChecker.checkRealname(t),()=>this.authChecker.checkTeamInfo(t)];for(let o of i)if(!n(await o()))return!1;return!(e.teamId&&!n(await this.authChecker.checkTeamId(e.teamId)))}async initToolchain(){try{let e=await C.new();return this.toolchainChecker=new op(e),this.deviceChecker=new ap(e),!0}catch(e){throw f(`[EnvCheck] ToolProvider.new() failed: ${e.message}`),new Error(be.TOOLCHAIN_INIT_FAILED,{cause:e})}}async runDeviceCheck(e,t){return(i=>i.passed?!0:(this.fail(i),!1))(await this.deviceChecker.checkDevice(t,e.teamId))}async runProjectChecks(e,t){let n=o=>o.passed?!0:(this.fail(o),!1);if(!n(this.projectChecker.checkProjectDir(t))||!n(this.projectChecker.checkAtomicService()))return!1;let i=[()=>this.projectChecker.checkProduct(e.productName,t),()=>this.projectChecker.checkBundleName(e.productName,t),()=>this.toolchainChecker.checkJava(t),()=>this.toolchainChecker.checkHapSignTools(t)];for(let o of i)if(!n(o()))return!1;return!0}async runAuxChecks(e){let t=n=>n.passed?!0:(this.fail(n),!1);return!e.teamId&&!t(await this.authChecker.checkTeamId(e.teamId))?!1:(await this.authChecker.checkRegion(n=>this.blockingFail(n)),!0)}blockingFail(e){return{passed:!1,message:e}}fail(e){throw f(`[EnvCheck] FAIL: ${e.message}`),new Error(e.message)}};var TR=5*1024*1024;function S2(r){try{let e=$i.statSync(r);if(e.size>TR)throw new Error(`Profile file too large: ${e.size} bytes (max ${TR} bytes): ${r}`);let t=$i.readFileSync(r,"utf-8");return _R.parse(t)}catch(e){if(e.code==="ENOENT")return{app:{signingConfigs:[],products:[]}};throw new Error(`Failed to read profile: ${r}`,{cause:e})}}function E2(r){r.app||(r.app={signingConfigs:[],products:[]}),r.app.signingConfigs||(r.app.signingConfigs=[]),r.app.products||(r.app.products=[])}async function P2(r){if(r.keyPwd===r.storePassword){let n=await Hn.encryptedPassword(r.keyPwd,r.p12FilePath);return{keyPassword:n,storePassword:n}}let e=await Hn.encryptedPassword(r.keyPwd,r.p12FilePath),t=await Hn.encryptedPassword(r.storePassword,r.p12FilePath);return{keyPassword:e,storePassword:t}}async function MR(r,e,t,n){let i=zh.join(r,"build-profile.json5"),o=S2(i);E2(o);let s=n==="release"?`${t??"default"}_release`:t??"default",{keyPassword:a,storePassword:c}=await P2(e),l={name:s,type:"HarmonyOS",material:{certpath:e.cerFilePath,keyAlias:e.keyAlias,keyPassword:a,profile:e.profileFilePath,signAlg:tn.signAlg,storeFile:e.p12FilePath,storePassword:c}},d=o.app?.signingConfigs?.findIndex(y=>y.name===s);d!==void 0&&d>=0?o.app.signingConfigs[d]=l:o.app.signingConfigs.push(l);let g=o.app?.products?.findIndex(y=>y.name===t);g!==void 0&&g>=0?o.app.products[g].signingConfig=s:o.app.products.push({name:t,signingConfig:s}),$i.writeFileSync(i,_R.stringify(o,null,2),"utf-8")}async function C2(r){let e=await Xe.getUserInfo(),t=await Xe.refreshToken();if(!e||!t)throw new Error("Failed to obtain login credentials. Run `devecocli auth login` again.");return{uid:e.userId??"",teamId:r.teamId??e.userId??"",accessToken:t.accessToken??""}}var NR=["debug","release"];async function k2(r){let e=r.product||"default";if(r.type&&!NR.includes(r.type))throw new Error(`Invalid signing type '${r.type}'. Valid types: ${NR.join(", ")}`);await new cp().preflight({productName:e,teamId:r.teamId,type:r.type}),await nt.warnInvalidBundledLinks(W.discover(process.cwd()).rootDir),console.log("Executing signature generate command");let n=await C2(r),i=await C.new(),{shouldRegenerate:o}=await ac.shouldRegenerate({force:r.force??!1,teamId:n.teamId,productName:r.product,type:r.type},i);if(!o){console.log(qh("Signature generation completed successfully."));return}await R2(r,n,i)||(process.exitCode=1)}async function R2(r,e,t){if(r.type==="release"&&await D2(r))return!1;let n=await Oh(e,r.product,r.type),i=I2(r,e,n,t);r.type!=="release"&&(i.allDeviceIds=await vR(e,t.hdcPath));try{await RR(e,i)}catch(s){if(r.type==="release")return x2(r,n);throw s}let o=W.discover(process.cwd()).rootDir;return await MR(o,n,r.product??"default",r.type),console.log(qh(`Signing config written to ${zh.join(o,"build-profile.json5")}`)),console.log(qh("Signature generation completed successfully.")),!0}async function x2(r,e){let t=r.product||"default",n=W.discover(process.cwd()).rootDir;return await MR(n,e,t,r.type),console.warn(OR(`
1384
1400
  Release certificate materials generated successfully, but the release Profile (.p7b) cannot be auto-generated.
1385
1401
  Signing config (with encrypted p12 password) has been written to build-profile.json5.
1386
1402
  Please go to AGC (https://developer.huawei.com/consumer/cn/doc/doccenter-deveco-studio/ide-publish-app#section1079214271414) to manually apply for a release Profile:
@@ -1394,8 +1410,8 @@ Generated files:
1394
1410
  csr: ${e.csrFilePath}
1395
1411
  cer: ${e.cerFilePath}
1396
1412
 
1397
- Signing config '${t}_release' written to ${eh.join(n,"build-profile.json5")}
1398
- `)),!1}async function K1(r){let e=W.discover(process.cwd()).rootDir,t=r.product||"default",n=await fu(t,e,r.type),i=Ii.existsSync(n.p12Path)&&Ii.existsSync(n.csrPath)&&Ii.existsSync(n.certPath),o=Ii.existsSync(n.profilePath);return!i||o?!1:(console.warn(rk(`
1413
+ Signing config '${t}_release' written to ${zh.join(n,"build-profile.json5")}
1414
+ `)),!1}async function D2(r){let e=W.discover(process.cwd()).rootDir,t=r.product||"default",n=await qu(t,e,r.type),i=$i.existsSync(n.p12Path)&&$i.existsSync(n.csrPath)&&$i.existsSync(n.certPath),o=$i.existsSync(n.profilePath);return!i||o?!1:(console.warn(OR(`
1399
1415
  Release certificate materials already exist. Profile (.p7b) is still missing.
1400
1416
  Please go to AGC (https://developer.huawei.com/consumer/cn/doc/doccenter-deveco-studio/ide-publish-app#section1079214271414) to manually apply for a release Profile:
1401
1417
  1. Use the generated .csr file to apply for a release certificate
@@ -1407,17 +1423,17 @@ Existing files:
1407
1423
  p12: ${n.p12Path}
1408
1424
  csr: ${n.csrPath}
1409
1425
  cer: ${n.certPath}
1410
- `)),!0)}function X1(r,e,t,n){let i=process.cwd(),o=W.discover(i),s=Pu(o,n);return ZC(s,o),{productName:r.product||"default",bundleName:o.getBundleName(r.product||"default"),projectPath:o.rootDir,teamId:e.teamId,force:r.force||!1,aclPermissionList:[...s],certIds:[t.certId],keyAlias:t.keyAlias,keyPwd:t.keyPwd,type:r.type||"debug"}}var ok=new U1("signature").description("Generate application signature.");ok.command("generate").description("Automatically generate signing materials and write them to the project configuration.").option("--force","Force overwrite existing local signing materials.").option("--team-id <team-id>","Specify the team ID to use.").option("--product <product>","Specify the product. The default value is default.").option("--type <type>","Signing type: debug or release (default: debug)").action(async r=>{let e={event:v.CommandExecuted,args:["signature","generate",...r.force?["--force"]:[],...r.teamId?["--team-id"]:[],...r.product?["--product"]:[],...r.type?["--type"]:[]]},t=Date.now(),n=!0,i=null;try{await z1(r)}catch(o){n=!1,i=X(o),console.error(B1(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await D.track(e,o)}});var sk=ok;import{Command as aB}from"commander";import{green as cB,red as lh}from"colorette";import Qo from"fs";import Nu from"path";import lB from"ora";import Tu from"fs";import th from"path";import{homedir as Z1}from"os";function ak(){let r=process.env.DEVECO_CLI_DATA_DIR?$():th.join(Z1(),be.CONFIG_DIR_NAME,be.APP_NAME);return th.join(r,"ui_verification_config.json")}function ck(){let r=ak();if(!Tu.existsSync(r))return{};try{let e=JSON.parse(Tu.readFileSync(r,"utf8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function rh(){let r=ck();if(Object.keys(r).length===0)return null;let e;if(Af(r.encryptedApiKey))try{e=xf(r.encryptedApiKey)}catch{}return{baseUrl:typeof r.baseUrl=="string"?r.baseUrl:void 0,modelName:typeof r.modelName=="string"?r.modelName:void 0,apiKey:e}}function nh(r){let e=ak();Tu.mkdirSync(th.dirname(e),{recursive:!0,mode:448});let t=ck();return r.baseUrl!==void 0&&(t.baseUrl=r.baseUrl),r.modelName!==void 0&&(t.modelName=r.modelName),r.apiKey!==void 0&&(t.encryptedApiKey=Rf(r.apiKey),delete t.apiKey),Tu.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),e}import Ou from"fs";import Q1 from"os";import lk from"path";var Ti=lk.join(Q1.tmpdir(),"ui-verification","cache"),eB=15;function ih(r=Ti,e=eB){if(!Ou.existsSync(r))return;let t=Ou.readdirSync(r,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>{let i=lk.join(r,n.name);return{entryPath:i,mtime:Ou.statSync(i).mtimeMs}}).sort((n,i)=>n.mtime-i.mtime);for(let n of t.slice(0,Math.max(0,t.length-e)))Ou.rmSync(n.entryPath,{recursive:!0,force:!0})}import{execFile as tB,spawn as rB}from"child_process";import nB from"fs";import oh from"path";import{fileURLToPath as iB}from"url";function oB(){let r=oh.dirname(iB(import.meta.url));for(;;){let e=oh.join(r,"node_modules","ui-verification-mcp","bin","ui-verification-mcp.cjs");if(nB.existsSync(e))return e;let t=oh.dirname(r);if(t===r)break;r=t}throw new Error("ui-verification-mcp is not installed. Run `npm install` and try again.")}var Wa=class r{constructor(e){this.child=e;this.stopped=new Promise(n=>e.once("close",()=>n())),e.stdout?.on("data",n=>{this.buffer+=n.toString();let i=this.buffer.split(`
1426
+ `)),!0)}function I2(r,e,t,n){let i=process.cwd(),o=W.discover(i),s=tp(o,n);return IR(s,o),{productName:r.product||"default",bundleName:o.getBundleName(r.product||"default"),projectPath:o.rootDir,teamId:e.teamId,force:r.force||!1,aclPermissionList:[...s],certIds:[t.certId],keyAlias:t.keyAlias,keyPwd:t.keyPwd,type:r.type||"debug"}}var LR=new v2("signature").description("Generate application signature.");LR.command("generate").description("Automatically generate signing materials and write them to the project configuration.").option("--force","Force overwrite existing local signing materials.").option("--team-id <team-id>","Specify the team ID to use.").option("--product <product>","Specify the product. The default value is default.").option("--type <type>","Signing type: debug or release (default: debug)").action(async r=>{let e={event:v.CommandExecuted,args:["signature","generate",...r.force?["--force"]:[],...r.teamId?["--team-id"]:[],...r.product?["--product"]:[],...r.type?["--type"]:[]]},t=Date.now(),n=!0,i=null;try{await k2(r)}catch(o){n=!1,i=Z(o),console.error(b2(o.message)),process.exitCode=1}finally{let o={duration_ms:Date.now()-t,success:n,error_code:i};await R.track(e,o)}});var FR=LR;import{Command as j2}from"commander";import{green as H2,red as ry}from"colorette";import us from"fs";import up from"path";import U2 from"ora";import lp from"fs";import Jh from"path";import{homedir as A2}from"os";function $R(){let r=process.env.DEVECO_CLI_DATA_DIR?$():Jh.join(A2(),Se.CONFIG_DIR_NAME,Se.APP_NAME);return Jh.join(r,"ui_verification_config.json")}function jR(){let r=$R();if(!lp.existsSync(r))return{};try{let e=JSON.parse(lp.readFileSync(r,"utf8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function Kh(){let r=jR();if(Object.keys(r).length===0)return null;let e;if(sg(r.encryptedApiKey))try{e=og(r.encryptedApiKey)}catch{}return{baseUrl:typeof r.baseUrl=="string"?r.baseUrl:void 0,modelName:typeof r.modelName=="string"?r.modelName:void 0,apiKey:e}}function Yh(r){let e=$R();lp.mkdirSync(Jh.dirname(e),{recursive:!0,mode:448});let t=jR();return r.baseUrl!==void 0&&(t.baseUrl=r.baseUrl),r.modelName!==void 0&&(t.modelName=r.modelName),r.apiKey!==void 0&&(t.encryptedApiKey=ig(r.apiKey),delete t.apiKey),lp.writeFileSync(e,JSON.stringify(t,null,2),{encoding:"utf8",mode:384}),e}import dp from"fs";import T2 from"os";import HR from"path";var ji=HR.join(T2.tmpdir(),"ui-verification","cache"),N2=15;function Xh(r=ji,e=N2){if(!dp.existsSync(r))return;let t=dp.readdirSync(r,{withFileTypes:!0}).filter(n=>n.isDirectory()).map(n=>{let i=HR.join(r,n.name);return{entryPath:i,mtime:dp.statSync(i).mtimeMs}}).sort((n,i)=>n.mtime-i.mtime);for(let n of t.slice(0,Math.max(0,t.length-e)))dp.rmSync(n.entryPath,{recursive:!0,force:!0})}import{execFile as O2,spawn as _2}from"child_process";import M2 from"fs";import Zh from"path";import{fileURLToPath as L2}from"url";function F2(){let r=Zh.dirname(L2(import.meta.url));for(;;){let e=Zh.join(r,"node_modules","ui-verification-mcp","bin","ui-verification-mcp.cjs");if(M2.existsSync(e))return e;let t=Zh.dirname(r);if(t===r)break;r=t}throw new Error("ui-verification-mcp is not installed. Run `npm install` and try again.")}var cc=class r{constructor(e){this.child=e;this.stopped=new Promise(n=>e.once("close",()=>n())),e.stdout?.on("data",n=>{this.buffer+=n.toString();let i=this.buffer.split(`
1411
1427
  `);this.buffer=i.pop()??"";for(let o of i)if(o.trim())try{this.handleMessage(JSON.parse(o))}catch{}});let t=n=>{this.closedError??=n;for(let i of this.pending.values())i.reject(n);this.pending.clear(),this.progressHandlers.clear()};e.on("error",t),e.on("exit",(n,i)=>{let o=n===null?`signal ${i??"unknown"}`:`code ${n}`;t(new Error(`ui-verification-mcp exited with ${o}`))})}buffer="";nextId=1;pending=new Map;progressHandlers=new Map;closedError;closePromise;stopped;abortCleanup;handleMessage(e){if(!("id"in e)){if(e.method!=="notifications/progress")return;let i=e.params;if(i?.progressToken===void 0||i.progress===void 0)return;this.progressHandlers.get(i.progressToken)?.(i.progress,i.total,i.message);return}let t=e.id;if(typeof t!="number")return;let n=this.pending.get(t);n&&(this.pending.delete(t),n.resolve(e))}sendAndWait(e,t,n,i="MCP request timed out"){return new Promise((o,s)=>{if(this.closedError){s(this.closedError);return}this.registerPending(e,o,s,n,i);try{this.child.stdin?.write(`${JSON.stringify(t)}
1412
- `)}catch(a){let c=this.pending.get(e);this.pending.delete(e),c?.reject(a instanceof Error?a:new Error(String(a)))}})}registerPending(e,t,n,i,o="MCP request timed out"){let s=!1,a=i===void 0?void 0:setTimeout(()=>{s||(s=!0,this.pending.delete(e),n(new Error(o)))},i),c=()=>{a!==void 0&&clearTimeout(a)};this.pending.set(e,{resolve:l=>{s||(s=!0,c(),t(l))},reject:l=>{s||(s=!0,c(),n(l))}})}static async start(e,t){t?.throwIfAborted();let n=oB();m(`Executing: ${process.execPath} ${n}`);let i=rB(process.execPath,[n],{env:e,detached:process.platform!=="win32",stdio:["pipe","pipe","ignore"]}),o=new r(i);o.attachCancellation(t);try{return await o.sendAndWait(0,{jsonrpc:"2.0",id:0,method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"devecocli",version:"1.0.0"}}}),o}catch(s){throw await o.close(s instanceof Error?s:new Error(String(s))),s}}async callTool(e,t,n,i){let o=this.nextId++;n&&this.progressHandlers.set(o,n);try{let s=await this.sendAndWait(o,{jsonrpc:"2.0",id:o,method:"tools/call",params:{name:e,arguments:t,...n?{_meta:{progressToken:o}}:{}}},i,`${e} timed out after ${Math.floor((i??0)/6e4)} minutes`);if(s.error){let l=s.error;throw new Error(String(l.message??`${e} failed`))}let a=s.result;if(a?.structuredContent!==void 0)return a.structuredContent;let c=a?.content;return c?.length&&typeof c[0].text=="string"?c[0].text:a}finally{this.progressHandlers.delete(o)}}attachCancellation(e){if(!e)return;let t=()=>{let n=e.reason;this.close(n instanceof Error?n:new Error("Verification cancelled by user"))};e.addEventListener("abort",t,{once:!0}),this.abortCleanup=()=>e.removeEventListener("abort",t),e.aborted&&t()}close(e=new Error("ui-verification-mcp session closed")){if(this.closePromise)return this.closePromise;this.closedError??=e,this.abortCleanup?.(),this.abortCleanup=void 0;for(let t of this.pending.values())t.reject(e);return this.pending.clear(),this.progressHandlers.clear(),this.closePromise=this.terminateProcessTree(),this.closePromise}async terminateProcessTree(){if(!this.child.pid){await this.stopped;return}if(process.platform==="win32"){let t=["/pid",String(this.child.pid),"/t","/f"];m(`Executing: taskkill ${t.join(" ")}`),await new Promise(n=>tB("taskkill",t,()=>n())),await this.stopped;return}this.killProcessGroup("SIGTERM");let e=setTimeout(()=>this.killProcessGroup("SIGKILL"),1e3);try{await this.stopped}finally{clearTimeout(e),this.killProcessGroup("SIGKILL")}}killProcessGroup(e){try{process.kill(-this.child.pid,e)}catch(t){if(t.code!=="ESRCH")throw t}}};import dk from"fs";import ch from"path";async function ah(r,e){let t=await new le(r).listTargets();if(t.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");if(e){let n=e.toLowerCase(),i=t.filter(o=>o.id===e||o.name.toLowerCase().includes(n));if(i.length===1)return i[0].id;throw i.length>1?new Error(`Multiple devices match '${e}'. Use a serial instead:
1413
- ${sh(i)}`):new Error(`Device '${e}' not found.
1428
+ `)}catch(a){let c=this.pending.get(e);this.pending.delete(e),c?.reject(a instanceof Error?a:new Error(String(a)))}})}registerPending(e,t,n,i,o="MCP request timed out"){let s=!1,a=i===void 0?void 0:setTimeout(()=>{s||(s=!0,this.pending.delete(e),n(new Error(o)))},i),c=()=>{a!==void 0&&clearTimeout(a)};this.pending.set(e,{resolve:l=>{s||(s=!0,c(),t(l))},reject:l=>{s||(s=!0,c(),n(l))}})}static async start(e,t){t?.throwIfAborted();let n=F2();f(`Executing: ${process.execPath} ${n}`);let i=_2(process.execPath,[n],{env:e,detached:process.platform!=="win32",stdio:["pipe","pipe","ignore"]}),o=new r(i);o.attachCancellation(t);try{return await o.sendAndWait(0,{jsonrpc:"2.0",id:0,method:"initialize",params:{protocolVersion:"2024-11-05",capabilities:{},clientInfo:{name:"devecocli",version:"1.0.0"}}}),o}catch(s){throw await o.close(s instanceof Error?s:new Error(String(s))),s}}async callTool(e,t,n,i){let o=this.nextId++;n&&this.progressHandlers.set(o,n);try{let s=await this.sendAndWait(o,{jsonrpc:"2.0",id:o,method:"tools/call",params:{name:e,arguments:t,...n?{_meta:{progressToken:o}}:{}}},i,`${e} timed out after ${Math.floor((i??0)/6e4)} minutes`);if(s.error){let l=s.error;throw new Error(String(l.message??`${e} failed`))}let a=s.result;if(a?.structuredContent!==void 0)return a.structuredContent;let c=a?.content;return c?.length&&typeof c[0].text=="string"?c[0].text:a}finally{this.progressHandlers.delete(o)}}attachCancellation(e){if(!e)return;let t=()=>{let n=e.reason;this.close(n instanceof Error?n:new Error("Verification cancelled by user"))};e.addEventListener("abort",t,{once:!0}),this.abortCleanup=()=>e.removeEventListener("abort",t),e.aborted&&t()}close(e=new Error("ui-verification-mcp session closed")){if(this.closePromise)return this.closePromise;this.closedError??=e,this.abortCleanup?.(),this.abortCleanup=void 0;for(let t of this.pending.values())t.reject(e);return this.pending.clear(),this.progressHandlers.clear(),this.closePromise=this.terminateProcessTree(),this.closePromise}async terminateProcessTree(){if(!this.child.pid){await this.stopped;return}if(process.platform==="win32"){let t=["/pid",String(this.child.pid),"/t","/f"];f(`Executing: taskkill ${t.join(" ")}`),await new Promise(n=>O2("taskkill",t,()=>n())),await this.stopped;return}this.killProcessGroup("SIGTERM");let e=setTimeout(()=>this.killProcessGroup("SIGKILL"),1e3);try{await this.stopped}finally{clearTimeout(e),this.killProcessGroup("SIGKILL")}}killProcessGroup(e){try{process.kill(-this.child.pid,e)}catch(t){if(t.code!=="ESRCH")throw t}}};import UR from"fs";import ty from"path";async function ey(r,e){let t=await new de(r).listTargets();if(t.length===0)throw new Error("No active devices found. Start an emulator or connect a physical device.");if(e){let n=e.toLowerCase(),i=t.filter(o=>o.id===e||o.name.toLowerCase().includes(n));if(i.length===1)return i[0].id;throw i.length>1?new Error(`Multiple devices match '${e}'. Use a serial instead:
1429
+ ${Qh(i)}`):new Error(`Device '${e}' not found.
1414
1430
  Available devices:
1415
- ${sh(t)}`)}if(t.length===1)return t[0].id;throw new Error(`Multiple devices connected. Use --device <name|serial> to specify one.
1431
+ ${Qh(t)}`)}if(t.length===1)return t[0].id;throw new Error(`Multiple devices connected. Use --device <name|serial> to specify one.
1416
1432
  Available devices:
1417
- ${sh(t)}`)}function sh(r){return r.map(e=>` - ${e.name} (${e.id})`).join(`
1418
- `)}var Hn=class extends Error{exitCode;constructor(e){super("Verification cancelled by user"),this.exitCode=e==="SIGINT"?130:143}};var sB=600*1e3,Va=class{async verifyUi(e,t,n){let i=this.resolveBundleName(e.bundleName),o=await C.new(),s=await ah(o,e.device),a=new AbortController,c=()=>a.abort(new Hn("SIGINT")),l=()=>a.abort(new Hn("SIGTERM"));process.on("SIGINT",c),process.on("SIGTERM",l);let d;try{d=await this.startSession(t,o.hdcPath,a.signal);let g=await d.callTool("verifyUI",{testPlan:e.testPlan,bundleName:i,freshStart:e.freshStart,device:s},n,sB),y=this.parseVerifyResult(g);return await this.cacheArtifacts(d,y.id,a.signal),a.signal.throwIfAborted(),ih(),y}finally{try{await d?.close()}finally{process.off("SIGINT",c),process.off("SIGTERM",l)}}}startSession(e,t,n){return Wa.start({...process.env,UI_VERIFY_BASE_URL:e.baseUrl,UI_VERIFY_API_KEY:e.apiKey,UI_VERIFY_MODEL_NAME:e.modelName,UI_VERIFY_HDC_PATH:t},n)}parseVerifyResult(e){if(typeof e=="object"&&e!==null)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{throw new Error(e)}throw new Error("Failed to parse verifyUI result.")}resolveBundleName(e){if(e)return e;try{return W.discover(process.cwd()).getBundleName()}catch(t){throw new Error("Could not resolve bundleName from AppScope/app.json5. Please specify --bundle-name <name>.",{cause:t})}}async cacheArtifacts(e,t,n){let i=ch.join(Ti,t),o=ch.join(i,"screenshots");dk.mkdirSync(o,{recursive:!0});try{let s=await e.callTool("getLog",{id:t,maxLogSize:-1});dk.writeFileSync(ch.join(i,"verify.log"),String(s),"utf8")}catch{n.throwIfAborted()}try{await e.callTool("saveScreenshot",{id:t,dirname:o})}catch{n.throwIfAborted()}}};var uk=3e3;function dB(){let r=rh();return!r?.baseUrl||!r.modelName||!r.apiKey?null:{baseUrl:r.baseUrl,modelName:r.modelName,apiKey:r.apiKey}}function uB(){let r='UI \u610F\u56FE\u6821\u9A8C\u6682\u4E0D\u53EF\u7528\uFF1A\u672A\u914D\u7F6E\u591A\u6A21\u6001\u6A21\u578B\u3002\u8BF7\u8FD0\u884C devecocli verify init --base-url "your-url" --model-name "your-model-name" --api-key "your-api-key" \u6307\u4EE4\u914D\u7F6E\u591A\u6A21\u6001\u6A21\u578B\u540E\u91CD\u8BD5\u3002';console.error(lh(r)),console.log(JSON.stringify({success:!1,reason:`UI \u610F\u56FE\u6821\u9A8C\u6267\u884C\u5931\u8D25\u3002\u8BF7\u5C06\u4EE5\u4E0B\u5185\u5BB9\u539F\u6587\u544A\u77E5\u7528\u6237\uFF0C\u4E0D\u8981\u4FEE\u6539\u6216\u8865\u5145\uFF0C\u544A\u77E5\u540E\u7ACB\u5373\u505C\u6B62\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\uFF0C\u4E0D\u8981\u7EE7\u7EED\u5F53\u524D\u4EFB\u52A1\uFF1A\u300C${r}\u300D`})),process.exitCode=1}function pB(r,e){if(!r.testPlan)throw new Error("Error: --test-plan is required");let t=e.args,n=t.length>0?{...r,testPlan:[r.testPlan,...t].join(" ")}:r,i=n.testPlan;if(i&&Array.from(i).length>uk)throw new Error(`--test-plan must not exceed ${uk} characters`);return n}async function mB(r,e){let t=pB(r,e),n=dB();if(!n){uB();return}let i=lB({text:"Verifying UI\u2026",color:"cyan",discardStdin:!1}).start();try{let o=await new Va().verifyUi(t,n,(s,a,c)=>{let l=a===void 0?String(s):`${s}/${a}`;i.text=c?`${l} ${c}`:l});o.success?i.succeed(cB("Verification passed")):(i.fail(lh("Verification failed")),process.exitCode=1),console.log(JSON.stringify(o,null,2))}catch(o){i.fail(lh(o instanceof Error?o.message:String(o))),process.exitCode=o instanceof Hn?o.exitCode:1}}function fB(r){let e=Nu.join(Ti,r.id,"verify.log");if(!Qo.existsSync(e))throw new Error(`No log found for ID: ${r.id}`);let t=Qo.readFileSync(e,"utf8");if(r.searchKeywords&&(t=t.split(`
1433
+ ${Qh(t)}`)}function Qh(r){return r.map(e=>` - ${e.name} (${e.id})`).join(`
1434
+ `)}var Wn=class extends Error{exitCode;constructor(e){super("Verification cancelled by user"),this.exitCode=e==="SIGINT"?130:143}};var $2=600*1e3,lc=class{async verifyUi(e,t,n){let i=this.resolveBundleName(e.bundleName),o=await C.new(),s=await ey(o,e.device),a=new AbortController,c=()=>a.abort(new Wn("SIGINT")),l=()=>a.abort(new Wn("SIGTERM"));process.on("SIGINT",c),process.on("SIGTERM",l);let d;try{d=await this.startSession(t,o.hdcPath,a.signal);let g=await d.callTool("verifyUI",{testPlan:e.testPlan,bundleName:i,freshStart:e.freshStart,device:s},n,$2),y=this.parseVerifyResult(g);return await this.cacheArtifacts(d,y.id,a.signal),a.signal.throwIfAborted(),Xh(),y}finally{try{await d?.close()}finally{process.off("SIGINT",c),process.off("SIGTERM",l)}}}startSession(e,t,n){return cc.start({...process.env,UI_VERIFY_BASE_URL:e.baseUrl,UI_VERIFY_API_KEY:e.apiKey,UI_VERIFY_MODEL_NAME:e.modelName,UI_VERIFY_HDC_PATH:t},n)}parseVerifyResult(e){if(typeof e=="object"&&e!==null)return e;if(typeof e=="string")try{return JSON.parse(e)}catch{throw new Error(e)}throw new Error("Failed to parse verifyUI result.")}resolveBundleName(e){if(e)return e;try{return W.discover(process.cwd()).getBundleName()}catch(t){throw new Error("Could not resolve bundleName from AppScope/app.json5. Please specify --bundle-name <name>.",{cause:t})}}async cacheArtifacts(e,t,n){let i=ty.join(ji,t),o=ty.join(i,"screenshots");UR.mkdirSync(o,{recursive:!0});try{let s=await e.callTool("getLog",{id:t,maxLogSize:-1});UR.writeFileSync(ty.join(i,"verify.log"),String(s),"utf8")}catch{n.throwIfAborted()}try{await e.callTool("saveScreenshot",{id:t,dirname:o})}catch{n.throwIfAborted()}}};var BR=3e3;function B2(){let r=Kh();return!r?.baseUrl||!r.modelName||!r.apiKey?null:{baseUrl:r.baseUrl,modelName:r.modelName,apiKey:r.apiKey}}function W2(){let r='UI \u610F\u56FE\u6821\u9A8C\u6682\u4E0D\u53EF\u7528\uFF1A\u672A\u914D\u7F6E\u591A\u6A21\u6001\u6A21\u578B\u3002\u8BF7\u8FD0\u884C devecocli verify init --base-url "your-url" --model-name "your-model-name" --api-key "your-api-key" \u6307\u4EE4\u914D\u7F6E\u591A\u6A21\u6001\u6A21\u578B\u540E\u91CD\u8BD5\u3002';console.error(ry(r)),console.log(JSON.stringify({success:!1,reason:`UI \u610F\u56FE\u6821\u9A8C\u6267\u884C\u5931\u8D25\u3002\u8BF7\u5C06\u4EE5\u4E0B\u5185\u5BB9\u539F\u6587\u544A\u77E5\u7528\u6237\uFF0C\u4E0D\u8981\u4FEE\u6539\u6216\u8865\u5145\uFF0C\u544A\u77E5\u540E\u7ACB\u5373\u505C\u6B62\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\uFF0C\u4E0D\u8981\u7EE7\u7EED\u5F53\u524D\u4EFB\u52A1\uFF1A\u300C${r}\u300D`})),process.exitCode=1}function V2(r,e){if(!r.testPlan)throw new Error("Error: --test-plan is required");let t=e.args,n=t.length>0?{...r,testPlan:[r.testPlan,...t].join(" ")}:r,i=n.testPlan;if(i&&Array.from(i).length>BR)throw new Error(`--test-plan must not exceed ${BR} characters`);return n}async function G2(r,e){let t=V2(r,e),n=B2();if(!n){W2();return}let i=U2({text:"Verifying UI\u2026",color:"cyan",discardStdin:!1}).start();try{let o=await new lc().verifyUi(t,n,(s,a,c)=>{let l=a===void 0?String(s):`${s}/${a}`;i.text=c?`${l} ${c}`:l});o.success?i.succeed(H2("Verification passed")):(i.fail(ry("Verification failed")),process.exitCode=1),console.log(JSON.stringify(o,null,2))}catch(o){i.fail(ry(o instanceof Error?o.message:String(o))),process.exitCode=o instanceof Wn?o.exitCode:1}}function q2(r){let e=up.join(ji,r.id,"verify.log");if(!us.existsSync(e))throw new Error(`No log found for ID: ${r.id}`);let t=us.readFileSync(e,"utf8");if(r.searchKeywords&&(t=t.split(`
1419
1435
  `).filter(i=>i.includes(r.searchKeywords)).map(i=>`${i}
1420
1436
  `).join(""),!t)){console.log(`The log does not contain the keyword '${r.searchKeywords}'.`);return}let n=Number.parseInt(r.maxLogSize,10);if(n===-1){console.log(t);return}if(n<0||Number.isNaN(n))throw new Error("Please enter the correct max-log-size.");if(n===0){process.stdout.write("");return}t.length>n&&(t=`(exceeded log size limit, showing last ${n} characters)...
1421
- ${t.slice(-n)}`),console.log(t)}function gB(r){let e=Nu.join(Ti,r.id,"screenshots");if(!Qo.existsSync(e))throw new Error(`No screenshots found for ID: ${r.id}`);Qo.mkdirSync(r.savePath,{recursive:!0});let t=Qo.readdirSync(e).map(n=>{let i=Nu.join(r.savePath,n);return Qo.copyFileSync(Nu.join(e,n),i),i});console.log(JSON.stringify({filenames:t,message:"Screenshots saved successfully"},null,2))}var Mu=new aB("verify").description("Run UI verification on a connected device").option("--test-plan <plan>","Natural-language test plan describing steps and expected results").option("--bundle-name <name>","Bundle name of the app to be tested").option("--no-fresh-start","Skip relaunching the app before verification").option("--device <name|serial>","Target device name or serial").allowExcessArguments(!0).action(mB);Mu.command("init").description("Configure the vision model for UI verification").option("--base-url <url>","Base URL of the vision model").option("--model-name <name>","Vision model name").option("--api-key <key>","API key for the vision model").action(r=>{if(!r.baseUrl&&!r.modelName&&!r.apiKey)throw new Error("Error: at least one of --base-url, --model-name, --api-key is required");let e=nh(r);console.log(`UI verification config saved to ${e}`)});Mu.command("log").description("Get verification log by ID").requiredOption("--id <id>","Verification task ID").option("--search-keywords <keywords>","Filter log by keywords").option("--max-log-size <n>","Max characters to show (-1 for unlimited)","5000").action(fB);Mu.command("screenshot").description("Save verification screenshots by ID").requiredOption("--id <id>","Verification task ID").requiredOption("--save-path <path>","Absolute path to save screenshots").action(gB);var pk=Mu;if(!Qe())try{D.init(Lu.join($(),"TraceLogData")),D.startScheduler()}catch(r){h.error(`[telemetry] init failed: ${r instanceof Error?r.message:String(r)}`)}(async()=>{if(!Qe())try{let r=await C.new();D.setSourceType(r.sourceType);let e=r.readVersion();e&&(r.sourceType==="clt"?D.setCltVersion(e):D.setStudioVersion(e))}catch(r){h.error(`[telemetry] toolchain info failed: ${r instanceof Error?r.message:String(r)}`)}})();ie.name("devecocli").description(`HarmonyOS application development command line tool
1437
+ ${t.slice(-n)}`),console.log(t)}function z2(r){let e=up.join(ji,r.id,"screenshots");if(!us.existsSync(e))throw new Error(`No screenshots found for ID: ${r.id}`);us.mkdirSync(r.savePath,{recursive:!0});let t=us.readdirSync(e).map(n=>{let i=up.join(r.savePath,n);return us.copyFileSync(up.join(e,n),i),i});console.log(JSON.stringify({filenames:t,message:"Screenshots saved successfully"},null,2))}var pp=new j2("verify").description("Run UI verification on a connected device").option("--test-plan <plan>","Natural-language test plan describing steps and expected results").option("--bundle-name <name>","Bundle name of the app to be tested").option("--no-fresh-start","Skip relaunching the app before verification").option("--device <name|serial>","Target device name or serial").allowExcessArguments(!0).action(G2);pp.command("init").description("Configure the vision model for UI verification").option("--base-url <url>","Base URL of the vision model").option("--model-name <name>","Vision model name").option("--api-key <key>","API key for the vision model").action(r=>{if(!r.baseUrl&&!r.modelName&&!r.apiKey)throw new Error("Error: at least one of --base-url, --model-name, --api-key is required");let e=Yh(r);console.log(`UI verification config saved to ${e}`)});pp.command("log").description("Get verification log by ID").requiredOption("--id <id>","Verification task ID").option("--search-keywords <keywords>","Filter log by keywords").option("--max-log-size <n>","Max characters to show (-1 for unlimited)","5000").action(q2);pp.command("screenshot").description("Save verification screenshots by ID").requiredOption("--id <id>","Verification task ID").requiredOption("--save-path <path>","Absolute path to save screenshots").action(z2);var WR=pp;function VR(r){let e=r.opts();if(r.name()==="log")return e.format==="json"||e.format==="hilog";if(r.name()!=="status"||e.format!=="json")return!1;let t=r.parent;for(;t!==null;){if(t.name()==="screenrecord")return!0;t=t.parent}return!1}if(!et())try{R.init(fp.join($(),"TraceLogData")),R.startScheduler()}catch(r){h.error(`[telemetry] init failed: ${r instanceof Error?r.message:String(r)}`)}(async()=>{if(!et())try{let r=await C.new();R.setSourceType(r.sourceType);let e=r.readVersion();e&&(r.sourceType==="clt"?R.setCltVersion(e):R.setStudioVersion(e))}catch(r){h.error(`[telemetry] toolchain info failed: ${r instanceof Error?r.message:String(r)}`)}})();se.name("devecocli").description(`HarmonyOS application development command line tool
1422
1438
 
1423
- Privacy: ${ts.PRIVACY_URL}`).version("1.3.7");var mk=ie.options.find(r=>r.long==="--version");mk&&(mk.flags="-V, -v, --version");ie.addCommand(vw);ie.addCommand(rb);ie.addCommand(ab);ie.addCommand(Xb);ie.addCommand(PS);ie.addCommand(qS);ie.addCommand(XS);ie.addCommand(dE);ie.addCommand(mE);ie.addCommand(kE);ie.addCommand(AE);ie.addCommand(sP);ie.addCommand(pP);ie.addCommand(_P);ie.addCommand(wC);ie.addCommand(sk);ie.addCommand(pk);for(let r=2;r<process.argv.length;r++){let e=process.argv[r];if(e==="-v"){process.argv[r]="-V";break}if(!e.startsWith("-"))break}var dh=process.argv.slice(2);dh.length>=2&&dh[dh.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);function yB(r){let e=r;for(;e.parent&&e.parent!==ie;)e=e.parent;return e}var wB=new Set(["update","auth","serve","plugin"]);ie.hook("preAction",async(r,e)=>{await Ay().catch(()=>{});let t=yB(e),n=ji();if(t.name()==="update"||t.name()==="docs"&&e.name()==="update")return;let i=new nn(Lu.join($(),"update")),o=ar();if(n==="off"&&i.getBlockedVersions().includes(o))throw new Error(`devecocli ${o} has been disabled, run \`devecocli update\` to upgrade`);process.env.DEVECO_CLI_SKIP_VERSION_CHECK||wB.has(t.name())||await C.checkVersion()});function vB(r){if(r.name()!=="status"||r.opts().format!=="json")return!1;let t=r.parent;for(;t&&t!==ie;){if(t.name()==="screenrecord")return!0;t=t.parent}return!1}ie.hook("postAction",async(r,e)=>{if(process.exitCode||ji()!=="off"||vB(e))return;await new gs(e).checkAndNotify()});ie.parseAsync(process.argv).finally(()=>{D.stopScheduler();try{Ku(Lu.join($(),"TraceLogData"))}catch(r){h.error(`[telemetry] background upload spawn check failed: ${r instanceof Error?r.message:String(r)}`)}}).catch(r=>{let e=r instanceof Error?r.message:String(r??"Unknown error");console.error(hB(`Error: ${e}`)),process.env.DEVECO_CLI_DEBUG==="1"&&r instanceof Error&&r.stack&&console.error(r.stack),process.exit(1)});
1439
+ Privacy: ${fs.PRIVACY_URL}`).version("1.3.10-Test.1");var GR=se.options.find(r=>r.long==="--version");GR&&(GR.flags="-V, -v, --version");se.addCommand(pv);se.addCommand(Kb);se.addCommand(eS);se.addCommand(VS);se.addCommand(hE);se.addCommand(jE);se.addCommand(VE);se.addCommand(nP);se.addCommand(VP);se.addCommand(rC);se.addCommand(sC);se.addCommand(FC);se.addCommand(WC);se.addCommand(fk);se.addCommand(Kk);se.addCommand(FR);se.addCommand(WR);for(let r=2;r<process.argv.length;r++){let e=process.argv[r];if(e==="-v"){process.argv[r]="-V";break}if(!e.startsWith("-"))break}var ny=process.argv.slice(2);ny.length>=2&&ny[ny.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);function K2(r){let e=r;for(;e.parent&&e.parent!==se;)e=e.parent;return e}var Y2=new Set(["update","auth","serve","plugin"]);se.hook("preAction",async(r,e)=>{await Ew().catch(()=>{});let t=K2(e),n=Ji();if(t.name()==="update"||t.name()==="docs"&&e.name()==="update")return;let i=new an(fp.join($(),"update")),o=ur();if(n==="off"&&i.getBlockedVersions().includes(o))throw new Error(`devecocli ${o} has been disabled, run \`devecocli update\` to upgrade`);process.env.DEVECO_CLI_SKIP_VERSION_CHECK||Y2.has(t.name())||await C.checkVersion()});se.hook("postAction",async(r,e)=>{if(process.exitCode||Ji()!=="off"||VR(e))return;await new xs(e).checkAndNotify()});se.parseAsync(process.argv).finally(()=>{R.stopScheduler();try{Dp(fp.join($(),"TraceLogData"))}catch(r){h.error(`[telemetry] background upload spawn check failed: ${r instanceof Error?r.message:String(r)}`)}}).catch(r=>{let e=r instanceof Error?r.message:String(r??"Unknown error");console.error(J2(`Error: ${e}`)),process.env.DEVECO_CLI_DEBUG==="1"&&r instanceof Error&&r.stack&&console.error(r.stack),process.exit(1)});