@oniroproject/oniro-app 0.13.0 → 0.14.0

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/README.md CHANGED
@@ -69,7 +69,7 @@ Install commands are idempotent (they skip when already present); pass `--force`
69
69
  | Command | Description |
70
70
  | --- | --- |
71
71
  | `cmdtools install [--from-zip <path>] [--force] [--tmp-dir <path>]` | Install the tools. `--from-zip` installs from a local archive instead of downloading (required on Windows/macOS — see [Configuration](#configuration)); `--tmp-dir` overrides where download/extract temporaries go (see [Temporary space](#temporary-space)). |
72
- | `cmdtools status [--json]` | Report whether the tools are installed and their version. Exits non-zero when not installed. |
72
+ | `cmdtools status [--json]` | Report whether the tools are installed, their version, their flavour (`HarmonyOS` when they bundle `sdk/default/hms`, as the Huawei developer-portal download does, else `OpenHarmony`), and the `hdc` binary every device command uses. Exits non-zero when not installed. |
73
73
  | `cmdtools remove` | Delete the configured command-line-tools directory. |
74
74
 
75
75
  #### `emulator` — manage the Oniro emulator (QEMU-based)
@@ -78,6 +78,7 @@ Install commands are idempotent (they skip when already present); pass `--force`
78
78
  | --- | --- |
79
79
  | `emulator install [--force] [--tmp-dir <path>]` | Download and install the emulator. `--tmp-dir` overrides where the downloaded ZIP goes (see [Temporary space](#temporary-space)). |
80
80
  | `emulator start [options]` | Start the emulator via the bundled launcher and detach, so the CLI can exit while it keeps running. |
81
+ | `emulator status [--address <host:port>] [--json]` | Report whether the emulator is installed, running, and connected to `hdc`, without starting it. Exits non-zero when not installed. DevEco Studio's HarmonyOS emulator is not covered; it shows up in `devices`. |
81
82
  | `emulator stop` | Kill running emulator processes. |
82
83
  | `emulator connect [--address <host:port>]` | Attempt an `hdc` connection (default `127.0.0.1:55555`). |
83
84
  | `emulator remove` | Delete the configured emulator directory. |
@@ -126,13 +127,14 @@ Only needed for HarmonyOS signing; see [HarmonyOS apps](#harmonyos-apps).
126
127
 
127
128
  #### `sign` — generate signing keys, certs, and `signingConfigs`
128
129
 
129
- `sign [project-dir]` (defaults to the current directory). Requires `java` on `PATH`. Rewrites only the `signingConfigs` block of `build-profile.json5` (other keys are preserved). The generated profile uses the SDK's built-in development cert (`issuer=pki_internal`) and its validity window — **dev/local builds only, not distribution.** See [Signing apps that need system permissions](#signing-apps-that-need-system-permissions) for `--apl` / `--acls`.
130
+ `sign [project-dir]` (defaults to the current directory). Requires `java` on `PATH`. Rewrites the `signingConfigs` block of `build-profile.json5`, and points any product that names no `signingConfig` at the generated one (other keys are preserved). The generated profile uses the SDK's built-in development cert (`issuer=pki_internal`) and its validity window — **dev/local builds only, not distribution.** See [Signing apps that need system permissions](#signing-apps-that-need-system-permissions) for `--apl` / `--acls`.
130
131
 
131
132
  | Flag | Description |
132
133
  | --- | --- |
133
134
  | `--apl <level>` | Ability Privilege Level: `normal` (default), `system_basic`, or `system_core`. |
134
135
  | `--app-feature <feature>` | `hos_normal_app` or `hos_system_app`. Defaults follow `--apl`. |
135
136
  | `--acls <list>` | Comma-separated permissions to write into the profile's `acls.allowed-acls`. |
137
+ | `--app-privilege-capabilities <list>` | Comma-separated privileges to write into the profile's `app-privilege-capabilities`, e.g. `AllowAppUsePrivilegeExtension` for an app with a privileged extension ability (without it, install fails with `9568344 not allow use privilege extension`). |
136
138
  | `--bootstrap` | No-op if signing material is already present; otherwise generate it. |
137
139
  | `--harmonyos` | Sign a HarmonyOS project via AppGallery Connect instead of the offline flow. See [HarmonyOS apps](#harmonyos-apps). |
138
140
  | `--team-id <id>` | With `--harmonyos`: AGC team to sign under. |
@@ -142,7 +144,7 @@ Only needed for HarmonyOS signing; see [HarmonyOS apps](#harmonyos-apps).
142
144
 
143
145
  #### `build` — build the app via `hvigorw`
144
146
 
145
- `build [project-dir]` (defaults to the current directory). Modules build in parallel by default.
147
+ `build [project-dir]` (defaults to the current directory). Modules build in parallel by default. An OpenHarmony project whose `compileSdkVersion` SDK is not installed fails before anything runs, naming the release to install. When the compiler output shows system-API errors (`'…' is not exported from Kit '…'`), the error adds a hint about the full SDK.
146
148
 
147
149
  | Flag | Description |
148
150
  | --- | --- |
@@ -152,34 +154,35 @@ Only needed for HarmonyOS signing; see [HarmonyOS apps](#harmonyos-apps).
152
154
  | `--task <task>` | hvigor task to run (default `assembleHap`). |
153
155
  | `--no-deps` | Skip the automatic `ohpm install --all` when `oh_modules/` is missing. |
154
156
  | `--no-parallel` | Build modules serially. |
157
+ | `--install-sdk` | Install the missing OpenHarmony SDK the project compiles against, then build. |
155
158
  | `--json` | Emit the result (discovered HAPs grouped by module, warnings) as JSON. |
156
159
 
157
160
  #### `lint` — run the OpenHarmony codelinter
158
161
 
159
- `lint [project-dir]` (defaults to the current directory). Exits with the codelinter's exit code.
162
+ `lint [project-dir]` (defaults to the current directory). Prints each finding as `file:line:col severity message [rule]`, then the totals (`N defects: E errors, W warnings, S suggestions.`). Exits 1 on error-severity findings or when codelinter fails to produce a report; warnings alone exit 0, although codelinter itself exits 1 for them. When codelinter says its report is incomplete, for example because the command-line tools' flavour (see `cmdtools status`) does not match the project's `runtimeOS`, a warning on stderr explains it: treat the counts as a lower bound.
160
163
 
161
164
  | Flag | Description |
162
165
  | --- | --- |
163
166
  | `--files <globs...>` | Specific files/globs to lint (default: the whole project). |
164
- | `--json` | Emit findings as JSON. |
167
+ | `--json` | Emit the report as JSON: `findings`, `summary` (codelinter's totals), `notices`, `incomplete`, `code`, and the cleaned `raw` output. |
165
168
 
166
169
  ### Device & app
167
170
 
168
- These commands target a connected device or emulator over `hdc`. Most accept `--device <serial>` to address a specific target; omit it to use the single connected device.
171
+ These commands target a connected device or emulator over `hdc`. Most accept `--device <serial>` to address a specific target. Without it they use `ONIRO_DEVICE_SERIAL`, then the single connected device. A TCP serial such as `127.0.0.1:5555` works like a USB one. hdc exits 0 even when it fails (`[Fail]ExecuteCommand need connect-key?` when several targets are connected and none was named); every command here reports that as an error.
169
172
 
170
173
  #### `devices` — list connected hdc devices
171
174
 
172
175
  | Command | Description |
173
176
  | --- | --- |
174
- | `devices [--json]` | List connected targets (`serial`, connection, status). |
177
+ | `devices [--long] [--json]` | List connected targets (`serial`, connection, status). `--long` also asks each connected one for its OS family and version (`os=HarmonyOS 6.1.0` / `os=OpenHarmony`), API level, CPU ABI, device type, model, and `const.ohos.fullname`. |
175
178
 
176
179
  #### `app` — install, launch, and manage built apps
177
180
 
178
181
  | Command | Description |
179
182
  | --- | --- |
180
- | `app install [project-dir] [--hap <path>] [--device <serial>]` | Install the signed `.hap` via `hdc`. `--hap` overrides the resolved path. |
183
+ | `app install [project-dir \| file.hap] [--hap <path>] [--device <serial>]` | Install a `.hap` via `hdc`: a given file, else the project's newest signed HAP, else its unsigned one (a `*-signed.hap` path that does not exist falls back to its `*-unsigned.hap`). Fails when the bundle manager rejects the HAP; when a target refuses an unsigned HAP, the error gives the bundle manager's reason and the `sign` command to run. |
181
184
  | `app launch [project-dir] [--module <m>] [--ability <name>] [--device <serial>]` | Launch the app. `--ability` defaults to the module's `mainElement` / first visible ability. |
182
- | `app apply [project-dir] --bundle <b> [options]` | Install a HAP **and verify the running process took the change** — handles sign-info mismatch, asset-cache invalidation, and persistent-bundle restart. |
185
+ | `app apply [project-dir] --bundle <b> [options]` | Install a HAP **and verify it took**: fails when the bundle manager rejects it or `bm dump` does not then list the bundle, and handles sign-info mismatch, asset-cache invalidation, and persistent-bundle restart. Uses the newest signed HAP, else the unsigned one, and explains a target's refusal of an unsigned HAP like `app install`. |
183
186
  | `app uninstall <bundle> [--device <serial>]` | Uninstall an app by bundle name. |
184
187
  | `app stop <bundle> [--device <serial>]` | Force-stop an app by bundle name. |
185
188
 
@@ -200,9 +203,33 @@ These commands target a connected device or emulator over `hdc`. Most accept `--
200
203
 
201
204
  | Command | Description |
202
205
  | --- | --- |
203
- | `file send <local> <remote> [--device <serial>]` | Push a local file to the device. |
206
+ | `file send <local> <remote> [--bundle <b>] [--device <serial>]` | Push a local file to the device and print the device path. With `--bundle`, `<remote>` may be relative to that app's sandbox (`files/x` is its application-level `filesDir`, `haps/entry/files/x` the entry module's), and the file is chowned to the app, which cannot read root-owned files. |
204
207
  | `file recv <remote> <local> [--device <serial>]` | Pull a file from the device. |
205
208
 
209
+ Local paths may be relative, or absolute with either slash. A device path that a Windows shell already rewrote (Git Bash turns `/data/local/tmp/x` into `C:/Program Files/Git/data/local/tmp/x`) is rejected: run the command with `MSYS_NO_PATHCONV=1`.
210
+
211
+ #### `logs` — capture hilog to a file for a whole session
212
+
213
+ `logs -o <file>` streams hilog into `<file>` until `--for` elapses or the process is interrupted, so start it in the background. The device's log buffer is small (256 KB per type by default) and chatty components such as ArkWeb wrap it within seconds, so a dump at the end of a session loses its start. Every line is written as it arrives, and the stream reconnects after a reboot.
214
+
215
+ | Flag | Description |
216
+ | --- | --- |
217
+ | `-o, --output <file>` | **Required.** File to append to. |
218
+ | `--for <ms>` | Stop after this long (default: until interrupted). |
219
+ | `--grep <regex>` | Keep only matching lines (default: all). |
220
+ | `--clear` | Clear the device log buffer first (`hilog -r`), so the file covers only this session. |
221
+ | `--domain <domain>` | hilog domain filter (e.g. `0xD003900`). |
222
+ | `--device <serial>` | Target device serial. |
223
+
224
+ #### `hdc` — run the bundled hdc
225
+
226
+ `hdc [args...]` runs the `hdc` binary oniro-app itself uses (the one `cmdtools status` shows), with stdio passed through, so it needs nothing on `PATH`. Device commands are addressed at `--device` or `ONIRO_DEVICE_SERIAL` unless the arguments start with `-t`. `hdc --path` prints the binary's location. The exit code is hdc's own, which is 0 even for a `[Fail]` line.
227
+
228
+ ```bash
229
+ oniro-app hdc shell param get const.ohos.apiversion
230
+ oniro-app hdc --device 127.0.0.1:5555 shell aa dump -l
231
+ ```
232
+
206
233
  #### `reboot` — reboot the device
207
234
 
208
235
  | Flag | Description |
@@ -333,6 +360,7 @@ oniro-app gesture --waypoints '[{"x":200,"y":600,"t":0},{"x":200,"y":200,"t":400
333
360
  - **Results → stdout.** Plain text by default; `--json` (where supported) writes `JSON.stringify(..., null, 2)`. Read/observe commands (`sdk list`, `cmdtools status`, `templates list`, `devices`, `wait --log` / `--target`, `watch`, `lint`, `app apply`, `build`) accept `--json` (and `screenshot` with `--contact-sheet`); `dump` emits JSON unless `--flat`; action-only commands do not.
334
361
  - **Progress & logs → stderr.** stdout stays clean for machine consumers, so `oniro-app create … > path.txt` or `oniro-app devices --json | jq` work cleanly.
335
362
  - **Exit code.** `0` on success, non-zero on failure (the error message is written to stderr). Set `ONIRO_DEBUG=1` to also print full stack traces.
363
+ - **Global options go before the command** (`oniro-app --version`), so `hdc` can pass its arguments through untouched.
336
364
 
337
365
  ## Configuration
338
366
 
@@ -344,6 +372,8 @@ The CLI reads paths and URLs from environment variables. All are optional; defau
344
372
  | `ONIRO_CMD_TOOLS_PATH` | `~/command-line-tools` | Command-line tools install root |
345
373
  | `ONIRO_EMULATOR_DIR` | `~/oniro-emulator` | Emulator install root |
346
374
  | `ONIRO_HAP_PATH` | `entry/build/.../entry-default-signed.hap` | Default `.hap` used by `app install` (relative to the project) |
375
+ | `ONIRO_DEVICE_SERIAL` | (unset) | Device every device command addresses when `--device` is not given (also read as `DEVICE_SERIAL`) |
376
+ | `ONIRO_HDC` | the cmd-tools `hdc` | `hdc` binary to use instead, e.g. a wrapper for a remote device |
347
377
  | `ONIRO_SDK_URL_BASE` | `https://repo.huaweicloud.com/openharmony/os` | Base URL for SDK downloads (point at a private/CI mirror) |
348
378
  | `ONIRO_CMD_TOOLS_URL_LINUX` | Huawei mirror, x64 5.1.0.840 | Override the Linux cmd-tools URL |
349
379
  | `ONIRO_CMD_TOOLS_URL_WINDOWS` | (unset) | Self-hosted Windows cmd-tools URL |
@@ -502,7 +532,16 @@ oniro-app sign --apl system_core \
502
532
  --acls ohos.permission.REBOOT,ohos.permission.INJECT_INPUT_EVENT
503
533
  ```
504
534
 
505
- The `signingConfigs` block written to `build-profile.json5` mirrors the names used by the project's `products[*].signingConfig` (e.g. `applications/standard/systemui` uses `release`, `launcher` uses `default`). If the project has no products section, `default` is used.
535
+ An app that declares a privileged extension ability, such as an `AccessibilityExtensionAbility`, also needs `AllowAppUsePrivilegeExtension` in the profile's `app-privilege-capabilities`; without it the install fails with `9568344 not allow use privilege extension`. Pass it, and any other privilege (`AllowAppMultiProcess`, `AllowAppDesktopIconHide`, …), via `--app-privilege-capabilities`:
536
+
537
+ ```bash
538
+ oniro-app sign --apl system_core --acls ohos.permission.ACCESSIBILITY_EXTENSION_ABILITY \
539
+ --app-privilege-capabilities AllowAppUsePrivilegeExtension
540
+ ```
541
+
542
+ Apps like these usually also call system APIs (`@systemapi`), which the public SDK that `sdk install` downloads leaves out: the build fails with errors such as `'config' is not exported from Kit '@kit.AccessibilityKit'`. Build them against the full OpenHarmony SDK by unpacking its components into `<root>/<os>/<api>` of a separate SDK root and pointing `ONIRO_SDK_ROOT_DIR` at that root.
543
+
544
+ The `signingConfigs` block written to `build-profile.json5` mirrors the names used by the project's `products[*].signingConfig` (e.g. `applications/standard/systemui` uses `release`, `launcher` uses `default`). If the project has no products section, `default` is used, and a product that names no `signingConfig` is pointed at it.
506
545
 
507
546
  ## Programmatic use
508
547
 
package/dist/oniro-app.js CHANGED
@@ -175,7 +175,9 @@ function registerCmdToolsCommand(program) {
175
175
  await installCmdTools({ config, progress, logger, localZipPath: opts.fromZip, tmpDir: opts.tmpDir });
176
176
  logger.info("Command-line tools installed.");
177
177
  });
178
- cmdtools.command("status").description("Report whether the command-line tools are installed and their version.").option("--json", "Emit machine-readable JSON.").action((opts) => {
178
+ cmdtools.command("status").description(
179
+ "Report whether the command-line tools are installed, their version and flavour (HarmonyOS or OpenHarmony), and the hdc binary every device command uses."
180
+ ).option("--json", "Emit machine-readable JSON.").action((opts) => {
179
181
  const { config } = getRuntime();
180
182
  const status = getCmdToolsStatus(config);
181
183
  if (opts.json) {
@@ -184,6 +186,12 @@ function registerCmdToolsCommand(program) {
184
186
  return;
185
187
  }
186
188
  process.stdout.write(`${status.status}
189
+ `);
190
+ process.stdout.write(`path: ${status.path}
191
+ `);
192
+ if (status.flavour) process.stdout.write(`flavour: ${status.flavour}
193
+ `);
194
+ process.stdout.write(`hdc: ${status.hdc.path}${status.hdc.exists ? "" : " (missing)"}
187
195
  `);
188
196
  if (!status.installed) process.exit(1);
189
197
  });
@@ -197,6 +205,7 @@ function registerCmdToolsCommand(program) {
197
205
  // src/commands/emulator.ts
198
206
  import {
199
207
  attemptHdcConnection,
208
+ getEmulatorStatus,
200
209
  installEmulator,
201
210
  isEmulatorInstalled,
202
211
  removeEmulator,
@@ -230,6 +239,24 @@ function registerEmulatorCommand(program) {
230
239
  });
231
240
  logger.info("Emulator start command complete.");
232
241
  });
242
+ emu.command("status").description(
243
+ "Report whether the Oniro emulator is installed, running, and connected to hdc, without starting it. Exits 1 when it is not installed."
244
+ ).option("--address <addr>", "hdc address the emulator listens on", "127.0.0.1:55555").option("--json", "Emit machine-readable JSON.").action(async (opts) => {
245
+ const { config, logger } = getRuntime();
246
+ const status = await getEmulatorStatus(config, { address: opts.address, logger });
247
+ if (opts.json) {
248
+ process.stdout.write(`${JSON.stringify(status, null, 2)}
249
+ `);
250
+ } else {
251
+ process.stdout.write(
252
+ `installed: ${status.installed ? "yes" : "no"} (${status.dir})
253
+ running: ${status.running ? "yes" : "no"}
254
+ connected: ${status.connected ? "yes" : "no"} (${status.address})
255
+ `
256
+ );
257
+ }
258
+ if (!status.installed) process.exitCode = 1;
259
+ });
233
260
  emu.command("stop").description("Kill running emulator processes.").action(async () => {
234
261
  const { logger } = getRuntime();
235
262
  await stopEmulator(logger);
@@ -253,15 +280,15 @@ function registerEmulatorCommand(program) {
253
280
 
254
281
  // src/commands/build.ts
255
282
  import * as path2 from "path";
256
- import { buildHap } from "@oniroproject/core";
283
+ import { SdkNotInstalledError, buildHap, downloadAndInstallSdk as downloadAndInstallSdk2 } from "@oniroproject/core";
257
284
  function registerBuildCommand(program) {
258
285
  program.command("build [project-dir]").description(
259
- 'Build an OpenHarmony or HarmonyOS app via hvigorw. Defaults to the current directory. Projects declaring runtimeOS "HarmonyOS" build against the HarmonyOS SDK (ONIRO_HARMONYOS_SDK_PATH or an installed DevEco Studio).'
260
- ).option("--product <product>", "hvigor product name", "default").option("--module <module>", "restrict the build to a specific module").option("--mode <mode>", "hvigor build mode (e.g. release, debug)").option("--task <task>", "hvigor task to run", "assembleHap").option("--no-deps", "skip the automatic `ohpm install --all` when oh_modules/ is missing").option("--no-parallel", "build modules serially (default: parallel)").option("--json", "emit the build result (discovered HAPs, warnings) as JSON").action(async (projectDir, opts) => {
261
- const { config, logger } = getRuntime();
286
+ 'Build an OpenHarmony or HarmonyOS app via hvigorw. Defaults to the current directory. Projects declaring runtimeOS "HarmonyOS" build against the HarmonyOS SDK (ONIRO_HARMONYOS_SDK_PATH or an installed DevEco Studio). An OpenHarmony project fails early, naming the release to install, when the SDK for its compileSdkVersion is missing.'
287
+ ).option("--product <product>", "hvigor product name", "default").option("--module <module>", "restrict the build to a specific module").option("--mode <mode>", "hvigor build mode (e.g. release, debug)").option("--task <task>", "hvigor task to run", "assembleHap").option("--no-deps", "skip the automatic `ohpm install --all` when oh_modules/ is missing").option("--no-parallel", "build modules serially (default: parallel)").option("--install-sdk", "install the OpenHarmony SDK the project compiles against when it is missing, then build").option("--json", "emit the build result (discovered HAPs, warnings) as JSON").action(async (projectDir, opts) => {
288
+ const { config, logger, progress } = getRuntime();
262
289
  const dir = path2.resolve(projectDir ?? process.cwd());
263
290
  logger.info(`Building project at ${dir}...`);
264
- const result = await buildHap({
291
+ const build = () => buildHap({
265
292
  config,
266
293
  projectDir: dir,
267
294
  product: opts.product,
@@ -275,6 +302,15 @@ function registerBuildCommand(program) {
275
302
  onOutput: () => {
276
303
  }
277
304
  });
305
+ let result;
306
+ try {
307
+ result = await build();
308
+ } catch (err) {
309
+ if (!(err instanceof SdkNotInstalledError && err.version && opts.installSdk)) throw err;
310
+ logger.info(`Installing OpenHarmony SDK ${err.version} (api ${err.api}), which the project compiles against...`);
311
+ await downloadAndInstallSdk2({ config, version: err.version, api: err.api, progress, logger });
312
+ result = await build();
313
+ }
278
314
  for (const w of result.warnings) logger.warn(w);
279
315
  if (opts.json) {
280
316
  process.stdout.write(`${JSON.stringify(result, null, 2)}
@@ -326,6 +362,11 @@ function registerSignCommand(program) {
326
362
  "--acls <list>",
327
363
  "Comma-separated permission names to write into the profile's acls.allowed-acls. Required for apps that request permissions above their apl (e.g. a system_basic app requesting ohos.permission.CAPTURE_SCREEN). Example: --acls ohos.permission.REBOOT,ohos.permission.INJECT_INPUT_EVENT"
328
364
  ).argParser(parseAclsList)
365
+ ).addOption(
366
+ new Option(
367
+ "--app-privilege-capabilities <list>",
368
+ `Comma-separated privileges to write into the profile's app-privilege-capabilities. An app that declares a privileged extension ability (e.g. an AccessibilityExtensionAbility) needs AllowAppUsePrivilegeExtension, else install fails with 9568344 "not allow use privilege extension". Others include AllowAppMultiProcess and AllowAppDesktopIconHide.`
369
+ ).argParser(parseAclsList)
329
370
  ).option(
330
371
  "--harmonyos",
331
372
  "Sign a HarmonyOS project through AppGallery Connect. Needs `oniro-app auth login`, and a connected device unless the team already has devices registered."
@@ -359,6 +400,7 @@ function registerSignCommand(program) {
359
400
  apl: opts.apl,
360
401
  appFeature: opts.appFeature,
361
402
  acls: opts.acls,
403
+ appPrivilegeCapabilities: opts.appPrivilegeCapabilities,
362
404
  passwords,
363
405
  logger
364
406
  });
@@ -373,6 +415,7 @@ function registerSignCommand(program) {
373
415
  apl: opts.apl,
374
416
  appFeature: opts.appFeature,
375
417
  acls: opts.acls,
418
+ appPrivilegeCapabilities: opts.appPrivilegeCapabilities,
376
419
  passwords,
377
420
  logger
378
421
  });
@@ -448,12 +491,16 @@ import * as path4 from "path";
448
491
  import { installApp, launchApp, uninstallApp, forceStop, applyChanges, getBundleName } from "@oniroproject/core";
449
492
  function registerAppCommand(program) {
450
493
  const app = program.command("app").description("Install, launch, and manage built apps on a connected device/emulator.");
451
- app.command("install [project-dir]").description("Install the signed .hap on the connected device/emulator via hdc.").option("--hap <path>", "Override the .hap path (relative to project-dir or absolute).").option("--device <serial>", "Target device serial.").action(async (projectDir, opts) => {
494
+ app.command("install [project-dir-or-hap]").description(
495
+ "Install a built .hap on the connected device/emulator via hdc. Takes a project dir (default: the current one), whose newest signed HAP is installed, else its unsigned one, or a .hap file. Fails when the bundle manager rejects the HAP, and says how to sign when a target refuses an unsigned one."
496
+ ).option("--hap <path>", "Override the .hap path (relative to project-dir or absolute).").option("--device <serial>", "Target device serial.").action(async (target, opts) => {
452
497
  const { config, logger } = getRuntime();
453
- const dir = path4.resolve(projectDir ?? process.cwd());
454
- logger.info(`Installing app from ${dir}...`);
455
- await installApp({ config, projectDir: dir, hapPath: opts.hap, deviceSerial: opts.device, logger });
456
- logger.info("App installed.");
498
+ const isHap = target !== void 0 && /\.hap$/i.test(target);
499
+ const dir = isHap ? process.cwd() : path4.resolve(target ?? process.cwd());
500
+ const hapPath = isHap ? path4.resolve(target) : opts.hap;
501
+ logger.info(`Installing ${hapPath ?? `app from ${dir}`}...`);
502
+ const result = await installApp({ config, projectDir: dir, hapPath, deviceSerial: opts.device, logger });
503
+ logger.info(`Installed ${result.hapPath}.`);
457
504
  });
458
505
  app.command("launch [project-dir]").description(
459
506
  "Launch an app on the connected device/emulator. Project mode (default): resolves bundle + main ability from the project. Bundle mode (--bundle): launch an already-installed app by bundle name, no project needed."
@@ -1071,13 +1118,42 @@ function registerDumpCommand(program) {
1071
1118
  }
1072
1119
 
1073
1120
  // src/commands/devices.ts
1074
- import { listDevices } from "@oniroproject/core";
1121
+ import { getDeviceInfo, listDevices } from "@oniroproject/core";
1122
+ function formatLongDevice(d, info) {
1123
+ const head = `${d.serial} ${d.connection ?? ""} ${d.status}`;
1124
+ if (!info) return head;
1125
+ const os2 = [info.osFamily, info.osFamily === "HarmonyOS" ? info.osDistVersion : void 0].filter(Boolean).join(" ");
1126
+ const fields = [
1127
+ ["os", os2 || void 0],
1128
+ ["api", info.sdkApiVersion],
1129
+ ["abi", info.abi],
1130
+ ["type", info.deviceType],
1131
+ ["model", info.model],
1132
+ ["fullname", info.osFullName]
1133
+ ];
1134
+ const rest = fields.filter(([, v]) => v).map(([k, v]) => `${k}=${/\s/.test(v) ? JSON.stringify(v) : v}`);
1135
+ return [head, ...rest].join(" ");
1136
+ }
1075
1137
  function registerDevicesCommand(program) {
1076
- program.command("devices").description("List connected hdc devices.").option("--json", "Emit machine-readable JSON.").action(async (opts) => {
1077
- const { config } = getRuntime();
1138
+ program.command("devices").description("List connected hdc devices.").option(
1139
+ "--long",
1140
+ "Also ask each connected device for its OS family (HarmonyOS / OpenHarmony), version, API level, CPU ABI, device type and model."
1141
+ ).option("--json", "Emit machine-readable JSON.").action(async (opts) => {
1142
+ const { config, logger } = getRuntime();
1078
1143
  const devices = await listDevices(config);
1144
+ const infos = /* @__PURE__ */ new Map();
1145
+ if (opts.long) {
1146
+ for (const d of devices.filter((x) => x.status === "Connected")) {
1147
+ try {
1148
+ infos.set(d.serial, await getDeviceInfo({ config, deviceSerial: d.serial, logger }));
1149
+ } catch (err) {
1150
+ logger.warn(`Could not query ${d.serial}: ${err.message}`);
1151
+ }
1152
+ }
1153
+ }
1079
1154
  if (opts.json) {
1080
- process.stdout.write(`${JSON.stringify(devices, null, 2)}
1155
+ const out = opts.long ? devices.map((d) => ({ ...d, info: infos.get(d.serial) ?? null })) : devices;
1156
+ process.stdout.write(`${JSON.stringify(out, null, 2)}
1081
1157
  `);
1082
1158
  return;
1083
1159
  }
@@ -1086,7 +1162,7 @@ function registerDevicesCommand(program) {
1086
1162
  return;
1087
1163
  }
1088
1164
  for (const d of devices) {
1089
- process.stdout.write(`${d.serial} ${d.connection ?? ""} ${d.status}
1165
+ process.stdout.write(`${opts.long ? formatLongDevice(d, infos.get(d.serial)) : `${d.serial} ${d.connection ?? ""} ${d.status}`}
1090
1166
  `);
1091
1167
  }
1092
1168
  });
@@ -1096,10 +1172,14 @@ function registerDevicesCommand(program) {
1096
1172
  import { sendFile, recvFile } from "@oniroproject/core";
1097
1173
  function registerFileCommand(program) {
1098
1174
  const file = program.command("file").description("Transfer files to/from the device (hdc file send/recv).");
1099
- file.command("send <local> <remote>").description("Push a local file to the device.").option("--device <serial>", "Target device serial.").action(async (local, remote, opts) => {
1175
+ file.command("send <local> <remote>").description(
1176
+ "Push a local file to the device. With --bundle, <remote> may be relative to that app's sandbox (files/x is its filesDir, haps/entry/files/x the entry module's), and the file is chowned to the app so it can read it. Prints the device path."
1177
+ ).option("--bundle <bundle>", "Push into this app's sandbox and give the file to the app's user.").option("--device <serial>", "Target device serial.").action(async (local, remote, opts) => {
1100
1178
  const { config, logger } = getRuntime();
1101
- await sendFile({ config, local, remote, deviceSerial: opts.device, logger });
1102
- logger.info(`Sent ${local} -> ${remote}.`);
1179
+ const written = await sendFile({ config, local, remote, bundle: opts.bundle, deviceSerial: opts.device, logger });
1180
+ logger.info(`Sent ${local} -> ${written}${opts.bundle ? ` (owned by ${opts.bundle})` : ""}.`);
1181
+ process.stdout.write(`${written}
1182
+ `);
1103
1183
  });
1104
1184
  file.command("recv <remote> <local>").description("Pull a file from the device.").option("--device <serial>", "Target device serial.").action(async (remote, local, opts) => {
1105
1185
  const { config, logger } = getRuntime();
@@ -1110,23 +1190,65 @@ function registerFileCommand(program) {
1110
1190
 
1111
1191
  // src/commands/lint.ts
1112
1192
  import * as path8 from "path";
1113
- import { runCodelinter } from "@oniroproject/core";
1193
+ import {
1194
+ detectCmdToolsFlavour,
1195
+ detectRuntimeOs as detectRuntimeOs2,
1196
+ getCmdToolsPath,
1197
+ runCodelinter
1198
+ } from "@oniroproject/core";
1199
+ function lintTotals(result) {
1200
+ if (result.summary) return result.summary;
1201
+ const count = (s) => result.findings.filter((f) => f.severity === s).length;
1202
+ return {
1203
+ defects: result.findings.length,
1204
+ errors: count("error"),
1205
+ warnings: count("warning"),
1206
+ suggestions: count("suggestion")
1207
+ };
1208
+ }
1209
+ function lintExitCode(result) {
1210
+ if (lintTotals(result).errors > 0) return 1;
1211
+ const noReport = result.summary === null && result.findings.length === 0;
1212
+ return noReport && result.code !== 0 ? result.code : 0;
1213
+ }
1114
1214
  function registerLintCommand(program) {
1115
- program.command("lint [project-dir]").description("Run the OpenHarmony codelinter on a project. Defaults to the current directory.").option("--files <globs...>", "Specific files/globs to lint (default: the whole project).").option("--json", "Emit findings as JSON.").action(async (projectDir, opts) => {
1215
+ program.command("lint [project-dir]").description(
1216
+ "Run the OpenHarmony codelinter on a project. Defaults to the current directory. Exits 1 on error-severity findings or when codelinter fails to run; warnings alone exit 0."
1217
+ ).option("--files <globs...>", "Specific files/globs to lint (default: the whole project).").option("--json", "Emit the report (findings, summary, notices, incomplete) as JSON.").action(async (projectDir, opts) => {
1116
1218
  const { config, logger } = getRuntime();
1117
1219
  const dir = path8.resolve(projectDir ?? process.cwd());
1118
1220
  const result = await runCodelinter({ config, projectDir: dir, files: opts.files, logger });
1221
+ const totals = lintTotals(result);
1119
1222
  if (opts.json) {
1120
1223
  process.stdout.write(`${JSON.stringify(result, null, 2)}
1121
1224
  `);
1122
1225
  } else {
1123
1226
  for (const f of result.findings) {
1124
- process.stdout.write(`${f.file}:${f.line} ${f.severity} ${f.message}${f.code ? ` [${f.code}]` : ""}
1227
+ const at = `${f.file}:${f.line}${f.column ? `:${f.column}` : ""}`;
1228
+ process.stdout.write(`${at} ${f.severity} ${f.message}${f.code ? ` [${f.code}]` : ""}
1125
1229
  `);
1126
1230
  }
1127
- if (result.findings.length === 0) process.stdout.write("No findings.\n");
1231
+ process.stdout.write(
1232
+ totals.defects === 0 ? "No defects found.\n" : `${totals.defects} defects: ${totals.errors} errors, ${totals.warnings} warnings, ${totals.suggestions} suggestions.
1233
+ `
1234
+ );
1235
+ }
1236
+ if (result.summary === null && result.findings.length === 0 && result.code !== 0) {
1237
+ logger.error(`codelinter exited ${result.code} without a report:
1238
+ ${result.raw.trim().split("\n").slice(-15).join("\n")}`);
1239
+ }
1240
+ if (result.incomplete) {
1241
+ for (const n of result.notices) logger.warn(`codelinter: ${n}`);
1242
+ const cmdToolsPath = getCmdToolsPath(config);
1243
+ const flavour = detectCmdToolsFlavour(cmdToolsPath);
1244
+ const projectOs = detectRuntimeOs2(dir);
1245
+ if (flavour !== projectOs) {
1246
+ logger.warn(
1247
+ `The command-line tools at ${cmdToolsPath} are the ${flavour} flavour, but the project targets ${projectOs} (runtimeOS in build-profile.json5), so codelinter skipped part of its checks: treat the counts as a lower bound. For a complete report, point ONIRO_CMD_TOOLS_PATH at ${projectOs} command-line tools. The build's ArkTS compiler checks are not affected.`
1248
+ );
1249
+ }
1128
1250
  }
1129
- if (result.code !== 0) process.exitCode = result.code;
1251
+ process.exitCode = lintExitCode(result);
1130
1252
  });
1131
1253
  }
1132
1254
 
@@ -1214,12 +1336,70 @@ function registerInputCommand(program) {
1214
1336
  });
1215
1337
  }
1216
1338
 
1339
+ // src/commands/logs.ts
1340
+ import * as path9 from "path";
1341
+ import { captureLog } from "@oniroproject/core";
1342
+ function registerLogsCommand(program) {
1343
+ program.command("logs").description(
1344
+ "Capture hilog to a file for a whole session: the device's small log buffer wraps within seconds under chatty components, so a dump at the end loses lines. Runs until --for elapses or the process is interrupted; start it in the background, e.g. `oniro-app logs --clear -o hilog_full.txt &`. Every line is flushed as it arrives and the stream reconnects after a reboot."
1345
+ ).requiredOption("-o, --output <file>", "File to append the lines to.").option("--for <ms>", "Stop after this many ms (default: run until interrupted).").option("--grep <regex>", "Keep only lines matching this regex (default: all).").option("--clear", "Clear the device log buffer first (hilog -r), so the file covers only this session.").option("--domain <domain>", "hilog domain filter (e.g. 0xD003900).").option("--device <serial>", "Target device serial.").action(async (opts) => {
1346
+ const { config, logger } = getRuntime();
1347
+ const file = path9.resolve(opts.output);
1348
+ const abort = new AbortController();
1349
+ const stop = () => abort.abort();
1350
+ process.once("SIGINT", stop);
1351
+ process.once("SIGTERM", stop);
1352
+ logger.info(`Capturing hilog to ${file}${opts.for ? ` for ${opts.for} ms` : " until interrupted"}...`);
1353
+ const result = await captureLog({
1354
+ config,
1355
+ file,
1356
+ durationMs: opts.for !== void 0 ? Number(opts.for) : void 0,
1357
+ pattern: opts.grep ? new RegExp(opts.grep) : void 0,
1358
+ clear: opts.clear,
1359
+ domain: opts.domain,
1360
+ deviceSerial: opts.device,
1361
+ abortSignal: abort.signal,
1362
+ logger
1363
+ });
1364
+ logger.info(`Wrote ${result.lines} lines to ${result.file} (${result.reconnects} reconnects).`);
1365
+ process.stdout.write(`${result.file}
1366
+ `);
1367
+ });
1368
+ }
1369
+
1370
+ // src/commands/hdc.ts
1371
+ import { getHdcPath, hdcTargetArgsFor, spawnCompat } from "@oniroproject/core";
1372
+ function hdcPassthroughArgv(args, device) {
1373
+ return args[0] === "-t" ? [...args] : [...hdcTargetArgsFor(args, device), ...args];
1374
+ }
1375
+ function registerHdcCommand(program) {
1376
+ program.command("hdc").description(
1377
+ "Run the hdc binary oniro-app itself uses (see `cmdtools status`), addressed at --device or ONIRO_DEVICE_SERIAL, with stdio passed through. Exits with hdc's own code, which is 0 even for a `[Fail]` line. Example: oniro-app hdc shell param get const.ohos.apiversion"
1378
+ ).argument("[args...]", "hdc arguments, passed through verbatim").option("--device <serial>", "Target device serial.").option("--path", "Print the hdc binary path and exit.").passThroughOptions().allowUnknownOption().action(async (args, opts) => {
1379
+ const { config } = getRuntime();
1380
+ const hdc = getHdcPath(config);
1381
+ if (opts.path) {
1382
+ process.stdout.write(`${hdc}
1383
+ `);
1384
+ return;
1385
+ }
1386
+ await new Promise((resolve8, reject) => {
1387
+ const child = spawnCompat(hdc, hdcPassthroughArgv(args, opts.device), { stdio: "inherit" });
1388
+ child.on("error", (err) => reject(new Error(`Failed to run ${hdc}: ${err.message}`)));
1389
+ child.on("close", (code) => {
1390
+ process.exitCode = code ?? 1;
1391
+ resolve8();
1392
+ });
1393
+ });
1394
+ });
1395
+ }
1396
+
1217
1397
  // src/bin/oniro-app.ts
1218
- var CLI_VERSION = "0.13.0";
1398
+ var CLI_VERSION = "0.14.0";
1219
1399
  function buildProgram() {
1220
1400
  const program = new Command4().name("oniro-app").description(
1221
1401
  "Cross-platform CLI for Oniro/OpenHarmony app development.\n\nDesigned for non-interactive use (CI, scripts, agents): every command\ntakes explicit flags, results go to stdout, progress/logs go to stderr,\nand a non-zero exit code indicates failure."
1222
- ).version(CLI_VERSION).showHelpAfterError();
1402
+ ).version(CLI_VERSION).showHelpAfterError().enablePositionalOptions();
1223
1403
  registerSdkCommand(program);
1224
1404
  registerCmdToolsCommand(program);
1225
1405
  registerEmulatorCommand(program);
@@ -1238,6 +1418,8 @@ function buildProgram() {
1238
1418
  registerFileCommand(program);
1239
1419
  registerLintCommand(program);
1240
1420
  registerInputCommand(program);
1421
+ registerLogsCommand(program);
1422
+ registerHdcCommand(program);
1241
1423
  return program;
1242
1424
  }
1243
1425
  async function main() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bin/oniro-app.ts","../src/commands/sdk.ts","../src/adapters/logger.ts","../src/adapters/progress.ts","../src/adapters/config.ts","../src/lib/runtime.ts","../src/commands/cmdtools.ts","../src/commands/emulator.ts","../src/commands/build.ts","../src/commands/sign.ts","../src/commands/auth.ts","../src/commands/app.ts","../src/commands/create.ts","../src/lib/templateRoot.ts","../src/commands/templates.ts","../src/commands/reboot.ts","../src/commands/wait.ts","../src/lib/target.ts","../src/commands/watch.ts","../src/commands/screenshot.ts","../src/lib/screenshotImage.ts","../src/commands/dump.ts","../src/lib/layoutText.ts","../src/commands/devices.ts","../src/commands/file.ts","../src/commands/lint.ts","../src/commands/input.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { OniroError } from '@oniroproject/core';\nimport { registerSdkCommand } from '../commands/sdk.js';\nimport { registerCmdToolsCommand } from '../commands/cmdtools.js';\nimport { registerEmulatorCommand } from '../commands/emulator.js';\nimport { registerBuildCommand } from '../commands/build.js';\nimport { registerSignCommand } from '../commands/sign.js';\nimport { registerAuthCommand } from '../commands/auth.js';\nimport { registerAppCommand } from '../commands/app.js';\nimport { registerCreateCommand } from '../commands/create.js';\nimport { registerTemplatesCommand } from '../commands/templates.js';\nimport { registerRebootCommand } from '../commands/reboot.js';\nimport { registerWaitCommand } from '../commands/wait.js';\nimport { registerWatchCommand } from '../commands/watch.js';\nimport { registerScreenshotCommand } from '../commands/screenshot.js';\nimport { registerDumpCommand } from '../commands/dump.js';\nimport { registerDevicesCommand } from '../commands/devices.js';\nimport { registerFileCommand } from '../commands/file.js';\nimport { registerLintCommand } from '../commands/lint.js';\nimport { registerInputCommand } from '../commands/input.js';\n\ndeclare const __CLI_VERSION__: string;\nconst CLI_VERSION = __CLI_VERSION__;\n\nfunction buildProgram(): Command {\n const program = new Command()\n .name('oniro-app')\n .description(\n 'Cross-platform CLI for Oniro/OpenHarmony app development.\\n\\n' +\n 'Designed for non-interactive use (CI, scripts, agents): every command\\n' +\n 'takes explicit flags, results go to stdout, progress/logs go to stderr,\\n' +\n 'and a non-zero exit code indicates failure.',\n )\n .version(CLI_VERSION)\n .showHelpAfterError();\n\n registerSdkCommand(program);\n registerCmdToolsCommand(program);\n registerEmulatorCommand(program);\n registerBuildCommand(program);\n registerSignCommand(program);\n registerAuthCommand(program);\n registerAppCommand(program);\n registerCreateCommand(program);\n registerTemplatesCommand(program);\n registerRebootCommand(program);\n registerWaitCommand(program);\n registerWatchCommand(program);\n registerScreenshotCommand(program);\n registerDumpCommand(program);\n registerDevicesCommand(program);\n registerFileCommand(program);\n registerLintCommand(program);\n registerInputCommand(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n const message = err instanceof OniroError ? err.message : err instanceof Error ? err.message : String(err);\n process.stderr.write(`[error] ${message}\\n`);\n if (process.env.ONIRO_DEBUG === '1' && err instanceof Error && err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n}\n\nvoid main();\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n downloadAndInstallSdk,\n getOsFolder,\n getSdkRootDir,\n getSupportedSdksForUi,\n removeSdk,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerSdkCommand(program: Command): void {\n const sdk = program.command('sdk').description('Manage OpenHarmony SDK installs.');\n\n sdk\n .command('install <version>')\n .description('Download and install an OpenHarmony SDK. Skips if already installed.')\n .option('--force', 'Reinstall even if the SDK is already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for download/extract temporaries (default: ONIRO_TMP_DIR, else .oniro-tmp next to ' +\n 'the install target). Use this when that filesystem is short on space.',\n )\n .action(async (version: string, opts: { force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n const release = ALL_SDKS.find((s) => s.version === version);\n if (!release) {\n throw new Error(\n `Unknown SDK version \"${version}\". Known: ${ALL_SDKS.map((s) => s.version).join(', ')}`,\n );\n }\n const sdkInstallDir = path.join(getSdkRootDir(config), getOsFolder(), release.api);\n if (fs.existsSync(sdkInstallDir) && !opts.force) {\n logger.info(\n `SDK ${release.version} (api ${release.api}) already installed at ${sdkInstallDir}; pass --force to reinstall.`,\n );\n return;\n }\n logger.info(`Installing OpenHarmony SDK ${release.version} (api ${release.api})...`);\n await downloadAndInstallSdk({\n config,\n version: release.version,\n api: release.api,\n progress,\n logger,\n tmpDir: opts.tmpDir,\n });\n logger.info('SDK installed.');\n });\n\n sdk\n .command('list')\n .description('List known SDK versions and whether they are installed on this machine.')\n .option('--json', 'Emit machine-readable JSON instead of a table.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const sdks = getSupportedSdksForUi(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(sdks, null, 2)}\\n`);\n return;\n }\n const rows = sdks.map((s) => `${s.installed ? '*' : ' '} ${s.version.padEnd(8)} api ${s.api}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n\n sdk\n .command('remove <api>')\n .description('Remove an installed SDK by API level (e.g. 18, 20).')\n .action((api: string) => {\n const { config, logger } = getRuntime();\n const removed = removeSdk(config, api);\n if (!removed) {\n logger.warn(`No SDK with api ${api} found under the configured SDK root.`);\n process.exit(1);\n }\n logger.info(`Removed SDK api ${api}.`);\n });\n}\n","import type { Logger } from '@oniroproject/core';\n\n/**\n * Stderr-only logger. All diagnostic output goes to stderr so command stdout\n * stays clean for machine consumers (json results, paths, etc.).\n *\n * Debug lines are suppressed unless `ONIRO_DEBUG=1`.\n */\nexport function createCliLogger(): Logger {\n const debugEnabled = process.env.ONIRO_DEBUG === '1' || process.env.ONIRO_DEBUG === 'true';\n return {\n debug(m) {\n if (debugEnabled) process.stderr.write(`[debug] ${m}\\n`);\n },\n info(m) {\n process.stderr.write(`${m}\\n`);\n },\n warn(m) {\n process.stderr.write(`[warn] ${m}\\n`);\n },\n error(m) {\n process.stderr.write(`[error] ${m}\\n`);\n },\n };\n}\n","import type { ProgressReporter } from '@oniroproject/core';\n\n/**\n * Line-per-update progress reporter, designed for machine consumers and log scrapers.\n * Format: `[progress NN%] message` (or `[progress] message` if no percent is known).\n * Updates that don't change the percent and don't carry a message are suppressed\n * to keep output volume reasonable on chatty downloads.\n */\nexport function createCliProgress(): ProgressReporter {\n let total = 0;\n let lastEmitted = -1;\n let lastMessage = '';\n return {\n report({ message, increment }) {\n if (typeof increment === 'number') total = Math.min(100, total + increment);\n const pct = total > 0 ? Math.round(total) : null;\n const msg = message ?? lastMessage;\n // Drop redundant updates: same message, same percent.\n if (pct === lastEmitted && msg === lastMessage) return;\n const prefix = pct === null ? '[progress]' : `[progress ${pct}%]`;\n process.stderr.write(`${prefix} ${msg}\\n`);\n lastEmitted = pct ?? lastEmitted;\n if (message) lastMessage = message;\n },\n };\n}\n","import * as os from 'node:os';\nimport type { ConfigKey, ConfigProvider } from '@oniroproject/core';\n\n/**\n * Maps a core ConfigKey to its environment variable name.\n * Convention: ONIRO_<UPPER_SNAKE>.\n */\nconst ENV_VAR_BY_KEY: Record<ConfigKey, string> = {\n sdkRootDir: 'ONIRO_SDK_ROOT_DIR',\n cmdToolsPath: 'ONIRO_CMD_TOOLS_PATH',\n hdcPath: 'ONIRO_HDC',\n emulatorDir: 'ONIRO_EMULATOR_DIR',\n hapPath: 'ONIRO_HAP_PATH',\n cmdToolsUrlLinux: 'ONIRO_CMD_TOOLS_URL_LINUX',\n cmdToolsUrlWindows: 'ONIRO_CMD_TOOLS_URL_WINDOWS',\n cmdToolsUrlMac: 'ONIRO_CMD_TOOLS_URL_MAC',\n emulatorUrl: 'ONIRO_EMULATOR_URL',\n tmpDir: 'ONIRO_TMP_DIR',\n sdkUrlBase: 'ONIRO_SDK_URL_BASE',\n applicationCertPath: 'ONIRO_APPLICATION_CERT_PATH',\n harmonyosSdkPath: 'ONIRO_HARMONYOS_SDK_PATH',\n harmonyosAuthDir: 'ONIRO_HARMONYOS_AUTH_DIR',\n harmonyosSigningDir: 'ONIRO_HARMONYOS_SIGNING_DIR',\n};\n\n/**\n * Reads configuration from environment variables (ONIRO_*). Returns the fallback\n * when the variable is unset or empty. Expands `${userHome}` to the user's home\n * directory for parity with the VS Code extension's `${userHome}` expansion.\n */\nexport function createEnvConfig(env: NodeJS.ProcessEnv = process.env): ConfigProvider {\n return {\n get<T extends string | number | boolean>(key: ConfigKey, fallback: T): T {\n const envName = ENV_VAR_BY_KEY[key];\n const raw = env[envName];\n if (raw === undefined || raw === '') return fallback;\n const expanded = raw.includes('${userHome}')\n ? raw.replace(/\\$\\{userHome\\}/g, os.homedir())\n : raw;\n return expanded as unknown as T;\n },\n };\n}\n","import type { ConfigProvider, Logger, ProgressReporter } from '@oniroproject/core';\nimport { createCliLogger } from '../adapters/logger.js';\nimport { createCliProgress } from '../adapters/progress.js';\nimport { createEnvConfig } from '../adapters/config.js';\n\nexport interface CliRuntime {\n logger: Logger;\n config: ConfigProvider;\n progress: ProgressReporter;\n}\n\nlet cached: CliRuntime | null = null;\n\n/**\n * Build (and cache) the per-process runtime used by every command. Tests can\n * override the cached runtime via `setRuntime` to inject mocks.\n */\nexport function getRuntime(): CliRuntime {\n if (!cached) {\n cached = {\n logger: createCliLogger(),\n config: createEnvConfig(),\n progress: createCliProgress(),\n };\n }\n return cached;\n}\n\nexport function setRuntime(runtime: CliRuntime | null): void {\n cached = runtime;\n}\n","import { Command } from 'commander';\nimport { getCmdToolsStatus, installCmdTools, isCmdToolsInstalled, removeCmdTools } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerCmdToolsCommand(program: Command): void {\n const cmdtools = program.command('cmdtools').description('Manage OpenHarmony command-line tools.');\n\n cmdtools\n .command('install')\n .description('Install the OpenHarmony command-line tools (hvigorw, ohpm, hdc). Skips if already installed.')\n .option('--from-zip <path>', 'Install from a local ZIP instead of downloading.')\n .option('--force', 'Reinstall even if the tools are already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for download/extract temporaries (default: ONIRO_TMP_DIR, else .oniro-tmp next to ' +\n 'the install target). Use this when that filesystem is short on space.',\n )\n .action(async (opts: { fromZip?: string; force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n if (isCmdToolsInstalled(config) && !opts.force) {\n logger.info('Command-line tools already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing OpenHarmony command-line tools...');\n await installCmdTools({ config, progress, logger, localZipPath: opts.fromZip, tmpDir: opts.tmpDir });\n logger.info('Command-line tools installed.');\n });\n\n cmdtools\n .command('status')\n .description('Report whether the command-line tools are installed and their version.')\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const status = getCmdToolsStatus(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${status.status}\\n`);\n if (!status.installed) process.exit(1);\n });\n\n cmdtools\n .command('remove')\n .description('Delete the configured command-line tools directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeCmdTools(config);\n logger.info('Command-line tools removed.');\n });\n}\n","import { Command } from 'commander';\nimport {\n attemptHdcConnection,\n installEmulator,\n isEmulatorInstalled,\n removeEmulator,\n startEmulator,\n stopEmulator,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerEmulatorCommand(program: Command): void {\n const emu = program.command('emulator').description('Manage the Oniro emulator.');\n\n emu\n .command('install')\n .description('Download and install the Oniro emulator (QEMU-based). Skips if already installed.')\n .option('--force', 'Reinstall even if the emulator is already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for the downloaded ZIP (default: ONIRO_TMP_DIR, else .oniro-tmp next to the ' +\n 'install target). Use this when that filesystem is short on space.',\n )\n .action(async (opts: { force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n if (isEmulatorInstalled(config) && !opts.force) {\n logger.info('Emulator already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing Oniro emulator...');\n await installEmulator({ config, progress, logger, tmpDir: opts.tmpDir });\n logger.info('Emulator installed.');\n });\n\n emu\n .command('start')\n .description('Start the Oniro emulator via the bundled launcher (run.sh / run.bat). Detaches so the CLI can exit while the emulator keeps running.')\n .option('--headless', 'Launch headless (VNC + telnet serial, no local window). Required in CI.')\n .option('--log <path>', 'Redirect launcher stdout/stderr to this file. Defaults to discarding output.')\n .option('--wait-for-hdc <seconds>', 'Wait up to N seconds for hdc to connect. 0 = do not wait.', (v) => parseInt(v, 10), 0)\n .option('--connect <host:port>', 'Override the launcher\\'s hdc port-forward bind address. Pass 0.0.0.0:55555 on hosts where QEMU refuses to bind 127.0.0.1 (some CI runners).')\n .action(async (opts: { headless?: boolean; log?: string; waitForHdc: number; connect?: string }) => {\n const { config, logger } = getRuntime();\n await startEmulator({\n config,\n logger,\n headless: opts.headless === true,\n logFile: opts.log,\n waitForHdcSeconds: opts.waitForHdc,\n connect: opts.connect,\n });\n logger.info('Emulator start command complete.');\n });\n\n emu\n .command('stop')\n .description('Kill running emulator processes.')\n .action(async () => {\n const { logger } = getRuntime();\n await stopEmulator(logger);\n logger.info('Emulator stopped.');\n });\n\n emu\n .command('connect')\n .description('Attempt to connect hdc to the emulator.')\n .option('--address <addr>', 'hdc address to connect to', '127.0.0.1:55555')\n .action(async (opts: { address: string }) => {\n const { config, logger } = getRuntime();\n const ok = await attemptHdcConnection(config, opts.address, logger);\n if (!ok) {\n logger.error(`Could not connect hdc to ${opts.address}.`);\n process.exit(1);\n }\n logger.info(`hdc connected to ${opts.address}.`);\n });\n\n emu\n .command('remove')\n .description('Delete the configured emulator directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeEmulator(config);\n logger.info('Emulator removed.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { buildHap } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface BuildOpts {\n product: string;\n module?: string;\n mode?: string;\n task: string;\n deps: boolean;\n parallel: boolean;\n json?: boolean;\n}\n\nexport function registerBuildCommand(program: Command): void {\n program\n .command('build [project-dir]')\n .description(\n 'Build an OpenHarmony or HarmonyOS app via hvigorw. Defaults to the current directory. ' +\n 'Projects declaring runtimeOS \"HarmonyOS\" build against the HarmonyOS SDK (ONIRO_HARMONYOS_SDK_PATH or an installed DevEco Studio).',\n )\n .option('--product <product>', 'hvigor product name', 'default')\n .option('--module <module>', 'restrict the build to a specific module')\n .option('--mode <mode>', 'hvigor build mode (e.g. release, debug)')\n .option('--task <task>', 'hvigor task to run', 'assembleHap')\n .option('--no-deps', 'skip the automatic `ohpm install --all` when oh_modules/ is missing')\n .option('--no-parallel', 'build modules serially (default: parallel)')\n .option('--json', 'emit the build result (discovered HAPs, warnings) as JSON')\n .action(async (projectDir: string | undefined, opts: BuildOpts) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Building project at ${dir}...`);\n const result = await buildHap({\n config,\n projectDir: dir,\n product: opts.product,\n module: opts.module,\n mode: opts.mode,\n task: opts.task,\n autoInstallDeps: opts.deps,\n parallel: opts.parallel,\n logger,\n // The logger already echoes spawn output; this hook is for streaming to other UIs.\n onOutput: () => {},\n });\n for (const w of result.warnings) logger.warn(w);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n }\n logger.info('Build complete.');\n });\n}\n","import { Command, Option } from 'commander';\nimport * as path from 'node:path';\nimport {\n APL_VALUES,\n APP_FEATURE_VALUES,\n OniroError,\n createHarmonyOsSession,\n detectRuntimeOs,\n generateSigningConfigs,\n harmonyOsAutoSign,\n prepareSigning,\n getOhosBaseSdkHome,\n type Apl,\n type AppFeature,\n type SigningPasswords,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nfunction parseAclsList(value: string): string[] {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nexport function registerSignCommand(program: Command): void {\n program\n .command('sign [project-dir]')\n .description(\n [\n 'Generate signing keys, certificates, and signingConfigs for an OpenHarmony project.',\n 'Requires java on PATH. The generated profile uses the SDK\\'s built-in development',\n 'cert (issuer=pki_internal) and its bundled validity window — dev/local builds only.',\n 'Overwrites the `signingConfigs` block in build-profile.json5 (other keys preserved).',\n 'HarmonyOS projects need --harmonyos instead, which has AppGallery Connect issue the',\n 'certificate and profile for a signed-in Huawei account (`oniro-app auth login`).',\n ].join(' '),\n )\n .addOption(\n new Option(\n '--apl <level>',\n 'Ability Privilege Level written into the profile. Apps that request permissions above `normal` (e.g. ohos.permission.GET_WIFI_INFO_INTERNAL) need system_basic or system_core, which also switches the HAP-signing key to \"OpenHarmony Application Release\".',\n )\n .choices([...APL_VALUES])\n .default('normal'),\n )\n .addOption(\n new Option(\n '--app-feature <feature>',\n 'App feature written into the profile. Defaults: hos_normal_app for apl=normal; hos_system_app for apl=system_basic/system_core.',\n ).choices([...APP_FEATURE_VALUES]),\n )\n .addOption(\n new Option(\n '--acls <list>',\n 'Comma-separated permission names to write into the profile\\'s acls.allowed-acls. Required for apps that request permissions above their apl (e.g. a system_basic app requesting ohos.permission.CAPTURE_SCREEN). Example: --acls ohos.permission.REBOOT,ohos.permission.INJECT_INPUT_EVENT',\n ).argParser(parseAclsList),\n )\n .option(\n '--harmonyos',\n 'Sign a HarmonyOS project through AppGallery Connect. Needs `oniro-app auth login`, and a connected device unless the team already has devices registered.',\n )\n .option('--team-id <id>', 'With --harmonyos: the AGC team to sign under. Default: the account\\'s own (`oniro-app auth team list`).')\n .option('--product <name>', 'With --harmonyos: the product to sign. Default `default`.')\n .option('--force', 'With --harmonyos: regenerate the certificate and profile even when they are still valid.')\n .option('--bootstrap', 'No-op if signing material is already present; otherwise generate it.')\n .option('--store-password <pwd>', 'Keystore store password (default 123456 — the SDK keystore password).')\n .option('--key-password <pwd>', 'Keystore key password (default 123456 — the SDK keystore password).')\n .action(\n async (\n projectDir: string | undefined,\n opts: {\n apl: Apl;\n appFeature?: AppFeature;\n acls?: string[];\n bootstrap?: boolean;\n storePassword?: string;\n keyPassword?: string;\n harmonyos?: boolean;\n teamId?: string;\n product?: string;\n force?: boolean;\n },\n ) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n\n if (opts.harmonyos) {\n const result = await harmonyOsAutoSign({\n config,\n session: createHarmonyOsSession({ config, logger }),\n projectDir: dir,\n productName: opts.product,\n teamId: opts.teamId,\n force: opts.force,\n logger,\n });\n logger.info(`Signing configs ready for ${result.bundleName} (profile names ${result.deviceIds.length} device(s)).`);\n return;\n }\n // The OpenHarmony development certificate cannot sign for a HarmonyOS device.\n if (detectRuntimeOs(dir, opts.product) === 'HarmonyOS') {\n throw new OniroError(\n `${dir} targets HarmonyOS, which needs a certificate from AppGallery Connect: run \\`oniro-app auth login\\` once, then \\`oniro-app sign --harmonyos\\`.`,\n );\n }\n const passwords: SigningPasswords | undefined =\n opts.storePassword || opts.keyPassword\n ? { store: opts.storePassword ?? '123456', key: opts.keyPassword ?? '123456' }\n : undefined;\n\n if (opts.bootstrap) {\n const result = prepareSigning({\n config,\n projectDir: dir,\n apl: opts.apl,\n appFeature: opts.appFeature,\n acls: opts.acls,\n passwords,\n logger,\n });\n logger.info(result.source === 'present' ? 'Signing material already present.' : 'Signing configs generated.');\n return;\n }\n\n const sdkHome = getOhosBaseSdkHome(config);\n logger.info(`Generating signing configs in ${dir} using SDK at ${sdkHome}...`);\n generateSigningConfigs({\n projectDir: dir,\n sdkHome,\n apl: opts.apl,\n appFeature: opts.appFeature,\n acls: opts.acls,\n passwords,\n logger,\n });\n logger.info('Signing configs generated.');\n },\n );\n}\n","import { Command } from 'commander';\nimport { HUAWEI_SITES, createHarmonyOsSession, type HarmonyOsSession } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\n/** A session bound to the CLI runtime. The sign-in URL goes to stderr for headless hosts. */\nfunction session(): HarmonyOsSession {\n const { config, logger } = getRuntime();\n return createHarmonyOsSession({\n config,\n logger,\n onLoginUrl: (url) => process.stderr.write(`Opening the Huawei sign-in page. If no browser opens, visit:\\n ${url}\\n`),\n });\n}\n\nexport function registerAuthCommand(program: Command): void {\n const auth = program\n .command('auth')\n .description(\n 'Sign in to a Huawei developer account, which HarmonyOS signing (`oniro-app sign --harmonyos`) needs. ' +\n 'OpenHarmony signing needs no account. The token is stored encrypted under ONIRO_HARMONYOS_AUTH_DIR ' +\n '(default ~/.oniro/harmonyos).',\n );\n\n auth\n .command('login')\n .description('Sign in through the browser, which redirects back to a loopback port on this machine.')\n .option('--timeout <seconds>', 'How long to wait for the browser sign-in. Default 600.', (v) => Number(v))\n .action(async (opts: { timeout?: number }) => {\n const user = await session().login(opts.timeout ? { timeoutMs: Math.max(1, opts.timeout) * 1000 } : undefined);\n process.stdout.write(`${user.userName || user.userId}\\n`);\n });\n\n auth\n .command('logout')\n .description('Sign out and delete the stored token.')\n .action(async () => {\n const signedOut = await session().logout();\n getRuntime().logger.info(signedOut ? 'Signed out.' : 'Not signed in; nothing to do.');\n });\n\n auth\n .command('status')\n .description('Show the signed-in account. Exits non-zero when not signed in.')\n .option('--json', 'Emit the account details as JSON.')\n .action(async (opts: { json?: boolean }) => {\n const s = session();\n // Refreshed: a stale access token makes the agreement check fail.\n const user = await s.getUserInfo({ refresh: true });\n if (!user) {\n process.stderr.write('Not signed in. Run `oniro-app auth login`.\\n');\n process.exitCode = 1;\n return;\n }\n // Without real-name verification, the developer agreement is what allows signing.\n const agreement = user.isRealName ? null : await s.getDeveloperAgreement(user);\n if (opts.json) {\n const { userId, userName, countryCode, siteCode, isRealName } = user;\n const agcBaseUrl = HUAWEI_SITES[siteCode].agcBaseUrl;\n const status = { userId, userName, countryCode, site: siteCode, agcBaseUrl, isRealName, developerAgreement: agreement, tokenPath: s.tokenPath };\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${user.userName || user.userId} (${user.userId}) [${user.siteCode}]\\n`);\n if (agreement && !(agreement.signed && agreement.latest)) {\n process.stderr.write(\n '[warn] This account has neither real-name verification nor the current HUAWEI Developer Basic Service Agreement accepted, so AppGallery Connect will not issue signing material. Accept the agreement in AppGallery Connect or DevEco Studio.\\n',\n );\n }\n });\n\n auth\n .command('team')\n .description('AGC teams this account belongs to.')\n .command('list')\n .description('List the AGC teams this account belongs to, for `oniro-app sign --harmonyos --team-id <id>`.')\n .option('--json', 'Emit the team list as JSON.')\n .action(async (opts: { json?: boolean }) => {\n const teams = await session().listTeams();\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(teams, null, 2)}\\n`);\n return;\n }\n for (const t of teams) process.stdout.write(`${t.id}\\t${t.name}\\n`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { installApp, launchApp, uninstallApp, forceStop, applyChanges, getBundleName } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface ApplyOpts {\n bundle?: string;\n module?: string;\n hap?: string;\n installedHap?: string;\n system?: boolean;\n allowUninstall?: boolean;\n device?: string;\n json?: boolean;\n}\n\nexport function registerAppCommand(program: Command): void {\n const app = program.command('app').description('Install, launch, and manage built apps on a connected device/emulator.');\n\n app\n .command('install [project-dir]')\n .description('Install the signed .hap on the connected device/emulator via hdc.')\n .option('--hap <path>', 'Override the .hap path (relative to project-dir or absolute).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (projectDir: string | undefined, opts: { hap?: string; device?: string }) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Installing app from ${dir}...`);\n await installApp({ config, projectDir: dir, hapPath: opts.hap, deviceSerial: opts.device, logger });\n logger.info('App installed.');\n });\n\n app\n .command('launch [project-dir]')\n .description(\n 'Launch an app on the connected device/emulator. Project mode (default): resolves ' +\n 'bundle + main ability from the project. Bundle mode (--bundle): launch an ' +\n 'already-installed app by bundle name, no project needed.',\n )\n .option('--bundle <bundle>', 'Launch an already-installed app by bundle name (no project needed).')\n .option('--module <module>', 'Module folder name (project mode).', 'entry')\n .option('--ability <name>', 'Explicit ability to launch (defaults to the module mainElement in project mode, or the installed bundle main ability in --bundle mode).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (projectDir: string | undefined, opts: { bundle?: string; module: string; ability?: string; device?: string }) => {\n const { config, logger } = getRuntime();\n if (opts.bundle) {\n logger.info(`Launching installed bundle ${opts.bundle}...`);\n await launchApp({ config, bundleName: opts.bundle, abilityName: opts.ability, deviceSerial: opts.device, logger });\n } else {\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Launching app from ${dir}...`);\n await launchApp({ config, projectDir: dir, moduleName: opts.module, abilityName: opts.ability, deviceSerial: opts.device, logger });\n }\n logger.info('App launched.');\n });\n\n app\n .command('apply [project-dir]')\n .description(\n 'Install a HAP and verify the running process took the change. Handles sign-info mismatch, ' +\n 'asset-cache invalidation, and persistent-bundle restart.',\n )\n .option('--bundle <bundle>', 'Bundle name to apply changes to. Defaults to the bundleName in the project AppScope/app.json5.')\n .option('--module <module>', 'Module to resolve the HAP from (multi-module projects).')\n .option('--hap <path>', 'Explicit .hap path (relative to project-dir or absolute).')\n .option('--installed-hap <path>', 'Local path to the currently-installed HAP, to enable the asset-cache reboot.')\n .option('--system', 'Treat as a persistent/system bundle (refuses uninstall on sign-info mismatch).')\n .option('--allow-uninstall', 'Permit uninstalling a system bundle on sign-info mismatch (dangerous).')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'Emit the result as JSON.')\n .action(async (projectDir: string | undefined, opts: ApplyOpts) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n const bundle = opts.bundle ?? getBundleName(dir);\n const result = await applyChanges({\n config,\n bundle,\n hapPath: opts.hap,\n projectDir: dir,\n module: opts.module,\n installedHapPath: opts.installedHap,\n isSystemBundle: opts.system,\n allowUninstall: opts.allowUninstall,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n logger.info(\n `apply: method=${result.method} pid ${result.preInstallPid ?? '-'} -> ${result.postInstallPid ?? '-'}` +\n `${result.cacheCleared ? ' (cache cleared)' : ''}`,\n );\n }\n });\n\n app\n .command('uninstall <bundle>')\n .description('Uninstall an app by bundle name.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (bundle: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await uninstallApp({ config, bundle, deviceSerial: opts.device, logger });\n logger.info(`Uninstalled ${bundle}.`);\n });\n\n app\n .command('stop <bundle>')\n .description('Force-stop an app by bundle name.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (bundle: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await forceStop({ config, bundle, deviceSerial: opts.device, logger });\n logger.info(`Stopped ${bundle}.`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n createScaffold,\n isValidBundleName,\n isValidProjectName,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\ninterface CreateOpts {\n name: string;\n bundle: string;\n location: string;\n sdk: string;\n template: string;\n module?: string;\n overwrite?: boolean;\n}\n\nexport function registerCreateCommand(program: Command): void {\n program\n .command('create')\n .description('Scaffold a new Oniro/OpenHarmony or HarmonyOS app from a template. All flags are required (non-interactive).')\n .requiredOption('--name <name>', 'Project folder name (letters, digits, ._- only)')\n .requiredOption('--bundle <bundleName>', 'Bundle name in reverse-DNS form, e.g. com.example.myapp')\n .requiredOption('--location <dir>', 'Parent directory where the new project folder will be created')\n .requiredOption('--sdk <api>', 'Target SDK API level (e.g. 18, 20)')\n .option('--template <id>', 'Template id', 'EmptyAbility')\n .option('--module <name>', 'Module folder name (defaults to the template default, usually `entry`)')\n .option('--overwrite', 'Replace the destination if it already exists')\n .action(async (opts: CreateOpts) => {\n const { config, logger } = getRuntime();\n\n if (!isValidProjectName(opts.name)) {\n throw new Error(`Invalid --name '${opts.name}'. Use letters/numbers/._- and no slashes.`);\n }\n if (!isValidBundleName(opts.bundle)) {\n throw new Error(`Invalid --bundle '${opts.bundle}'. Example: com.example.myapp`);\n }\n const sdkApi = Number(opts.sdk);\n if (!Number.isFinite(sdkApi)) {\n throw new Error(`--sdk must be a numeric api level. Known: ${ALL_SDKS.map((s) => s.api).join(', ')}`);\n }\n\n const templateRoot = getBundledTemplateRoot();\n const result = await createScaffold({\n config,\n templateId: opts.template,\n projectName: opts.name,\n bundleName: opts.bundle,\n location: path.resolve(opts.location),\n sdkApi,\n moduleName: opts.module,\n templateRoot,\n overwrite: opts.overwrite,\n logger,\n });\n\n logger.info(`Project created at ${result.projectDir}`);\n process.stdout.write(`${result.projectDir}\\n`);\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Resolve the bundled `templates/` directory shipped inside this CLI package.\n *\n * The CLI's `dist/oniro-app.js` lives at `<pkg>/dist/oniro-app.js` after build\n * and the templates ship at `<pkg>/templates/`. During development the entrypoint\n * lives at `<pkg>/src/bin/oniro-app.ts` so we also try `../../templates` from there.\n */\nexport function getBundledTemplateRoot(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../templates'), // dist/oniro-app.js → ../templates\n path.resolve(here, '../../templates'), // src/bin/oniro-app.ts → ../../templates\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n // Return the most likely path even if it doesn't exist yet; createScaffold will\n // surface a clear error from there.\n return candidates[0]!;\n}\n","import { Command } from 'commander';\nimport { listTemplates } from '@oniroproject/core';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\nexport function registerTemplatesCommand(program: Command): void {\n const templates = program.command('templates').description('Inspect the templates bundled with this CLI.');\n\n templates\n .command('list')\n .description('List available project templates.')\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const root = getBundledTemplateRoot();\n const list = listTemplates(root);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(list, null, 2)}\\n`);\n return;\n }\n if (list.length === 0) {\n process.stdout.write('No templates available.\\n');\n return;\n }\n const rows = list.map((t) => `${t.id.padEnd(20)} ${t.label.padEnd(24)} ${t.description}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n}\n","import { Command, Option } from 'commander';\nimport { reboot } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerRebootCommand(program: Command): void {\n program\n .command('reboot')\n .description('Reboot the connected device/emulator.')\n .addOption(\n new Option('--mode <mode>', 'Reboot target.').choices(['system', 'bootloader', 'recovery']).default('system'),\n )\n .option('--wait-bundle <bundle>', 'After a system reboot, wait until this bundle is running again.')\n .option('--timeout <ms>', 'Max time to wait for the bundle, ms.', '180000')\n .option('--device <serial>', 'Target device serial.')\n .action(\n async (opts: {\n mode: 'system' | 'bootloader' | 'recovery';\n waitBundle?: string;\n timeout: string;\n device?: string;\n }) => {\n const { config, logger } = getRuntime();\n logger.info(`Rebooting device (${opts.mode})...`);\n await reboot({\n config,\n mode: opts.mode,\n waitForBundle: opts.waitBundle,\n timeoutMs: Number(opts.timeout),\n deviceSerial: opts.device,\n logger,\n });\n logger.info('Reboot complete.');\n },\n );\n}\n","import { Command } from 'commander';\nimport { waitForLog, waitForBoot, waitForBundle, waitForTarget, describeLayoutNode } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { addTargetOptions, selectorFrom, type TargetOpts } from '../lib/target.js';\n\ninterface WaitOpts extends TargetOpts {\n log?: string;\n boot?: boolean;\n bundle?: string;\n pidOf?: string;\n domain?: string;\n gone?: boolean;\n interval: string;\n timeout: string;\n device?: string;\n json?: boolean;\n}\n\nexport function registerWaitCommand(program: Command): void {\n const wait = program\n .command('wait')\n .description(\n 'Wait for a device condition: a log line (--log), boot (--boot), a bundle to start (--bundle), ' +\n 'or an on-screen element (--target / --target-id / --target-type).',\n )\n .option('--log <pattern>', 'Resolve when a hilog line (tag: message) matches this regex.')\n .option('--boot', 'Resolve when the device is reachable (optionally also --pid-of).')\n .option('--bundle <bundle>', 'With --log: filter to this bundle. Alone: wait until this bundle is running.')\n .option('--pid-of <name>', 'With --boot: also require this process to have a pid.')\n .option('--domain <domain>', 'With --log: hilog domain filter (e.g. 0xD003900).');\n addTargetOptions(wait, 'Resolve when', { index: false });\n wait\n .option('--gone', 'With --target*: resolve when no uncovered element matches any more.')\n .option('--interval <ms>', 'With --target*: poll interval, ms (each poll is a layout dump).', '500')\n .option('--timeout <ms>', 'Max wait, ms.', '30000')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'With --log or --target*: emit the matched entry/element as JSON.')\n .action(async (opts: WaitOpts) => {\n const { config, logger } = getRuntime();\n const timeoutMs = Number(opts.timeout);\n const selector = selectorFrom(opts);\n\n if (opts.log) {\n const entry = await waitForLog({\n config,\n pattern: new RegExp(opts.log),\n timeoutMs,\n bundle: opts.bundle,\n domain: opts.domain,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) process.stdout.write(`${JSON.stringify(entry, null, 2)}\\n`);\n else logger.info(`matched: ${entry.tag}: ${entry.message}`);\n return;\n }\n if (opts.boot) {\n await waitForBoot({ config, untilPidOf: opts.pidOf, timeoutMs, deviceSerial: opts.device, logger });\n logger.info('Device booted.');\n return;\n }\n if (selector) {\n const node = await waitForTarget({\n config,\n selector,\n gone: opts.gone,\n timeoutMs,\n pollMs: Number(opts.interval) || 500,\n deviceSerial: opts.device,\n logger,\n });\n if (!node) {\n logger.info('Element is gone.');\n return;\n }\n if (opts.json) process.stdout.write(`${JSON.stringify(node, null, 2)}\\n`);\n else logger.info(`found: ${describeLayoutNode(node)}`);\n return;\n }\n if (opts.bundle) {\n await waitForBundle({ config, bundle: opts.bundle, timeoutMs, deviceSerial: opts.device, logger });\n logger.info(`Bundle ${opts.bundle} is running.`);\n return;\n }\n throw new Error('Specify one of --log <pattern>, --boot, --bundle <bundle>, or --target <text> (or --target-id / --target-type).');\n });\n}\n","import type { Command } from 'commander';\nimport type { LayoutSelector } from '@oniroproject/core';\n\n/** The shared element-selector flags, as commander parses them. */\nexport interface TargetOpts {\n target?: string;\n targetId?: string;\n targetType?: string;\n targetIndex?: string;\n}\n\n/**\n * Add the element-selector flags shared by `input`, `wait`, and `screenshot`.\n * `verb` completes the `--target` help text (e.g. \"Tap\" → \"Tap the element …\").\n */\nexport function addTargetOptions(cmd: Command, verb: string, opts: { index?: boolean } = {}): Command {\n cmd\n .option(\n '--target <text>',\n `${verb} the element whose text, description, or placeholder matches ` +\n '(case-insensitive; exact matches win, else substring). Covered elements are skipped.',\n )\n .option('--target-id <id>', 'Match the element by its id or key.')\n .option('--target-type <type>', 'Restrict the match to a component type (e.g. Button, TextInput).');\n if (opts.index !== false) {\n cmd.option('--target-index <n>', 'Pick the n-th (0-based) of several matching elements.');\n }\n return cmd;\n}\n\n/** The selector built from the flags, or undefined when none was given. */\nexport function selectorFrom(opts: TargetOpts): LayoutSelector | undefined {\n if (opts.target === undefined && opts.targetId === undefined && opts.targetType === undefined) return undefined;\n return { text: opts.target, id: opts.targetId, type: opts.targetType };\n}\n\nexport function targetIndexFrom(opts: TargetOpts): number | undefined {\n if (opts.targetIndex === undefined) return undefined;\n const n = Number(opts.targetIndex);\n if (!Number.isInteger(n) || n < 0) throw new Error(`--target-index must be a non-negative integer; got ${opts.targetIndex}.`);\n return n;\n}\n","import { Command } from 'commander';\nimport { watchLog } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface WatchOpts {\n log?: string;\n for: string;\n bundle?: string;\n domain?: string;\n dedup: boolean;\n device?: string;\n json?: boolean;\n}\n\nexport function registerWatchCommand(program: Command): void {\n program\n .command('watch')\n .description('Collect hilog lines matching a pattern for a fixed duration.')\n .option('--log <pattern>', 'Regex tested against each line (tag: message).')\n .option('--for <ms>', 'Duration to watch, ms.', '10000')\n .option('--bundle <bundle>', 'Filter to this bundle.')\n .option('--domain <domain>', 'hilog domain filter (e.g. 0xD003900).')\n .option('--no-dedup', 'Do not collapse consecutive duplicate lines.')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'Emit the entries as JSON.')\n .action(async (opts: WatchOpts) => {\n const { config, logger } = getRuntime();\n if (!opts.log) throw new Error('watch requires --log <pattern>.');\n const entries = await watchLog({\n config,\n pattern: new RegExp(opts.log),\n durationMs: Number(opts.for),\n bundle: opts.bundle,\n domain: opts.domain,\n dedup: opts.dedup,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(entries, null, 2)}\\n`);\n } else {\n for (const e of entries) process.stdout.write(`${e.time} ${e.level} ${e.tag}: ${e.message}\\n`);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { takeScreenshot, captureBurst, locateTarget, describeLayoutNode } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport {\n renderWithGrid,\n buildContactSheet,\n frameDiffs,\n cropImage,\n parseCropRect,\n padCropRect,\n type CropRect,\n} from '../lib/screenshotImage.js';\nimport { addTargetOptions, selectorFrom, targetIndexFrom, type TargetOpts } from '../lib/target.js';\n\ninterface ScreenshotOpts extends TargetOpts {\n output: string;\n grid?: boolean;\n maxDim: string;\n crop?: string;\n contactSheet?: boolean;\n burst?: string;\n interval: string;\n json?: boolean;\n device?: string;\n}\n\nconst DEFAULT_CONTACT_SHEET_FRAMES = 8;\n// Margin kept around a --target element when cropping to it, as a fraction of the display.\nconst TARGET_CROP_PAD = 0.02;\n\nfunction clampMaxDim(raw: string): number {\n const n = Number(raw);\n if (!Number.isFinite(n)) return 1024;\n return Math.max(256, Math.min(4096, Math.round(n)));\n}\n\nexport function registerScreenshotCommand(program: Command): void {\n const screenshot = program\n .command('screenshot')\n .description(\n 'Capture the screen. Default: full-resolution raw JPEG. ' +\n '--grid: downscaled JPEG with a 10x10 grid (axes 0.0-1.0) for picking tap coordinates. ' +\n '--crop / --target: a full-resolution crop of one region or element, for checking detail cheaply. ' +\n '--contact-sheet: capture a burst and tile it into one image with per-frame change diffs.',\n )\n .option('-o, --output <file>', 'Output file path.', 'screenshot.jpeg')\n .option('--grid', 'Downscale (to --max-dim) and overlay a 10x10 coordinate grid.')\n .option('--max-dim <px>', 'Longest-side cap for --grid / --crop / --target / --contact-sheet (256-4096).', '1024')\n .option('--crop <x1,y1,x2,y2>', 'Crop to this region, given as 0-1 fractions of the screen.');\n addTargetOptions(screenshot, 'Crop to');\n screenshot\n .option('--contact-sheet', 'Capture a burst and composite it into one tiled contact sheet.')\n .option('--burst <count>', 'Capture N frames; writes <base>-<i><ext> (or feeds --contact-sheet).')\n .option('--interval <ms>', 'Delay between burst frames, ms.', '50')\n .option('--json', 'Emit the full result object as JSON on stdout (with --contact-sheet).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: ScreenshotOpts, command: Command) => {\n const { config, logger } = getRuntime();\n const maxDim = clampMaxDim(opts.maxDim);\n const intervalMs = Number(opts.interval) || 50;\n\n // --- Crop: one region (or element) at full resolution ---\n const selector = selectorFrom(opts);\n if (opts.crop !== undefined || selector) {\n if (opts.crop !== undefined && selector) throw new Error('Use either --crop or --target*, not both.');\n if (opts.grid || opts.contactSheet || opts.burst) {\n throw new Error('--crop / --target cannot be combined with --grid, --contact-sheet, or --burst.');\n }\n let rect: CropRect;\n let label: string;\n if (selector) {\n // Leave the keyboard alone: dismissing it would change what we are capturing.\n const located = await locateTarget({\n config,\n selector,\n index: targetIndexFrom(opts),\n hideKeyboard: false,\n deviceSerial: opts.device,\n logger,\n });\n if (!located.node.b) throw new Error(`${describeLayoutNode(located.node)} has no bounds to crop to.`);\n rect = padCropRect(located.node.b, TARGET_CROP_PAD);\n label = describeLayoutNode(located.node);\n } else {\n rect = parseCropRect(opts.crop!);\n label = rect.map((n) => n.toFixed(3)).join(',');\n }\n const shot = await takeScreenshot({ config, deviceSerial: opts.device, logger });\n const cropped = await cropImage(shot.pixels, rect, { maxDim });\n fs.writeFileSync(opts.output, cropped.buf);\n logger.info(\n `Wrote ${opts.output} (${cropped.width}x${cropped.height} from a ${cropped.cropWidth}x${cropped.cropHeight} ` +\n `crop at ${cropped.left},${cropped.top}: ${label}).`,\n );\n return;\n }\n\n // --- Contact sheet: burst -> one tiled image + per-frame diffs ---\n if (opts.contactSheet) {\n const count = opts.burst ? Math.max(1, Number(opts.burst)) : DEFAULT_CONTACT_SHEET_FRAMES;\n const frames = await captureBurst({ config, count, intervalMs, deviceSerial: opts.device, logger });\n const diffs = await frameDiffs(frames);\n const sheet = await buildContactSheet(frames, { maxDim, diffs });\n fs.writeFileSync(opts.output, sheet.buf);\n\n // Only fan out the individual raw frames when --burst was also requested.\n if (opts.burst) {\n const ext = path.extname(opts.output) || '.jpeg';\n const base = opts.output.slice(0, opts.output.length - ext.length);\n frames.forEach((frame, i) => fs.writeFileSync(`${base}-${i}${ext}`, frame));\n }\n\n const perFrame = frames.map((_, i) => ({ idx: i, t_ms: i * intervalMs, diffVsPrev: diffs[i] ?? 0 }));\n if (opts.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n sheet: opts.output,\n frameCount: frames.length,\n cols: sheet.cols,\n rows: sheet.rows,\n intervalMs,\n note: 't_ms is nominal (idx*interval); diffVsPrev is 0..1 mean greyscale diff vs the previous frame.',\n frames: perFrame,\n },\n null,\n 2,\n )}\\n`,\n );\n } else {\n process.stdout.write(`${JSON.stringify(perFrame)}\\n`);\n }\n\n let peak = 0;\n for (let i = 1; i < diffs.length; i++) if ((diffs[i] ?? 0) > (diffs[peak] ?? 0)) peak = i;\n logger.info(\n `Wrote contact sheet ${opts.output} (${sheet.cols}x${sheet.rows}, ${frames.length} frames). ` +\n `Biggest change at frame ${peak} (Δ${(diffs[peak] ?? 0).toFixed(2)}).`,\n );\n return;\n }\n\n // --- Burst (raw frames) — unchanged behaviour ---\n if (opts.burst) {\n const frames = await captureBurst({\n config,\n count: Number(opts.burst),\n intervalMs,\n deviceSerial: opts.device,\n logger,\n });\n const ext = path.extname(opts.output) || '.jpeg';\n const base = opts.output.slice(0, opts.output.length - ext.length);\n frames.forEach((frame, i) => fs.writeFileSync(`${base}-${i}${ext}`, frame));\n logger.info(`Wrote ${frames.length} frames to ${base}-<0..${frames.length - 1}>${ext}.`);\n return;\n }\n\n // --- Single shot ---\n const shot = await takeScreenshot({ config, deviceSerial: opts.device, logger });\n const maxDimProvided = command.getOptionValueSource('maxDim') === 'cli';\n if (opts.grid || maxDimProvided) {\n const rendered = await renderWithGrid(shot.pixels, { maxDim, grid: !!opts.grid });\n fs.writeFileSync(opts.output, rendered.buf);\n logger.info(\n `Wrote ${opts.output} (${rendered.width}x${rendered.height} from ` +\n `${rendered.originalWidth}x${rendered.originalHeight}${opts.grid ? ', 10x10 grid' : ''}).`,\n );\n return;\n }\n fs.writeFileSync(opts.output, shot.pixels);\n logger.info(`Wrote ${opts.output} (${shot.width}x${shot.height}).`);\n });\n}\n","import sharp from 'sharp';\n\n/**\n * Agent-facing screenshot image processing for the CLI.\n *\n * `@oniroproject/core` deliberately ships no image dependency — it returns raw\n * JPEG buffers. The grid overlay / downscale and the burst contact-sheet live\n * here (the CLI is the affordance layer), so `oniro-app screenshot` can produce\n * exactly what the ohos-hdc MCP used to. The grid drawing is ported verbatim\n * from that MCP so the output is equivalent.\n */\n\nexport interface RenderResult {\n /** Encoded JPEG. */\n buf: Buffer;\n /** Rendered (post-downscale) dimensions. */\n width: number;\n height: number;\n /** Source dimensions, before downscale. */\n originalWidth: number;\n originalHeight: number;\n}\n\nexport interface RenderWithGridOptions {\n /** Longest-side cap in pixels. The image is downscaled (never upscaled) to fit. */\n maxDim: number;\n /** Overlay the 10x10 grid with 0.0–1.0 axis labels after downscaling. */\n grid?: boolean;\n}\n\n/**\n * Build an SVG overlay: a 10x10 grid with X/Y axis labels (0.0–1.0) sized to the\n * given image dimensions. Ported verbatim from the ohos-hdc MCP so the gridded\n * output matches what agents are used to.\n */\nexport function buildGridSvg(width: number, height: number): string {\n const lineColor = 'rgba(255,80,80,0.55)';\n const labelBg = 'rgba(0,0,0,0.7)';\n const labelFg = '#fff';\n const fontSize = Math.max(10, Math.round(Math.min(width, height) / 60));\n const padding = Math.round(fontSize * 0.4);\n const labels: string[] = [];\n const lines: string[] = [];\n for (let i = 0; i <= 10; i++) {\n const f = i / 10;\n const x = Math.round(f * (width - 1));\n const y = Math.round(f * (height - 1));\n // grid lines (skip 0 and 10 — those are the image edges)\n if (i > 0 && i < 10) {\n lines.push(`<line x1=\"${x}\" y1=\"0\" x2=\"${x}\" y2=\"${height}\" stroke=\"${lineColor}\" stroke-width=\"1\"/>`);\n lines.push(`<line x1=\"0\" y1=\"${y}\" x2=\"${width}\" y2=\"${y}\" stroke=\"${lineColor}\" stroke-width=\"1\"/>`);\n }\n const tag = f.toFixed(1);\n // X-axis labels along the top\n const tx = i === 0 ? padding : i === 10 ? width - padding : x;\n const anchorX = i === 0 ? 'start' : i === 10 ? 'end' : 'middle';\n labels.push(\n `<text x=\"${tx}\" y=\"${fontSize + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"${anchorX}\">${tag}</text>`,\n );\n // Y-axis labels along the left\n const ty = i === 0 ? fontSize + padding : i === 10 ? height - padding : y + fontSize / 3;\n labels.push(\n `<text x=\"${padding}\" y=\"${ty}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">${tag}</text>`,\n );\n }\n // Axis title markers in the corners\n labels.push(\n `<text x=\"${width / 2}\" y=\"${fontSize * 2.4 + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"middle\">X →</text>`,\n );\n labels.push(\n `<text x=\"${padding}\" y=\"${fontSize * 2.6 + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">Y ↓</text>`,\n );\n return `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">${lines.join('')}${labels.join('')}</svg>`;\n}\n\n/**\n * Downscale a JPEG so its longest side is <= `maxDim` (never upscaling) and,\n * when `grid` is set, overlay the coordinate grid. Returns the encoded JPEG plus\n * rendered and original dimensions.\n */\nexport async function renderWithGrid(jpeg: Buffer, opts: RenderWithGridOptions): Promise<RenderResult> {\n const meta = await sharp(jpeg).metadata();\n const originalWidth = meta.width ?? 0;\n const originalHeight = meta.height ?? 0;\n const longest = Math.max(originalWidth, originalHeight) || 1;\n const scale = Math.min(1, opts.maxDim / longest);\n const width = Math.max(1, Math.round(originalWidth * scale));\n const height = Math.max(1, Math.round(originalHeight * scale));\n const resized = await sharp(jpeg).resize(width, height).jpeg({ quality: 80 }).toBuffer();\n if (!opts.grid) {\n return { buf: resized, width, height, originalWidth, originalHeight };\n }\n const svg = buildGridSvg(width, height);\n const buf = await sharp(resized)\n .composite([{ input: Buffer.from(svg) }])\n .jpeg({ quality: 80 })\n .toBuffer();\n return { buf, width, height, originalWidth, originalHeight };\n}\n\n/** A region as [x1, y1, x2, y2] fractions (0–1) of the image. */\nexport type CropRect = [number, number, number, number];\n\n/** Parse `\"x1,y1,x2,y2\"` (0–1 fractions, x1<x2, y1<y2) into a {@link CropRect}. */\nexport function parseCropRect(spec: string): CropRect {\n const parts = spec.split(',').map((s) => Number(s.trim()));\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n) || n < 0 || n > 1)) {\n throw new Error(`--crop expects four 0-1 fractions \"x1,y1,x2,y2\"; got \"${spec}\".`);\n }\n const [x1, y1, x2, y2] = parts as CropRect;\n if (!(x2 > x1 && y2 > y1)) throw new Error(`--crop needs x1 < x2 and y1 < y2; got \"${spec}\".`);\n return [x1, y1, x2, y2];\n}\n\n/** Grow a rect by `pad` (a fraction) on every side, clamped to 0–1. */\nexport function padCropRect(r: CropRect, pad: number): CropRect {\n return [Math.max(0, r[0] - pad), Math.max(0, r[1] - pad), Math.min(1, r[2] + pad), Math.min(1, r[3] + pad)];\n}\n\nexport interface CropResult {\n /** Encoded JPEG. */\n buf: Buffer;\n /** Rendered (post-downscale) dimensions. */\n width: number;\n height: number;\n /** The cropped region in source pixels. */\n left: number;\n top: number;\n cropWidth: number;\n cropHeight: number;\n}\n\n/**\n * Crop a JPEG to a 0–1 region at full resolution, then downscale so the longest\n * side is <= `maxDim` (never upscaling). Detail where it is needed, at a\n * fraction of a full-resolution screenshot's size.\n */\nexport async function cropImage(jpeg: Buffer, rect: CropRect, opts: { maxDim: number }): Promise<CropResult> {\n const meta = await sharp(jpeg).metadata();\n const w = meta.width ?? 1;\n const h = meta.height ?? 1;\n const left = Math.min(w - 1, Math.floor(rect[0] * w));\n const top = Math.min(h - 1, Math.floor(rect[1] * h));\n const cropWidth = Math.max(1, Math.min(w, Math.ceil(rect[2] * w)) - left);\n const cropHeight = Math.max(1, Math.min(h, Math.ceil(rect[3] * h)) - top);\n const scale = Math.min(1, opts.maxDim / Math.max(cropWidth, cropHeight));\n const width = Math.max(1, Math.round(cropWidth * scale));\n const height = Math.max(1, Math.round(cropHeight * scale));\n const buf = await sharp(jpeg)\n .extract({ left, top, width: cropWidth, height: cropHeight })\n .resize(width, height)\n .jpeg({ quality: 85 })\n .toBuffer();\n return { buf, width, height, left, top, cropWidth, cropHeight };\n}\n\nexport interface ContactSheetOptions {\n /** Longest-side cap for the whole sheet; per-tile size derives from this. */\n maxDim: number;\n /** Tiles per row. Defaults to ceil(sqrt(N)). */\n cols?: number;\n /** Per-frame diff (0..1), index-aligned with `frames`; printed on each tile. */\n diffs?: number[];\n /** Gap between tiles, px. */\n gap?: number;\n}\n\nexport interface ContactSheetResult {\n buf: Buffer;\n width: number;\n height: number;\n cols: number;\n rows: number;\n tileWidth: number;\n tileHeight: number;\n count: number;\n}\n\nfunction buildTileLabelSvg(width: number, height: number, idx: number, diff?: number): string {\n const fontSize = Math.max(12, Math.round(Math.min(width, height) / 16));\n const pad = Math.round(fontSize * 0.4);\n let label = `#${idx}`;\n if (typeof diff === 'number') label += ` Δ${diff.toFixed(2)}`;\n const boxW = Math.round(label.length * fontSize * 0.62) + pad * 2;\n const boxH = fontSize + pad * 2;\n return (\n `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">` +\n `<rect x=\"0\" y=\"0\" width=\"${boxW}\" height=\"${boxH}\" fill=\"rgba(0,0,0,0.6)\"/>` +\n `<text x=\"${pad}\" y=\"${fontSize + pad - 1}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"#fff\" stroke=\"rgba(0,0,0,0.85)\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">${label}</text>` +\n `</svg>`\n );\n}\n\n/**\n * Composite a burst of JPEG frames into a single tiled contact sheet, each tile\n * labelled with its frame index (and per-frame diff when provided). One image\n * replaces N — a large token saving when verifying transient UI.\n */\nexport async function buildContactSheet(frames: Buffer[], opts: ContactSheetOptions): Promise<ContactSheetResult> {\n if (frames.length === 0) throw new Error('buildContactSheet: no frames');\n const count = frames.length;\n const cols = Math.max(1, opts.cols ?? Math.ceil(Math.sqrt(count)));\n const rows = Math.ceil(count / cols);\n const gap = opts.gap ?? 8;\n\n const meta0 = await sharp(frames[0]).metadata();\n const fw = meta0.width ?? 1;\n const fh = meta0.height ?? 1;\n const longest = Math.max(fw, fh) || 1;\n const tileScale = Math.min(1, opts.maxDim / cols / longest);\n const tileWidth = Math.max(1, Math.round(fw * tileScale));\n const tileHeight = Math.max(1, Math.round(fh * tileScale));\n\n const tiles = await Promise.all(\n frames.map((frame, i) => {\n const label = Buffer.from(buildTileLabelSvg(tileWidth, tileHeight, i, opts.diffs?.[i]));\n return sharp(frame)\n .resize(tileWidth, tileHeight, { fit: 'fill' })\n .composite([{ input: label, top: 0, left: 0 }])\n .png()\n .toBuffer();\n }),\n );\n\n const width = cols * tileWidth + (cols + 1) * gap;\n const height = rows * tileHeight + (rows + 1) * gap;\n const placements = tiles.map((input, i) => {\n const r = Math.floor(i / cols);\n const c = i % cols;\n return { input, left: gap + c * (tileWidth + gap), top: gap + r * (tileHeight + gap) };\n });\n\n const buf = await sharp({\n create: { width, height, channels: 3, background: { r: 20, g: 20, b: 20 } },\n })\n .composite(placements)\n .jpeg({ quality: 80 })\n .toBuffer();\n\n return { buf, width, height, cols, rows, tileWidth, tileHeight, count };\n}\n\n/**\n * Per-frame change metric: mean absolute difference of a downscaled greyscale\n * thumbnail vs. the previous frame, normalised to 0..1. Frame 0 is 0 (no\n * predecessor). Cheap, deterministic, and device-free.\n */\nexport async function frameDiffs(frames: Buffer[], opts: { sample?: number } = {}): Promise<number[]> {\n if (frames.length === 0) return [];\n const sample = opts.sample ?? 32;\n const thumbs = await Promise.all(\n frames.map((f) => sharp(f).greyscale().resize(sample, sample, { fit: 'fill' }).raw().toBuffer()),\n );\n const out: number[] = [0];\n for (let i = 1; i < thumbs.length; i++) {\n const a = thumbs[i - 1];\n const b = thumbs[i];\n if (!a || !b) {\n out.push(0);\n continue;\n }\n const n = Math.min(a.length, b.length) || 1;\n let s = 0;\n for (let k = 0; k < n; k++) s += Math.abs((a[k] ?? 0) - (b[k] ?? 0));\n out.push(+(s / n / 255).toFixed(4));\n }\n return out;\n}\n","import { Command } from 'commander';\nimport { dumpLayout } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { formatFlatLayout } from '../lib/layoutText.js';\n\ninterface DumpOpts {\n bundle?: string;\n raw?: boolean;\n flat?: boolean;\n device?: string;\n}\n\nexport function registerDumpCommand(program: Command): void {\n program\n .command('dump [target]')\n .description(\n 'Dump device state. Currently supports `dump layout` (the default target): JSON by default, ' +\n 'or one line per element with --flat.',\n )\n .option('--bundle <bundle>', 'Filter the layout to a single window/bundle.')\n .option('--raw', 'Return the unpruned layout tree.')\n .option('--flat', 'One line per element (type, label, center as 0-1 fractions, flags) instead of a JSON tree.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (target: string | undefined, opts: DumpOpts) => {\n const { config, logger } = getRuntime();\n const what = target ?? 'layout';\n if (what !== 'layout') throw new Error(`Unknown dump target \"${what}\". Supported: layout.`);\n if (opts.raw && opts.flat) throw new Error('--raw and --flat cannot be combined.');\n const result = await dumpLayout({\n config,\n bundleName: opts.bundle,\n prune: !opts.raw,\n detectKeyboard: !opts.raw,\n deviceSerial: opts.device,\n logger,\n });\n process.stdout.write(opts.flat ? formatFlatLayout(result) : `${JSON.stringify(result, null, 2)}\\n`);\n });\n}\n","import { flattenLayout, type DumpLayoutResult, type FlatLayoutNode } from '@oniroproject/core';\n\nconst MAX_TEXT = 80;\n\nfunction quote(s: string): string {\n return JSON.stringify(s.length > MAX_TEXT ? `${s.slice(0, MAX_TEXT - 1)}…` : s);\n}\n\nfunction flags(n: FlatLayoutNode): string[] {\n const out: string[] = [];\n if (n.click) out.push('click');\n if (n.longClick) out.push('longClick');\n if (n.scroll) out.push('scroll');\n if (n.checked) out.push('checked');\n else if (n.check) out.push('checkable');\n if (n.sel) out.push('selected');\n if (n.focus) out.push('focus');\n if (n.disabled) out.push('disabled');\n if (n.covered) out.push('covered');\n return out;\n}\n\n/** One line per element: type, label, center (0–1 fractions), and state flags. */\nexport function formatLayoutLine(n: FlatLayoutNode): string {\n const parts: string[] = [n.type ?? 'node'];\n if (n.text !== undefined) parts.push(quote(n.text));\n if (n.desc !== undefined) parts.push(`desc=${quote(n.desc)}`);\n if (n.hint !== undefined) parts.push(`hint=${quote(n.hint)}`);\n if (n.id !== undefined) parts.push(`#${n.id}`);\n if (n.key !== undefined) parts.push(`key=${n.key}`);\n if (n.c) parts.push(`c=${n.c[0].toFixed(3)},${n.c[1].toFixed(3)}`);\n parts.push(...flags(n));\n return parts.join(' ');\n}\n\n/** Worth a line: it has a label to read or match, or it can be interacted with. */\nfunction isListed(n: FlatLayoutNode): boolean {\n const labelled = n.text !== undefined || n.desc !== undefined || n.hint !== undefined;\n return labelled || !!(n.click || n.longClick || n.scroll || n.check || n.focus);\n}\n\n/**\n * Render a pruned layout as compact text for agents: a `[window <bundle>]`\n * header per window, then one line per labelled or interactive element in\n * paint order (decorative images and id-only wrappers are left to the JSON\n * output). The soft keyboard collapses to a single `[keyboard <bundle>]` line\n * instead of listing every key.\n */\nexport function formatFlatLayout(result: DumpLayoutResult): string {\n const lines: string[] = [];\n const d = result.display;\n lines.push(\n `# display ${d ? `${d.width}x${d.height}` : 'unknown'}; c = element center as 0-1 fractions ` +\n '(input --fx/--fy), or act by label with input --target \"<text>\"',\n );\n const keyboardBundle = result.keyboard?.shown ? result.keyboard.bundle : undefined;\n let window: string | undefined;\n for (const n of flattenLayout(result.tree)) {\n if (n.window !== window) {\n window = n.window;\n if (window !== undefined && window === keyboardBundle) {\n lines.push(`[keyboard ${window}] up — dismiss with input --type hideKeyboard`);\n } else if (window !== undefined) {\n lines.push(`[window ${window}]`);\n }\n }\n if (window !== undefined && window === keyboardBundle) continue;\n if (n.bundle !== undefined && n.text === undefined && !n.click) continue; // the window root itself\n if (isListed(n)) lines.push(formatLayoutLine(n));\n }\n return `${lines.join('\\n')}\\n`;\n}\n","import { Command } from 'commander';\nimport { listDevices } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerDevicesCommand(program: Command): void {\n program\n .command('devices')\n .description('List connected hdc devices.')\n .option('--json', 'Emit machine-readable JSON.')\n .action(async (opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const devices = await listDevices(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(devices, null, 2)}\\n`);\n return;\n }\n if (devices.length === 0) {\n process.stdout.write('(no devices)\\n');\n return;\n }\n for (const d of devices) {\n process.stdout.write(`${d.serial}\\t${d.connection ?? ''}\\t${d.status}\\n`);\n }\n });\n}\n","import { Command } from 'commander';\nimport { sendFile, recvFile } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerFileCommand(program: Command): void {\n const file = program.command('file').description('Transfer files to/from the device (hdc file send/recv).');\n\n file\n .command('send <local> <remote>')\n .description('Push a local file to the device.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (local: string, remote: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await sendFile({ config, local, remote, deviceSerial: opts.device, logger });\n logger.info(`Sent ${local} -> ${remote}.`);\n });\n\n file\n .command('recv <remote> <local>')\n .description('Pull a file from the device.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (remote: string, local: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await recvFile({ config, remote, local, deviceSerial: opts.device, logger });\n logger.info(`Received ${remote} -> ${local}.`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { runCodelinter } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface LintOpts {\n files?: string[];\n json?: boolean;\n}\n\nexport function registerLintCommand(program: Command): void {\n program\n .command('lint [project-dir]')\n .description('Run the OpenHarmony codelinter on a project. Defaults to the current directory.')\n .option('--files <globs...>', 'Specific files/globs to lint (default: the whole project).')\n .option('--json', 'Emit findings as JSON.')\n .action(async (projectDir: string | undefined, opts: LintOpts) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n const result = await runCodelinter({ config, projectDir: dir, files: opts.files, logger });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n for (const f of result.findings) {\n process.stdout.write(`${f.file}:${f.line} ${f.severity} ${f.message}${f.code ? ` [${f.code}]` : ''}\\n`);\n }\n if (result.findings.length === 0) process.stdout.write('No findings.\\n');\n }\n // Surface a non-zero codelinter exit to the caller (CI), but let output flush.\n if (result.code !== 0) process.exitCode = result.code;\n });\n}\n","import { Command, Option } from 'commander';\nimport {\n performInput,\n sendGesture,\n getDisplaySize,\n describeLayoutNode,\n type UiInputType,\n type Waypoint,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { addTargetOptions, selectorFrom, targetIndexFrom, type TargetOpts } from '../lib/target.js';\n\nconst INPUT_TYPES: UiInputType[] = [\n 'click',\n 'doubleClick',\n 'longClick',\n 'swipe',\n 'drag',\n 'fling',\n 'keyEvent',\n 'inputText',\n 'clearText',\n 'hideKeyboard',\n];\n\nconst num = (v: string | undefined): number | undefined => (v === undefined ? undefined : Number(v));\n\ninterface InputOpts extends TargetOpts {\n type: UiInputType;\n x?: string;\n y?: string;\n x2?: string;\n y2?: string;\n fx?: string;\n fy?: string;\n fx2?: string;\n fy2?: string;\n speed?: string;\n key?: string;\n text?: string;\n clear?: boolean;\n hideKeyboard?: boolean;\n device?: string;\n}\n\ninterface GestureOpts {\n waypoints: string;\n fractions?: boolean;\n holdStart?: string;\n holdEnd?: string;\n device?: string;\n}\n\nexport function registerInputCommand(program: Command): void {\n const input = program\n .command('input')\n .description(\n 'Inject a UI input event via uitest uiInput. Position it with --target (an on-screen element), ' +\n '--fx/--fy (0-1 fractions of the display, as in `dump layout` and the screenshot grid), or --x/--y (pixels).',\n )\n .addOption(new Option('--type <type>', 'Input type.').choices(INPUT_TYPES).makeOptionMandatory());\n addTargetOptions(input, 'Act on');\n input\n .option('--fx <fraction>', 'Start X as a 0-1 fraction of the display width.')\n .option('--fy <fraction>', 'Start Y as a 0-1 fraction of the display height.')\n .option('--fx2 <fraction>', 'End X fraction (swipe/drag/fling).')\n .option('--fy2 <fraction>', 'End Y fraction (swipe/drag/fling).')\n .option('--x <px>', 'X pixel (click/swipe start).')\n .option('--y <px>', 'Y pixel (click/swipe start).')\n .option('--x2 <px>', 'End X pixel (swipe/drag/fling).')\n .option('--y2 <px>', 'End Y pixel (swipe/drag/fling).')\n .option('--speed <px-per-s>', 'Velocity for swipe/drag/fling.')\n .option(\n '--key <key>',\n 'Key for keyEvent: Back/Home/Power, a name (Delete, Enter, Tab, Escape, MoveHome, MoveEnd, …), ' +\n 'a letter, a KeyCode id, or a combo like Ctrl+A.',\n )\n .option('--text <text>', 'Text for inputText.')\n .option('--clear', 'inputText: clear the field (Ctrl+A, Delete) before typing.')\n .option('--hide-keyboard', 'Dismiss the soft keyboard afterwards, if it is up.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: InputOpts) => {\n const { config, logger } = getRuntime();\n const result = await performInput({\n config,\n type: opts.type,\n target: selectorFrom(opts),\n targetIndex: targetIndexFrom(opts),\n fx: num(opts.fx),\n fy: num(opts.fy),\n fx2: num(opts.fx2),\n fy2: num(opts.fy2),\n pxX: num(opts.x),\n pxY: num(opts.y),\n pxX2: num(opts.x2),\n pxY2: num(opts.y2),\n speed: num(opts.speed),\n key: opts.key,\n text: opts.text,\n clear: opts.clear,\n hideKeyboard: opts.hideKeyboard,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.type === 'hideKeyboard') {\n logger.info(result.keyboardHidden ? 'Dismissed the keyboard.' : 'The keyboard was not shown.');\n return;\n }\n const at = result.x !== undefined ? ` at ${result.x},${result.y}` : '';\n const on = result.target ? ` on ${describeLayoutNode(result.target)}` : '';\n const kb = result.keyboardHidden ? ' (dismissed the keyboard)' : '';\n logger.info(`Sent ${opts.type}${at}${on}${kb}.`);\n });\n\n program\n .command('gesture')\n .description('Inject a multi-waypoint gesture. Waypoints are JSON: [{\"x\":..,\"y\":..,\"t\":..}] in pixels (or fractions with --fractions).')\n .requiredOption('--waypoints <json>', 'JSON array of {x,y,t} waypoints (t = ms from start).')\n .option('--fractions', 'Waypoint x/y are 0-1 fractions of the display instead of pixels.')\n .option('--hold-start <ms>', 'Leading press-hold before moving (best-effort: uses `uitest drag`).')\n .option('--hold-end <ms>', 'Trailing hold before lifting (no uitest equivalent; ignored).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: GestureOpts) => {\n const { config, logger } = getRuntime();\n let waypoints = JSON.parse(opts.waypoints) as Waypoint[];\n if (opts.fractions) {\n const bad = waypoints.find((w) => !(w.x >= 0 && w.x <= 1 && w.y >= 0 && w.y <= 1));\n if (bad) throw new Error(`With --fractions, waypoint x and y must be 0-1; got ${bad.x},${bad.y}.`);\n const display = await getDisplaySize(config, { deviceSerial: opts.device, logger });\n if (!display) throw new Error('Could not read the display size to convert fractions to pixels.');\n // 1.0 maps to the last pixel, not one past the edge.\n const px = (f: number, size: number): number => Math.min(size - 1, Math.round(f * size));\n waypoints = waypoints.map((w) => ({ ...w, x: px(w.x, display.width), y: px(w.y, display.height) }));\n }\n await sendGesture({\n config,\n waypoints,\n holdStartMs: num(opts.holdStart),\n holdEndMs: num(opts.holdEnd),\n deviceSerial: opts.device,\n logger,\n });\n logger.info('Gesture sent.');\n });\n}\n"],"mappings":"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","names":["Command","OniroError","path","path","createHarmonyOsSession","createHarmonyOsSession","path","path","ALL_SDKS","fs","path","ALL_SDKS","Option","Option","fs","path","describeLayoutNode","describeLayoutNode","shot","path","Option","describeLayoutNode","Option","describeLayoutNode","Command","OniroError"]}
1
+ {"version":3,"sources":["../src/bin/oniro-app.ts","../src/commands/sdk.ts","../src/adapters/logger.ts","../src/adapters/progress.ts","../src/adapters/config.ts","../src/lib/runtime.ts","../src/commands/cmdtools.ts","../src/commands/emulator.ts","../src/commands/build.ts","../src/commands/sign.ts","../src/commands/auth.ts","../src/commands/app.ts","../src/commands/create.ts","../src/lib/templateRoot.ts","../src/commands/templates.ts","../src/commands/reboot.ts","../src/commands/wait.ts","../src/lib/target.ts","../src/commands/watch.ts","../src/commands/screenshot.ts","../src/lib/screenshotImage.ts","../src/commands/dump.ts","../src/lib/layoutText.ts","../src/commands/devices.ts","../src/commands/file.ts","../src/commands/lint.ts","../src/commands/input.ts","../src/commands/logs.ts","../src/commands/hdc.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { OniroError } from '@oniroproject/core';\nimport { registerSdkCommand } from '../commands/sdk.js';\nimport { registerCmdToolsCommand } from '../commands/cmdtools.js';\nimport { registerEmulatorCommand } from '../commands/emulator.js';\nimport { registerBuildCommand } from '../commands/build.js';\nimport { registerSignCommand } from '../commands/sign.js';\nimport { registerAuthCommand } from '../commands/auth.js';\nimport { registerAppCommand } from '../commands/app.js';\nimport { registerCreateCommand } from '../commands/create.js';\nimport { registerTemplatesCommand } from '../commands/templates.js';\nimport { registerRebootCommand } from '../commands/reboot.js';\nimport { registerWaitCommand } from '../commands/wait.js';\nimport { registerWatchCommand } from '../commands/watch.js';\nimport { registerScreenshotCommand } from '../commands/screenshot.js';\nimport { registerDumpCommand } from '../commands/dump.js';\nimport { registerDevicesCommand } from '../commands/devices.js';\nimport { registerFileCommand } from '../commands/file.js';\nimport { registerLintCommand } from '../commands/lint.js';\nimport { registerInputCommand } from '../commands/input.js';\nimport { registerLogsCommand } from '../commands/logs.js';\nimport { registerHdcCommand } from '../commands/hdc.js';\n\ndeclare const __CLI_VERSION__: string;\nconst CLI_VERSION = __CLI_VERSION__;\n\nfunction buildProgram(): Command {\n const program = new Command()\n .name('oniro-app')\n .description(\n 'Cross-platform CLI for Oniro/OpenHarmony app development.\\n\\n' +\n 'Designed for non-interactive use (CI, scripts, agents): every command\\n' +\n 'takes explicit flags, results go to stdout, progress/logs go to stderr,\\n' +\n 'and a non-zero exit code indicates failure.',\n )\n .version(CLI_VERSION)\n .showHelpAfterError()\n // Lets `hdc` pass its arguments through untouched; global options go before the command.\n .enablePositionalOptions();\n\n registerSdkCommand(program);\n registerCmdToolsCommand(program);\n registerEmulatorCommand(program);\n registerBuildCommand(program);\n registerSignCommand(program);\n registerAuthCommand(program);\n registerAppCommand(program);\n registerCreateCommand(program);\n registerTemplatesCommand(program);\n registerRebootCommand(program);\n registerWaitCommand(program);\n registerWatchCommand(program);\n registerScreenshotCommand(program);\n registerDumpCommand(program);\n registerDevicesCommand(program);\n registerFileCommand(program);\n registerLintCommand(program);\n registerInputCommand(program);\n registerLogsCommand(program);\n registerHdcCommand(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n const message = err instanceof OniroError ? err.message : err instanceof Error ? err.message : String(err);\n process.stderr.write(`[error] ${message}\\n`);\n if (process.env.ONIRO_DEBUG === '1' && err instanceof Error && err.stack) {\n process.stderr.write(`${err.stack}\\n`);\n }\n process.exit(1);\n }\n}\n\nvoid main();\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n downloadAndInstallSdk,\n getOsFolder,\n getSdkRootDir,\n getSupportedSdksForUi,\n removeSdk,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerSdkCommand(program: Command): void {\n const sdk = program.command('sdk').description('Manage OpenHarmony SDK installs.');\n\n sdk\n .command('install <version>')\n .description('Download and install an OpenHarmony SDK. Skips if already installed.')\n .option('--force', 'Reinstall even if the SDK is already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for download/extract temporaries (default: ONIRO_TMP_DIR, else .oniro-tmp next to ' +\n 'the install target). Use this when that filesystem is short on space.',\n )\n .action(async (version: string, opts: { force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n const release = ALL_SDKS.find((s) => s.version === version);\n if (!release) {\n throw new Error(\n `Unknown SDK version \"${version}\". Known: ${ALL_SDKS.map((s) => s.version).join(', ')}`,\n );\n }\n const sdkInstallDir = path.join(getSdkRootDir(config), getOsFolder(), release.api);\n if (fs.existsSync(sdkInstallDir) && !opts.force) {\n logger.info(\n `SDK ${release.version} (api ${release.api}) already installed at ${sdkInstallDir}; pass --force to reinstall.`,\n );\n return;\n }\n logger.info(`Installing OpenHarmony SDK ${release.version} (api ${release.api})...`);\n await downloadAndInstallSdk({\n config,\n version: release.version,\n api: release.api,\n progress,\n logger,\n tmpDir: opts.tmpDir,\n });\n logger.info('SDK installed.');\n });\n\n sdk\n .command('list')\n .description('List known SDK versions and whether they are installed on this machine.')\n .option('--json', 'Emit machine-readable JSON instead of a table.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const sdks = getSupportedSdksForUi(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(sdks, null, 2)}\\n`);\n return;\n }\n const rows = sdks.map((s) => `${s.installed ? '*' : ' '} ${s.version.padEnd(8)} api ${s.api}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n\n sdk\n .command('remove <api>')\n .description('Remove an installed SDK by API level (e.g. 18, 20).')\n .action((api: string) => {\n const { config, logger } = getRuntime();\n const removed = removeSdk(config, api);\n if (!removed) {\n logger.warn(`No SDK with api ${api} found under the configured SDK root.`);\n process.exit(1);\n }\n logger.info(`Removed SDK api ${api}.`);\n });\n}\n","import type { Logger } from '@oniroproject/core';\n\n/**\n * Stderr-only logger. All diagnostic output goes to stderr so command stdout\n * stays clean for machine consumers (json results, paths, etc.).\n *\n * Debug lines are suppressed unless `ONIRO_DEBUG=1`.\n */\nexport function createCliLogger(): Logger {\n const debugEnabled = process.env.ONIRO_DEBUG === '1' || process.env.ONIRO_DEBUG === 'true';\n return {\n debug(m) {\n if (debugEnabled) process.stderr.write(`[debug] ${m}\\n`);\n },\n info(m) {\n process.stderr.write(`${m}\\n`);\n },\n warn(m) {\n process.stderr.write(`[warn] ${m}\\n`);\n },\n error(m) {\n process.stderr.write(`[error] ${m}\\n`);\n },\n };\n}\n","import type { ProgressReporter } from '@oniroproject/core';\n\n/**\n * Line-per-update progress reporter, designed for machine consumers and log scrapers.\n * Format: `[progress NN%] message` (or `[progress] message` if no percent is known).\n * Updates that don't change the percent and don't carry a message are suppressed\n * to keep output volume reasonable on chatty downloads.\n */\nexport function createCliProgress(): ProgressReporter {\n let total = 0;\n let lastEmitted = -1;\n let lastMessage = '';\n return {\n report({ message, increment }) {\n if (typeof increment === 'number') total = Math.min(100, total + increment);\n const pct = total > 0 ? Math.round(total) : null;\n const msg = message ?? lastMessage;\n // Drop redundant updates: same message, same percent.\n if (pct === lastEmitted && msg === lastMessage) return;\n const prefix = pct === null ? '[progress]' : `[progress ${pct}%]`;\n process.stderr.write(`${prefix} ${msg}\\n`);\n lastEmitted = pct ?? lastEmitted;\n if (message) lastMessage = message;\n },\n };\n}\n","import * as os from 'node:os';\nimport type { ConfigKey, ConfigProvider } from '@oniroproject/core';\n\n/**\n * Maps a core ConfigKey to its environment variable name.\n * Convention: ONIRO_<UPPER_SNAKE>.\n */\nconst ENV_VAR_BY_KEY: Record<ConfigKey, string> = {\n sdkRootDir: 'ONIRO_SDK_ROOT_DIR',\n cmdToolsPath: 'ONIRO_CMD_TOOLS_PATH',\n hdcPath: 'ONIRO_HDC',\n emulatorDir: 'ONIRO_EMULATOR_DIR',\n hapPath: 'ONIRO_HAP_PATH',\n cmdToolsUrlLinux: 'ONIRO_CMD_TOOLS_URL_LINUX',\n cmdToolsUrlWindows: 'ONIRO_CMD_TOOLS_URL_WINDOWS',\n cmdToolsUrlMac: 'ONIRO_CMD_TOOLS_URL_MAC',\n emulatorUrl: 'ONIRO_EMULATOR_URL',\n tmpDir: 'ONIRO_TMP_DIR',\n sdkUrlBase: 'ONIRO_SDK_URL_BASE',\n applicationCertPath: 'ONIRO_APPLICATION_CERT_PATH',\n harmonyosSdkPath: 'ONIRO_HARMONYOS_SDK_PATH',\n harmonyosAuthDir: 'ONIRO_HARMONYOS_AUTH_DIR',\n harmonyosSigningDir: 'ONIRO_HARMONYOS_SIGNING_DIR',\n};\n\n/**\n * Reads configuration from environment variables (ONIRO_*). Returns the fallback\n * when the variable is unset or empty. Expands `${userHome}` to the user's home\n * directory for parity with the VS Code extension's `${userHome}` expansion.\n */\nexport function createEnvConfig(env: NodeJS.ProcessEnv = process.env): ConfigProvider {\n return {\n get<T extends string | number | boolean>(key: ConfigKey, fallback: T): T {\n const envName = ENV_VAR_BY_KEY[key];\n const raw = env[envName];\n if (raw === undefined || raw === '') return fallback;\n const expanded = raw.includes('${userHome}')\n ? raw.replace(/\\$\\{userHome\\}/g, os.homedir())\n : raw;\n return expanded as unknown as T;\n },\n };\n}\n","import type { ConfigProvider, Logger, ProgressReporter } from '@oniroproject/core';\nimport { createCliLogger } from '../adapters/logger.js';\nimport { createCliProgress } from '../adapters/progress.js';\nimport { createEnvConfig } from '../adapters/config.js';\n\nexport interface CliRuntime {\n logger: Logger;\n config: ConfigProvider;\n progress: ProgressReporter;\n}\n\nlet cached: CliRuntime | null = null;\n\n/**\n * Build (and cache) the per-process runtime used by every command. Tests can\n * override the cached runtime via `setRuntime` to inject mocks.\n */\nexport function getRuntime(): CliRuntime {\n if (!cached) {\n cached = {\n logger: createCliLogger(),\n config: createEnvConfig(),\n progress: createCliProgress(),\n };\n }\n return cached;\n}\n\nexport function setRuntime(runtime: CliRuntime | null): void {\n cached = runtime;\n}\n","import { Command } from 'commander';\nimport { getCmdToolsStatus, installCmdTools, isCmdToolsInstalled, removeCmdTools } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerCmdToolsCommand(program: Command): void {\n const cmdtools = program.command('cmdtools').description('Manage OpenHarmony command-line tools.');\n\n cmdtools\n .command('install')\n .description('Install the OpenHarmony command-line tools (hvigorw, ohpm, hdc). Skips if already installed.')\n .option('--from-zip <path>', 'Install from a local ZIP instead of downloading.')\n .option('--force', 'Reinstall even if the tools are already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for download/extract temporaries (default: ONIRO_TMP_DIR, else .oniro-tmp next to ' +\n 'the install target). Use this when that filesystem is short on space.',\n )\n .action(async (opts: { fromZip?: string; force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n if (isCmdToolsInstalled(config) && !opts.force) {\n logger.info('Command-line tools already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing OpenHarmony command-line tools...');\n await installCmdTools({ config, progress, logger, localZipPath: opts.fromZip, tmpDir: opts.tmpDir });\n logger.info('Command-line tools installed.');\n });\n\n cmdtools\n .command('status')\n .description(\n 'Report whether the command-line tools are installed, their version and flavour (HarmonyOS or ' +\n 'OpenHarmony), and the hdc binary every device command uses.',\n )\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const { config } = getRuntime();\n const status = getCmdToolsStatus(config);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${status.status}\\n`);\n process.stdout.write(`path: ${status.path}\\n`);\n if (status.flavour) process.stdout.write(`flavour: ${status.flavour}\\n`);\n process.stdout.write(`hdc: ${status.hdc.path}${status.hdc.exists ? '' : ' (missing)'}\\n`);\n if (!status.installed) process.exit(1);\n });\n\n cmdtools\n .command('remove')\n .description('Delete the configured command-line tools directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeCmdTools(config);\n logger.info('Command-line tools removed.');\n });\n}\n","import { Command } from 'commander';\nimport {\n attemptHdcConnection,\n getEmulatorStatus,\n installEmulator,\n isEmulatorInstalled,\n removeEmulator,\n startEmulator,\n stopEmulator,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerEmulatorCommand(program: Command): void {\n const emu = program.command('emulator').description('Manage the Oniro emulator.');\n\n emu\n .command('install')\n .description('Download and install the Oniro emulator (QEMU-based). Skips if already installed.')\n .option('--force', 'Reinstall even if the emulator is already present.')\n .option(\n '--tmp-dir <path>',\n 'Directory for the downloaded ZIP (default: ONIRO_TMP_DIR, else .oniro-tmp next to the ' +\n 'install target). Use this when that filesystem is short on space.',\n )\n .action(async (opts: { force?: boolean; tmpDir?: string }) => {\n const { config, logger, progress } = getRuntime();\n if (isEmulatorInstalled(config) && !opts.force) {\n logger.info('Emulator already installed; pass --force to reinstall.');\n return;\n }\n logger.info('Installing Oniro emulator...');\n await installEmulator({ config, progress, logger, tmpDir: opts.tmpDir });\n logger.info('Emulator installed.');\n });\n\n emu\n .command('start')\n .description('Start the Oniro emulator via the bundled launcher (run.sh / run.bat). Detaches so the CLI can exit while the emulator keeps running.')\n .option('--headless', 'Launch headless (VNC + telnet serial, no local window). Required in CI.')\n .option('--log <path>', 'Redirect launcher stdout/stderr to this file. Defaults to discarding output.')\n .option('--wait-for-hdc <seconds>', 'Wait up to N seconds for hdc to connect. 0 = do not wait.', (v) => parseInt(v, 10), 0)\n .option('--connect <host:port>', 'Override the launcher\\'s hdc port-forward bind address. Pass 0.0.0.0:55555 on hosts where QEMU refuses to bind 127.0.0.1 (some CI runners).')\n .action(async (opts: { headless?: boolean; log?: string; waitForHdc: number; connect?: string }) => {\n const { config, logger } = getRuntime();\n await startEmulator({\n config,\n logger,\n headless: opts.headless === true,\n logFile: opts.log,\n waitForHdcSeconds: opts.waitForHdc,\n connect: opts.connect,\n });\n logger.info('Emulator start command complete.');\n });\n\n emu\n .command('status')\n .description(\n 'Report whether the Oniro emulator is installed, running, and connected to hdc, without starting it. ' +\n 'Exits 1 when it is not installed.',\n )\n .option('--address <addr>', 'hdc address the emulator listens on', '127.0.0.1:55555')\n .option('--json', 'Emit machine-readable JSON.')\n .action(async (opts: { address: string; json?: boolean }) => {\n const { config, logger } = getRuntime();\n const status = await getEmulatorStatus(config, { address: opts.address, logger });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n } else {\n process.stdout.write(\n `installed: ${status.installed ? 'yes' : 'no'} (${status.dir})\\n` +\n `running: ${status.running ? 'yes' : 'no'}\\n` +\n `connected: ${status.connected ? 'yes' : 'no'} (${status.address})\\n`,\n );\n }\n if (!status.installed) process.exitCode = 1;\n });\n\n emu\n .command('stop')\n .description('Kill running emulator processes.')\n .action(async () => {\n const { logger } = getRuntime();\n await stopEmulator(logger);\n logger.info('Emulator stopped.');\n });\n\n emu\n .command('connect')\n .description('Attempt to connect hdc to the emulator.')\n .option('--address <addr>', 'hdc address to connect to', '127.0.0.1:55555')\n .action(async (opts: { address: string }) => {\n const { config, logger } = getRuntime();\n const ok = await attemptHdcConnection(config, opts.address, logger);\n if (!ok) {\n logger.error(`Could not connect hdc to ${opts.address}.`);\n process.exit(1);\n }\n logger.info(`hdc connected to ${opts.address}.`);\n });\n\n emu\n .command('remove')\n .description('Delete the configured emulator directory.')\n .action(() => {\n const { config, logger } = getRuntime();\n removeEmulator(config);\n logger.info('Emulator removed.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { SdkNotInstalledError, buildHap, downloadAndInstallSdk } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface BuildOpts {\n product: string;\n module?: string;\n mode?: string;\n task: string;\n deps: boolean;\n parallel: boolean;\n installSdk?: boolean;\n json?: boolean;\n}\n\nexport function registerBuildCommand(program: Command): void {\n program\n .command('build [project-dir]')\n .description(\n 'Build an OpenHarmony or HarmonyOS app via hvigorw. Defaults to the current directory. ' +\n 'Projects declaring runtimeOS \"HarmonyOS\" build against the HarmonyOS SDK (ONIRO_HARMONYOS_SDK_PATH or an installed DevEco Studio). ' +\n 'An OpenHarmony project fails early, naming the release to install, when the SDK for its compileSdkVersion is missing.',\n )\n .option('--product <product>', 'hvigor product name', 'default')\n .option('--module <module>', 'restrict the build to a specific module')\n .option('--mode <mode>', 'hvigor build mode (e.g. release, debug)')\n .option('--task <task>', 'hvigor task to run', 'assembleHap')\n .option('--no-deps', 'skip the automatic `ohpm install --all` when oh_modules/ is missing')\n .option('--no-parallel', 'build modules serially (default: parallel)')\n .option('--install-sdk', 'install the OpenHarmony SDK the project compiles against when it is missing, then build')\n .option('--json', 'emit the build result (discovered HAPs, warnings) as JSON')\n .action(async (projectDir: string | undefined, opts: BuildOpts) => {\n const { config, logger, progress } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Building project at ${dir}...`);\n const build = () =>\n buildHap({\n config,\n projectDir: dir,\n product: opts.product,\n module: opts.module,\n mode: opts.mode,\n task: opts.task,\n autoInstallDeps: opts.deps,\n parallel: opts.parallel,\n logger,\n // The logger already echoes spawn output; this hook is for streaming to other UIs.\n onOutput: () => {},\n });\n let result;\n try {\n result = await build();\n } catch (err) {\n if (!(err instanceof SdkNotInstalledError && err.version && opts.installSdk)) throw err;\n logger.info(`Installing OpenHarmony SDK ${err.version} (api ${err.api}), which the project compiles against...`);\n await downloadAndInstallSdk({ config, version: err.version, api: err.api, progress, logger });\n result = await build();\n }\n for (const w of result.warnings) logger.warn(w);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n }\n logger.info('Build complete.');\n });\n}\n","import { Command, Option } from 'commander';\nimport * as path from 'node:path';\nimport {\n APL_VALUES,\n APP_FEATURE_VALUES,\n OniroError,\n createHarmonyOsSession,\n detectRuntimeOs,\n generateSigningConfigs,\n harmonyOsAutoSign,\n prepareSigning,\n getOhosBaseSdkHome,\n type Apl,\n type AppFeature,\n type SigningPasswords,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nfunction parseAclsList(value: string): string[] {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nexport function registerSignCommand(program: Command): void {\n program\n .command('sign [project-dir]')\n .description(\n [\n 'Generate signing keys, certificates, and signingConfigs for an OpenHarmony project.',\n 'Requires java on PATH. The generated profile uses the SDK\\'s built-in development',\n 'cert (issuer=pki_internal) and its bundled validity window — dev/local builds only.',\n 'Overwrites the `signingConfigs` block in build-profile.json5 (other keys preserved).',\n 'HarmonyOS projects need --harmonyos instead, which has AppGallery Connect issue the',\n 'certificate and profile for a signed-in Huawei account (`oniro-app auth login`).',\n ].join(' '),\n )\n .addOption(\n new Option(\n '--apl <level>',\n 'Ability Privilege Level written into the profile. Apps that request permissions above `normal` (e.g. ohos.permission.GET_WIFI_INFO_INTERNAL) need system_basic or system_core, which also switches the HAP-signing key to \"OpenHarmony Application Release\".',\n )\n .choices([...APL_VALUES])\n .default('normal'),\n )\n .addOption(\n new Option(\n '--app-feature <feature>',\n 'App feature written into the profile. Defaults: hos_normal_app for apl=normal; hos_system_app for apl=system_basic/system_core.',\n ).choices([...APP_FEATURE_VALUES]),\n )\n .addOption(\n new Option(\n '--acls <list>',\n 'Comma-separated permission names to write into the profile\\'s acls.allowed-acls. Required for apps that request permissions above their apl (e.g. a system_basic app requesting ohos.permission.CAPTURE_SCREEN). Example: --acls ohos.permission.REBOOT,ohos.permission.INJECT_INPUT_EVENT',\n ).argParser(parseAclsList),\n )\n .addOption(\n new Option(\n '--app-privilege-capabilities <list>',\n 'Comma-separated privileges to write into the profile\\'s app-privilege-capabilities. An app that declares a privileged extension ability (e.g. an AccessibilityExtensionAbility) needs AllowAppUsePrivilegeExtension, else install fails with 9568344 \"not allow use privilege extension\". Others include AllowAppMultiProcess and AllowAppDesktopIconHide.',\n ).argParser(parseAclsList),\n )\n .option(\n '--harmonyos',\n 'Sign a HarmonyOS project through AppGallery Connect. Needs `oniro-app auth login`, and a connected device unless the team already has devices registered.',\n )\n .option('--team-id <id>', 'With --harmonyos: the AGC team to sign under. Default: the account\\'s own (`oniro-app auth team list`).')\n .option('--product <name>', 'With --harmonyos: the product to sign. Default `default`.')\n .option('--force', 'With --harmonyos: regenerate the certificate and profile even when they are still valid.')\n .option('--bootstrap', 'No-op if signing material is already present; otherwise generate it.')\n .option('--store-password <pwd>', 'Keystore store password (default 123456 — the SDK keystore password).')\n .option('--key-password <pwd>', 'Keystore key password (default 123456 — the SDK keystore password).')\n .action(\n async (\n projectDir: string | undefined,\n opts: {\n apl: Apl;\n appFeature?: AppFeature;\n acls?: string[];\n appPrivilegeCapabilities?: string[];\n bootstrap?: boolean;\n storePassword?: string;\n keyPassword?: string;\n harmonyos?: boolean;\n teamId?: string;\n product?: string;\n force?: boolean;\n },\n ) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n\n if (opts.harmonyos) {\n const result = await harmonyOsAutoSign({\n config,\n session: createHarmonyOsSession({ config, logger }),\n projectDir: dir,\n productName: opts.product,\n teamId: opts.teamId,\n force: opts.force,\n logger,\n });\n logger.info(`Signing configs ready for ${result.bundleName} (profile names ${result.deviceIds.length} device(s)).`);\n return;\n }\n // The OpenHarmony development certificate cannot sign for a HarmonyOS device.\n if (detectRuntimeOs(dir, opts.product) === 'HarmonyOS') {\n throw new OniroError(\n `${dir} targets HarmonyOS, which needs a certificate from AppGallery Connect: run \\`oniro-app auth login\\` once, then \\`oniro-app sign --harmonyos\\`.`,\n );\n }\n const passwords: SigningPasswords | undefined =\n opts.storePassword || opts.keyPassword\n ? { store: opts.storePassword ?? '123456', key: opts.keyPassword ?? '123456' }\n : undefined;\n\n if (opts.bootstrap) {\n const result = prepareSigning({\n config,\n projectDir: dir,\n apl: opts.apl,\n appFeature: opts.appFeature,\n acls: opts.acls,\n appPrivilegeCapabilities: opts.appPrivilegeCapabilities,\n passwords,\n logger,\n });\n logger.info(result.source === 'present' ? 'Signing material already present.' : 'Signing configs generated.');\n return;\n }\n\n const sdkHome = getOhosBaseSdkHome(config);\n logger.info(`Generating signing configs in ${dir} using SDK at ${sdkHome}...`);\n generateSigningConfigs({\n projectDir: dir,\n sdkHome,\n apl: opts.apl,\n appFeature: opts.appFeature,\n acls: opts.acls,\n appPrivilegeCapabilities: opts.appPrivilegeCapabilities,\n passwords,\n logger,\n });\n logger.info('Signing configs generated.');\n },\n );\n}\n","import { Command } from 'commander';\nimport { HUAWEI_SITES, createHarmonyOsSession, type HarmonyOsSession } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\n/** A session bound to the CLI runtime. The sign-in URL goes to stderr for headless hosts. */\nfunction session(): HarmonyOsSession {\n const { config, logger } = getRuntime();\n return createHarmonyOsSession({\n config,\n logger,\n onLoginUrl: (url) => process.stderr.write(`Opening the Huawei sign-in page. If no browser opens, visit:\\n ${url}\\n`),\n });\n}\n\nexport function registerAuthCommand(program: Command): void {\n const auth = program\n .command('auth')\n .description(\n 'Sign in to a Huawei developer account, which HarmonyOS signing (`oniro-app sign --harmonyos`) needs. ' +\n 'OpenHarmony signing needs no account. The token is stored encrypted under ONIRO_HARMONYOS_AUTH_DIR ' +\n '(default ~/.oniro/harmonyos).',\n );\n\n auth\n .command('login')\n .description('Sign in through the browser, which redirects back to a loopback port on this machine.')\n .option('--timeout <seconds>', 'How long to wait for the browser sign-in. Default 600.', (v) => Number(v))\n .action(async (opts: { timeout?: number }) => {\n const user = await session().login(opts.timeout ? { timeoutMs: Math.max(1, opts.timeout) * 1000 } : undefined);\n process.stdout.write(`${user.userName || user.userId}\\n`);\n });\n\n auth\n .command('logout')\n .description('Sign out and delete the stored token.')\n .action(async () => {\n const signedOut = await session().logout();\n getRuntime().logger.info(signedOut ? 'Signed out.' : 'Not signed in; nothing to do.');\n });\n\n auth\n .command('status')\n .description('Show the signed-in account. Exits non-zero when not signed in.')\n .option('--json', 'Emit the account details as JSON.')\n .action(async (opts: { json?: boolean }) => {\n const s = session();\n // Refreshed: a stale access token makes the agreement check fail.\n const user = await s.getUserInfo({ refresh: true });\n if (!user) {\n process.stderr.write('Not signed in. Run `oniro-app auth login`.\\n');\n process.exitCode = 1;\n return;\n }\n // Without real-name verification, the developer agreement is what allows signing.\n const agreement = user.isRealName ? null : await s.getDeveloperAgreement(user);\n if (opts.json) {\n const { userId, userName, countryCode, siteCode, isRealName } = user;\n const agcBaseUrl = HUAWEI_SITES[siteCode].agcBaseUrl;\n const status = { userId, userName, countryCode, site: siteCode, agcBaseUrl, isRealName, developerAgreement: agreement, tokenPath: s.tokenPath };\n process.stdout.write(`${JSON.stringify(status, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${user.userName || user.userId} (${user.userId}) [${user.siteCode}]\\n`);\n if (agreement && !(agreement.signed && agreement.latest)) {\n process.stderr.write(\n '[warn] This account has neither real-name verification nor the current HUAWEI Developer Basic Service Agreement accepted, so AppGallery Connect will not issue signing material. Accept the agreement in AppGallery Connect or DevEco Studio.\\n',\n );\n }\n });\n\n auth\n .command('team')\n .description('AGC teams this account belongs to.')\n .command('list')\n .description('List the AGC teams this account belongs to, for `oniro-app sign --harmonyos --team-id <id>`.')\n .option('--json', 'Emit the team list as JSON.')\n .action(async (opts: { json?: boolean }) => {\n const teams = await session().listTeams();\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(teams, null, 2)}\\n`);\n return;\n }\n for (const t of teams) process.stdout.write(`${t.id}\\t${t.name}\\n`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { installApp, launchApp, uninstallApp, forceStop, applyChanges, getBundleName } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface ApplyOpts {\n bundle?: string;\n module?: string;\n hap?: string;\n installedHap?: string;\n system?: boolean;\n allowUninstall?: boolean;\n device?: string;\n json?: boolean;\n}\n\nexport function registerAppCommand(program: Command): void {\n const app = program.command('app').description('Install, launch, and manage built apps on a connected device/emulator.');\n\n app\n .command('install [project-dir-or-hap]')\n .description(\n 'Install a built .hap on the connected device/emulator via hdc. Takes a project dir (default: the ' +\n 'current one), whose newest signed HAP is installed, else its unsigned one, or a .hap file. Fails ' +\n 'when the bundle manager rejects the HAP, and says how to sign when a target refuses an unsigned one.',\n )\n .option('--hap <path>', 'Override the .hap path (relative to project-dir or absolute).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (target: string | undefined, opts: { hap?: string; device?: string }) => {\n const { config, logger } = getRuntime();\n const isHap = target !== undefined && /\\.hap$/i.test(target);\n const dir = isHap ? process.cwd() : path.resolve(target ?? process.cwd());\n const hapPath = isHap ? path.resolve(target) : opts.hap;\n logger.info(`Installing ${hapPath ?? `app from ${dir}`}...`);\n const result = await installApp({ config, projectDir: dir, hapPath, deviceSerial: opts.device, logger });\n logger.info(`Installed ${result.hapPath}.`);\n });\n\n app\n .command('launch [project-dir]')\n .description(\n 'Launch an app on the connected device/emulator. Project mode (default): resolves ' +\n 'bundle + main ability from the project. Bundle mode (--bundle): launch an ' +\n 'already-installed app by bundle name, no project needed.',\n )\n .option('--bundle <bundle>', 'Launch an already-installed app by bundle name (no project needed).')\n .option('--module <module>', 'Module folder name (project mode).', 'entry')\n .option('--ability <name>', 'Explicit ability to launch (defaults to the module mainElement in project mode, or the installed bundle main ability in --bundle mode).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (projectDir: string | undefined, opts: { bundle?: string; module: string; ability?: string; device?: string }) => {\n const { config, logger } = getRuntime();\n if (opts.bundle) {\n logger.info(`Launching installed bundle ${opts.bundle}...`);\n await launchApp({ config, bundleName: opts.bundle, abilityName: opts.ability, deviceSerial: opts.device, logger });\n } else {\n const dir = path.resolve(projectDir ?? process.cwd());\n logger.info(`Launching app from ${dir}...`);\n await launchApp({ config, projectDir: dir, moduleName: opts.module, abilityName: opts.ability, deviceSerial: opts.device, logger });\n }\n logger.info('App launched.');\n });\n\n app\n .command('apply [project-dir]')\n .description(\n 'Install a HAP and verify the running process took the change. Handles sign-info mismatch, ' +\n 'asset-cache invalidation, and persistent-bundle restart.',\n )\n .option('--bundle <bundle>', 'Bundle name to apply changes to. Defaults to the bundleName in the project AppScope/app.json5.')\n .option('--module <module>', 'Module to resolve the HAP from (multi-module projects).')\n .option('--hap <path>', 'Explicit .hap path (relative to project-dir or absolute).')\n .option('--installed-hap <path>', 'Local path to the currently-installed HAP, to enable the asset-cache reboot.')\n .option('--system', 'Treat as a persistent/system bundle (refuses uninstall on sign-info mismatch).')\n .option('--allow-uninstall', 'Permit uninstalling a system bundle on sign-info mismatch (dangerous).')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'Emit the result as JSON.')\n .action(async (projectDir: string | undefined, opts: ApplyOpts) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n const bundle = opts.bundle ?? getBundleName(dir);\n const result = await applyChanges({\n config,\n bundle,\n hapPath: opts.hap,\n projectDir: dir,\n module: opts.module,\n installedHapPath: opts.installedHap,\n isSystemBundle: opts.system,\n allowUninstall: opts.allowUninstall,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n logger.info(\n `apply: method=${result.method} pid ${result.preInstallPid ?? '-'} -> ${result.postInstallPid ?? '-'}` +\n `${result.cacheCleared ? ' (cache cleared)' : ''}`,\n );\n }\n });\n\n app\n .command('uninstall <bundle>')\n .description('Uninstall an app by bundle name.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (bundle: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await uninstallApp({ config, bundle, deviceSerial: opts.device, logger });\n logger.info(`Uninstalled ${bundle}.`);\n });\n\n app\n .command('stop <bundle>')\n .description('Force-stop an app by bundle name.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (bundle: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await forceStop({ config, bundle, deviceSerial: opts.device, logger });\n logger.info(`Stopped ${bundle}.`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport {\n ALL_SDKS,\n createScaffold,\n isValidBundleName,\n isValidProjectName,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\ninterface CreateOpts {\n name: string;\n bundle: string;\n location: string;\n sdk: string;\n template: string;\n module?: string;\n overwrite?: boolean;\n}\n\nexport function registerCreateCommand(program: Command): void {\n program\n .command('create')\n .description('Scaffold a new Oniro/OpenHarmony or HarmonyOS app from a template. All flags are required (non-interactive).')\n .requiredOption('--name <name>', 'Project folder name (letters, digits, ._- only)')\n .requiredOption('--bundle <bundleName>', 'Bundle name in reverse-DNS form, e.g. com.example.myapp')\n .requiredOption('--location <dir>', 'Parent directory where the new project folder will be created')\n .requiredOption('--sdk <api>', 'Target SDK API level (e.g. 18, 20)')\n .option('--template <id>', 'Template id', 'EmptyAbility')\n .option('--module <name>', 'Module folder name (defaults to the template default, usually `entry`)')\n .option('--overwrite', 'Replace the destination if it already exists')\n .action(async (opts: CreateOpts) => {\n const { config, logger } = getRuntime();\n\n if (!isValidProjectName(opts.name)) {\n throw new Error(`Invalid --name '${opts.name}'. Use letters/numbers/._- and no slashes.`);\n }\n if (!isValidBundleName(opts.bundle)) {\n throw new Error(`Invalid --bundle '${opts.bundle}'. Example: com.example.myapp`);\n }\n const sdkApi = Number(opts.sdk);\n if (!Number.isFinite(sdkApi)) {\n throw new Error(`--sdk must be a numeric api level. Known: ${ALL_SDKS.map((s) => s.api).join(', ')}`);\n }\n\n const templateRoot = getBundledTemplateRoot();\n const result = await createScaffold({\n config,\n templateId: opts.template,\n projectName: opts.name,\n bundleName: opts.bundle,\n location: path.resolve(opts.location),\n sdkApi,\n moduleName: opts.module,\n templateRoot,\n overwrite: opts.overwrite,\n logger,\n });\n\n logger.info(`Project created at ${result.projectDir}`);\n process.stdout.write(`${result.projectDir}\\n`);\n });\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Resolve the bundled `templates/` directory shipped inside this CLI package.\n *\n * The CLI's `dist/oniro-app.js` lives at `<pkg>/dist/oniro-app.js` after build\n * and the templates ship at `<pkg>/templates/`. During development the entrypoint\n * lives at `<pkg>/src/bin/oniro-app.ts` so we also try `../../templates` from there.\n */\nexport function getBundledTemplateRoot(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../templates'), // dist/oniro-app.js → ../templates\n path.resolve(here, '../../templates'), // src/bin/oniro-app.ts → ../../templates\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n // Return the most likely path even if it doesn't exist yet; createScaffold will\n // surface a clear error from there.\n return candidates[0]!;\n}\n","import { Command } from 'commander';\nimport { listTemplates } from '@oniroproject/core';\nimport { getBundledTemplateRoot } from '../lib/templateRoot.js';\n\nexport function registerTemplatesCommand(program: Command): void {\n const templates = program.command('templates').description('Inspect the templates bundled with this CLI.');\n\n templates\n .command('list')\n .description('List available project templates.')\n .option('--json', 'Emit machine-readable JSON.')\n .action((opts: { json?: boolean }) => {\n const root = getBundledTemplateRoot();\n const list = listTemplates(root);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(list, null, 2)}\\n`);\n return;\n }\n if (list.length === 0) {\n process.stdout.write('No templates available.\\n');\n return;\n }\n const rows = list.map((t) => `${t.id.padEnd(20)} ${t.label.padEnd(24)} ${t.description}`);\n process.stdout.write(`${rows.join('\\n')}\\n`);\n });\n}\n","import { Command, Option } from 'commander';\nimport { reboot } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerRebootCommand(program: Command): void {\n program\n .command('reboot')\n .description('Reboot the connected device/emulator.')\n .addOption(\n new Option('--mode <mode>', 'Reboot target.').choices(['system', 'bootloader', 'recovery']).default('system'),\n )\n .option('--wait-bundle <bundle>', 'After a system reboot, wait until this bundle is running again.')\n .option('--timeout <ms>', 'Max time to wait for the bundle, ms.', '180000')\n .option('--device <serial>', 'Target device serial.')\n .action(\n async (opts: {\n mode: 'system' | 'bootloader' | 'recovery';\n waitBundle?: string;\n timeout: string;\n device?: string;\n }) => {\n const { config, logger } = getRuntime();\n logger.info(`Rebooting device (${opts.mode})...`);\n await reboot({\n config,\n mode: opts.mode,\n waitForBundle: opts.waitBundle,\n timeoutMs: Number(opts.timeout),\n deviceSerial: opts.device,\n logger,\n });\n logger.info('Reboot complete.');\n },\n );\n}\n","import { Command } from 'commander';\nimport { waitForLog, waitForBoot, waitForBundle, waitForTarget, describeLayoutNode } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { addTargetOptions, selectorFrom, type TargetOpts } from '../lib/target.js';\n\ninterface WaitOpts extends TargetOpts {\n log?: string;\n boot?: boolean;\n bundle?: string;\n pidOf?: string;\n domain?: string;\n gone?: boolean;\n interval: string;\n timeout: string;\n device?: string;\n json?: boolean;\n}\n\nexport function registerWaitCommand(program: Command): void {\n const wait = program\n .command('wait')\n .description(\n 'Wait for a device condition: a log line (--log), boot (--boot), a bundle to start (--bundle), ' +\n 'or an on-screen element (--target / --target-id / --target-type).',\n )\n .option('--log <pattern>', 'Resolve when a hilog line (tag: message) matches this regex.')\n .option('--boot', 'Resolve when the device is reachable (optionally also --pid-of).')\n .option('--bundle <bundle>', 'With --log: filter to this bundle. Alone: wait until this bundle is running.')\n .option('--pid-of <name>', 'With --boot: also require this process to have a pid.')\n .option('--domain <domain>', 'With --log: hilog domain filter (e.g. 0xD003900).');\n addTargetOptions(wait, 'Resolve when', { index: false });\n wait\n .option('--gone', 'With --target*: resolve when no uncovered element matches any more.')\n .option('--interval <ms>', 'With --target*: poll interval, ms (each poll is a layout dump).', '500')\n .option('--timeout <ms>', 'Max wait, ms.', '30000')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'With --log or --target*: emit the matched entry/element as JSON.')\n .action(async (opts: WaitOpts) => {\n const { config, logger } = getRuntime();\n const timeoutMs = Number(opts.timeout);\n const selector = selectorFrom(opts);\n\n if (opts.log) {\n const entry = await waitForLog({\n config,\n pattern: new RegExp(opts.log),\n timeoutMs,\n bundle: opts.bundle,\n domain: opts.domain,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) process.stdout.write(`${JSON.stringify(entry, null, 2)}\\n`);\n else logger.info(`matched: ${entry.tag}: ${entry.message}`);\n return;\n }\n if (opts.boot) {\n await waitForBoot({ config, untilPidOf: opts.pidOf, timeoutMs, deviceSerial: opts.device, logger });\n logger.info('Device booted.');\n return;\n }\n if (selector) {\n const node = await waitForTarget({\n config,\n selector,\n gone: opts.gone,\n timeoutMs,\n pollMs: Number(opts.interval) || 500,\n deviceSerial: opts.device,\n logger,\n });\n if (!node) {\n logger.info('Element is gone.');\n return;\n }\n if (opts.json) process.stdout.write(`${JSON.stringify(node, null, 2)}\\n`);\n else logger.info(`found: ${describeLayoutNode(node)}`);\n return;\n }\n if (opts.bundle) {\n await waitForBundle({ config, bundle: opts.bundle, timeoutMs, deviceSerial: opts.device, logger });\n logger.info(`Bundle ${opts.bundle} is running.`);\n return;\n }\n throw new Error('Specify one of --log <pattern>, --boot, --bundle <bundle>, or --target <text> (or --target-id / --target-type).');\n });\n}\n","import type { Command } from 'commander';\nimport type { LayoutSelector } from '@oniroproject/core';\n\n/** The shared element-selector flags, as commander parses them. */\nexport interface TargetOpts {\n target?: string;\n targetId?: string;\n targetType?: string;\n targetIndex?: string;\n}\n\n/**\n * Add the element-selector flags shared by `input`, `wait`, and `screenshot`.\n * `verb` completes the `--target` help text (e.g. \"Tap\" → \"Tap the element …\").\n */\nexport function addTargetOptions(cmd: Command, verb: string, opts: { index?: boolean } = {}): Command {\n cmd\n .option(\n '--target <text>',\n `${verb} the element whose text, description, or placeholder matches ` +\n '(case-insensitive; exact matches win, else substring). Covered elements are skipped.',\n )\n .option('--target-id <id>', 'Match the element by its id or key.')\n .option('--target-type <type>', 'Restrict the match to a component type (e.g. Button, TextInput).');\n if (opts.index !== false) {\n cmd.option('--target-index <n>', 'Pick the n-th (0-based) of several matching elements.');\n }\n return cmd;\n}\n\n/** The selector built from the flags, or undefined when none was given. */\nexport function selectorFrom(opts: TargetOpts): LayoutSelector | undefined {\n if (opts.target === undefined && opts.targetId === undefined && opts.targetType === undefined) return undefined;\n return { text: opts.target, id: opts.targetId, type: opts.targetType };\n}\n\nexport function targetIndexFrom(opts: TargetOpts): number | undefined {\n if (opts.targetIndex === undefined) return undefined;\n const n = Number(opts.targetIndex);\n if (!Number.isInteger(n) || n < 0) throw new Error(`--target-index must be a non-negative integer; got ${opts.targetIndex}.`);\n return n;\n}\n","import { Command } from 'commander';\nimport { watchLog } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface WatchOpts {\n log?: string;\n for: string;\n bundle?: string;\n domain?: string;\n dedup: boolean;\n device?: string;\n json?: boolean;\n}\n\nexport function registerWatchCommand(program: Command): void {\n program\n .command('watch')\n .description('Collect hilog lines matching a pattern for a fixed duration.')\n .option('--log <pattern>', 'Regex tested against each line (tag: message).')\n .option('--for <ms>', 'Duration to watch, ms.', '10000')\n .option('--bundle <bundle>', 'Filter to this bundle.')\n .option('--domain <domain>', 'hilog domain filter (e.g. 0xD003900).')\n .option('--no-dedup', 'Do not collapse consecutive duplicate lines.')\n .option('--device <serial>', 'Target device serial.')\n .option('--json', 'Emit the entries as JSON.')\n .action(async (opts: WatchOpts) => {\n const { config, logger } = getRuntime();\n if (!opts.log) throw new Error('watch requires --log <pattern>.');\n const entries = await watchLog({\n config,\n pattern: new RegExp(opts.log),\n durationMs: Number(opts.for),\n bundle: opts.bundle,\n domain: opts.domain,\n dedup: opts.dedup,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(entries, null, 2)}\\n`);\n } else {\n for (const e of entries) process.stdout.write(`${e.time} ${e.level} ${e.tag}: ${e.message}\\n`);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { takeScreenshot, captureBurst, locateTarget, describeLayoutNode } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport {\n renderWithGrid,\n buildContactSheet,\n frameDiffs,\n cropImage,\n parseCropRect,\n padCropRect,\n type CropRect,\n} from '../lib/screenshotImage.js';\nimport { addTargetOptions, selectorFrom, targetIndexFrom, type TargetOpts } from '../lib/target.js';\n\ninterface ScreenshotOpts extends TargetOpts {\n output: string;\n grid?: boolean;\n maxDim: string;\n crop?: string;\n contactSheet?: boolean;\n burst?: string;\n interval: string;\n json?: boolean;\n device?: string;\n}\n\nconst DEFAULT_CONTACT_SHEET_FRAMES = 8;\n// Margin kept around a --target element when cropping to it, as a fraction of the display.\nconst TARGET_CROP_PAD = 0.02;\n\nfunction clampMaxDim(raw: string): number {\n const n = Number(raw);\n if (!Number.isFinite(n)) return 1024;\n return Math.max(256, Math.min(4096, Math.round(n)));\n}\n\nexport function registerScreenshotCommand(program: Command): void {\n const screenshot = program\n .command('screenshot')\n .description(\n 'Capture the screen. Default: full-resolution raw JPEG. ' +\n '--grid: downscaled JPEG with a 10x10 grid (axes 0.0-1.0) for picking tap coordinates. ' +\n '--crop / --target: a full-resolution crop of one region or element, for checking detail cheaply. ' +\n '--contact-sheet: capture a burst and tile it into one image with per-frame change diffs.',\n )\n .option('-o, --output <file>', 'Output file path.', 'screenshot.jpeg')\n .option('--grid', 'Downscale (to --max-dim) and overlay a 10x10 coordinate grid.')\n .option('--max-dim <px>', 'Longest-side cap for --grid / --crop / --target / --contact-sheet (256-4096).', '1024')\n .option('--crop <x1,y1,x2,y2>', 'Crop to this region, given as 0-1 fractions of the screen.');\n addTargetOptions(screenshot, 'Crop to');\n screenshot\n .option('--contact-sheet', 'Capture a burst and composite it into one tiled contact sheet.')\n .option('--burst <count>', 'Capture N frames; writes <base>-<i><ext> (or feeds --contact-sheet).')\n .option('--interval <ms>', 'Delay between burst frames, ms.', '50')\n .option('--json', 'Emit the full result object as JSON on stdout (with --contact-sheet).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: ScreenshotOpts, command: Command) => {\n const { config, logger } = getRuntime();\n const maxDim = clampMaxDim(opts.maxDim);\n const intervalMs = Number(opts.interval) || 50;\n\n // --- Crop: one region (or element) at full resolution ---\n const selector = selectorFrom(opts);\n if (opts.crop !== undefined || selector) {\n if (opts.crop !== undefined && selector) throw new Error('Use either --crop or --target*, not both.');\n if (opts.grid || opts.contactSheet || opts.burst) {\n throw new Error('--crop / --target cannot be combined with --grid, --contact-sheet, or --burst.');\n }\n let rect: CropRect;\n let label: string;\n if (selector) {\n // Leave the keyboard alone: dismissing it would change what we are capturing.\n const located = await locateTarget({\n config,\n selector,\n index: targetIndexFrom(opts),\n hideKeyboard: false,\n deviceSerial: opts.device,\n logger,\n });\n if (!located.node.b) throw new Error(`${describeLayoutNode(located.node)} has no bounds to crop to.`);\n rect = padCropRect(located.node.b, TARGET_CROP_PAD);\n label = describeLayoutNode(located.node);\n } else {\n rect = parseCropRect(opts.crop!);\n label = rect.map((n) => n.toFixed(3)).join(',');\n }\n const shot = await takeScreenshot({ config, deviceSerial: opts.device, logger });\n const cropped = await cropImage(shot.pixels, rect, { maxDim });\n fs.writeFileSync(opts.output, cropped.buf);\n logger.info(\n `Wrote ${opts.output} (${cropped.width}x${cropped.height} from a ${cropped.cropWidth}x${cropped.cropHeight} ` +\n `crop at ${cropped.left},${cropped.top}: ${label}).`,\n );\n return;\n }\n\n // --- Contact sheet: burst -> one tiled image + per-frame diffs ---\n if (opts.contactSheet) {\n const count = opts.burst ? Math.max(1, Number(opts.burst)) : DEFAULT_CONTACT_SHEET_FRAMES;\n const frames = await captureBurst({ config, count, intervalMs, deviceSerial: opts.device, logger });\n const diffs = await frameDiffs(frames);\n const sheet = await buildContactSheet(frames, { maxDim, diffs });\n fs.writeFileSync(opts.output, sheet.buf);\n\n // Only fan out the individual raw frames when --burst was also requested.\n if (opts.burst) {\n const ext = path.extname(opts.output) || '.jpeg';\n const base = opts.output.slice(0, opts.output.length - ext.length);\n frames.forEach((frame, i) => fs.writeFileSync(`${base}-${i}${ext}`, frame));\n }\n\n const perFrame = frames.map((_, i) => ({ idx: i, t_ms: i * intervalMs, diffVsPrev: diffs[i] ?? 0 }));\n if (opts.json) {\n process.stdout.write(\n `${JSON.stringify(\n {\n sheet: opts.output,\n frameCount: frames.length,\n cols: sheet.cols,\n rows: sheet.rows,\n intervalMs,\n note: 't_ms is nominal (idx*interval); diffVsPrev is 0..1 mean greyscale diff vs the previous frame.',\n frames: perFrame,\n },\n null,\n 2,\n )}\\n`,\n );\n } else {\n process.stdout.write(`${JSON.stringify(perFrame)}\\n`);\n }\n\n let peak = 0;\n for (let i = 1; i < diffs.length; i++) if ((diffs[i] ?? 0) > (diffs[peak] ?? 0)) peak = i;\n logger.info(\n `Wrote contact sheet ${opts.output} (${sheet.cols}x${sheet.rows}, ${frames.length} frames). ` +\n `Biggest change at frame ${peak} (Δ${(diffs[peak] ?? 0).toFixed(2)}).`,\n );\n return;\n }\n\n // --- Burst (raw frames) — unchanged behaviour ---\n if (opts.burst) {\n const frames = await captureBurst({\n config,\n count: Number(opts.burst),\n intervalMs,\n deviceSerial: opts.device,\n logger,\n });\n const ext = path.extname(opts.output) || '.jpeg';\n const base = opts.output.slice(0, opts.output.length - ext.length);\n frames.forEach((frame, i) => fs.writeFileSync(`${base}-${i}${ext}`, frame));\n logger.info(`Wrote ${frames.length} frames to ${base}-<0..${frames.length - 1}>${ext}.`);\n return;\n }\n\n // --- Single shot ---\n const shot = await takeScreenshot({ config, deviceSerial: opts.device, logger });\n const maxDimProvided = command.getOptionValueSource('maxDim') === 'cli';\n if (opts.grid || maxDimProvided) {\n const rendered = await renderWithGrid(shot.pixels, { maxDim, grid: !!opts.grid });\n fs.writeFileSync(opts.output, rendered.buf);\n logger.info(\n `Wrote ${opts.output} (${rendered.width}x${rendered.height} from ` +\n `${rendered.originalWidth}x${rendered.originalHeight}${opts.grid ? ', 10x10 grid' : ''}).`,\n );\n return;\n }\n fs.writeFileSync(opts.output, shot.pixels);\n logger.info(`Wrote ${opts.output} (${shot.width}x${shot.height}).`);\n });\n}\n","import sharp from 'sharp';\n\n/**\n * Agent-facing screenshot image processing for the CLI.\n *\n * `@oniroproject/core` deliberately ships no image dependency — it returns raw\n * JPEG buffers. The grid overlay / downscale and the burst contact-sheet live\n * here (the CLI is the affordance layer), so `oniro-app screenshot` can produce\n * exactly what the ohos-hdc MCP used to. The grid drawing is ported verbatim\n * from that MCP so the output is equivalent.\n */\n\nexport interface RenderResult {\n /** Encoded JPEG. */\n buf: Buffer;\n /** Rendered (post-downscale) dimensions. */\n width: number;\n height: number;\n /** Source dimensions, before downscale. */\n originalWidth: number;\n originalHeight: number;\n}\n\nexport interface RenderWithGridOptions {\n /** Longest-side cap in pixels. The image is downscaled (never upscaled) to fit. */\n maxDim: number;\n /** Overlay the 10x10 grid with 0.0–1.0 axis labels after downscaling. */\n grid?: boolean;\n}\n\n/**\n * Build an SVG overlay: a 10x10 grid with X/Y axis labels (0.0–1.0) sized to the\n * given image dimensions. Ported verbatim from the ohos-hdc MCP so the gridded\n * output matches what agents are used to.\n */\nexport function buildGridSvg(width: number, height: number): string {\n const lineColor = 'rgba(255,80,80,0.55)';\n const labelBg = 'rgba(0,0,0,0.7)';\n const labelFg = '#fff';\n const fontSize = Math.max(10, Math.round(Math.min(width, height) / 60));\n const padding = Math.round(fontSize * 0.4);\n const labels: string[] = [];\n const lines: string[] = [];\n for (let i = 0; i <= 10; i++) {\n const f = i / 10;\n const x = Math.round(f * (width - 1));\n const y = Math.round(f * (height - 1));\n // grid lines (skip 0 and 10 — those are the image edges)\n if (i > 0 && i < 10) {\n lines.push(`<line x1=\"${x}\" y1=\"0\" x2=\"${x}\" y2=\"${height}\" stroke=\"${lineColor}\" stroke-width=\"1\"/>`);\n lines.push(`<line x1=\"0\" y1=\"${y}\" x2=\"${width}\" y2=\"${y}\" stroke=\"${lineColor}\" stroke-width=\"1\"/>`);\n }\n const tag = f.toFixed(1);\n // X-axis labels along the top\n const tx = i === 0 ? padding : i === 10 ? width - padding : x;\n const anchorX = i === 0 ? 'start' : i === 10 ? 'end' : 'middle';\n labels.push(\n `<text x=\"${tx}\" y=\"${fontSize + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"${anchorX}\">${tag}</text>`,\n );\n // Y-axis labels along the left\n const ty = i === 0 ? fontSize + padding : i === 10 ? height - padding : y + fontSize / 3;\n labels.push(\n `<text x=\"${padding}\" y=\"${ty}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">${tag}</text>`,\n );\n }\n // Axis title markers in the corners\n labels.push(\n `<text x=\"${width / 2}\" y=\"${fontSize * 2.4 + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"middle\">X →</text>`,\n );\n labels.push(\n `<text x=\"${padding}\" y=\"${fontSize * 2.6 + padding}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"${labelFg}\" stroke=\"${labelBg}\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">Y ↓</text>`,\n );\n return `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">${lines.join('')}${labels.join('')}</svg>`;\n}\n\n/**\n * Downscale a JPEG so its longest side is <= `maxDim` (never upscaling) and,\n * when `grid` is set, overlay the coordinate grid. Returns the encoded JPEG plus\n * rendered and original dimensions.\n */\nexport async function renderWithGrid(jpeg: Buffer, opts: RenderWithGridOptions): Promise<RenderResult> {\n const meta = await sharp(jpeg).metadata();\n const originalWidth = meta.width ?? 0;\n const originalHeight = meta.height ?? 0;\n const longest = Math.max(originalWidth, originalHeight) || 1;\n const scale = Math.min(1, opts.maxDim / longest);\n const width = Math.max(1, Math.round(originalWidth * scale));\n const height = Math.max(1, Math.round(originalHeight * scale));\n const resized = await sharp(jpeg).resize(width, height).jpeg({ quality: 80 }).toBuffer();\n if (!opts.grid) {\n return { buf: resized, width, height, originalWidth, originalHeight };\n }\n const svg = buildGridSvg(width, height);\n const buf = await sharp(resized)\n .composite([{ input: Buffer.from(svg) }])\n .jpeg({ quality: 80 })\n .toBuffer();\n return { buf, width, height, originalWidth, originalHeight };\n}\n\n/** A region as [x1, y1, x2, y2] fractions (0–1) of the image. */\nexport type CropRect = [number, number, number, number];\n\n/** Parse `\"x1,y1,x2,y2\"` (0–1 fractions, x1<x2, y1<y2) into a {@link CropRect}. */\nexport function parseCropRect(spec: string): CropRect {\n const parts = spec.split(',').map((s) => Number(s.trim()));\n if (parts.length !== 4 || parts.some((n) => !Number.isFinite(n) || n < 0 || n > 1)) {\n throw new Error(`--crop expects four 0-1 fractions \"x1,y1,x2,y2\"; got \"${spec}\".`);\n }\n const [x1, y1, x2, y2] = parts as CropRect;\n if (!(x2 > x1 && y2 > y1)) throw new Error(`--crop needs x1 < x2 and y1 < y2; got \"${spec}\".`);\n return [x1, y1, x2, y2];\n}\n\n/** Grow a rect by `pad` (a fraction) on every side, clamped to 0–1. */\nexport function padCropRect(r: CropRect, pad: number): CropRect {\n return [Math.max(0, r[0] - pad), Math.max(0, r[1] - pad), Math.min(1, r[2] + pad), Math.min(1, r[3] + pad)];\n}\n\nexport interface CropResult {\n /** Encoded JPEG. */\n buf: Buffer;\n /** Rendered (post-downscale) dimensions. */\n width: number;\n height: number;\n /** The cropped region in source pixels. */\n left: number;\n top: number;\n cropWidth: number;\n cropHeight: number;\n}\n\n/**\n * Crop a JPEG to a 0–1 region at full resolution, then downscale so the longest\n * side is <= `maxDim` (never upscaling). Detail where it is needed, at a\n * fraction of a full-resolution screenshot's size.\n */\nexport async function cropImage(jpeg: Buffer, rect: CropRect, opts: { maxDim: number }): Promise<CropResult> {\n const meta = await sharp(jpeg).metadata();\n const w = meta.width ?? 1;\n const h = meta.height ?? 1;\n const left = Math.min(w - 1, Math.floor(rect[0] * w));\n const top = Math.min(h - 1, Math.floor(rect[1] * h));\n const cropWidth = Math.max(1, Math.min(w, Math.ceil(rect[2] * w)) - left);\n const cropHeight = Math.max(1, Math.min(h, Math.ceil(rect[3] * h)) - top);\n const scale = Math.min(1, opts.maxDim / Math.max(cropWidth, cropHeight));\n const width = Math.max(1, Math.round(cropWidth * scale));\n const height = Math.max(1, Math.round(cropHeight * scale));\n const buf = await sharp(jpeg)\n .extract({ left, top, width: cropWidth, height: cropHeight })\n .resize(width, height)\n .jpeg({ quality: 85 })\n .toBuffer();\n return { buf, width, height, left, top, cropWidth, cropHeight };\n}\n\nexport interface ContactSheetOptions {\n /** Longest-side cap for the whole sheet; per-tile size derives from this. */\n maxDim: number;\n /** Tiles per row. Defaults to ceil(sqrt(N)). */\n cols?: number;\n /** Per-frame diff (0..1), index-aligned with `frames`; printed on each tile. */\n diffs?: number[];\n /** Gap between tiles, px. */\n gap?: number;\n}\n\nexport interface ContactSheetResult {\n buf: Buffer;\n width: number;\n height: number;\n cols: number;\n rows: number;\n tileWidth: number;\n tileHeight: number;\n count: number;\n}\n\nfunction buildTileLabelSvg(width: number, height: number, idx: number, diff?: number): string {\n const fontSize = Math.max(12, Math.round(Math.min(width, height) / 16));\n const pad = Math.round(fontSize * 0.4);\n let label = `#${idx}`;\n if (typeof diff === 'number') label += ` Δ${diff.toFixed(2)}`;\n const boxW = Math.round(label.length * fontSize * 0.62) + pad * 2;\n const boxH = fontSize + pad * 2;\n return (\n `<svg width=\"${width}\" height=\"${height}\" xmlns=\"http://www.w3.org/2000/svg\">` +\n `<rect x=\"0\" y=\"0\" width=\"${boxW}\" height=\"${boxH}\" fill=\"rgba(0,0,0,0.6)\"/>` +\n `<text x=\"${pad}\" y=\"${fontSize + pad - 1}\" font-family=\"monospace\" font-size=\"${fontSize}\" font-weight=\"bold\" fill=\"#fff\" stroke=\"rgba(0,0,0,0.85)\" stroke-width=\"3\" paint-order=\"stroke\" text-anchor=\"start\">${label}</text>` +\n `</svg>`\n );\n}\n\n/**\n * Composite a burst of JPEG frames into a single tiled contact sheet, each tile\n * labelled with its frame index (and per-frame diff when provided). One image\n * replaces N — a large token saving when verifying transient UI.\n */\nexport async function buildContactSheet(frames: Buffer[], opts: ContactSheetOptions): Promise<ContactSheetResult> {\n if (frames.length === 0) throw new Error('buildContactSheet: no frames');\n const count = frames.length;\n const cols = Math.max(1, opts.cols ?? Math.ceil(Math.sqrt(count)));\n const rows = Math.ceil(count / cols);\n const gap = opts.gap ?? 8;\n\n const meta0 = await sharp(frames[0]).metadata();\n const fw = meta0.width ?? 1;\n const fh = meta0.height ?? 1;\n const longest = Math.max(fw, fh) || 1;\n const tileScale = Math.min(1, opts.maxDim / cols / longest);\n const tileWidth = Math.max(1, Math.round(fw * tileScale));\n const tileHeight = Math.max(1, Math.round(fh * tileScale));\n\n const tiles = await Promise.all(\n frames.map((frame, i) => {\n const label = Buffer.from(buildTileLabelSvg(tileWidth, tileHeight, i, opts.diffs?.[i]));\n return sharp(frame)\n .resize(tileWidth, tileHeight, { fit: 'fill' })\n .composite([{ input: label, top: 0, left: 0 }])\n .png()\n .toBuffer();\n }),\n );\n\n const width = cols * tileWidth + (cols + 1) * gap;\n const height = rows * tileHeight + (rows + 1) * gap;\n const placements = tiles.map((input, i) => {\n const r = Math.floor(i / cols);\n const c = i % cols;\n return { input, left: gap + c * (tileWidth + gap), top: gap + r * (tileHeight + gap) };\n });\n\n const buf = await sharp({\n create: { width, height, channels: 3, background: { r: 20, g: 20, b: 20 } },\n })\n .composite(placements)\n .jpeg({ quality: 80 })\n .toBuffer();\n\n return { buf, width, height, cols, rows, tileWidth, tileHeight, count };\n}\n\n/**\n * Per-frame change metric: mean absolute difference of a downscaled greyscale\n * thumbnail vs. the previous frame, normalised to 0..1. Frame 0 is 0 (no\n * predecessor). Cheap, deterministic, and device-free.\n */\nexport async function frameDiffs(frames: Buffer[], opts: { sample?: number } = {}): Promise<number[]> {\n if (frames.length === 0) return [];\n const sample = opts.sample ?? 32;\n const thumbs = await Promise.all(\n frames.map((f) => sharp(f).greyscale().resize(sample, sample, { fit: 'fill' }).raw().toBuffer()),\n );\n const out: number[] = [0];\n for (let i = 1; i < thumbs.length; i++) {\n const a = thumbs[i - 1];\n const b = thumbs[i];\n if (!a || !b) {\n out.push(0);\n continue;\n }\n const n = Math.min(a.length, b.length) || 1;\n let s = 0;\n for (let k = 0; k < n; k++) s += Math.abs((a[k] ?? 0) - (b[k] ?? 0));\n out.push(+(s / n / 255).toFixed(4));\n }\n return out;\n}\n","import { Command } from 'commander';\nimport { dumpLayout } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { formatFlatLayout } from '../lib/layoutText.js';\n\ninterface DumpOpts {\n bundle?: string;\n raw?: boolean;\n flat?: boolean;\n device?: string;\n}\n\nexport function registerDumpCommand(program: Command): void {\n program\n .command('dump [target]')\n .description(\n 'Dump device state. Currently supports `dump layout` (the default target): JSON by default, ' +\n 'or one line per element with --flat.',\n )\n .option('--bundle <bundle>', 'Filter the layout to a single window/bundle.')\n .option('--raw', 'Return the unpruned layout tree.')\n .option('--flat', 'One line per element (type, label, center as 0-1 fractions, flags) instead of a JSON tree.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (target: string | undefined, opts: DumpOpts) => {\n const { config, logger } = getRuntime();\n const what = target ?? 'layout';\n if (what !== 'layout') throw new Error(`Unknown dump target \"${what}\". Supported: layout.`);\n if (opts.raw && opts.flat) throw new Error('--raw and --flat cannot be combined.');\n const result = await dumpLayout({\n config,\n bundleName: opts.bundle,\n prune: !opts.raw,\n detectKeyboard: !opts.raw,\n deviceSerial: opts.device,\n logger,\n });\n process.stdout.write(opts.flat ? formatFlatLayout(result) : `${JSON.stringify(result, null, 2)}\\n`);\n });\n}\n","import { flattenLayout, type DumpLayoutResult, type FlatLayoutNode } from '@oniroproject/core';\n\nconst MAX_TEXT = 80;\n\nfunction quote(s: string): string {\n return JSON.stringify(s.length > MAX_TEXT ? `${s.slice(0, MAX_TEXT - 1)}…` : s);\n}\n\nfunction flags(n: FlatLayoutNode): string[] {\n const out: string[] = [];\n if (n.click) out.push('click');\n if (n.longClick) out.push('longClick');\n if (n.scroll) out.push('scroll');\n if (n.checked) out.push('checked');\n else if (n.check) out.push('checkable');\n if (n.sel) out.push('selected');\n if (n.focus) out.push('focus');\n if (n.disabled) out.push('disabled');\n if (n.covered) out.push('covered');\n return out;\n}\n\n/** One line per element: type, label, center (0–1 fractions), and state flags. */\nexport function formatLayoutLine(n: FlatLayoutNode): string {\n const parts: string[] = [n.type ?? 'node'];\n if (n.text !== undefined) parts.push(quote(n.text));\n if (n.desc !== undefined) parts.push(`desc=${quote(n.desc)}`);\n if (n.hint !== undefined) parts.push(`hint=${quote(n.hint)}`);\n if (n.id !== undefined) parts.push(`#${n.id}`);\n if (n.key !== undefined) parts.push(`key=${n.key}`);\n if (n.c) parts.push(`c=${n.c[0].toFixed(3)},${n.c[1].toFixed(3)}`);\n parts.push(...flags(n));\n return parts.join(' ');\n}\n\n/** Worth a line: it has a label to read or match, or it can be interacted with. */\nfunction isListed(n: FlatLayoutNode): boolean {\n const labelled = n.text !== undefined || n.desc !== undefined || n.hint !== undefined;\n return labelled || !!(n.click || n.longClick || n.scroll || n.check || n.focus);\n}\n\n/**\n * Render a pruned layout as compact text for agents: a `[window <bundle>]`\n * header per window, then one line per labelled or interactive element in\n * paint order (decorative images and id-only wrappers are left to the JSON\n * output). The soft keyboard collapses to a single `[keyboard <bundle>]` line\n * instead of listing every key.\n */\nexport function formatFlatLayout(result: DumpLayoutResult): string {\n const lines: string[] = [];\n const d = result.display;\n lines.push(\n `# display ${d ? `${d.width}x${d.height}` : 'unknown'}; c = element center as 0-1 fractions ` +\n '(input --fx/--fy), or act by label with input --target \"<text>\"',\n );\n const keyboardBundle = result.keyboard?.shown ? result.keyboard.bundle : undefined;\n let window: string | undefined;\n for (const n of flattenLayout(result.tree)) {\n if (n.window !== window) {\n window = n.window;\n if (window !== undefined && window === keyboardBundle) {\n lines.push(`[keyboard ${window}] up — dismiss with input --type hideKeyboard`);\n } else if (window !== undefined) {\n lines.push(`[window ${window}]`);\n }\n }\n if (window !== undefined && window === keyboardBundle) continue;\n if (n.bundle !== undefined && n.text === undefined && !n.click) continue; // the window root itself\n if (isListed(n)) lines.push(formatLayoutLine(n));\n }\n return `${lines.join('\\n')}\\n`;\n}\n","import { Command } from 'commander';\nimport { getDeviceInfo, listDevices, type DeviceFullInfo, type DeviceInfo } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\n/** One `devices --long` line: the target-list columns, then what the device reports about itself. */\nexport function formatLongDevice(d: DeviceInfo, info: DeviceFullInfo | undefined): string {\n const head = `${d.serial}\\t${d.connection ?? ''}\\t${d.status}`;\n if (!info) return head;\n const os = [info.osFamily, info.osFamily === 'HarmonyOS' ? info.osDistVersion : undefined].filter(Boolean).join(' ');\n const fields: Array<[string, string | undefined]> = [\n ['os', os || undefined],\n ['api', info.sdkApiVersion],\n ['abi', info.abi],\n ['type', info.deviceType],\n ['model', info.model],\n ['fullname', info.osFullName],\n ];\n const rest = fields.filter(([, v]) => v).map(([k, v]) => `${k}=${/\\s/.test(v!) ? JSON.stringify(v) : v}`);\n return [head, ...rest].join('\\t');\n}\n\nexport function registerDevicesCommand(program: Command): void {\n program\n .command('devices')\n .description('List connected hdc devices.')\n .option(\n '--long',\n 'Also ask each connected device for its OS family (HarmonyOS / OpenHarmony), version, API level, ' +\n 'CPU ABI, device type and model.',\n )\n .option('--json', 'Emit machine-readable JSON.')\n .action(async (opts: { long?: boolean; json?: boolean }) => {\n const { config, logger } = getRuntime();\n const devices = await listDevices(config);\n const infos = new Map<string, DeviceFullInfo>();\n if (opts.long) {\n for (const d of devices.filter((x) => x.status === 'Connected')) {\n try {\n infos.set(d.serial, await getDeviceInfo({ config, deviceSerial: d.serial, logger }));\n } catch (err) {\n logger.warn(`Could not query ${d.serial}: ${(err as Error).message}`);\n }\n }\n }\n if (opts.json) {\n const out = opts.long ? devices.map((d) => ({ ...d, info: infos.get(d.serial) ?? null })) : devices;\n process.stdout.write(`${JSON.stringify(out, null, 2)}\\n`);\n return;\n }\n if (devices.length === 0) {\n process.stdout.write('(no devices)\\n');\n return;\n }\n for (const d of devices) {\n process.stdout.write(`${opts.long ? formatLongDevice(d, infos.get(d.serial)) : `${d.serial}\\t${d.connection ?? ''}\\t${d.status}`}\\n`);\n }\n });\n}\n","import { Command } from 'commander';\nimport { sendFile, recvFile } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\nexport function registerFileCommand(program: Command): void {\n const file = program.command('file').description('Transfer files to/from the device (hdc file send/recv).');\n\n file\n .command('send <local> <remote>')\n .description(\n 'Push a local file to the device. With --bundle, <remote> may be relative to that app\\'s sandbox ' +\n '(files/x is its filesDir, haps/entry/files/x the entry module\\'s), and the file is chowned to the app ' +\n 'so it can read it. Prints the device path.',\n )\n .option('--bundle <bundle>', 'Push into this app\\'s sandbox and give the file to the app\\'s user.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (local: string, remote: string, opts: { bundle?: string; device?: string }) => {\n const { config, logger } = getRuntime();\n const written = await sendFile({ config, local, remote, bundle: opts.bundle, deviceSerial: opts.device, logger });\n logger.info(`Sent ${local} -> ${written}${opts.bundle ? ` (owned by ${opts.bundle})` : ''}.`);\n process.stdout.write(`${written}\\n`);\n });\n\n file\n .command('recv <remote> <local>')\n .description('Pull a file from the device.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (remote: string, local: string, opts: { device?: string }) => {\n const { config, logger } = getRuntime();\n await recvFile({ config, remote, local, deviceSerial: opts.device, logger });\n logger.info(`Received ${remote} -> ${local}.`);\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport {\n detectCmdToolsFlavour,\n detectRuntimeOs,\n getCmdToolsPath,\n runCodelinter,\n type CodelinterResult,\n type CodelinterSummary,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface LintOpts {\n files?: string[];\n json?: boolean;\n}\n\n/** codelinter's totals, or totals counted from the findings when it printed none. */\nexport function lintTotals(result: Pick<CodelinterResult, 'findings' | 'summary'>): CodelinterSummary {\n if (result.summary) return result.summary;\n const count = (s: string): number => result.findings.filter((f) => f.severity === s).length;\n return {\n defects: result.findings.length,\n errors: count('error'),\n warnings: count('warning'),\n suggestions: count('suggestion'),\n };\n}\n\n/**\n * The exit code for a lint run: 1 when there is an error-severity finding, or when\n * codelinter exited non-zero without printing a report (so it did not really run).\n * Warnings and suggestions alone exit 0, although codelinter itself exits 1 for them.\n */\nexport function lintExitCode(result: Pick<CodelinterResult, 'code' | 'findings' | 'summary'>): number {\n if (lintTotals(result).errors > 0) return 1;\n const noReport = result.summary === null && result.findings.length === 0;\n return noReport && result.code !== 0 ? result.code : 0;\n}\n\nexport function registerLintCommand(program: Command): void {\n program\n .command('lint [project-dir]')\n .description(\n 'Run the OpenHarmony codelinter on a project. Defaults to the current directory. ' +\n 'Exits 1 on error-severity findings or when codelinter fails to run; warnings alone exit 0.',\n )\n .option('--files <globs...>', 'Specific files/globs to lint (default: the whole project).')\n .option('--json', 'Emit the report (findings, summary, notices, incomplete) as JSON.')\n .action(async (projectDir: string | undefined, opts: LintOpts) => {\n const { config, logger } = getRuntime();\n const dir = path.resolve(projectDir ?? process.cwd());\n const result = await runCodelinter({ config, projectDir: dir, files: opts.files, logger });\n const totals = lintTotals(result);\n if (opts.json) {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n for (const f of result.findings) {\n const at = `${f.file}:${f.line}${f.column ? `:${f.column}` : ''}`;\n process.stdout.write(`${at} ${f.severity} ${f.message}${f.code ? ` [${f.code}]` : ''}\\n`);\n }\n process.stdout.write(\n totals.defects === 0\n ? 'No defects found.\\n'\n : `${totals.defects} defects: ${totals.errors} errors, ${totals.warnings} warnings, ` +\n `${totals.suggestions} suggestions.\\n`,\n );\n }\n\n if (result.summary === null && result.findings.length === 0 && result.code !== 0) {\n logger.error(`codelinter exited ${result.code} without a report:\\n${result.raw.trim().split('\\n').slice(-15).join('\\n')}`);\n }\n if (result.incomplete) {\n for (const n of result.notices) logger.warn(`codelinter: ${n}`);\n const cmdToolsPath = getCmdToolsPath(config);\n const flavour = detectCmdToolsFlavour(cmdToolsPath);\n const projectOs = detectRuntimeOs(dir);\n if (flavour !== projectOs) {\n logger.warn(\n `The command-line tools at ${cmdToolsPath} are the ${flavour} flavour, but the project targets ` +\n `${projectOs} (runtimeOS in build-profile.json5), so codelinter skipped part of its checks: treat the ` +\n `counts as a lower bound. For a complete report, point ONIRO_CMD_TOOLS_PATH at ${projectOs} ` +\n \"command-line tools. The build's ArkTS compiler checks are not affected.\",\n );\n }\n }\n // Let output flush before exiting non-zero.\n process.exitCode = lintExitCode(result);\n });\n}\n","import { Command, Option } from 'commander';\nimport {\n performInput,\n sendGesture,\n getDisplaySize,\n describeLayoutNode,\n type UiInputType,\n type Waypoint,\n} from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\nimport { addTargetOptions, selectorFrom, targetIndexFrom, type TargetOpts } from '../lib/target.js';\n\nconst INPUT_TYPES: UiInputType[] = [\n 'click',\n 'doubleClick',\n 'longClick',\n 'swipe',\n 'drag',\n 'fling',\n 'keyEvent',\n 'inputText',\n 'clearText',\n 'hideKeyboard',\n];\n\nconst num = (v: string | undefined): number | undefined => (v === undefined ? undefined : Number(v));\n\ninterface InputOpts extends TargetOpts {\n type: UiInputType;\n x?: string;\n y?: string;\n x2?: string;\n y2?: string;\n fx?: string;\n fy?: string;\n fx2?: string;\n fy2?: string;\n speed?: string;\n key?: string;\n text?: string;\n clear?: boolean;\n hideKeyboard?: boolean;\n device?: string;\n}\n\ninterface GestureOpts {\n waypoints: string;\n fractions?: boolean;\n holdStart?: string;\n holdEnd?: string;\n device?: string;\n}\n\nexport function registerInputCommand(program: Command): void {\n const input = program\n .command('input')\n .description(\n 'Inject a UI input event via uitest uiInput. Position it with --target (an on-screen element), ' +\n '--fx/--fy (0-1 fractions of the display, as in `dump layout` and the screenshot grid), or --x/--y (pixels).',\n )\n .addOption(new Option('--type <type>', 'Input type.').choices(INPUT_TYPES).makeOptionMandatory());\n addTargetOptions(input, 'Act on');\n input\n .option('--fx <fraction>', 'Start X as a 0-1 fraction of the display width.')\n .option('--fy <fraction>', 'Start Y as a 0-1 fraction of the display height.')\n .option('--fx2 <fraction>', 'End X fraction (swipe/drag/fling).')\n .option('--fy2 <fraction>', 'End Y fraction (swipe/drag/fling).')\n .option('--x <px>', 'X pixel (click/swipe start).')\n .option('--y <px>', 'Y pixel (click/swipe start).')\n .option('--x2 <px>', 'End X pixel (swipe/drag/fling).')\n .option('--y2 <px>', 'End Y pixel (swipe/drag/fling).')\n .option('--speed <px-per-s>', 'Velocity for swipe/drag/fling.')\n .option(\n '--key <key>',\n 'Key for keyEvent: Back/Home/Power, a name (Delete, Enter, Tab, Escape, MoveHome, MoveEnd, …), ' +\n 'a letter, a KeyCode id, or a combo like Ctrl+A.',\n )\n .option('--text <text>', 'Text for inputText.')\n .option('--clear', 'inputText: clear the field (Ctrl+A, Delete) before typing.')\n .option('--hide-keyboard', 'Dismiss the soft keyboard afterwards, if it is up.')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: InputOpts) => {\n const { config, logger } = getRuntime();\n const result = await performInput({\n config,\n type: opts.type,\n target: selectorFrom(opts),\n targetIndex: targetIndexFrom(opts),\n fx: num(opts.fx),\n fy: num(opts.fy),\n fx2: num(opts.fx2),\n fy2: num(opts.fy2),\n pxX: num(opts.x),\n pxY: num(opts.y),\n pxX2: num(opts.x2),\n pxY2: num(opts.y2),\n speed: num(opts.speed),\n key: opts.key,\n text: opts.text,\n clear: opts.clear,\n hideKeyboard: opts.hideKeyboard,\n deviceSerial: opts.device,\n logger,\n });\n if (opts.type === 'hideKeyboard') {\n logger.info(result.keyboardHidden ? 'Dismissed the keyboard.' : 'The keyboard was not shown.');\n return;\n }\n const at = result.x !== undefined ? ` at ${result.x},${result.y}` : '';\n const on = result.target ? ` on ${describeLayoutNode(result.target)}` : '';\n const kb = result.keyboardHidden ? ' (dismissed the keyboard)' : '';\n logger.info(`Sent ${opts.type}${at}${on}${kb}.`);\n });\n\n program\n .command('gesture')\n .description('Inject a multi-waypoint gesture. Waypoints are JSON: [{\"x\":..,\"y\":..,\"t\":..}] in pixels (or fractions with --fractions).')\n .requiredOption('--waypoints <json>', 'JSON array of {x,y,t} waypoints (t = ms from start).')\n .option('--fractions', 'Waypoint x/y are 0-1 fractions of the display instead of pixels.')\n .option('--hold-start <ms>', 'Leading press-hold before moving (best-effort: uses `uitest drag`).')\n .option('--hold-end <ms>', 'Trailing hold before lifting (no uitest equivalent; ignored).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: GestureOpts) => {\n const { config, logger } = getRuntime();\n let waypoints = JSON.parse(opts.waypoints) as Waypoint[];\n if (opts.fractions) {\n const bad = waypoints.find((w) => !(w.x >= 0 && w.x <= 1 && w.y >= 0 && w.y <= 1));\n if (bad) throw new Error(`With --fractions, waypoint x and y must be 0-1; got ${bad.x},${bad.y}.`);\n const display = await getDisplaySize(config, { deviceSerial: opts.device, logger });\n if (!display) throw new Error('Could not read the display size to convert fractions to pixels.');\n // 1.0 maps to the last pixel, not one past the edge.\n const px = (f: number, size: number): number => Math.min(size - 1, Math.round(f * size));\n waypoints = waypoints.map((w) => ({ ...w, x: px(w.x, display.width), y: px(w.y, display.height) }));\n }\n await sendGesture({\n config,\n waypoints,\n holdStartMs: num(opts.holdStart),\n holdEndMs: num(opts.holdEnd),\n deviceSerial: opts.device,\n logger,\n });\n logger.info('Gesture sent.');\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'node:path';\nimport { captureLog } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\ninterface LogsOpts {\n output: string;\n for?: string;\n grep?: string;\n clear?: boolean;\n domain?: string;\n device?: string;\n}\n\nexport function registerLogsCommand(program: Command): void {\n program\n .command('logs')\n .description(\n 'Capture hilog to a file for a whole session: the device\\'s small log buffer wraps within ' +\n 'seconds under chatty components, so a dump at the end loses lines. Runs until --for elapses ' +\n 'or the process is interrupted; start it in the background, e.g. `oniro-app logs --clear -o ' +\n 'hilog_full.txt &`. Every line is flushed as it arrives and the stream reconnects after a reboot.',\n )\n .requiredOption('-o, --output <file>', 'File to append the lines to.')\n .option('--for <ms>', 'Stop after this many ms (default: run until interrupted).')\n .option('--grep <regex>', 'Keep only lines matching this regex (default: all).')\n .option('--clear', 'Clear the device log buffer first (hilog -r), so the file covers only this session.')\n .option('--domain <domain>', 'hilog domain filter (e.g. 0xD003900).')\n .option('--device <serial>', 'Target device serial.')\n .action(async (opts: LogsOpts) => {\n const { config, logger } = getRuntime();\n const file = path.resolve(opts.output);\n const abort = new AbortController();\n const stop = (): void => abort.abort();\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n logger.info(`Capturing hilog to ${file}${opts.for ? ` for ${opts.for} ms` : ' until interrupted'}...`);\n const result = await captureLog({\n config,\n file,\n durationMs: opts.for !== undefined ? Number(opts.for) : undefined,\n pattern: opts.grep ? new RegExp(opts.grep) : undefined,\n clear: opts.clear,\n domain: opts.domain,\n deviceSerial: opts.device,\n abortSignal: abort.signal,\n logger,\n });\n logger.info(`Wrote ${result.lines} lines to ${result.file} (${result.reconnects} reconnects).`);\n process.stdout.write(`${result.file}\\n`);\n });\n}\n","import { Command } from 'commander';\nimport { getHdcPath, hdcTargetArgsFor, spawnCompat } from '@oniroproject/core';\nimport { getRuntime } from '../lib/runtime.js';\n\n/** The argv for the passthrough: verbatim when the caller already picked a target with `-t`. */\nexport function hdcPassthroughArgv(args: readonly string[], device?: string): string[] {\n return args[0] === '-t' ? [...args] : [...hdcTargetArgsFor(args, device), ...args];\n}\n\nexport function registerHdcCommand(program: Command): void {\n program\n .command('hdc')\n .description(\n 'Run the hdc binary oniro-app itself uses (see `cmdtools status`), addressed at --device or ' +\n 'ONIRO_DEVICE_SERIAL, with stdio passed through. Exits with hdc\\'s own code, which is 0 even for ' +\n 'a `[Fail]` line. Example: oniro-app hdc shell param get const.ohos.apiversion',\n )\n .argument('[args...]', 'hdc arguments, passed through verbatim')\n .option('--device <serial>', 'Target device serial.')\n .option('--path', 'Print the hdc binary path and exit.')\n .passThroughOptions()\n .allowUnknownOption()\n .action(async (args: string[], opts: { device?: string; path?: boolean }) => {\n const { config } = getRuntime();\n const hdc = getHdcPath(config);\n if (opts.path) {\n process.stdout.write(`${hdc}\\n`);\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const child = spawnCompat(hdc, hdcPassthroughArgv(args, opts.device), { stdio: 'inherit' });\n child.on('error', (err) => reject(new Error(`Failed to run ${hdc}: ${err.message}`)));\n child.on('close', (code) => {\n process.exitCode = code ?? 1;\n resolve();\n });\n });\n });\n}\n"],"mappings":"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","names":["Command","OniroError","path","downloadAndInstallSdk","downloadAndInstallSdk","path","createHarmonyOsSession","createHarmonyOsSession","path","path","ALL_SDKS","fs","path","ALL_SDKS","Option","Option","fs","path","describeLayoutNode","describeLayoutNode","shot","os","path","detectRuntimeOs","detectRuntimeOs","Option","describeLayoutNode","Option","describeLayoutNode","path","resolve","Command","OniroError"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oniroproject/oniro-app",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Cross-platform CLI for Oniro/OpenHarmony application development.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -24,7 +24,7 @@
24
24
  "clean": "rm -rf dist"
25
25
  },
26
26
  "dependencies": {
27
- "@oniroproject/core": "0.13.0",
27
+ "@oniroproject/core": "0.14.0",
28
28
  "commander": "^12.1.0",
29
29
  "sharp": "^0.34.5"
30
30
  },