@deveco-test/hmos-deveco-cli 0.1.0-TD.6 → 0.1.0-TD.6.2
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/SKILL.md +7 -22
- package/dist/cli.js +3 -3
- package/index.zip +0 -0
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: deveco-cli
|
|
3
3
|
description: >-
|
|
4
|
-
**MUST** use 'devecocli' for HarmonyOS apps (scaffold, build, run, debug, devices,
|
|
4
|
+
**MUST** use 'devecocli' for HarmonyOS apps (scaffold, build, run, debug, devices, logs, docs, 鸿蒙开发文档, skills, multi-preview). **REQUIRED** and **MANDATORY** if workspace has build-profile.json5 or oh-package.json5, or user mentions HarmonyOS, 鸿蒙, DevEco, ArkTS, ArkUI, docs, 鸿蒙文档, 知识, 搜索, skills, or preview/预览/预览器/多预览器/多设备预览器.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# DevEco CLI
|
|
8
8
|
|
|
9
|
-
`devecocli` wraps DevEco Studio's `hvigor`, `ohpm`, `hdc`,
|
|
9
|
+
`devecocli` wraps DevEco Studio's `hvigor`, `ohpm`, `hdc`, and HarmonyOS-skills installer. **Prefer `devecocli` over invoking underlying tools directly.**
|
|
10
10
|
|
|
11
11
|
**Do NOT use these legacy commands** — use the `devecocli` equivalent instead:
|
|
12
12
|
- ❌ `deveco preview` / `hvigorw preview` → ✅ `devecocli run --device <product-name>` (launches DevEco Studio previewer; product name in `--device` triggers previewer mode)
|
|
13
13
|
- ❌ `hvigorw` directly → ✅ `devecocli build`
|
|
14
14
|
- ❌ `hdc` directly (when a `devecocli` wrapper exists) → ✅ `devecocli device` / `devecocli log` / `devecocli run`
|
|
15
15
|
|
|
16
|
-
Available commands: `build`, `run`, `update`, `device`, `
|
|
16
|
+
Available commands: `build`, `run`, `update`, `device`, `skills`, `log`, `create`, `init`, `serve`, `docs`.
|
|
17
17
|
|
|
18
18
|
**Sandbox Rule**: Commands tagged `[Outside sandbox]` must be run outside the sandbox.
|
|
19
19
|
|
|
@@ -36,17 +36,6 @@ Compile and package project/modules. (Defaults: `--product default`, `--build-mo
|
|
|
36
36
|
| Whole product bundle (.app) | `devecocli build --product <name>` |
|
|
37
37
|
| Clean build outputs | `devecocli build clean` |
|
|
38
38
|
|
|
39
|
-
### `devecocli emulator`
|
|
40
|
-
Manage local emulator instances and system images.
|
|
41
|
-
- `list`: Show instances (status, serial, device type).
|
|
42
|
-
- `start <names...>`: Start instances. Quote names with spaces. (See Troubleshooting if blocked).
|
|
43
|
-
- `stop <names...>`: Stop by name or serial (`127.0.0.1:<port>`).
|
|
44
|
-
- `create <name>` (Req: `--device-type`, `--os-version`): Create instance. Optional: `--force`.
|
|
45
|
-
- `delete <name>`: Delete instance.
|
|
46
|
-
- `image list`: List downloaded images. Opts: `--device-type <type>`, `--all`, `--format <table|json>`.
|
|
47
|
-
- `image download` / `image remove` (Req: `--device-type`, `--os-version`): Download/remove image. (Takes 30+ min, set long timeout).
|
|
48
|
-
*Device types*: `phone`, `foldable`, `widefold`, `triplefold`, `tablet`, `2in1`, `2in1 foldable`, `wearable`, `tv`.
|
|
49
|
-
|
|
50
39
|
### `devecocli docs`
|
|
51
40
|
Search/read local HarmonyOS docs.
|
|
52
41
|
- `search <keywords...>`: Match any keyword. Opts: `--catalog <name>`, `--format <default|json>`, `--limit <n>`.
|
|
@@ -54,7 +43,7 @@ Search/read local HarmonyOS docs.
|
|
|
54
43
|
- `catalog`: List available catalogs.
|
|
55
44
|
|
|
56
45
|
### `devecocli device`
|
|
57
|
-
- `list`: Show active real devices
|
|
46
|
+
- `list`: Show active real devices.
|
|
58
47
|
- `view`: Detailed info. Req `-t <name|serial>` on multi-device hosts.
|
|
59
48
|
|
|
60
49
|
### `devecocli run` `[Outside sandbox]`
|
|
@@ -105,8 +94,8 @@ Manage HarmonyOS skills in AI agents/projects.
|
|
|
105
94
|
|
|
106
95
|
## Recipes
|
|
107
96
|
|
|
108
|
-
- **Fresh checkout to
|
|
109
|
-
`devecocli build` -> `devecocli
|
|
97
|
+
- **Fresh checkout to real device**:
|
|
98
|
+
`devecocli build` -> `devecocli device list` -> `devecocli run --device <serial>`
|
|
110
99
|
- **Launch previewer for current project** (instead of `deveco preview`):
|
|
111
100
|
- Single previewer (specific device type): `devecocli run --module entry --device "Pura 90 Pro"`
|
|
112
101
|
- Multi-preview by device types: `devecocli run --module entry --device "Pura 90 Pro,Mate XT"`
|
|
@@ -121,12 +110,8 @@ Manage HarmonyOS skills in AI agents/projects.
|
|
|
121
110
|
|
|
122
111
|
- **"Product / Build mode `<x>` not found"**: Check `build-profile.json5`.
|
|
123
112
|
- **"Multiple entry modules" / "No entry module"**: Pass `--modules` (build) or `--module` (run).
|
|
124
|
-
- **"No active devices" / "Multiple devices connected"**: Connect
|
|
113
|
+
- **"No active devices" / "Multiple devices connected"**: Connect a real device (or self-connect via wireless debugging on HarmonyOS native PC). Pass `-t <serial>` (device view) or `--device <name|serial>` (run/log).
|
|
125
114
|
- **`error:install sign info inconsistent`**: Signing key changed. Run `devecocli run --uninstall`.
|
|
126
115
|
- **`skills add` agent not found**: Valid: `codebuddy`, `cursor`, `opencode`, `qoder`, `trae-cn`.
|
|
127
|
-
- **`emulator start` / `image download` blocked on agreement**: User MUST run `devecocli emulator license accept` in interactive TTY. Agents cannot do this. Do not retry until accepted.
|
|
128
|
-
- **`image download` failure / timeout**: Do NOT auto-retry. Give the command to the user to run manually in their terminal.
|
|
129
|
-
- **`emulator create` timeout**: Treat as user-action step. Ask user to open DevEco Studio -> Device Manager. Check `emulator list` after user confirms. Do NOT auto-retry or edit SDK files.
|
|
130
|
-
- **`image list` duplicate OS rows**: `phone`/`foldable`/`widefold`/`triplefold` share the same image. Download/remove ONCE per OS version.
|
|
131
116
|
- **HarmonyOS native (2in1 PC) — `hdc list targets` shows `[Empty]`**: hdc on HarmonyOS does NOT auto-discover the local device. Open "Settings → System → Developer options → Wireless debugging", note the port, then `hdc tconn 127.0.0.1:<port>`. For normal run: pass `--device 127.0.0.1:<port>`. For previewer mode: set `DEVECO_HDC_PORT=<port>` env var (previewer mode uses `--device` for product name, not hdc target).
|
|
132
117
|
- **Previewer mode — "DevEco Studio is not running"**: The previewer's rendering depends on the DevEco Studio desktop process. If the CLI returns this error, do NOT retry. Use natural language to tell the user: "预览器需要 DevEco Studio 处于运行状态,请先手动启动 DevEco Studio,启动后再重试此命令。" On HarmonyOS PC, also remind the user that process detection may be limited by UID isolation (currentUser cannot see Studio's process), but if the CLI reports this error it means detection genuinely failed.
|
package/dist/cli.js
CHANGED
|
@@ -48,7 +48,7 @@ Available runnable modules:
|
|
|
48
48
|
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(Js(`
|
|
49
49
|
Application '${t}': ${s}`))}else console.log(`
|
|
50
50
|
Application '${t}' installed successfully (no ability to launch).`)}var Rp=new Ep("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 _p(n)}catch(e){console.error(Dp(e.message)),process.exit(1)}});async function Mp(n,e,t,r,o){let i=new Le(e,n.rootDir),s=new Pe(e,n.rootDir),a=new Set;for(let{moduleName:h,targetName:v}of t)for(let D of n.collectNonHarDependentModuleList(h))a.add(`${D}@${v}`);let c=[...a],l=zt(n,c),u={type:"modules",modulesToBuild:c,moduleTasks:l};await Xe(n.rootDir,()=>qt(i,s,r,o,u,n.rootDir),()=>console.log("Another build is already running for this project. Waiting for completion...")),console.log(`
|
|
51
|
-
`+Js("Build completed successfully."))}async function Op(n,e,t,r,o){let i=new Yt(t),s=K.from(t),a=r[0]?.moduleName||o[0];await Ys(n,e,t,i,s,a)||process.exit(1)}function Np(n,e){for(let{moduleName:t}of e){let r=n.getModuleType(t);if(r!=="entry"&&r!=="feature"&&r!=="shared")throw new Error(`Module '${t}' '${r}' is not runnable. Specify an entry or feature module.`)}}function Lp(n,e,t,r){let o=new Set;for(let{moduleName:i,targetName:s}of e){let a=n.collectNonHarDependentModuleList(i);for(let c of a)o.add(n.findArtifactPath(c,s,t,r));o.add(n.findArtifactPath(i,s,t,r))}return[...o]}async function _p(n){let e=Ze.discover(process.cwd());console.warn(Ip("Ensure the project source is trusted before proceeding."));let t=await _.new(),r=Tp(e,n.module),o=r.map(Cp);if(await Gs(n.device)){await Op(n,e,t,o,r);return}Np(e,o);let i=new Yt(t),s=K.from(t),a=await Ap(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 Mp(e,t,o,l,u);let h=Lp(e,o,c,l),v=e.getBundleName(),D=xp(e,o,n.ability);await kp(i,a,v,h,D,!!n.uninstall)}var Ks=Rp;import{Command as Hp}from"commander";import{green as Zs,red as Xs,cyan as Fo}from"colorette";import{execa as Qs}from"execa";function jp(){return"@deveco-test/hmos-deveco-cli"}function Fp(){return"0.1.0-TD.6"}var $p=new Hp("update").description("Update deveco-cli to latest").action(async()=>{let n=jp(),e=Fp();console.log(Fo("Checking for updates..."));try{let{stdout:t}=await Qs("npm",["view",n,"version"]),r=t.trim();if(r===e){console.log(Zs(`
|
|
51
|
+
`+Js("Build completed successfully."))}async function Op(n,e,t,r,o){let i=new Yt(t),s=K.from(t),a=r[0]?.moduleName||o[0];await Ys(n,e,t,i,s,a)||process.exit(1)}function Np(n,e){for(let{moduleName:t}of e){let r=n.getModuleType(t);if(r!=="entry"&&r!=="feature"&&r!=="shared")throw new Error(`Module '${t}' '${r}' is not runnable. Specify an entry or feature module.`)}}function Lp(n,e,t,r){let o=new Set;for(let{moduleName:i,targetName:s}of e){let a=n.collectNonHarDependentModuleList(i);for(let c of a)o.add(n.findArtifactPath(c,s,t,r));o.add(n.findArtifactPath(i,s,t,r))}return[...o]}async function _p(n){let e=Ze.discover(process.cwd());console.warn(Ip("Ensure the project source is trusted before proceeding."));let t=await _.new(),r=Tp(e,n.module),o=r.map(Cp);if(await Gs(n.device)){await Op(n,e,t,o,r);return}Np(e,o);let i=new Yt(t),s=K.from(t),a=await Ap(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 Mp(e,t,o,l,u);let h=Lp(e,o,c,l),v=e.getBundleName(),D=xp(e,o,n.ability);await kp(i,a,v,h,D,!!n.uninstall)}var Ks=Rp;import{Command as Hp}from"commander";import{green as Zs,red as Xs,cyan as Fo}from"colorette";import{execa as Qs}from"execa";function jp(){return"@deveco-test/hmos-deveco-cli"}function Fp(){return"0.1.0-TD.6.2"}var $p=new Hp("update").description("Update deveco-cli to latest").action(async()=>{let n=jp(),e=Fp();console.log(Fo("Checking for updates..."));try{let{stdout:t}=await Qs("npm",["view",n,"version"]),r=t.trim();if(r===e){console.log(Zs(`
|
|
52
52
|
${n} is already up to date (version ${e}.)`));return}console.log(Fo(`
|
|
53
53
|
New version found: ${r} (current: ${e})`)),console.log(Fo(`Updating ${n}...`)),await Qs("npm",["install","-g",`${n}@latest`],{stdio:"inherit"}),console.log(`
|
|
54
54
|
`+Zs(`${n} updated successfully to version ${r}.`))}catch(t){let r=t;console.error(Xs(`Failed to update ${n}`)),r.message&&console.error(Xs(r.message)),process.exit(1)}}),ea=$p;import{Command as cm}from"commander";import{execa as Uo}from"execa";function V(n){return n.normalize("NFKC").replace(/\s+/g," ").trim()}import{spawn as Bp}from"child_process";var Wp=2500;function Up(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 zp(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,Wp);n.once("error",u=>c(u.message)),Up(n,l,s,a,c,i)}function ta(n,e,t){return g(`Spawning emulator: ${n} ${t.join(" ")}`),new Promise((r,o)=>{let i=[],s=Bp(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)),zp(s,i,r,o)})}import*as gt from"path";function qp(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 Vp(n){let e=n.instancePath?.trim();if(e)return gt.dirname(gt.normalize(e)).replace(/\\/g,"/");let t=n.path?.trim();return t?gt.dirname(gt.normalize(t)).replace(/\\/g,"/"):""}function Gp(n){let e=[];return n&&e.push(["-imageRoot",n]),e.push([]),e}function na(n,e){return e?[...n,"-bootmode",e]:n}function Yp(n,e,t){let r=[na(["-start",n],t)],o=Vp(e);if(o)for(let i of Gp(e.imageRoot))r.push(na(["-hvd",n,"-path",o,...i],t));return qp(r)}async function ra(n,e,t,r){let o=new Error("No start strategy ran"),i=Yp(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 $o(n){return(await K.withHdcPath(n).listDevices()).map(t=>t.serial).filter(Gt)}async function Bo(n){let e=await $o(n);return e.length===0?[]:(await Promise.all(e.map(r=>Wn(n,r,"ohos.qemu.hvd.name")))).filter(r=>!!r)}async function oa(n,e){return(await Bo(n)).includes(e)}import*as vt from"path";import{existsSync as Jp,statSync as Kp}from"fs";function yt(n,e){for(let t of e){let r=n[t];if(typeof r=="string"&&r.trim())return r.trim()}return""}function Zp(n){let e=yt(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 Xp(n){return yt(n,["uuid","UUID","Uuid","instanceUuid","instance_uuid","InstanceUuid"])}function Qp(n){let e=n.find(r=>r.instancePath?.trim());if(!e?.instancePath?.trim())return;let t=vt.dirname(vt.normalize(e.instancePath));for(let r of n){if(r.instancePath?.trim())continue;let o=vt.join(t,r.name);Jp(o)&&Kp(o).isDirectory()&&(r.instancePath=o.replace(/\\/g,"/"))}}function em(n){try{let e=JSON.parse(n);return Array.isArray(e)?e.map(t=>{let r=Xp(t),o=yt(t,["deviceType","DeviceType","devicetype"]),i=yt(t,["os.osVersion","osVersion","OsVersion","OSVersion"]);return{name:t.name||t.Name||"",isRunning:t.isRunning===!0||String(t.isRunning).toLowerCase()==="true",instancePath:Zp(t),path:yt(t,["path","Path","hvdPath","hvd_path"]),imageRoot:yt(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 tm(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 ia(n){let t=em(n)??tm(n);return Qp(t),t}function Wo(n,e){for(let t of e){let r=n[t];if(typeof r=="string"&&r.trim())return r.trim()}return""}function nm(n){let e=n.downloaded??n.Downloaded;return e===!0||String(e).toLowerCase()==="true"}function rm(n){if(!nm(n))return null;let e=Wo(n,["osVersion","OsVersion","OSVersion"]),t=Wo(n,["SoftWareVersion","SoftwareVersion","softwareVersion"]),r=Wo(n,["deviceType","DeviceType"]);return!e&&!t?null:{osVersion:e,softwareVersion:t,deviceType:r}}function Vn(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=rm(o);i&&r.push(i)}return r}catch{return[]}}function sa(n){let t=Vn(n).map(r=>r.osVersion).filter(Boolean);return[...new Set(t)]}var aa=/no images are available/i;function he(n){return n.normalize("NFKC").trim().toLowerCase()}function om(n){let e=n.message||"";return aa.test(e)}var wt=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 Uo(this.emulatorPath,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,DEVECO_SDK_HOME:this.sdkPath}})}executeEmulatorDetached(e){return ta(this.emulatorPath,this.sdkPath,e)}async listEmulators(){let{stdout:e}=await this.executeEmulator(["-list","-details"]);return ia(e)}async getDeviceTypeByName(){let e=new Map;try{let t=await this.listEmulators();for(let r of t)r.name&&r.deviceType&&e.set(V(r.name),r.deviceType)}catch{}return e}async startEmulator(e){let t=await this.listEmulators(),r=V(e),o=t.find(a=>V(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 ra(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.
|
|
@@ -1265,7 +1265,7 @@ Output so far:
|
|
|
1265
1265
|
`):"\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=we.isAbsolute(i)?i:we.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 Tc(500);try{let i=await this.checkFile(o);r.push(pg(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(`
|
|
1266
1266
|
`)),t.length>0&&r.push(t.join(`
|
|
1267
1267
|
`));let o=r.join(`
|
|
1268
|
-
`).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(un),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=ln(e),r=this.popDiagnosticWaiter(t);if(r)return r;for(let o of kc(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=we.join(lr(),"ArkTSCheck"),r=we.join(t,"mapping-config.properties"),o=Rc(e,r),i=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=we.join(t,"lsp-log",String(o),i),a=we.join(t,"lsp-index",String(o));return xe.mkdirSync(s,{recursive:!0}),xe.mkdirSync(a,{recursive:!0}),{logPath:ve(s),indexPath:ve(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function pg(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 mg}from"child_process";import*as C from"fs";import*as Z from"path";import{z as ki}from"zod";var sl=60*1e3,fg=30*1e3,hg=new Set(["textDocument/didOpen","textDocument/didChange","textDocument/didClose","textDocument/didSave"]),gg=1e3,Mi=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=ve(this.projectPath),o=rt(r),i=Z.basename(r)||"workspace",s={processId:null,clientInfo:{name:"devecocli-mcp-server",version:"0.1.0-TD.6"},rootPath:r,rootUri:o,workspaceFolders:[{uri:o,name:i}],capabilities:{}};await this.sendRequestToClangd("initialize",s,sl),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=sl,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=C.realpathSync(e)}catch{t=e}let r=rt(t),o=xc(t),i=await C.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}`))},fg);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}hg.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
|
|
1268
|
+
`).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(un),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=ln(e),r=this.popDiagnosticWaiter(t);if(r)return r;for(let o of kc(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=we.join(lr(),"ArkTSCheck"),r=we.join(t,"mapping-config.properties"),o=Rc(e,r),i=`${Date.now()}${process.hrtime.bigint()%1000000n}`,s=we.join(t,"lsp-log",String(o),i),a=we.join(t,"lsp-index",String(o));return xe.mkdirSync(s,{recursive:!0}),xe.mkdirSync(a,{recursive:!0}),{logPath:ve(s),indexPath:ve(a)}}catch{return{logPath:"auto",indexPath:"auto"}}}};function pg(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 mg}from"child_process";import*as C from"fs";import*as Z from"path";import{z as ki}from"zod";var sl=60*1e3,fg=30*1e3,hg=new Set(["textDocument/didOpen","textDocument/didChange","textDocument/didClose","textDocument/didSave"]),gg=1e3,Mi=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=ve(this.projectPath),o=rt(r),i=Z.basename(r)||"workspace",s={processId:null,clientInfo:{name:"devecocli-mcp-server",version:"0.1.0-TD.6.2"},rootPath:r,rootUri:o,workspaceFolders:[{uri:o,name:i}],capabilities:{}};await this.sendRequestToClangd("initialize",s,sl),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=sl,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=C.realpathSync(e)}catch{t=e}let r=rt(t),o=xc(t),i=await C.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}`))},fg);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}hg.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
|
|
1269
1269
|
\r
|
|
1270
1270
|
`,"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
|
|
1271
1271
|
\r
|
|
@@ -1351,4 +1351,4 @@ CREATE INDEX segments_doc_id_idx ON segments(doc_id);
|
|
|
1351
1351
|
Detail: ${n.message}`):n}try{await Ye()}catch(n){let e=n instanceof Error?n.message:String(n);throw new Ln(`${gw()}
|
|
1352
1352
|
|
|
1353
1353
|
Detail: ${e}`)}try{await Mn()}catch(n){let e=n instanceof Error?n.message:String(n);throw new Ln(yw(e))}}var vs=class extends Error{constructor(t,r){super(r);this.code=t;this.name="DocNotReadyError"}code};function bw(n){return new Promise(e=>setTimeout(e,n))}async function Sw(n){let e=jt();await z.promises.mkdir(Bt.dirname(e),{recursive:!0}),await z.promises.appendFile(e,`${new Date().toISOString()} ${n}
|
|
1354
|
-
`)}async function Pw(n){let e=qe();if(!e)throw new Error("docs.zip not found");await z.promises.rm(n,{recursive:!0,force:!0}),await z.promises.mkdir(n,{recursive:!0}),new vw(e).extractAllTo(n,!0),await gu(n)}async function Ew(){let n=X(),e=Ht(),t=await z.promises.readdir(e);for(let r of t){let o=Bt.join(n,r);await z.promises.rm(o,{force:!0}),await z.promises.rename(Bt.join(e,r),o)}await z.promises.rm(e,{recursive:!0,force:!0}),await z.promises.rm(Bt.join(n,"orama.dpack"),{force:!0})}async function Dw(n,e){e?.start("Installing documentation index\u2026"),await Ge({state:"installing",phase:1,phaseLabel:"Installing index",message:"Installing documentation index\u2026"}),await nd(n),e&&(e.text="Documentation index installed.")}async function Iw(n,e,t){let r=Ht(),o=await hu();await z.promises.mkdir(X(),{recursive:!0}),await z.promises.rm(r,{recursive:!0,force:!0}),t?.start("Building search index\u2026"),await Ge({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"});try{await Pw(o),await fu({docsDir:o,tmpDir:r,docsZipSha256:e,termsHash:ro(),synonymsHash:no(),builtBy:n.builtBy??"doc-init",onProgress:async i=>{t&&(t.text=i.message),await Ge({state:"indexing",current:i.current,total:i.total,message:i.message})}})}finally{await z.promises.rm(o,{recursive:!0,force:!0})}await Ge({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await Ew(),Ud()}async function vu(n){await Ge({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),n?.succeed("Documentation ready.")}async function Cw(n){let e=await Zi(),t=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";n?.succeed(t),await Ge({state:"done",message:t,error:null})}async function Aw(n,e){let t=n instanceof Error?n.message:String(n);throw await Ge({state:"error",error:t}),await Sw(`ERROR: ${t}`),e?.fail(t),n}async function Tw(){let n=X();await z.promises.mkdir(n,{recursive:!0});let e=Ul();return z.existsSync(e)||await z.promises.writeFile(e,"","utf-8"),e}async function xw(){let n=await Tw();return ww.lock(n,{stale:1800*1e3})}async function kw(){let n=qe(),e=(n?await to(n):null)??await Ki();if(!e)throw new Error("docs.zip not found");return e}async function Rw(n,e){let t=await kw(),r=n.force||await Qi(n.force),o=await Xi(n.force);if(!r&&!o&&In()){await Cw(e);return}if(Vi()&&!n.force){await Dw(t,e),await vu(e);return}await Iw(n,t,e),await vu(e)}var ws=class{static async run(e={}){let t=e.background??!1,o=e.quiet??t?void 0:bu({text:"Checking documentation\u2026",color:"cyan"}),i;try{i=await xw(),await Ji(ad("Starting documentation setup\u2026")),await Rw(e,o)}catch(s){await Aw(s,o)}finally{i&&await i()}}};async function Mw(n){for(;;){let e=await oo();if(e.state==="done"&&In())return;if(e.state==="error")throw new vs("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 bw(500)}}async function wu(n,e=!1){n.text=e?"Repairing documentation index\u2026":"Starting documentation setup\u2026",await ws.run({builtBy:"doc-init",force:e,quiet:!0})}async function Ow(){if(In())return;let n=bu({text:"Documentation is being prepared\u2026",color:"cyan"}).start();try{if(await cd()){await Mw(n),n.succeed("Documentation ready.");return}if(await Qi()){await wu(n),n.succeed("Documentation ready.");return}await wu(n,!0),n.succeed("Documentation ready.")}catch(e){throw n.fail(e.message),e}}async function _n(){await Ow(),await yu()}var bs=class{async search(e,t,r=20){return await _n(),Vd(e,t,r)}async readDocument(e){return await _n(),Ql(e)}},Ss=new bs;function Su(...n){return e=>{if(!n.includes(e))throw new Ps(`Allowed values: ${n.join(", ")}`);return e}}function _w(n){let e=Number(n);if(!Number.isInteger(e)||e<=0)throw new Ps("Must be a positive integer.");return e}var Hw=Su("json","default"),jw=Su("json","default"),Po=new Nw("docs").description("Search and read HarmonyOS documentation from local docs directory");Po.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)",$w,"all").option("--format <fmt>","Output format (default, json)",Hw,"default").option("--limit <n>","Max number of results",_w,20).action(async(n,e)=>{try{let t=Fw(n),r=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await Ss.search(t,r,e.limit);e.format==="json"?console.log(JSON.stringify(o,null,2)):Bw(o)}catch(t){console.error(So(t.message)),process.exit(1)}});Po.command("read <documentId>").description("Read full content of a document by document ID").action(async n=>{try{let e=n.trim();e||(console.error(So("Document ID cannot be empty.")),process.exit(1));let t=await Ss.readDocument(e);console.log(t)}catch(e){console.error(So(e.message)),process.exit(1)}});Po.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",jw,"default").action(async n=>{try{if(await _n(),n.format==="json"){let e=Ue.map(t=>({name:t,title:at[t]}));console.log(JSON.stringify(e,null,2))}else for(let e of Ue)console.log(` ${e.padEnd(20)} ${Lw(at[e])}`)}catch(e){console.error(So(e.message)),process.exit(1)}});function Fw(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>Sn)throw new Error(`Query exceeds ${Sn} characters.`);return e}function $w(n){if(n==="all")return"all";if(!Ue.includes(n))throw new Ps(`Invalid catalog "${n}". Allowed: all, ${Ue.join(", ")}`);return n}function Bw(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 Pu=Po;process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE="";Ww();Q.name("devecocli").description("HarmonyOS application development command line tool").version("0.1.0-TD.6");Q.addCommand(Fs);Q.addCommand(Ks);Q.addCommand(ea);Q.addCommand(pa);I()||Q.addCommand(Oa);Q.addCommand(oc);Q.addCommand(lc);Q.addCommand(vc);Q.addCommand(Cc);Q.addCommand(fl);Q.addCommand(Pu);var Es=process.argv.slice(2);Es.length>=2&&Es[Es.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);var zw=new Set(["update"]);Q.hook("preAction",async(n,e)=>{if(process.env.DEVECO_CLI_SKIP_VERSION_CHECK)return;let t=e;for(;t.parent&&t.parent!==Q;)t=t.parent;zw.has(t.name())||await _.checkVersion()});Q.parseAsync(process.argv).catch(n=>{let e=n instanceof Error?n.message:String(n??"Unknown error");console.error(Uw(`Error: ${e}`)),process.env.DEVECO_CLI_DEBUG==="1"&&n instanceof Error&&n.stack&&console.error(n.stack),process.exit(1)});
|
|
1354
|
+
`)}async function Pw(n){let e=qe();if(!e)throw new Error("docs.zip not found");await z.promises.rm(n,{recursive:!0,force:!0}),await z.promises.mkdir(n,{recursive:!0}),new vw(e).extractAllTo(n,!0),await gu(n)}async function Ew(){let n=X(),e=Ht(),t=await z.promises.readdir(e);for(let r of t){let o=Bt.join(n,r);await z.promises.rm(o,{force:!0}),await z.promises.rename(Bt.join(e,r),o)}await z.promises.rm(e,{recursive:!0,force:!0}),await z.promises.rm(Bt.join(n,"orama.dpack"),{force:!0})}async function Dw(n,e){e?.start("Installing documentation index\u2026"),await Ge({state:"installing",phase:1,phaseLabel:"Installing index",message:"Installing documentation index\u2026"}),await nd(n),e&&(e.text="Documentation index installed.")}async function Iw(n,e,t){let r=Ht(),o=await hu();await z.promises.mkdir(X(),{recursive:!0}),await z.promises.rm(r,{recursive:!0,force:!0}),t?.start("Building search index\u2026"),await Ge({state:"indexing",phase:2,phaseLabel:"Building search index",message:"Building search index\u2026"});try{await Pw(o),await fu({docsDir:o,tmpDir:r,docsZipSha256:e,termsHash:ro(),synonymsHash:no(),builtBy:n.builtBy??"doc-init",onProgress:async i=>{t&&(t.text=i.message),await Ge({state:"indexing",current:i.current,total:i.total,message:i.message})}})}finally{await z.promises.rm(o,{recursive:!0,force:!0})}await Ge({state:"persisting",phase:3,phaseLabel:"Persisting index",message:"Persisting index\u2026"}),await Ew(),Ud()}async function vu(n){await Ge({state:"done",phase:3,phaseLabel:"Done",message:"Documentation ready.",error:null}),n?.succeed("Documentation ready.")}async function Cw(n){let e=await Zi(),t=e?`Documentation already up to date. Documents: ${e.segmentCount.toLocaleString()}`:"Documentation already up to date.";n?.succeed(t),await Ge({state:"done",message:t,error:null})}async function Aw(n,e){let t=n instanceof Error?n.message:String(n);throw await Ge({state:"error",error:t}),await Sw(`ERROR: ${t}`),e?.fail(t),n}async function Tw(){let n=X();await z.promises.mkdir(n,{recursive:!0});let e=Ul();return z.existsSync(e)||await z.promises.writeFile(e,"","utf-8"),e}async function xw(){let n=await Tw();return ww.lock(n,{stale:1800*1e3})}async function kw(){let n=qe(),e=(n?await to(n):null)??await Ki();if(!e)throw new Error("docs.zip not found");return e}async function Rw(n,e){let t=await kw(),r=n.force||await Qi(n.force),o=await Xi(n.force);if(!r&&!o&&In()){await Cw(e);return}if(Vi()&&!n.force){await Dw(t,e),await vu(e);return}await Iw(n,t,e),await vu(e)}var ws=class{static async run(e={}){let t=e.background??!1,o=e.quiet??t?void 0:bu({text:"Checking documentation\u2026",color:"cyan"}),i;try{i=await xw(),await Ji(ad("Starting documentation setup\u2026")),await Rw(e,o)}catch(s){await Aw(s,o)}finally{i&&await i()}}};async function Mw(n){for(;;){let e=await oo();if(e.state==="done"&&In())return;if(e.state==="error")throw new vs("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 bw(500)}}async function wu(n,e=!1){n.text=e?"Repairing documentation index\u2026":"Starting documentation setup\u2026",await ws.run({builtBy:"doc-init",force:e,quiet:!0})}async function Ow(){if(In())return;let n=bu({text:"Documentation is being prepared\u2026",color:"cyan"}).start();try{if(await cd()){await Mw(n),n.succeed("Documentation ready.");return}if(await Qi()){await wu(n),n.succeed("Documentation ready.");return}await wu(n,!0),n.succeed("Documentation ready.")}catch(e){throw n.fail(e.message),e}}async function _n(){await Ow(),await yu()}var bs=class{async search(e,t,r=20){return await _n(),Vd(e,t,r)}async readDocument(e){return await _n(),Ql(e)}},Ss=new bs;function Su(...n){return e=>{if(!n.includes(e))throw new Ps(`Allowed values: ${n.join(", ")}`);return e}}function _w(n){let e=Number(n);if(!Number.isInteger(e)||e<=0)throw new Ps("Must be a positive integer.");return e}var Hw=Su("json","default"),jw=Su("json","default"),Po=new Nw("docs").description("Search and read HarmonyOS documentation from local docs directory");Po.command("search <keywords...>").description("Search documentation by keywords").option("--catalog <name>","Catalog name (all for all catalogs)",$w,"all").option("--format <fmt>","Output format (default, json)",Hw,"default").option("--limit <n>","Max number of results",_w,20).action(async(n,e)=>{try{let t=Fw(n),r=e.catalog&&e.catalog!=="all"?e.catalog:void 0,o=await Ss.search(t,r,e.limit);e.format==="json"?console.log(JSON.stringify(o,null,2)):Bw(o)}catch(t){console.error(So(t.message)),process.exit(1)}});Po.command("read <documentId>").description("Read full content of a document by document ID").action(async n=>{try{let e=n.trim();e||(console.error(So("Document ID cannot be empty.")),process.exit(1));let t=await Ss.readDocument(e);console.log(t)}catch(e){console.error(So(e.message)),process.exit(1)}});Po.command("catalog").description("List all available catalogs").option("--format <fmt>","Output format (default, json)",jw,"default").action(async n=>{try{if(await _n(),n.format==="json"){let e=Ue.map(t=>({name:t,title:at[t]}));console.log(JSON.stringify(e,null,2))}else for(let e of Ue)console.log(` ${e.padEnd(20)} ${Lw(at[e])}`)}catch(e){console.error(So(e.message)),process.exit(1)}});function Fw(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>Sn)throw new Error(`Query exceeds ${Sn} characters.`);return e}function $w(n){if(n==="all")return"all";if(!Ue.includes(n))throw new Ps(`Invalid catalog "${n}". Allowed: all, ${Ue.join(", ")}`);return n}function Bw(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 Pu=Po;process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE="";Ww();Q.name("devecocli").description("HarmonyOS application development command line tool").version("0.1.0-TD.6.2");Q.addCommand(Fs);Q.addCommand(Ks);Q.addCommand(ea);Q.addCommand(pa);I()||Q.addCommand(Oa);Q.addCommand(oc);Q.addCommand(lc);Q.addCommand(vc);Q.addCommand(Cc);Q.addCommand(fl);Q.addCommand(Pu);var Es=process.argv.slice(2);Es.length>=2&&Es[Es.length-1]==="help"&&(process.argv=[...process.argv.slice(0,-1),"--help"]);var zw=new Set(["update"]);Q.hook("preAction",async(n,e)=>{if(process.env.DEVECO_CLI_SKIP_VERSION_CHECK)return;let t=e;for(;t.parent&&t.parent!==Q;)t=t.parent;zw.has(t.name())||await _.checkVersion()});Q.parseAsync(process.argv).catch(n=>{let e=n instanceof Error?n.message:String(n??"Unknown error");console.error(Uw(`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
|