@deveco-test/hmos-deveco-cli 0.1.0-TD.4-alpha1 → 0.1.0-TD.4

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
@@ -33,7 +33,7 @@ Available runnable modules:
33
33
  Installing artifacts to device ${e}...`),await n.installApp(e,r),o){console.log(`Launching ${t}/${o}...`);let s=await n.launchApp(e,t,o);console.log(Ns(`
34
34
  Application '${t}': ${s}`))}else console.log(`
35
35
  Application '${t}' installed successfully (no ability to launch).`)}var Ku=new Wu("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").action(async n=>{try{await Xu(n)}catch(e){console.error(Uu(e.message)),process.exit(1)}});async function Zu(n,e,t,r,o){let i=new ut(e,n.rootDir),s=new Ze(e,n.rootDir),a=new Set;for(let{moduleName:h,targetName:E}of t)for(let C of n.collectNonHarDependentModuleList(h))a.add(`${C}@${E}`);let c=[...a],l=Po(n,c),u={type:"modules",modulesToBuild:c,moduleTasks:l};await $t(n.rootDir,()=>Eo(i,s,r,o,u,n.rootDir),()=>console.log("Another build is already running for this project. Waiting for completion...")),console.log(`
36
- `+Ns("Build completed successfully."))}async function Xu(n){let e=Ke.discover(process.cwd());console.warn(zu("Ensure the project source is trusted before proceeding."));let t=await _.new(),o=Gu(e,n.module).map(qu);for(let{moduleName:Q}of o){let ce=e.getModuleType(Q);if(ce!=="entry"&&ce!=="feature"&&ce!=="shared")throw new Error(`Module '${Q}' '${ce}' is not runnable. Specify an entry or feature module.`)}let i=new Hn(t),s=ee.from(t),a=await Vu(s,n.device),c=a.includes("127.0.0.1")||a.includes("localhost"),l=n.product||"default";e.validateProduct(l);let u=n.buildMode||"debug";n.skipBuild||await Zu(e,t,o,l,u);let h=new Set;for(let{moduleName:Q,targetName:ce}of o){let kn=e.collectNonHarDependentModuleList(Q);for(let cu of kn)h.add(e.findArtifactPath(cu,ce,c,l));h.add(e.findArtifactPath(Q,ce,c,l))}let E=[...h],C=e.getBundleName(),M=Yu(e,o,n.ability);await Ju(i,a,C,E,M,!!n.uninstall)}var Ls=Ku;import{Command as Qu}from"commander";import{green as _s,red as Hs,cyan as Do}from"colorette";import{execa as js}from"execa";function ep(){return"@deveco-test/hmos-deveco-cli"}function tp(){return"0.1.0-TD.4-alpha1"}var np=new Qu("update").description("Update deveco-cli to latest").action(async()=>{let n=ep(),e=tp();console.log(Do("Checking for updates..."));try{let{stdout:t}=await js("npm",["view",n,"version"]),r=t.trim();if(r===e){console.log(_s(`
36
+ `+Ns("Build completed successfully."))}async function Xu(n){let e=Ke.discover(process.cwd());console.warn(zu("Ensure the project source is trusted before proceeding."));let t=await _.new(),o=Gu(e,n.module).map(qu);for(let{moduleName:Q}of o){let ce=e.getModuleType(Q);if(ce!=="entry"&&ce!=="feature"&&ce!=="shared")throw new Error(`Module '${Q}' '${ce}' is not runnable. Specify an entry or feature module.`)}let i=new Hn(t),s=ee.from(t),a=await Vu(s,n.device),c=a.includes("127.0.0.1")||a.includes("localhost"),l=n.product||"default";e.validateProduct(l);let u=n.buildMode||"debug";n.skipBuild||await Zu(e,t,o,l,u);let h=new Set;for(let{moduleName:Q,targetName:ce}of o){let kn=e.collectNonHarDependentModuleList(Q);for(let cu of kn)h.add(e.findArtifactPath(cu,ce,c,l));h.add(e.findArtifactPath(Q,ce,c,l))}let E=[...h],C=e.getBundleName(),M=Yu(e,o,n.ability);await Ju(i,a,C,E,M,!!n.uninstall)}var Ls=Ku;import{Command as Qu}from"commander";import{green as _s,red as Hs,cyan as Do}from"colorette";import{execa as js}from"execa";function ep(){return"@deveco-test/hmos-deveco-cli"}function tp(){return"0.1.0-TD.4"}var np=new Qu("update").description("Update deveco-cli to latest").action(async()=>{let n=ep(),e=tp();console.log(Do("Checking for updates..."));try{let{stdout:t}=await js("npm",["view",n,"version"]),r=t.trim();if(r===e){console.log(_s(`
37
37
  ${n} is already up to date (version ${e}.)`));return}console.log(Do(`
38
38
  New version found: ${r} (current: ${e})`)),console.log(Do(`Updating ${n}...`)),await js("npm",["install","-g",`${n}@latest`],{stdio:"inherit"}),console.log(`
39
39
  `+_s(`${n} updated successfully to version ${r}.`))}catch(t){let r=t;console.error(Hs(`Failed to update ${n}`)),r.message&&console.error(Hs(r.message)),process.exit(1)}}),Fs=np;import{Command as Ip}from"commander";import{execa as ko}from"execa";function q(n){return n.normalize("NFKC").replace(/\s+/g," ").trim()}import{spawn as rp}from"child_process";var op=2500;function ip(n,e,t,r,o,i){n.once("exit",s=>{if(i())return;clearTimeout(e);let a=t();s===0||s===null?r():o(a||`Emulator process exited with code ${s}`)})}function sp(n,e,t,r){let o=!1,i=()=>o,s=()=>Buffer.concat(e).toString("utf8").trim(),a=()=>{o||(o=!0,clearTimeout(l),n.removeAllListeners(),n.stderr?.removeAllListeners(),n.stderr?.destroy(),n.unref(),t())},c=u=>{if(!o){o=!0,clearTimeout(l),n.removeAllListeners(),n.stderr?.removeAllListeners();try{n.kill()}catch{}r(new Error(u))}},l=setTimeout(a,op);n.once("error",u=>c(u.message)),ip(n,l,s,a,c,i)}function $s(n,e,t){return g(`Spawning emulator: ${n} ${t.join(" ")}`),new Promise((r,o)=>{let i=[],s=rp(n,t,{detached:!0,stdio:["ignore","ignore","pipe"],env:{...process.env,DEVECO_SDK_HOME:e},windowsHide:!0});s.stderr?.on("data",a=>i.push(a)),sp(s,i,r,o)})}import*as ft from"path";function ap(n){let e=new Set,t=[];for(let r of n){let o=JSON.stringify(r);e.has(o)||(e.add(o),t.push(r))}return t}function cp(n){let e=n.instancePath?.trim();if(e)return ft.dirname(ft.normalize(e)).replace(/\\/g,"/");let t=n.path?.trim();return t?ft.dirname(ft.normalize(t)).replace(/\\/g,"/"):""}function lp(n){let e=[];return n&&e.push(["-imageRoot",n]),e.push([]),e}function Bs(n,e){return e?[...n,"-bootmode",e]:n}function dp(n,e,t){let r=[Bs(["-start",n],t)],o=cp(e);if(o)for(let i of lp(e.imageRoot))r.push(Bs(["-hvd",n,"-path",o,...i],t));return ap(r)}async function Ws(n,e,t,r){let o=new Error("No start strategy ran"),i=dp(n,e,r);for(let s of i)try{return await t(s),{ok:!0}}catch(a){o=a}return{ok:!1,lastError:o}}async function Ao(n){return(await ee.withHdcPath(n).listDevices()).map(t=>t.serial).filter(Ut)}async function To(n){let e=await Ao(n);return e.length===0?[]:(await Promise.all(e.map(r=>_n(n,r,"ohos.qemu.hvd.name")))).filter(r=>!!r)}async function Us(n,e){return(await To(n)).includes(e)}import*as gt from"path";import{existsSync as up,statSync as pp}from"fs";function ht(n,e){for(let t of e){let r=n[t];if(typeof r=="string"&&r.trim())return r.trim()}return""}function mp(n){let e=ht(n,["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,r]of Object.entries(n)){if(typeof r!="string"||!r.trim())continue;let o=t.toLowerCase();if(o.includes("instance")&&(o.includes("path")||o.includes("dir"))||o==="deployedpath")return r.trim()}return""}function fp(n){return ht(n,["uuid","UUID","Uuid","instanceUuid","instance_uuid","InstanceUuid"])}function hp(n){let e=n.find(r=>r.instancePath?.trim());if(!e?.instancePath?.trim())return;let t=gt.dirname(gt.normalize(e.instancePath));for(let r of n){if(r.instancePath?.trim())continue;let o=gt.join(t,r.name);up(o)&&pp(o).isDirectory()&&(r.instancePath=o.replace(/\\/g,"/"))}}function gp(n){try{let e=JSON.parse(n);return Array.isArray(e)?e.map(t=>{let r=fp(t),o=ht(t,["deviceType","DeviceType","devicetype"]),i=ht(t,["os.osVersion","osVersion","OsVersion","OSVersion"]);return{name:t.name||t.Name||"",isRunning:t.isRunning===!0||String(t.isRunning).toLowerCase()==="true",instancePath:mp(t),path:ht(t,["path","Path","hvdPath","hvd_path"]),imageRoot:ht(t,["imageRoot","image_root","ImageRoot"]),uuid:r||void 0,deviceType:o||void 0,osVersion:i||void 0}}).filter(t=>t.name):null}catch{return null}}function yp(n){let e=[],t=/^(name|isrunning|instancepath|path|imageroot|devicetype|os\.osversion)\s*:\s*(.+)/gim,r=null,o;for(;(o=t.exec(n))!==null;){let[,i,s]=o;if(i.toLowerCase()==="name")r&&e.push(r),r={name:s.trim()};else if(r){let a=i.toLowerCase();a==="isrunning"?r.isRunning=s.trim().toLowerCase()==="true":a==="instancepath"?r.instancePath=s.trim():a==="path"?r.path=s.trim():a==="imageroot"?r.imageRoot=s.trim():a==="devicetype"?r.deviceType=s.trim():a==="os.osversion"&&(r.osVersion=s.trim())}}return r&&e.push(r),e}function zs(n){let t=gp(n)??yp(n);return hp(t),t}function xo(n,e){for(let t of e){let r=n[t];if(typeof r=="string"&&r.trim())return r.trim()}return""}function vp(n){let e=n.downloaded??n.Downloaded;return e===!0||String(e).toLowerCase()==="true"}function wp(n){if(!vp(n))return null;let e=xo(n,["osVersion","OsVersion","OSVersion"]),t=xo(n,["SoftWareVersion","SoftwareVersion","softwareVersion"]),r=xo(n,["deviceType","DeviceType"]);return!e&&!t?null:{osVersion:e,softwareVersion:t,deviceType:r}}function jn(n){let e=n.trim();if(!e)return[];try{let t=JSON.parse(e);if(!Array.isArray(t))return[];let r=[];for(let o of t){if(!o||typeof o!="object")continue;let i=wp(o);i&&r.push(i)}return r}catch{return[]}}function qs(n){let t=jn(n).map(r=>r.osVersion).filter(Boolean);return[...new Set(t)]}var Vs=/no images are available/i;function ge(n){return n.normalize("NFKC").trim().toLowerCase()}function bp(n){let e=n.message||"";return Vs.test(e)}var yt=class n{emulatorPath;sdkPath;hdcPath;constructor(e,t,r){this.emulatorPath=e,this.sdkPath=t,this.hdcPath=r}static from(e){return new n(e.emulatorPath,e.sdkPath,e.hdcPath)}async executeEmulator(e){return ko(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath}})}executeEmulatorDetached(e){return $s(this.emulatorPath,this.sdkPath,e)}async listEmulators(){let{stdout:e}=await this.executeEmulator(["-list","-details"]);return zs(e)}async getDeviceTypeByName(){let e=new Map;try{let t=await this.listEmulators();for(let r of t)r.name&&r.deviceType&&e.set(q(r.name),r.deviceType)}catch{}return e}async startEmulator(e){let t=await this.listEmulators(),r=q(e),o=t.find(a=>q(a.name)===r);if(!o)throw new Error(`Emulator "${e}" not found.`);let i=o.name;if(await this.isAlreadyRunning(i,o))return"already-running";await this.assertSystemImageAvailable(o);let s=await Ws(i,o,a=>this.executeEmulatorDetached(a),"snapshot");if(s.ok)return"started";if(await this.isAlreadyRunning(i))return"already-running";throw new Error(`Unable to start emulator "${e}". All methods failed.
@@ -1250,7 +1250,7 @@ Output so far:
1250
1250
  `):"\u6CA1\u6709\u6709\u6548\u7684 .ets \u6587\u4EF6"}],isError:!0}:(await this.runDiagnosticsForFiles(o,t,r),this.formatCallResult(t,r))}buildNotReadyResponse(){return{content:[{type:"text",text:this.initializing?"LSP \u6B63\u5728\u521D\u59CB\u5316\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5":this.projectPath?"LSP\u672A\u521D\u59CB\u5316":"\u6CA1\u6709\u914D\u7F6E\u5DE5\u7A0B\u8DEF\u5F84\uFF0C\u8BF7\u914D\u7F6EPROJECT_PATH\u53C2\u6570"}],isError:!0}}collectValidFiles(e,t){let r=this.projectPath,o=[];for(let i of e){let s=be.isAbsolute(i)?i:be.join(r,i);if(!xe.existsSync(s)){t.push(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${i}`);continue}if(!xe.statSync(s).isFile()){t.push(`\u4E0D\u662F\u666E\u901A\u6587\u4EF6: ${i}`);continue}if(!s.endsWith(".ets")){t.push(`\u4E0D\u662F .ets \u6587\u4EF6: ${i}`);continue}o.push(s)}return o}async runDiagnosticsForFiles(e,t,r){for(let o of e){await mc(500);try{let i=await this.checkFile(o);r.push(Ah(o,i))}catch(i){t.push(`${o} => wait for diagnostics failed: ${i.message}`)}}}formatCallResult(e,t){let r=[];e.length>0&&r.push(e.join(`
1251
1251
  `)),t.length>0&&r.push(t.join(`
1252
1252
  `));let o=r.join(`
1253
- `).trim(),i=e.length>0;return!i&&t.length===0&&(o="\u672A\u6536\u96C6\u5230\u8BCA\u65AD\u4FE1\u606F"),{content:[{type:"text",text:o}],isError:i}}async shutdown(){if(this.failAllPending(new Error("LSP shutting down")),this.manager){try{await this.manager.dispose()}catch(e){f.warn(`Failed to dispose ArktsLspManager: ${e}`)}this.manager=null}this.initialized=!1,this.initializing=!1,this.initPromise=null,this.clearInitHandlers()}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,r=t.method;if(r)switch(r){case"textDocument/publishDiagnostics":case"textDocument/didOpen":this.handleDiagnosticsNotification(t.params);break;case"arkts/indexingProgress":this.initResolve&&(this.armInitTimer(rn),f.debug("Received arkts/indexingProgress, reset init timeout"));break;case"arkts/initialized":{f.info("Received arkts/initialized");let o=this.initResolve;this.clearInitHandlers(),o?.();break}case"arkts/initializationFailed":{let i=t.params?.message??"unknown";f.error(`LSP initialization failed: ${i}`);let s=this.initReject;this.clearInitHandlers(),s?.(new Error(`LSP initialize failed: ${i}`));break}case"workspace/didChangeConfiguration":f.info("Received workspace/didChangeConfiguration, sync deferred to next check");break;default:break}}handleDiagnosticsNotification(e){if(!e)return;let t=e.uri;if(!t)return;let r=this.resolveDiagnosticWaiter(t);if(!r)return;if(typeof e.errorMessage=="string"){f.warn(`diagnostics error uri=${t} message=${e.errorMessage}`),r.resolve({errorMessage:e.errorMessage});return}let o=e.diagnostics,i=Array.isArray(o)?o.length:0;f.debug(`diagnostics received uri=${t} count=${i}`),r.resolve(Array.isArray(o)?o:[])}resolveDiagnosticWaiter(e){let t=tn(e),r=this.popDiagnosticWaiter(t);if(r)return r;for(let o of hc(e)){let i=this.popDiagnosticWaiter(o);if(i)return i}}popDiagnosticWaiter(e){let t=this.diagnosticWaiters.get(e);if(t)return this.diagnosticWaiters.delete(e),clearTimeout(t.timer),t}failAllPending(e){for(let[,r]of this.diagnosticWaiters)clearTimeout(r.timer),r.reject(e);this.diagnosticWaiters.clear();let t=this.initReject;this.clearInitHandlers(),t?.(e)}getLogAndIndexPath(e){try{let t=be.join(tr(),"ArkTSCheck"),r=be.join(t,"mapping-config.properties"),o=gc(e,r),i=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=be.join(t,"lsp-log",String(o),i),a=be.join(t,"lsp-index",String(o));return xe.mkdirSync(s,{recursive:!0}),xe.mkdirSync(a,{recursive:!0}),{logPath:we(s),indexPath:we(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function Ah(n,e){if(Array.isArray(e))return e.length===0?`${n} => no diagnostics`:`${n} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${n} diagnostic failed, error_message: ${t}`}return`${n} => diagnostic failed, result: ${JSON.stringify(e)}`}import{spawn as Th}from"child_process";import*as D from"fs";import*as K from"path";import{z as yi}from"zod";var qc=60*1e3,xh=30*1e3,kh=new Set(["textDocument/didOpen","textDocument/didChange","textDocument/didClose","textDocument/didSave"]),Rh=1e3,wi=class{nextRequestId=1;pendingRequests=new Map;diagnosticWaiters=new Map;fileCheckLock=Promise.resolve();closed=!1;wrapperState="preInitialize";queuedDocumentNotifications=[];backendReady=!1;projectPath=null;clangdStdin=null;clangdStdout=null;clangdBuffer=Buffer.alloc(0);constructor(){}isClosed(){return this.closed}async initialize(e){this.projectPath=e,this.wrapperState="waitingForDatabase"}async connectClangdProcess(e,t){if(this.closed)throw new Error("Client is already closed");this.clangdStdin=e,this.clangdStdout=t,this.wrapperState="startingBackend",this.clangdStdout.on("data",a=>this.handleClangdData(a)),this.clangdStdout.on("error",a=>{f.warn(`[CppCheck] clangd stdout error: ${a}`),this.failAll(new Error(`clangd stdout error: ${a}`))}),this.clangdStdout.on("end",()=>{this.failAll(new Error("C++ language server connection closed"))});let r=we(this.projectPath),o=nt(r),i=K.basename(r)||"workspace",s={processId:null,clientInfo:{name:"devecocli-mcp-server",version:"0.1.0-TD.4-alpha1"},rootPath:r,rootUri:o,workspaceFolders:[{uri:o,name:i}],capabilities:{}};await this.sendRequestToClangd("initialize",s,qc),await this.sendNotificationToClangd("initialized",{}),this.backendReady=!0,this.wrapperState="proxying";for(let a of this.queuedDocumentNotifications)await this.writeToClangd(a);this.queuedDocumentNotifications.length=0,f.info("[CppCheck] clangd backend ready, switched to proxying mode")}async waitForBackendReady(){if(this.backendReady)return;let e=qc,t=Date.now();for(;!this.backendReady&&!this.closed&&Date.now()-t<e;)await new Promise(r=>setTimeout(r,500));if(!this.backendReady)throw new Error("Timed out waiting for clangd backend to be ready")}async checkFile(e){await this.waitForBackendReady();let t=await this.acquireFileCheckLock();try{return await this.doCheckFile(e)}finally{t()}}async doCheckFile(e){let t;try{t=D.realpathSync(e)}catch{t=e}let r=nt(t),o=fc(t),i=await D.promises.readFile(t,"utf8"),s=new Promise((a,c)=>{let l=setTimeout(()=>{this.diagnosticWaiters.delete(r)&&c(new Error(`Timed out waiting for diagnostics: ${e}`))},xh);this.diagnosticWaiters.set(r,{resolve:a,reject:c,timer:l})});try{await this.sendNotification("textDocument/didOpen",{textDocument:{uri:r,languageId:o,version:1,text:i}})}catch(a){let c=this.diagnosticWaiters.get(r);throw c&&(clearTimeout(c.timer),this.diagnosticWaiters.delete(r)),a}try{return await s}finally{await this.closeFile(r).catch(a=>{f.warn(`[CppCheck] didClose failed for ${r}: ${a}`)})}}async close(){if(!this.closed&&(this.closed=!0,this.wrapperState="shuttingDown",this.backendReady&&this.clangdStdin)){try{await this.sendRequestToClangd("shutdown",null,3e3)}catch(e){f.warn(`[CppCheck] shutdown request failed: ${e}`)}try{await this.sendNotificationToClangd("exit",null)}catch(e){f.warn(`[CppCheck] exit notification failed: ${e}`)}try{this.clangdStdin.end()}catch(e){f.warn(`[CppCheck] stdin.end() failed: ${e}`)}}}async sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t??void 0};if(this.backendReady&&this.clangdStdin){await this.writeToClangd(r);return}kh.has(e)&&this.queuedDocumentNotifications.push(r)}async closeFile(e){await this.sendNotification("textDocument/didClose",{textDocument:{uri:e}})}async sendRequestToClangd(e,t,r){let o=this.nextRequestId++;return new Promise((i,s)=>{let a=setTimeout(()=>{this.pendingRequests.delete(o)&&s(new Error(`Timed out waiting for ${e} response`))},r);this.pendingRequests.set(o,{resolve:i,reject:s,timer:a}),this.writeToClangd({jsonrpc:"2.0",id:o,method:e,params:t??void 0}).catch(c=>{this.pendingRequests.delete(o)&&(clearTimeout(a),s(c))})})}async sendNotificationToClangd(e,t){await this.writeToClangd({jsonrpc:"2.0",method:e,params:t??void 0})}async writeToClangd(e){if(!this.clangdStdin)throw new Error("clangd stdin not available");return new Promise((t,r)=>{let o;try{o=JSON.stringify(e)}catch(u){r(new Error(`Failed to encode LSP message: ${u}`));return}let i=Buffer.from(o,"utf8"),s=Buffer.from(`Content-Length: ${i.length}\r
1253
+ `).trim(),i=e.length>0;return!i&&t.length===0&&(o="\u672A\u6536\u96C6\u5230\u8BCA\u65AD\u4FE1\u606F"),{content:[{type:"text",text:o}],isError:i}}async shutdown(){if(this.failAllPending(new Error("LSP shutting down")),this.manager){try{await this.manager.dispose()}catch(e){f.warn(`Failed to dispose ArktsLspManager: ${e}`)}this.manager=null}this.initialized=!1,this.initializing=!1,this.initPromise=null,this.clearInitHandlers()}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,r=t.method;if(r)switch(r){case"textDocument/publishDiagnostics":case"textDocument/didOpen":this.handleDiagnosticsNotification(t.params);break;case"arkts/indexingProgress":this.initResolve&&(this.armInitTimer(rn),f.debug("Received arkts/indexingProgress, reset init timeout"));break;case"arkts/initialized":{f.info("Received arkts/initialized");let o=this.initResolve;this.clearInitHandlers(),o?.();break}case"arkts/initializationFailed":{let i=t.params?.message??"unknown";f.error(`LSP initialization failed: ${i}`);let s=this.initReject;this.clearInitHandlers(),s?.(new Error(`LSP initialize failed: ${i}`));break}case"workspace/didChangeConfiguration":f.info("Received workspace/didChangeConfiguration, sync deferred to next check");break;default:break}}handleDiagnosticsNotification(e){if(!e)return;let t=e.uri;if(!t)return;let r=this.resolveDiagnosticWaiter(t);if(!r)return;if(typeof e.errorMessage=="string"){f.warn(`diagnostics error uri=${t} message=${e.errorMessage}`),r.resolve({errorMessage:e.errorMessage});return}let o=e.diagnostics,i=Array.isArray(o)?o.length:0;f.debug(`diagnostics received uri=${t} count=${i}`),r.resolve(Array.isArray(o)?o:[])}resolveDiagnosticWaiter(e){let t=tn(e),r=this.popDiagnosticWaiter(t);if(r)return r;for(let o of hc(e)){let i=this.popDiagnosticWaiter(o);if(i)return i}}popDiagnosticWaiter(e){let t=this.diagnosticWaiters.get(e);if(t)return this.diagnosticWaiters.delete(e),clearTimeout(t.timer),t}failAllPending(e){for(let[,r]of this.diagnosticWaiters)clearTimeout(r.timer),r.reject(e);this.diagnosticWaiters.clear();let t=this.initReject;this.clearInitHandlers(),t?.(e)}getLogAndIndexPath(e){try{let t=be.join(tr(),"ArkTSCheck"),r=be.join(t,"mapping-config.properties"),o=gc(e,r),i=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=be.join(t,"lsp-log",String(o),i),a=be.join(t,"lsp-index",String(o));return xe.mkdirSync(s,{recursive:!0}),xe.mkdirSync(a,{recursive:!0}),{logPath:we(s),indexPath:we(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function Ah(n,e){if(Array.isArray(e))return e.length===0?`${n} => no diagnostics`:`${n} => Diagnostic: ${JSON.stringify(e)}`;if(e&&typeof e=="object"&&typeof e.errorMessage=="string"){let t=e.errorMessage;return`${n} diagnostic failed, error_message: ${t}`}return`${n} => diagnostic failed, result: ${JSON.stringify(e)}`}import{spawn as Th}from"child_process";import*as D from"fs";import*as K from"path";import{z as yi}from"zod";var qc=60*1e3,xh=30*1e3,kh=new Set(["textDocument/didOpen","textDocument/didChange","textDocument/didClose","textDocument/didSave"]),Rh=1e3,wi=class{nextRequestId=1;pendingRequests=new Map;diagnosticWaiters=new Map;fileCheckLock=Promise.resolve();closed=!1;wrapperState="preInitialize";queuedDocumentNotifications=[];backendReady=!1;projectPath=null;clangdStdin=null;clangdStdout=null;clangdBuffer=Buffer.alloc(0);constructor(){}isClosed(){return this.closed}async initialize(e){this.projectPath=e,this.wrapperState="waitingForDatabase"}async connectClangdProcess(e,t){if(this.closed)throw new Error("Client is already closed");this.clangdStdin=e,this.clangdStdout=t,this.wrapperState="startingBackend",this.clangdStdout.on("data",a=>this.handleClangdData(a)),this.clangdStdout.on("error",a=>{f.warn(`[CppCheck] clangd stdout error: ${a}`),this.failAll(new Error(`clangd stdout error: ${a}`))}),this.clangdStdout.on("end",()=>{this.failAll(new Error("C++ language server connection closed"))});let r=we(this.projectPath),o=nt(r),i=K.basename(r)||"workspace",s={processId:null,clientInfo:{name:"devecocli-mcp-server",version:"0.1.0-TD.4"},rootPath:r,rootUri:o,workspaceFolders:[{uri:o,name:i}],capabilities:{}};await this.sendRequestToClangd("initialize",s,qc),await this.sendNotificationToClangd("initialized",{}),this.backendReady=!0,this.wrapperState="proxying";for(let a of this.queuedDocumentNotifications)await this.writeToClangd(a);this.queuedDocumentNotifications.length=0,f.info("[CppCheck] clangd backend ready, switched to proxying mode")}async waitForBackendReady(){if(this.backendReady)return;let e=qc,t=Date.now();for(;!this.backendReady&&!this.closed&&Date.now()-t<e;)await new Promise(r=>setTimeout(r,500));if(!this.backendReady)throw new Error("Timed out waiting for clangd backend to be ready")}async checkFile(e){await this.waitForBackendReady();let t=await this.acquireFileCheckLock();try{return await this.doCheckFile(e)}finally{t()}}async doCheckFile(e){let t;try{t=D.realpathSync(e)}catch{t=e}let r=nt(t),o=fc(t),i=await D.promises.readFile(t,"utf8"),s=new Promise((a,c)=>{let l=setTimeout(()=>{this.diagnosticWaiters.delete(r)&&c(new Error(`Timed out waiting for diagnostics: ${e}`))},xh);this.diagnosticWaiters.set(r,{resolve:a,reject:c,timer:l})});try{await this.sendNotification("textDocument/didOpen",{textDocument:{uri:r,languageId:o,version:1,text:i}})}catch(a){let c=this.diagnosticWaiters.get(r);throw c&&(clearTimeout(c.timer),this.diagnosticWaiters.delete(r)),a}try{return await s}finally{await this.closeFile(r).catch(a=>{f.warn(`[CppCheck] didClose failed for ${r}: ${a}`)})}}async close(){if(!this.closed&&(this.closed=!0,this.wrapperState="shuttingDown",this.backendReady&&this.clangdStdin)){try{await this.sendRequestToClangd("shutdown",null,3e3)}catch(e){f.warn(`[CppCheck] shutdown request failed: ${e}`)}try{await this.sendNotificationToClangd("exit",null)}catch(e){f.warn(`[CppCheck] exit notification failed: ${e}`)}try{this.clangdStdin.end()}catch(e){f.warn(`[CppCheck] stdin.end() failed: ${e}`)}}}async sendNotification(e,t){let r={jsonrpc:"2.0",method:e,params:t??void 0};if(this.backendReady&&this.clangdStdin){await this.writeToClangd(r);return}kh.has(e)&&this.queuedDocumentNotifications.push(r)}async closeFile(e){await this.sendNotification("textDocument/didClose",{textDocument:{uri:e}})}async sendRequestToClangd(e,t,r){let o=this.nextRequestId++;return new Promise((i,s)=>{let a=setTimeout(()=>{this.pendingRequests.delete(o)&&s(new Error(`Timed out waiting for ${e} response`))},r);this.pendingRequests.set(o,{resolve:i,reject:s,timer:a}),this.writeToClangd({jsonrpc:"2.0",id:o,method:e,params:t??void 0}).catch(c=>{this.pendingRequests.delete(o)&&(clearTimeout(a),s(c))})})}async sendNotificationToClangd(e,t){await this.writeToClangd({jsonrpc:"2.0",method:e,params:t??void 0})}async writeToClangd(e){if(!this.clangdStdin)throw new Error("clangd stdin not available");return new Promise((t,r)=>{let o;try{o=JSON.stringify(e)}catch(u){r(new Error(`Failed to encode LSP message: ${u}`));return}let i=Buffer.from(o,"utf8"),s=Buffer.from(`Content-Length: ${i.length}\r
1254
1254
  \r
1255
1255
  `,"ascii"),a=!1,c=u=>{a||(a=!0,u?r(u):t())};if(this.clangdStdin.write(Buffer.concat([s,i]),u=>{u?c(u):a||c()}))c();else{let u=()=>c();this.clangdStdin.once("drain",u)}})}handleClangdData(e){for(this.clangdBuffer=this.clangdBuffer.length===0?e:Buffer.concat([this.clangdBuffer,e]);;){let t=this.clangdBuffer.indexOf(`\r
1256
1256
  \r
@@ -1336,4 +1336,4 @@ CREATE INDEX segments_doc_id_idx ON segments(doc_id);
1336
1336
  Detail: ${n.message}`):n}try{await Ge()}catch(n){let e=n instanceof Error?n.message:String(n);throw new Tn(`${Rv()}
1337
1337
 
1338
1338
  Detail: ${e}`)}try{await Cn()}catch(n){let e=n instanceof Error?n.message:String(n);throw new Tn(Mv(e))}}var is=class extends Error{constructor(t,r){super(r);this.code=t;this.name="DocNotReadyError"}code};function Lv(n){return new Promise(e=>setTimeout(e,n))}async function _v(n){let e=_t();await U.promises.mkdir(Ft.dirname(e),{recursive:!0}),await U.promises.appendFile(e,`${new Date().toISOString()} ${n}
1339
- `)}async function Hv(n){let e=ze();if(!e)throw new Error("docs.zip not found");await U.promises.rm(n,{recursive:!0,force:!0}),await U.promises.mkdir(n,{recursive:!0}),new Ov(e).extractAllTo(n,!0),await tu(n)}async function jv(){let n=Z(),e=Lt(),t=await U.promises.readdir(e);for(let r of t){let o=Ft.join(n,r);await U.promises.rm(o,{force:!0}),await U.promises.rename(Ft.join(e,r),o)}await U.promises.rm(e,{recursive:!0,force:!0}),await U.promises.rm(Ft.join(n,"orama.dpack"),{force:!0})}async function Fv(n,e){e?.start("Installing documentation index\u2026"),await Ve({state:"installing",phase:1,phaseLabel:"Installing index",message:"Installing documentation index\u2026"}),await Bl(n),e&&(e.text="Documentation index installed.")}async function $v(n,e,t){let r=Lt(),o=await eu();await U.promises.mkdir(Z(),{recursive:!0}),await U.promises.rm(r,{recursive:!0,force:!0}),t?.start("Building search index\u2026"),await Ve({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"});try{await Hv(o),await Qd({docsDir:o,tmpDir:r,docsZipSha256:e,termsHash:Jr(),synonymsHash:Yr(),builtBy:n.builtBy??"doc-init",onProgress:async i=>{t&&(t.text=i.message),await Ve({state:"indexing",current:i.current,total:i.total,message:i.message})}})}finally{await U.promises.rm(o,{recursive:!0,force:!0})}await Ve({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await jv(),Td()}async function ru(n){await Ve({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),n?.succeed("Documentation ready.")}async function Bv(n){let e=await ji(),t=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";n?.succeed(t),await Ve({state:"done",message:t,error:null})}async function Wv(n,e){let t=n instanceof Error?n.message:String(n);throw await Ve({state:"error",error:t}),await _v(`ERROR: ${t}`),e?.fail(t),n}async function Uv(){let n=Z();await U.promises.mkdir(n,{recursive:!0});let e=Tl();return U.existsSync(e)||await U.promises.writeFile(e,"","utf-8"),e}async function zv(){let n=await Uv();return Nv.lock(n,{stale:1800*1e3})}async function qv(){let n=ze(),e=(n?await Gr(n):null)??await Hi();if(!e)throw new Error("docs.zip not found");return e}async function Vv(n,e){let t=await qv(),r=n.force||await $i(n.force),o=await Fi(n.force);if(!r&&!o&&vn()){await Bv(e);return}if(Oi()&&!n.force){await Fv(t,e),await ru(e);return}await $v(n,t,e),await ru(e)}var ss=class{static async run(e={}){let t=e.background??!1,o=e.quiet??t?void 0:iu({text:"Checking documentation\u2026",color:"cyan"}),i;try{i=await zv(),await _i(Vl("Starting documentation setup\u2026")),await Vv(e,o)}catch(s){return Wv(s,o)}finally{i&&await i()}}};async function Gv(n){for(;;){let e=await Kr();if(e.state==="done"&&vn())return;if(e.state==="error")throw new is("build-failed",e.error??"Documentation setup failed. Try your docs command again in a moment.");n.text=e.message||"Documentation is being prepared\u2026",await Lv(500)}}async function ou(n,e=!1){n.text=e?"Repairing documentation index\u2026":"Starting documentation setup\u2026",await ss.run({builtBy:"doc-init",force:e,quiet:!0})}async function Yv(){if(vn())return;let n=iu({text:"Documentation is being prepared\u2026",color:"cyan"}).start();try{if(await Gl()){await Gv(n),n.succeed("Documentation ready.");return}if(await $i()){await ou(n),n.succeed("Documentation ready.");return}await ou(n,!0),n.succeed("Documentation ready.")}catch(e){throw n.fail(e.message),e}}async function xn(){await Yv(),await nu()}var as=class{async search(e,t,r=20){return await xn(),Rd(e,t,r)}async readDocument(e){return await xn(),jl(e)}},cs=new as;function su(...n){return e=>{if(!n.includes(e))throw new ls(`Allowed values: ${n.join(", ")}`);return e}}function Zv(n){let e=Number(n);if(!Number.isInteger(e)||e<=0)throw new ls("Must be a positive integer.");return e}var Xv=su("json","default"),Qv=su("json","default"),fo=new Jv("docs").description("Search and read HarmonyOS documentation from local docs directory");fo.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)",tw,"all").option("--format <fmt>","Output format (default, json)",Xv,"default").option("--limit <n>","Max number of results",Zv,20).action(async(n,e)=>{try{let t=ew(n),r=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await cs.search(t,r,e.limit);e.format==="json"?console.log(JSON.stringify(o,null,2)):nw(o)}catch(t){console.error(mo(t.message)),process.exit(1)}});fo.command("read <documentId>").description("Read full content of a document by document ID").action(async n=>{try{let e=n.trim();e||(console.error(mo("Document ID cannot be empty.")),process.exit(1));let t=await cs.readDocument(e);console.log(t)}catch(e){console.error(mo(e.message)),process.exit(1)}});fo.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",Qv,"default").action(async n=>{try{if(await xn(),n.format==="json"){let e=We.map(t=>({name:t,title:st[t]}));console.log(JSON.stringify(e,null,2))}else for(let e of We)console.log(` ${e.padEnd(20)} ${Kv(st[e])}`)}catch(e){console.error(mo(e.message)),process.exit(1)}});function ew(n){let e=n.map(r=>r.trim()).filter(Boolean);if(e.length===0)throw new Error("Keywords cannot be empty.");if(e.join(" ").length>fn)throw new Error(`Query exceeds ${fn} characters.`);return e}function tw(n){if(n==="all")return"all";if(!We.includes(n))throw new ls(`Invalid catalog "${n}". Allowed: all, ${We.join(", ")}`);return n}function nw(n){for(let e=0;e<n.length;e++){let t=n[e];console.log(t.documentId),console.log(` Title: ${t.title}`),t.snippet&&console.log(` Content: ${t.snippet}`),e<n.length-1&&console.log()}}var au=fo;process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE="";rw();X.name("devecocli").description("HarmonyOS application development command line tool").version("0.1.0-TD.4-alpha1");X.addCommand(As);X.addCommand(Ls);X.addCommand(Fs);X.addCommand(Zs);I()||X.addCommand(va);X.addCommand(Ua);X.addCommand(Ya);X.addCommand(rc);X.addCommand(uc);X.addCommand(Qc);X.addCommand(au);var ds=process.argv.slice(2);ds.length>=2&&ds[ds.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);var iw=new Set(["update"]);X.hook("preAction",async(n,e)=>{if(process.env.DEVECO_CLI_SKIP_VERSION_CHECK)return;let t=e;for(;t.parent&&t.parent!==X;)t=t.parent;iw.has(t.name())||await _.checkVersion()});X.parseAsync(process.argv).catch(n=>{let e=n instanceof Error?n.message:String(n??"Unknown error");console.error(ow(`Error: ${e}`)),process.env.DEVECO_CLI_DEBUG==="1"&&n instanceof Error&&n.stack&&console.error(n.stack),process.exit(1)});
1339
+ `)}async function Hv(n){let e=ze();if(!e)throw new Error("docs.zip not found");await U.promises.rm(n,{recursive:!0,force:!0}),await U.promises.mkdir(n,{recursive:!0}),new Ov(e).extractAllTo(n,!0),await tu(n)}async function jv(){let n=Z(),e=Lt(),t=await U.promises.readdir(e);for(let r of t){let o=Ft.join(n,r);await U.promises.rm(o,{force:!0}),await U.promises.rename(Ft.join(e,r),o)}await U.promises.rm(e,{recursive:!0,force:!0}),await U.promises.rm(Ft.join(n,"orama.dpack"),{force:!0})}async function Fv(n,e){e?.start("Installing documentation index\u2026"),await Ve({state:"installing",phase:1,phaseLabel:"Installing index",message:"Installing documentation index\u2026"}),await Bl(n),e&&(e.text="Documentation index installed.")}async function $v(n,e,t){let r=Lt(),o=await eu();await U.promises.mkdir(Z(),{recursive:!0}),await U.promises.rm(r,{recursive:!0,force:!0}),t?.start("Building search index\u2026"),await Ve({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"});try{await Hv(o),await Qd({docsDir:o,tmpDir:r,docsZipSha256:e,termsHash:Jr(),synonymsHash:Yr(),builtBy:n.builtBy??"doc-init",onProgress:async i=>{t&&(t.text=i.message),await Ve({state:"indexing",current:i.current,total:i.total,message:i.message})}})}finally{await U.promises.rm(o,{recursive:!0,force:!0})}await Ve({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await jv(),Td()}async function ru(n){await Ve({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),n?.succeed("Documentation ready.")}async function Bv(n){let e=await ji(),t=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";n?.succeed(t),await Ve({state:"done",message:t,error:null})}async function Wv(n,e){let t=n instanceof Error?n.message:String(n);throw await Ve({state:"error",error:t}),await _v(`ERROR: ${t}`),e?.fail(t),n}async function Uv(){let n=Z();await U.promises.mkdir(n,{recursive:!0});let e=Tl();return U.existsSync(e)||await U.promises.writeFile(e,"","utf-8"),e}async function zv(){let n=await Uv();return Nv.lock(n,{stale:1800*1e3})}async function qv(){let n=ze(),e=(n?await Gr(n):null)??await Hi();if(!e)throw new Error("docs.zip not found");return e}async function Vv(n,e){let t=await qv(),r=n.force||await $i(n.force),o=await Fi(n.force);if(!r&&!o&&vn()){await Bv(e);return}if(Oi()&&!n.force){await Fv(t,e),await ru(e);return}await $v(n,t,e),await ru(e)}var ss=class{static async run(e={}){let t=e.background??!1,o=e.quiet??t?void 0:iu({text:"Checking documentation\u2026",color:"cyan"}),i;try{i=await zv(),await _i(Vl("Starting documentation setup\u2026")),await Vv(e,o)}catch(s){return Wv(s,o)}finally{i&&await i()}}};async function Gv(n){for(;;){let e=await Kr();if(e.state==="done"&&vn())return;if(e.state==="error")throw new is("build-failed",e.error??"Documentation setup failed. Try your docs command again in a moment.");n.text=e.message||"Documentation is being prepared\u2026",await Lv(500)}}async function ou(n,e=!1){n.text=e?"Repairing documentation index\u2026":"Starting documentation setup\u2026",await ss.run({builtBy:"doc-init",force:e,quiet:!0})}async function Yv(){if(vn())return;let n=iu({text:"Documentation is being prepared\u2026",color:"cyan"}).start();try{if(await Gl()){await Gv(n),n.succeed("Documentation ready.");return}if(await $i()){await ou(n),n.succeed("Documentation ready.");return}await ou(n,!0),n.succeed("Documentation ready.")}catch(e){throw n.fail(e.message),e}}async function xn(){await Yv(),await nu()}var as=class{async search(e,t,r=20){return await xn(),Rd(e,t,r)}async readDocument(e){return await xn(),jl(e)}},cs=new as;function su(...n){return e=>{if(!n.includes(e))throw new ls(`Allowed values: ${n.join(", ")}`);return e}}function Zv(n){let e=Number(n);if(!Number.isInteger(e)||e<=0)throw new ls("Must be a positive integer.");return e}var Xv=su("json","default"),Qv=su("json","default"),fo=new Jv("docs").description("Search and read HarmonyOS documentation from local docs directory");fo.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)",tw,"all").option("--format <fmt>","Output format (default, json)",Xv,"default").option("--limit <n>","Max number of results",Zv,20).action(async(n,e)=>{try{let t=ew(n),r=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await cs.search(t,r,e.limit);e.format==="json"?console.log(JSON.stringify(o,null,2)):nw(o)}catch(t){console.error(mo(t.message)),process.exit(1)}});fo.command("read <documentId>").description("Read full content of a document by document ID").action(async n=>{try{let e=n.trim();e||(console.error(mo("Document ID cannot be empty.")),process.exit(1));let t=await cs.readDocument(e);console.log(t)}catch(e){console.error(mo(e.message)),process.exit(1)}});fo.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",Qv,"default").action(async n=>{try{if(await xn(),n.format==="json"){let e=We.map(t=>({name:t,title:st[t]}));console.log(JSON.stringify(e,null,2))}else for(let e of We)console.log(` ${e.padEnd(20)} ${Kv(st[e])}`)}catch(e){console.error(mo(e.message)),process.exit(1)}});function ew(n){let e=n.map(r=>r.trim()).filter(Boolean);if(e.length===0)throw new Error("Keywords cannot be empty.");if(e.join(" ").length>fn)throw new Error(`Query exceeds ${fn} characters.`);return e}function tw(n){if(n==="all")return"all";if(!We.includes(n))throw new ls(`Invalid catalog "${n}". Allowed: all, ${We.join(", ")}`);return n}function nw(n){for(let e=0;e<n.length;e++){let t=n[e];console.log(t.documentId),console.log(` Title: ${t.title}`),t.snippet&&console.log(` Content: ${t.snippet}`),e<n.length-1&&console.log()}}var au=fo;process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE="";rw();X.name("devecocli").description("HarmonyOS application development command line tool").version("0.1.0-TD.4");X.addCommand(As);X.addCommand(Ls);X.addCommand(Fs);X.addCommand(Zs);I()||X.addCommand(va);X.addCommand(Ua);X.addCommand(Ya);X.addCommand(rc);X.addCommand(uc);X.addCommand(Qc);X.addCommand(au);var ds=process.argv.slice(2);ds.length>=2&&ds[ds.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);var iw=new Set(["update"]);X.hook("preAction",async(n,e)=>{if(process.env.DEVECO_CLI_SKIP_VERSION_CHECK)return;let t=e;for(;t.parent&&t.parent!==X;)t=t.parent;iw.has(t.name())||await _.checkVersion()});X.parseAsync(process.argv).catch(n=>{let e=n instanceof Error?n.message:String(n??"Unknown error");console.error(ow(`Error: ${e}`)),process.env.DEVECO_CLI_DEBUG==="1"&&n instanceof Error&&n.stack&&console.error(n.stack),process.exit(1)});
package/index.zip CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deveco-test/hmos-deveco-cli",
3
- "version": "0.1.0-TD.4-alpha1",
3
+ "version": "0.1.0-TD.4",
4
4
  "description": "HarmonyOS application development command line tool",
5
5
  "license": "MIT",
6
6
  "type": "module",