@oniroproject/core 0.6.2 → 0.8.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 +267 -7
- package/dist/index.cjs +2088 -416
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1074 -24
- package/dist/index.d.ts +1074 -24
- package/dist/index.js +2013 -417
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,12 @@ interface Logger {
|
|
|
8
8
|
}
|
|
9
9
|
declare const noopLogger: Logger;
|
|
10
10
|
declare const consoleLogger: Logger;
|
|
11
|
+
/**
|
|
12
|
+
* Wrap a Logger so every message is prefixed with `[<scope>] `. Standardizes the
|
|
13
|
+
* ad-hoc `[hdc]` / `[build]` / `[sign]` / `[hilog]` / `[emulator]` prefixes that
|
|
14
|
+
* were previously hand-written at each call site.
|
|
15
|
+
*/
|
|
16
|
+
declare function scopedLogger(logger: Logger, scope: string): Logger;
|
|
11
17
|
|
|
12
18
|
interface ProgressUpdate {
|
|
13
19
|
message?: string;
|
|
@@ -22,7 +28,7 @@ declare const noopProgress: ProgressReporter;
|
|
|
22
28
|
* Keys read from the ConfigProvider by core. Frontends (CLI, VS Code extension)
|
|
23
29
|
* implement the provider however they like (env vars, settings.json, etc.).
|
|
24
30
|
*/
|
|
25
|
-
type ConfigKey = 'sdkRootDir' | 'cmdToolsPath' | 'emulatorDir' | 'hapPath' | 'cmdToolsUrlLinux' | 'cmdToolsUrlWindows' | 'cmdToolsUrlMac' | 'emulatorUrl';
|
|
31
|
+
type ConfigKey = 'sdkRootDir' | 'cmdToolsPath' | 'hdcPath' | 'emulatorDir' | 'hapPath' | 'cmdToolsUrlLinux' | 'cmdToolsUrlWindows' | 'cmdToolsUrlMac' | 'emulatorUrl' | 'tmpDir' | 'sdkUrlBase' | 'applicationCertPath';
|
|
26
32
|
interface ConfigProvider {
|
|
27
33
|
/**
|
|
28
34
|
* Get the configured value for `key`, or `fallback` if unset/empty.
|
|
@@ -90,9 +96,29 @@ declare class ChecksumMismatchError extends OniroError {
|
|
|
90
96
|
readonly actual: string;
|
|
91
97
|
constructor(expected: string, actual: string);
|
|
92
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* A download/extract ran out of room on the filesystem holding its scratch
|
|
101
|
+
* directory. The message is built by the caller (see `sdk/tmp.ts`) so it can name
|
|
102
|
+
* the directory, whether it is RAM-backed, and how to point elsewhere.
|
|
103
|
+
*/
|
|
104
|
+
declare class InsufficientSpaceError extends OniroError {
|
|
105
|
+
readonly dir: string;
|
|
106
|
+
constructor(message: string, dir: string, cause?: unknown);
|
|
107
|
+
}
|
|
93
108
|
declare class CancelledError extends OniroError {
|
|
94
109
|
constructor(message?: string);
|
|
95
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* A spawned command ran to completion but exited non-zero. Lets callers
|
|
113
|
+
* distinguish "the tool ran and failed" from "the tool could not be spawned"
|
|
114
|
+
* (a missing binary surfaces as an OniroError / CmdToolsNotInstalledError).
|
|
115
|
+
*/
|
|
116
|
+
declare class CommandFailedError extends OniroError {
|
|
117
|
+
readonly command: string;
|
|
118
|
+
readonly exitCode: number;
|
|
119
|
+
readonly stderr: string;
|
|
120
|
+
constructor(command: string, exitCode: number, stderr: string);
|
|
121
|
+
}
|
|
96
122
|
|
|
97
123
|
/**
|
|
98
124
|
* Carries the cross-cutting dependencies most core functions need: a Logger and a ConfigProvider.
|
|
@@ -107,6 +133,17 @@ declare function defaultContext(overrides?: Partial<OniroContext>): OniroContext
|
|
|
107
133
|
interface SdkRelease {
|
|
108
134
|
version: string;
|
|
109
135
|
api: string;
|
|
136
|
+
/**
|
|
137
|
+
* Number of leading path components to strip when extracting the release
|
|
138
|
+
* tarball, per OS family. The Huawei mirror packs linux+windows in one
|
|
139
|
+
* tarball (no top-level wrapper for some releases → 0, else 1); macOS
|
|
140
|
+
* tarballs have a deeper layout (3). This table is the single source of
|
|
141
|
+
* truth read by `getSdkFilename()`.
|
|
142
|
+
*/
|
|
143
|
+
tarballStrip: {
|
|
144
|
+
linuxWindows: number;
|
|
145
|
+
darwin: number;
|
|
146
|
+
};
|
|
110
147
|
}
|
|
111
148
|
/**
|
|
112
149
|
* Known OpenHarmony SDK releases. Kept in sync with the bash CLI / extension.
|
|
@@ -131,9 +168,9 @@ interface SdkArchiveInfo {
|
|
|
131
168
|
* Resolve the SDK archive filename, OS folder, and tar strip count for the current platform.
|
|
132
169
|
*
|
|
133
170
|
* The Huawei mirror packages Linux and Windows together in one tarball with `linux/` and
|
|
134
|
-
* `windows/` subfolders
|
|
135
|
-
*
|
|
136
|
-
*
|
|
171
|
+
* `windows/` subfolders; macOS tarballs have a deeper layout. The per-release strip counts
|
|
172
|
+
* live in {@link ALL_SDKS} (`tarballStrip`). An unrecognized version falls back to the
|
|
173
|
+
* historical default (linux/windows=1, darwin=3).
|
|
137
174
|
*/
|
|
138
175
|
declare function getSdkFilename(version?: string): SdkArchiveInfo;
|
|
139
176
|
|
|
@@ -146,18 +183,27 @@ declare function getOhosBaseSdkHome(config: ConfigProvider): string;
|
|
|
146
183
|
declare function getCmdToolsPath(config: ConfigProvider): string;
|
|
147
184
|
declare function getEmulatorDir(config: ConfigProvider): string;
|
|
148
185
|
/**
|
|
149
|
-
* Resolve
|
|
150
|
-
*
|
|
186
|
+
* Resolve a binary inside the command-line tools `bin/` directory by name
|
|
187
|
+
* (e.g. `'ohpm'`, `'hvigorw'`, `'codelinter'`). On Windows tries common
|
|
188
|
+
* executable suffixes (.exe, .cmd, .bat) before the POSIX name.
|
|
151
189
|
*/
|
|
152
|
-
declare function getCmdToolsBin(config: ConfigProvider): string;
|
|
190
|
+
declare function getCmdToolsBin(config: ConfigProvider, name?: string): string;
|
|
191
|
+
/** Resolve the OHPM binary path inside the command-line tools install. */
|
|
192
|
+
declare function getOhpmPath(config: ConfigProvider): string;
|
|
153
193
|
/**
|
|
154
|
-
* Resolve the hdc binary
|
|
194
|
+
* Resolve the hdc binary. An explicit `hdcPath` override (config key / `ONIRO_HDC`
|
|
195
|
+
* env var) wins — point it at a wrapper/proxy hdc when the device is not directly
|
|
196
|
+
* attached here (e.g. a remote device behind an SSH-tunnel `hdc` wrapper). When
|
|
197
|
+
* unset, fall back to the hdc bundled in the SDK toolchains tree.
|
|
155
198
|
*/
|
|
156
199
|
declare function getHdcPath(config: ConfigProvider): string;
|
|
157
200
|
/**
|
|
158
|
-
* Resolve the hvigorw wrapper for a project
|
|
159
|
-
* (which carries the project's pinned hvigor version)
|
|
160
|
-
*
|
|
201
|
+
* Resolve the hvigorw wrapper for a project. Prefers the project-local copy
|
|
202
|
+
* (which carries the project's pinned hvigor version) — but ONLY when that
|
|
203
|
+
* wrapper is structurally complete. HMOS-vendored projects (systemui, launcher)
|
|
204
|
+
* ship a project-local `hvigorw` whose `hvigor/` install is absent, so the
|
|
205
|
+
* wrapper crashes on startup; in that case we fall back to the hvigorw bundled
|
|
206
|
+
* with the command-line tools, which is always installed.
|
|
161
207
|
*/
|
|
162
208
|
declare function getHvigorwPath(config: ConfigProvider, projectDir: string): string;
|
|
163
209
|
|
|
@@ -168,6 +214,82 @@ declare function getHvigorwPath(config: ConfigProvider, projectDir: string): str
|
|
|
168
214
|
*/
|
|
169
215
|
declare function detectProjectSdkVersion(projectRoot: string, logger?: Logger): number | undefined;
|
|
170
216
|
|
|
217
|
+
/** Name of the scratch folder created next to an install target. */
|
|
218
|
+
declare const INSTALL_TMP_DIRNAME = ".oniro-tmp";
|
|
219
|
+
/** Advice appended to out-of-space failures in the scratch directory. */
|
|
220
|
+
declare const TMP_DIR_HINT: string;
|
|
221
|
+
/**
|
|
222
|
+
* Resolve the directory that download/extract scratch space is created in.
|
|
223
|
+
*
|
|
224
|
+
* Precedence: explicit override (CLI `--tmp-dir`) → `tmpDir` config key
|
|
225
|
+
* (`ONIRO_TMP_DIR`) → `<installRoot>/.oniro-tmp` → the system temp dir.
|
|
226
|
+
*
|
|
227
|
+
* The default sits next to the install target so that the unpacked tree is renamed
|
|
228
|
+
* into place rather than copied across a device boundary, and so the system temp dir
|
|
229
|
+
* — a RAM-backed `tmpfs` on most Linux systems, and far smaller than a multi-GB
|
|
230
|
+
* archive — is never in the picture.
|
|
231
|
+
*/
|
|
232
|
+
declare function resolveTmpRoot(config: ConfigProvider, override?: string, installRoot?: string): string;
|
|
233
|
+
/** Create a private scratch directory under `root`, creating `root` if needed. */
|
|
234
|
+
declare function createTempWorkDir(root: string, prefix: string): string;
|
|
235
|
+
/**
|
|
236
|
+
* Remove a scratch directory once an install is done, taking the `.oniro-tmp` root
|
|
237
|
+
* with it when that leaves it empty. A root the caller named explicitly is left alone,
|
|
238
|
+
* as are roots another install is still using (the rmdir simply fails).
|
|
239
|
+
*/
|
|
240
|
+
declare function removeTempWorkDir(dir: string, root?: string): void;
|
|
241
|
+
interface InstallTempDirOptions {
|
|
242
|
+
config: ConfigProvider;
|
|
243
|
+
/** Explicit scratch directory (CLI `--tmp-dir`). */
|
|
244
|
+
override?: string;
|
|
245
|
+
/** Directory the install lands in; the default scratch root is created inside it. */
|
|
246
|
+
installRoot: string;
|
|
247
|
+
prefix: string;
|
|
248
|
+
logger?: Logger;
|
|
249
|
+
}
|
|
250
|
+
interface InstallTempDir {
|
|
251
|
+
/** The private per-run scratch directory. Remove it when the install finishes. */
|
|
252
|
+
dir: string;
|
|
253
|
+
/** The configurable root it was created under, for out-of-space messages. */
|
|
254
|
+
root: string;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Create the scratch directory for an install, defaulting to `<installRoot>/.oniro-tmp`.
|
|
258
|
+
*
|
|
259
|
+
* When that default is unusable — a read-only or root-owned install parent, say — the
|
|
260
|
+
* system temp dir is used instead. A directory the caller asked for explicitly is never
|
|
261
|
+
* swapped out silently, and a full filesystem is reported rather than papered over.
|
|
262
|
+
*/
|
|
263
|
+
declare function createInstallTempDir(opts: InstallTempDirOptions): InstallTempDir;
|
|
264
|
+
/**
|
|
265
|
+
* Bytes available to an unprivileged user on the filesystem holding `dir`.
|
|
266
|
+
* Returns null when the platform cannot report it.
|
|
267
|
+
*/
|
|
268
|
+
declare function getFreeSpaceBytes(dir: string): number | null;
|
|
269
|
+
/**
|
|
270
|
+
* Whether `dir` lives on a RAM-backed filesystem (`tmpfs`/`ramfs`), i.e. one whose
|
|
271
|
+
* capacity comes out of memory rather than disk.
|
|
272
|
+
*/
|
|
273
|
+
declare function isRamBackedPath(dir: string): boolean;
|
|
274
|
+
declare function formatBytes(bytes: number): string;
|
|
275
|
+
/** Recognise an out-of-disk-space failure from fs/stream errors and their wrappers. */
|
|
276
|
+
declare function isOutOfSpaceError(err: unknown): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Fail before writing a byte when the filesystem holding `dir` cannot take
|
|
279
|
+
* `requiredBytes`. A no-op when free space cannot be determined.
|
|
280
|
+
*/
|
|
281
|
+
declare function ensureFreeSpace(dir: string, requiredBytes: number, what: string): void;
|
|
282
|
+
/**
|
|
283
|
+
* Convert an out-of-space failure into an {@link InsufficientSpaceError}; any other
|
|
284
|
+
* error is returned unchanged, so callers can `throw toSpaceError(err, ...)`.
|
|
285
|
+
*
|
|
286
|
+
* `tmpRoot` is the scratch directory the operation was using. Failures under it are
|
|
287
|
+
* reported against it (not the per-run subdirectory the user cannot configure) and get
|
|
288
|
+
* the `--tmp-dir` remedy; failures elsewhere — an install target that is full — name
|
|
289
|
+
* their own directory and skip the remedy, which would not help.
|
|
290
|
+
*/
|
|
291
|
+
declare function toSpaceError(err: unknown, tmpRoot: string, what: string): unknown;
|
|
292
|
+
|
|
171
293
|
interface DownloadOptions {
|
|
172
294
|
url: string;
|
|
173
295
|
dest: string;
|
|
@@ -177,10 +299,21 @@ interface DownloadOptions {
|
|
|
177
299
|
start?: number;
|
|
178
300
|
/** Overall progress range to consume (0..100). Default 100. */
|
|
179
301
|
range?: number;
|
|
302
|
+
/** What the download is for, used in out-of-space messages. */
|
|
303
|
+
what?: string;
|
|
304
|
+
/**
|
|
305
|
+
* Configurable scratch root that `dest` lives under, if any. Out-of-space messages
|
|
306
|
+
* name it instead of the per-run subdirectory, since that is what the user can change.
|
|
307
|
+
*/
|
|
308
|
+
tmpRoot?: string;
|
|
180
309
|
}
|
|
181
310
|
/**
|
|
182
311
|
* Stream a remote file to disk with optional progress reporting and cancellation.
|
|
183
312
|
* Follows redirects via the `follow-redirects` library.
|
|
313
|
+
*
|
|
314
|
+
* Fails fast with an `InsufficientSpaceError` when the destination filesystem cannot
|
|
315
|
+
* hold the advertised `content-length` — the common case being a system temp dir on a
|
|
316
|
+
* RAM-backed tmpfs that is far smaller than the SDK/tools archives.
|
|
184
317
|
*/
|
|
185
318
|
declare function downloadFile(opts: DownloadOptions): Promise<void>;
|
|
186
319
|
/**
|
|
@@ -239,6 +372,11 @@ interface InstallSdkOptions {
|
|
|
239
372
|
progress?: ProgressReporter;
|
|
240
373
|
abortSignal?: AbortSignal;
|
|
241
374
|
logger?: Logger;
|
|
375
|
+
/**
|
|
376
|
+
* Scratch directory for the download/extract temporaries. Overrides the `tmpDir`
|
|
377
|
+
* config key and the default location next to the install target.
|
|
378
|
+
*/
|
|
379
|
+
tmpDir?: string;
|
|
242
380
|
}
|
|
243
381
|
/**
|
|
244
382
|
* Download and install an OpenHarmony SDK release into `<sdkRootDir>/<osFolder>/<api>`.
|
|
@@ -276,6 +414,11 @@ interface InstallCmdToolsOptions {
|
|
|
276
414
|
logger?: Logger;
|
|
277
415
|
/** Skip download and install from a local zip the caller already has. */
|
|
278
416
|
localZipPath?: string;
|
|
417
|
+
/**
|
|
418
|
+
* Scratch directory for the download/extract temporaries. Overrides the `tmpDir`
|
|
419
|
+
* config key and the default location next to the install target.
|
|
420
|
+
*/
|
|
421
|
+
tmpDir?: string;
|
|
279
422
|
}
|
|
280
423
|
/**
|
|
281
424
|
* Install the OpenHarmony command-line tools into `<cmdToolsPath>`.
|
|
@@ -321,6 +464,11 @@ type Apl = 'normal' | 'system_basic' | 'system_core';
|
|
|
321
464
|
type AppFeature = 'hos_normal_app' | 'hos_system_app';
|
|
322
465
|
declare const APL_VALUES: readonly Apl[];
|
|
323
466
|
declare const APP_FEATURE_VALUES: readonly AppFeature[];
|
|
467
|
+
/** Keystore passwords. These must match the keystore in use. */
|
|
468
|
+
interface SigningPasswords {
|
|
469
|
+
store: string;
|
|
470
|
+
key: string;
|
|
471
|
+
}
|
|
324
472
|
/**
|
|
325
473
|
* Which signing key pairs with the chosen `apl`.
|
|
326
474
|
*
|
|
@@ -362,6 +510,18 @@ interface GenerateSigningConfigsOptions {
|
|
|
362
510
|
* existing `allowed-acls` is left alone.
|
|
363
511
|
*/
|
|
364
512
|
acls?: string[];
|
|
513
|
+
/**
|
|
514
|
+
* Keystore passwords written into the profile sign step and the build-profile
|
|
515
|
+
* signingConfigs. Defaults to `'123456'` (the SDK's bundled OpenHarmony.p12
|
|
516
|
+
* password). Only override when supplying a matching custom keystore.
|
|
517
|
+
*/
|
|
518
|
+
passwords?: SigningPasswords;
|
|
519
|
+
/**
|
|
520
|
+
* Override the bundled application cert chain (application-release kind only).
|
|
521
|
+
* When set, this file is copied to `signatures/OpenHarmonyApplication.cer`
|
|
522
|
+
* instead of the inlined cert. May also be sourced from `config.applicationCertPath`.
|
|
523
|
+
*/
|
|
524
|
+
applicationCertPath?: string;
|
|
365
525
|
/** Optional logger; defaults to no-op. */
|
|
366
526
|
logger?: Logger;
|
|
367
527
|
}
|
|
@@ -386,14 +546,20 @@ interface InstallEmulatorOptions {
|
|
|
386
546
|
progress?: ProgressReporter;
|
|
387
547
|
abortSignal?: AbortSignal;
|
|
388
548
|
logger?: Logger;
|
|
549
|
+
/**
|
|
550
|
+
* Scratch directory for the downloaded ZIP. Overrides the `tmpDir` config key and
|
|
551
|
+
* the default location next to the install target.
|
|
552
|
+
*/
|
|
553
|
+
tmpDir?: string;
|
|
389
554
|
}
|
|
390
555
|
/**
|
|
391
556
|
* Download and extract the Oniro emulator into the configured `emulatorDir`.
|
|
392
557
|
*/
|
|
393
558
|
declare function installEmulator(opts: InstallEmulatorOptions): Promise<void>;
|
|
394
559
|
/**
|
|
395
|
-
* Heuristic: emulator is considered installed if
|
|
396
|
-
*
|
|
560
|
+
* Heuristic: the emulator is considered installed if either bundled launcher
|
|
561
|
+
* (`images/run.sh` or `images/run.bat`) is present, so a Windows-only build is
|
|
562
|
+
* detected too.
|
|
397
563
|
*/
|
|
398
564
|
declare function isEmulatorInstalled(config: ConfigProvider): boolean;
|
|
399
565
|
declare function removeEmulator(config: ConfigProvider): void;
|
|
@@ -439,16 +605,485 @@ interface StartEmulatorOptions {
|
|
|
439
605
|
declare function startEmulator(opts: StartEmulatorOptions): Promise<void>;
|
|
440
606
|
declare function stopEmulator(logger?: Logger): Promise<void>;
|
|
441
607
|
|
|
608
|
+
/** Result of a spawned command. `code` is the process exit code (-1 if it was killed). */
|
|
609
|
+
interface HdcExecResult {
|
|
610
|
+
code: number;
|
|
611
|
+
stdout: string;
|
|
612
|
+
stderr: string;
|
|
613
|
+
}
|
|
614
|
+
/** Streamed output callback, invoked per stdout/stderr chunk as it arrives. */
|
|
615
|
+
type OutputSink = (chunk: string, stream: 'stdout' | 'stderr') => void;
|
|
616
|
+
interface RunProcessOptions {
|
|
617
|
+
/** Executable to spawn. */
|
|
618
|
+
command: string;
|
|
619
|
+
/** Args passed verbatim (spawn runs with `shell: false`, so no shell parsing). */
|
|
620
|
+
args: readonly string[];
|
|
621
|
+
cwd?: string;
|
|
622
|
+
env?: NodeJS.ProcessEnv;
|
|
623
|
+
/** Kill the process after this many ms and reject. Default 60_000. */
|
|
624
|
+
timeoutMs?: number;
|
|
625
|
+
/** Abort the process; rejects with CancelledError. */
|
|
626
|
+
abortSignal?: AbortSignal;
|
|
627
|
+
/** Receive stdout/stderr chunks as they arrive (in addition to the buffered result). */
|
|
628
|
+
onOutput?: OutputSink;
|
|
629
|
+
/** Reserved for future scoped diagnostics; the buffered result is returned regardless. */
|
|
630
|
+
logger?: Logger;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Spawn an arbitrary process with `shell: false` and collect its output. The
|
|
634
|
+
* single low-level primitive every other command in the package builds on —
|
|
635
|
+
* because args are passed as an array and never interpolated into a shell
|
|
636
|
+
* string, command construction is injection-safe by construction.
|
|
637
|
+
*
|
|
638
|
+
* Resolves with `{ code, stdout, stderr }` for ANY exit code (callers opt into
|
|
639
|
+
* throw-on-non-zero via {@link ensureOk}). Rejects only on spawn failure
|
|
640
|
+
* (e.g. missing binary), timeout, or abort.
|
|
641
|
+
*/
|
|
642
|
+
declare function runProcess(opts: RunProcessOptions): Promise<HdcExecResult>;
|
|
643
|
+
interface HdcExecOptions {
|
|
644
|
+
config: ConfigProvider;
|
|
645
|
+
/** Args passed to hdc verbatim, e.g. `['shell','aa','start','-a',ability,'-b',bundle]`. */
|
|
646
|
+
args: readonly string[];
|
|
647
|
+
/** Device serial; when set, prepends `['-t', serial]`. */
|
|
648
|
+
deviceSerial?: string;
|
|
649
|
+
/** Default 60_000. */
|
|
650
|
+
timeoutMs?: number;
|
|
651
|
+
abortSignal?: AbortSignal;
|
|
652
|
+
onOutput?: OutputSink;
|
|
653
|
+
logger?: Logger;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Run `hdc [-t <serial>] <args...>`. Resolves with `{ code, stdout, stderr }`
|
|
657
|
+
* for any exit code; use {@link ensureOk} to throw on non-zero.
|
|
658
|
+
*/
|
|
659
|
+
declare function hdcExec(opts: HdcExecOptions): Promise<HdcExecResult>;
|
|
660
|
+
interface HdcShellOptions extends Omit<HdcExecOptions, 'args'> {
|
|
661
|
+
/** A single shell command, run as `hdc shell <command>` (one argv element — not host word-split). */
|
|
662
|
+
command: string;
|
|
663
|
+
}
|
|
664
|
+
/** Convenience wrapper for `hdc shell <command>`. */
|
|
665
|
+
declare function shell(opts: HdcShellOptions): Promise<HdcExecResult>;
|
|
666
|
+
/**
|
|
667
|
+
* Throw a typed {@link CommandFailedError} when `result.code !== 0`, otherwise
|
|
668
|
+
* return the result unchanged. Lets callers opt into throw-semantics.
|
|
669
|
+
*/
|
|
670
|
+
declare function ensureOk(result: HdcExecResult, command: string): HdcExecResult;
|
|
671
|
+
/**
|
|
672
|
+
* Parse the exit-code marker appended by {@link shellChecked}. Pure/testable.
|
|
673
|
+
* Returns the remote exit code plus stdout with every marker occurrence
|
|
674
|
+
* stripped, or `null` when no marker is present (the command was killed/timed
|
|
675
|
+
* out, or the device shell never reached the trailing `echo`).
|
|
676
|
+
*/
|
|
677
|
+
declare function parseRemoteExit(stdout: string): {
|
|
678
|
+
code: number;
|
|
679
|
+
stdout: string;
|
|
680
|
+
} | null;
|
|
681
|
+
/**
|
|
682
|
+
* Like {@link shell}, but recovers the REMOTE command's exit status.
|
|
683
|
+
*
|
|
684
|
+
* `hdc shell "<cmd>"` reports hdc's OWN exit code (≈ always 0) regardless of
|
|
685
|
+
* whether `<cmd>` succeeded on the device — so on-device failures (`uinput`
|
|
686
|
+
* rejecting its args, a `bm install` error, a missing binary) otherwise look
|
|
687
|
+
* like success. We append an exit-code marker, parse it back out, and report
|
|
688
|
+
* it as `code`, with the marker stripped from stdout. Pair with
|
|
689
|
+
* {@link ensureRemoteOk} to throw on a non-zero remote exit.
|
|
690
|
+
*/
|
|
691
|
+
declare function shellChecked(opts: HdcShellOptions): Promise<HdcExecResult>;
|
|
692
|
+
/**
|
|
693
|
+
* Throw a typed {@link CommandFailedError} on a non-zero result, preferring
|
|
694
|
+
* stderr but falling back to stdout for the detail — device tools like
|
|
695
|
+
* `uinput`/`uitest` print their errors to stdout, not stderr.
|
|
696
|
+
*/
|
|
697
|
+
declare function ensureRemoteOk(result: HdcExecResult, command: string): HdcExecResult;
|
|
698
|
+
|
|
699
|
+
interface DeviceInfo {
|
|
700
|
+
/** Connect key — a USB serial or a `host:port` for a TCP target. */
|
|
701
|
+
serial: string;
|
|
702
|
+
/** 'Connected' | 'Offline' | 'Unauthorized' | … | 'Unknown' when not reported. */
|
|
703
|
+
status: string;
|
|
704
|
+
/** 'USB' | 'TCP' | … when reported by `-v`. */
|
|
705
|
+
connection?: string;
|
|
706
|
+
/** Device model, populated by getDeviceInfo (not by the bare target list). */
|
|
707
|
+
model?: string;
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Parse the output of `hdc list targets -v` into structured rows. The first token
|
|
711
|
+
* of each non-empty row is the connect key (serial); connection/status are matched
|
|
712
|
+
* by keyword among the remaining tokens. `[Empty]` (no devices) yields `[]`.
|
|
713
|
+
*/
|
|
714
|
+
declare function parseDeviceList(stdout: string): DeviceInfo[];
|
|
715
|
+
/** List connected hdc targets via `hdc list targets -v`. Empty list when none. */
|
|
716
|
+
declare function listDevices(config: ConfigProvider, opts?: {
|
|
717
|
+
timeoutMs?: number;
|
|
718
|
+
logger?: Logger;
|
|
719
|
+
}): Promise<DeviceInfo[]>;
|
|
720
|
+
/**
|
|
721
|
+
* Resolve which device serial to address: an explicit `serial` wins, then the
|
|
722
|
+
* `ONIRO_DEVICE_SERIAL` / `DEVICE_SERIAL` env vars, then the single connected
|
|
723
|
+
* device. Throws when none or more than one is connected and nothing was specified.
|
|
724
|
+
*/
|
|
725
|
+
declare function selectDevice(config: ConfigProvider, serial?: string, opts?: {
|
|
726
|
+
timeoutMs?: number;
|
|
727
|
+
logger?: Logger;
|
|
728
|
+
}): Promise<string>;
|
|
729
|
+
|
|
730
|
+
interface ParamOptions {
|
|
731
|
+
deviceSerial?: string;
|
|
732
|
+
timeoutMs?: number;
|
|
733
|
+
logger?: Logger;
|
|
734
|
+
}
|
|
735
|
+
/** Read a system property via `hdc shell param get <key>`. Returns the trimmed value. */
|
|
736
|
+
declare function paramGet(config: ConfigProvider, key: string, opts?: ParamOptions): Promise<string>;
|
|
737
|
+
/**
|
|
738
|
+
* Set a system property via `hdc shell param set <key> <value>`. The canonical
|
|
739
|
+
* reboot path is `paramSet(config, 'ohos.startup.powerctrl', 'reboot')`.
|
|
740
|
+
*/
|
|
741
|
+
declare function paramSet(config: ConfigProvider, key: string, value: string, opts?: ParamOptions): Promise<void>;
|
|
742
|
+
|
|
743
|
+
interface SendFileOptions {
|
|
744
|
+
config: ConfigProvider;
|
|
745
|
+
/** Local source path. */
|
|
746
|
+
local: string;
|
|
747
|
+
/** Remote destination path on the device. */
|
|
748
|
+
remote: string;
|
|
749
|
+
deviceSerial?: string;
|
|
750
|
+
timeoutMs?: number;
|
|
751
|
+
abortSignal?: AbortSignal;
|
|
752
|
+
onOutput?: OutputSink;
|
|
753
|
+
logger?: Logger;
|
|
754
|
+
}
|
|
755
|
+
/** Push a local file to the device via `hdc file send <local> <remote>`. */
|
|
756
|
+
declare function sendFile(opts: SendFileOptions): Promise<void>;
|
|
757
|
+
interface RecvFileOptions {
|
|
758
|
+
config: ConfigProvider;
|
|
759
|
+
/** Remote source path on the device. */
|
|
760
|
+
remote: string;
|
|
761
|
+
/** Local destination path. */
|
|
762
|
+
local: string;
|
|
763
|
+
deviceSerial?: string;
|
|
764
|
+
timeoutMs?: number;
|
|
765
|
+
abortSignal?: AbortSignal;
|
|
766
|
+
onOutput?: OutputSink;
|
|
767
|
+
logger?: Logger;
|
|
768
|
+
}
|
|
769
|
+
/** Pull a file from the device via `hdc file recv <remote> <local>`. */
|
|
770
|
+
declare function recvFile(opts: RecvFileOptions): Promise<void>;
|
|
771
|
+
|
|
772
|
+
interface DisplaySize {
|
|
773
|
+
width: number;
|
|
774
|
+
height: number;
|
|
775
|
+
}
|
|
776
|
+
interface DisplaySizeOptions {
|
|
777
|
+
deviceSerial?: string;
|
|
778
|
+
timeoutMs?: number;
|
|
779
|
+
logger?: Logger;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Resolve the device's render resolution from `hidumper -s 10 -a screen`
|
|
783
|
+
* (`render resolution=WxH`). Returns null when unavailable. This is the W/H
|
|
784
|
+
* source for screenshots and the 0–1 normalization of layout bounds — no image
|
|
785
|
+
* decoding is involved.
|
|
786
|
+
*/
|
|
787
|
+
declare function getDisplaySize(config: ConfigProvider, opts?: DisplaySizeOptions): Promise<DisplaySize | null>;
|
|
788
|
+
|
|
789
|
+
interface WaitForConditionOptions {
|
|
790
|
+
/** Resolves true when the condition is satisfied. Called once per poll. */
|
|
791
|
+
probe: () => Promise<boolean>;
|
|
792
|
+
/** Overall deadline. */
|
|
793
|
+
timeoutMs: number;
|
|
794
|
+
/** Poll interval. Default 2000. */
|
|
795
|
+
pollMs?: number;
|
|
796
|
+
/** Abort the wait; rejects with CancelledError. */
|
|
797
|
+
abortSignal?: AbortSignal;
|
|
798
|
+
/** Called every `heartbeatEvery` attempts (default 6) with progress info. */
|
|
799
|
+
onHeartbeat?: (attempt: number, remainingMs: number) => void;
|
|
800
|
+
heartbeatEvery?: number;
|
|
801
|
+
logger?: Logger;
|
|
802
|
+
/** Message for the timeout error. */
|
|
803
|
+
timeoutMessage?: string;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Generic deadline + poll + heartbeat loop. Calls `probe()` every `pollMs` until
|
|
807
|
+
* it resolves true (→ resolve) or the deadline passes (→ throw OniroError).
|
|
808
|
+
* A probe that throws is treated as "not yet" (the loop keeps polling) — this is
|
|
809
|
+
* what lets device waits tolerate transient hdc disconnects mid-reboot. Aborting
|
|
810
|
+
* the signal rejects with CancelledError.
|
|
811
|
+
*
|
|
812
|
+
* Extracted from the emulator hdc-wait loop so device lifecycle helpers share it.
|
|
813
|
+
*/
|
|
814
|
+
declare function waitForCondition(opts: WaitForConditionOptions): Promise<void>;
|
|
815
|
+
|
|
816
|
+
interface WaitForBundleOptions {
|
|
817
|
+
config: ConfigProvider;
|
|
818
|
+
bundle: string;
|
|
819
|
+
deviceSerial?: string;
|
|
820
|
+
timeoutMs?: number;
|
|
821
|
+
abortSignal?: AbortSignal;
|
|
822
|
+
logger?: Logger;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Poll `pidof <bundle>` until the bundle has a clean numeric pid. Empty/failed
|
|
826
|
+
* pidof responses (including while the device is unreachable) do NOT count.
|
|
827
|
+
*/
|
|
828
|
+
declare function waitForBundle(opts: WaitForBundleOptions): Promise<void>;
|
|
829
|
+
interface WaitForBootOptions {
|
|
830
|
+
config: ConfigProvider;
|
|
831
|
+
/** Require a clean numeric pid for this process/bundle name before returning. */
|
|
832
|
+
untilPidOf?: string;
|
|
833
|
+
deviceSerial?: string;
|
|
834
|
+
timeoutMs?: number;
|
|
835
|
+
abortSignal?: AbortSignal;
|
|
836
|
+
logger?: Logger;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* Poll until the device responds AND (when `untilPidOf` is set) that process has
|
|
840
|
+
* a clean numeric pid. Tolerates the transient hdc disconnect during a reboot.
|
|
841
|
+
*/
|
|
842
|
+
declare function waitForBoot(opts: WaitForBootOptions): Promise<void>;
|
|
843
|
+
interface RebootOptions {
|
|
844
|
+
config: ConfigProvider;
|
|
845
|
+
/** 'system' (default) reboots via param set; bootloader/recovery via `reboot <mode>`. */
|
|
846
|
+
mode?: 'system' | 'bootloader' | 'recovery';
|
|
847
|
+
/** When set (system mode), block until this bundle has a clean numeric pid after the reboot. */
|
|
848
|
+
waitForBundle?: string;
|
|
849
|
+
deviceSerial?: string;
|
|
850
|
+
timeoutMs?: number;
|
|
851
|
+
abortSignal?: AbortSignal;
|
|
852
|
+
logger?: Logger;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Reboot the device. System reboots use `param set ohos.startup.powerctrl reboot`
|
|
856
|
+
* (the path that works when force-stopping systemui is blocked); bootloader/
|
|
857
|
+
* recovery use `hdc shell reboot <mode>`. A reboot frequently tears down the hdc
|
|
858
|
+
* connection before the command returns, so command failure here is tolerated.
|
|
859
|
+
*
|
|
860
|
+
* When `waitForBundle` is set (system mode), waits for the device to drop and
|
|
861
|
+
* come back with the bundle running — so it doesn't return on the pre-reboot pid.
|
|
862
|
+
* A TCP target (e.g. an emulator at `127.0.0.1:55555`) is reconnected via
|
|
863
|
+
* `hdc tconn` during that wait, since hdc does not auto-reconnect TCP sessions
|
|
864
|
+
* across a reboot the way it does USB devices — pass the address as `deviceSerial`.
|
|
865
|
+
*/
|
|
866
|
+
declare function reboot(opts: RebootOptions): Promise<void>;
|
|
867
|
+
|
|
868
|
+
interface Screenshot {
|
|
869
|
+
/** Raw JPEG bytes, exactly as `snapshot_display` wrote them (no decode/resize). */
|
|
870
|
+
pixels: Buffer;
|
|
871
|
+
/** Device render width/height from hidumper; 0 when it couldn't be resolved. */
|
|
872
|
+
width: number;
|
|
873
|
+
height: number;
|
|
874
|
+
}
|
|
875
|
+
interface ScreenshotOptions {
|
|
876
|
+
config: ConfigProvider;
|
|
877
|
+
deviceSerial?: string;
|
|
878
|
+
timeoutMs?: number;
|
|
879
|
+
logger?: Logger;
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Capture the screen via on-device `snapshot_display`, pull the JPEG bytes back,
|
|
883
|
+
* and return them raw alongside the device resolution. The agent-facing grid
|
|
884
|
+
* overlay / downscale / base64 encoding stays in the MCP — core does no image
|
|
885
|
+
* decoding and adds no image dependency.
|
|
886
|
+
*/
|
|
887
|
+
declare function takeScreenshot(opts: ScreenshotOptions): Promise<Screenshot>;
|
|
888
|
+
interface CaptureBurstOptions {
|
|
889
|
+
config: ConfigProvider;
|
|
890
|
+
count: number;
|
|
891
|
+
/** Delay between device-side captures, ms. */
|
|
892
|
+
intervalMs: number;
|
|
893
|
+
deviceSerial?: string;
|
|
894
|
+
timeoutMs?: number;
|
|
895
|
+
logger?: Logger;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Capture `count` frames `intervalMs` apart in a single device-side loop, then
|
|
899
|
+
* pull each frame back. Returns the raw JPEG buffers in order. The MCP composites
|
|
900
|
+
* these into a contact sheet + per-frame diff; core just returns the frames.
|
|
901
|
+
*/
|
|
902
|
+
declare function captureBurst(opts: CaptureBurstOptions): Promise<Buffer[]>;
|
|
903
|
+
|
|
904
|
+
type InputType = 'click' | 'doubleClick' | 'longClick' | 'swipe' | 'drag' | 'fling' | 'keyEvent' | 'inputText';
|
|
905
|
+
interface SendInputOptions {
|
|
906
|
+
config: ConfigProvider;
|
|
907
|
+
type: InputType;
|
|
908
|
+
/** Pixel coordinates. The %→px conversion lives in the MCP, not core. */
|
|
909
|
+
pxX?: number;
|
|
910
|
+
pxY?: number;
|
|
911
|
+
pxX2?: number;
|
|
912
|
+
pxY2?: number;
|
|
913
|
+
/** Velocity for swipe/drag/fling. */
|
|
914
|
+
speed?: number;
|
|
915
|
+
/** Key id or symbolic name (Back/Home/Power) for keyEvent. */
|
|
916
|
+
key?: string | number;
|
|
917
|
+
/** Text for inputText. */
|
|
918
|
+
text?: string;
|
|
919
|
+
deviceSerial?: string;
|
|
920
|
+
logger?: Logger;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Build the `uitest uiInput …` command for an input action, in pixel space.
|
|
924
|
+
* Pure (no I/O) so it is unit-testable. Mirrors the proven MCP construction
|
|
925
|
+
* minus the percentage→pixel step.
|
|
926
|
+
*/
|
|
927
|
+
declare function buildInputCommand(opts: SendInputOptions): string;
|
|
928
|
+
/** Inject a UI input action via `uitest uiInput` (pixel coordinates). */
|
|
929
|
+
declare function sendInput(opts: SendInputOptions): Promise<void>;
|
|
930
|
+
interface Waypoint {
|
|
931
|
+
/** Pixel x. */
|
|
932
|
+
x: number;
|
|
933
|
+
/** Pixel y. */
|
|
934
|
+
y: number;
|
|
935
|
+
/** Time in ms relative to the gesture start. */
|
|
936
|
+
t: number;
|
|
937
|
+
}
|
|
938
|
+
interface SendGestureOptions {
|
|
939
|
+
config: ConfigProvider;
|
|
940
|
+
waypoints: Waypoint[];
|
|
941
|
+
/** Hold at the first point before moving (ms). Honored via the raw-touch path. */
|
|
942
|
+
holdStartMs?: number;
|
|
943
|
+
/** Hold at the last point before lifting (ms). Honored via the raw-touch path. */
|
|
944
|
+
holdEndMs?: number;
|
|
945
|
+
deviceSerial?: string;
|
|
946
|
+
logger?: Logger;
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Build the chained `uitest uiInput drag` commands for a multi-segment path.
|
|
950
|
+
* Per segment, speed is derived from the waypoint time deltas (px/s). Pure.
|
|
951
|
+
*/
|
|
952
|
+
declare function buildGestureCommands(waypoints: Waypoint[]): string[];
|
|
953
|
+
interface RawTouchEvent {
|
|
954
|
+
type: 'down' | 'move' | 'up';
|
|
955
|
+
x: number;
|
|
956
|
+
y: number;
|
|
957
|
+
/** Time in ms relative to the gesture start. */
|
|
958
|
+
t: number;
|
|
959
|
+
}
|
|
960
|
+
interface SendRawTouchOptions {
|
|
961
|
+
config: ConfigProvider;
|
|
962
|
+
events: RawTouchEvent[];
|
|
963
|
+
deviceSerial?: string;
|
|
964
|
+
logger?: Logger;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Build a single `uinput -T` touch operation sequence from down/move/up events,
|
|
968
|
+
* interleaving `-i <ms>` intervals from the event time deltas. Pure.
|
|
969
|
+
*/
|
|
970
|
+
declare function buildRawTouchCommand(events: RawTouchEvent[]): string;
|
|
971
|
+
/** Expand a waypoint path (+ optional holds) into raw down/move/up events for
|
|
972
|
+
* the `uinput` escape hatch ({@link sendRawTouch} / {@link buildRawTouchCommand}). */
|
|
973
|
+
declare function waypointsToRawEvents(waypoints: Waypoint[], holdStartMs?: number, holdEndMs?: number): RawTouchEvent[];
|
|
974
|
+
interface GestureUitestOptions {
|
|
975
|
+
/** A leading press-hold; when > 0 the stroke uses `drag` (press-and-hold,
|
|
976
|
+
* then move) instead of `swipe`. uitest has no arbitrary hold duration. */
|
|
977
|
+
holdStartMs?: number;
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* Build a single continuous `uitest uiInput` stroke for a waypoint path. Pure.
|
|
981
|
+
*
|
|
982
|
+
* uitest has no polyline or stationary-hold primitive, so the path is collapsed
|
|
983
|
+
* to first→last (gesture-nav strokes are straight lines) with the velocity
|
|
984
|
+
* derived from the total elapsed time and clamped to uitest's range. A
|
|
985
|
+
* requested `holdStartMs` maps to `drag` (which presses-and-holds before
|
|
986
|
+
* moving — uitest's nearest equivalent to a leading hold); otherwise `swipe`.
|
|
987
|
+
*/
|
|
988
|
+
declare function buildGestureUitestCommand(waypoints: Waypoint[], opts?: GestureUitestOptions): string;
|
|
989
|
+
/**
|
|
990
|
+
* Drive a swipe-style gesture via a single continuous `uitest uiInput` stroke —
|
|
991
|
+
* the MMI-injection path that `inputMonitor`-based services (gesture-nav,
|
|
992
|
+
* systemui overlays) actually observe. Preferred over raw `uinput`, whose
|
|
993
|
+
* kernel virtual-device events do not reach `inputMonitor` on some native-boot
|
|
994
|
+
* devices (and whose multi-op form some on-device `uinput` builds reject).
|
|
995
|
+
*
|
|
996
|
+
* uitest has no polyline or stationary-hold primitive: a multi-waypoint path is
|
|
997
|
+
* collapsed to first→last, `holdStartMs` maps to `drag` (press-hold-then-move),
|
|
998
|
+
* and `holdEndMs` has no equivalent (ignored). For true press-time control use
|
|
999
|
+
* {@link sendRawTouch} (raw `uinput`) — accepting the device caveats above.
|
|
1000
|
+
*/
|
|
1001
|
+
declare function sendGesture(opts: SendGestureOptions): Promise<void>;
|
|
1002
|
+
/**
|
|
1003
|
+
* Low-level touch injection via `uinput -T`. The escape hatch when press timing
|
|
1004
|
+
* matters (e.g. Quickstep motion-pause), which `uitest uiInput` can't express.
|
|
1005
|
+
*
|
|
1006
|
+
* WARNING: uinput's gesture form `uinput -T -g x1 y1 x2 y2 [press] [total]`
|
|
1007
|
+
* silently no-ops if `press < 500ms` or `total - press < 500ms` ("press time is
|
|
1008
|
+
* out of range" — it runs nothing). Keep press and post-press windows ≥ 500ms.
|
|
1009
|
+
*
|
|
1010
|
+
* DEVICE CAVEAT: on some native-boot devices these kernel-`uinput` events never
|
|
1011
|
+
* reach MMI `inputMonitor` services (gesture-nav, systemui), and some on-device
|
|
1012
|
+
* `uinput` builds reject the multi-op `-d/-m/-u` form with "wrong number of
|
|
1013
|
+
* parameters". Prefer {@link sendGesture} (uitest) for those; this path now
|
|
1014
|
+
* surfaces such failures instead of silently succeeding.
|
|
1015
|
+
*/
|
|
1016
|
+
declare function sendRawTouch(opts: SendRawTouchOptions): Promise<void>;
|
|
1017
|
+
|
|
1018
|
+
/** A raw `uitest dumpLayout` node (attributes are strings). */
|
|
1019
|
+
interface RawLayoutNode {
|
|
1020
|
+
attributes?: Record<string, string>;
|
|
1021
|
+
children?: RawLayoutNode[];
|
|
1022
|
+
}
|
|
1023
|
+
/** A pruned, 0–1-normalized layout node. */
|
|
1024
|
+
interface LayoutNode {
|
|
1025
|
+
/** bounds [x1,y1,x2,y2] normalized to 0–1 of the display. */
|
|
1026
|
+
b?: [number, number, number, number];
|
|
1027
|
+
/** center [x,y] normalized to 0–1. */
|
|
1028
|
+
c?: [number, number];
|
|
1029
|
+
type?: string;
|
|
1030
|
+
text?: string;
|
|
1031
|
+
desc?: string;
|
|
1032
|
+
id?: string;
|
|
1033
|
+
key?: string;
|
|
1034
|
+
bundle?: string;
|
|
1035
|
+
click?: boolean;
|
|
1036
|
+
check?: boolean;
|
|
1037
|
+
checked?: boolean;
|
|
1038
|
+
sel?: boolean;
|
|
1039
|
+
focus?: boolean;
|
|
1040
|
+
scroll?: boolean;
|
|
1041
|
+
longClick?: boolean;
|
|
1042
|
+
children?: LayoutNode[];
|
|
1043
|
+
}
|
|
1044
|
+
interface DumpLayoutResult {
|
|
1045
|
+
display: DisplaySize | null;
|
|
1046
|
+
tree: LayoutNode;
|
|
1047
|
+
}
|
|
1048
|
+
/** Parse a uitest bounds string `"[x1,y1][x2,y2]"` into a tuple, or null. */
|
|
1049
|
+
declare function parseBounds(s: string | undefined): [number, number, number, number] | null;
|
|
1050
|
+
/**
|
|
1051
|
+
* Prune a raw `uitest dumpLayout` tree into a compact, signal-bearing tree with
|
|
1052
|
+
* bounds/center normalized to 0–1 of the display. Structural wrapper nodes with
|
|
1053
|
+
* no signal collapse into their children. Returns a node, a flat list of nodes
|
|
1054
|
+
* (collapsed wrapper with multiple children), or null (nothing useful). Ported
|
|
1055
|
+
* verbatim from the proven MCP `pruneNode`.
|
|
1056
|
+
*/
|
|
1057
|
+
declare function pruneLayout(node: RawLayoutNode, display: DisplaySize | null): LayoutNode | LayoutNode[] | null;
|
|
1058
|
+
interface DumpLayoutOptions {
|
|
1059
|
+
config: ConfigProvider;
|
|
1060
|
+
/** Filter to a single window/bundle (`uitest dumpLayout -b '<bundle>'`). */
|
|
1061
|
+
bundleName?: string;
|
|
1062
|
+
/** When false, return the parsed-but-unpruned tree. Default true. */
|
|
1063
|
+
prune?: boolean;
|
|
1064
|
+
deviceSerial?: string;
|
|
1065
|
+
timeoutMs?: number;
|
|
1066
|
+
logger?: Logger;
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Dump the current on-screen layout via `uitest dumpLayout`, pull the JSON, and
|
|
1070
|
+
* return a pruned, 0–1-normalized tree (or the raw parsed tree when `prune:false`).
|
|
1071
|
+
*/
|
|
1072
|
+
declare function dumpLayout(opts: DumpLayoutOptions): Promise<DumpLayoutResult>;
|
|
1073
|
+
|
|
442
1074
|
/**
|
|
443
1075
|
* Read the project's bundle name from `AppScope/app.json5`.
|
|
444
1076
|
*/
|
|
445
1077
|
declare function getBundleName(projectDir: string): string;
|
|
446
1078
|
/**
|
|
447
|
-
* Read the
|
|
448
|
-
* for the module folder name
|
|
449
|
-
*
|
|
1079
|
+
* Read the ability to launch from `<module>/src/main/module.json5`. Defaults to
|
|
1080
|
+
* `entry` for the module folder name. Resolution order:
|
|
1081
|
+
* 1. `abilityName`, if given and present in `module.abilities[]`.
|
|
1082
|
+
* 2. `module.mainElement`.
|
|
1083
|
+
* 3. The first `visible` ability, then the first ability, from `module.abilities[]`.
|
|
1084
|
+
* Modules with multiple abilities can be targeted explicitly via `abilityName`.
|
|
450
1085
|
*/
|
|
451
|
-
declare function getMainAbility(projectDir: string, moduleName?: string): string;
|
|
1086
|
+
declare function getMainAbility(projectDir: string, moduleName?: string, abilityName?: string): string;
|
|
452
1087
|
|
|
453
1088
|
interface InstallAppOptions {
|
|
454
1089
|
config: ConfigProvider;
|
|
@@ -460,14 +1095,48 @@ interface InstallAppOptions {
|
|
|
460
1095
|
hapPath?: string;
|
|
461
1096
|
logger?: Logger;
|
|
462
1097
|
}
|
|
463
|
-
|
|
1098
|
+
interface InstallAppResult {
|
|
1099
|
+
installed: boolean;
|
|
1100
|
+
/** Bundle name read from the project's AppScope/app.json5, or '' if unavailable. */
|
|
1101
|
+
bundleName: string;
|
|
1102
|
+
/** The resolved absolute HAP path that was installed. */
|
|
1103
|
+
hapPath: string;
|
|
1104
|
+
/** Combined stdout+stderr from the install, trimmed. */
|
|
1105
|
+
output: string;
|
|
1106
|
+
}
|
|
1107
|
+
declare function installApp(opts: InstallAppOptions): Promise<InstallAppResult>;
|
|
464
1108
|
interface LaunchAppOptions {
|
|
465
1109
|
config: ConfigProvider;
|
|
466
|
-
|
|
467
|
-
|
|
1110
|
+
/** Project mode: resolve bundle + main ability from the project. Required unless `bundleName` is given. */
|
|
1111
|
+
projectDir?: string;
|
|
1112
|
+
/**
|
|
1113
|
+
* Bundle mode: launch an already-installed app directly by bundle name (no
|
|
1114
|
+
* project needed). When set, `projectDir` is ignored. If `abilityName` is
|
|
1115
|
+
* omitted, the main ability is resolved from the device via `bm dump -n`.
|
|
1116
|
+
*/
|
|
1117
|
+
bundleName?: string;
|
|
1118
|
+
/** Override the module name if it isn't the default `entry` (project mode). */
|
|
468
1119
|
moduleName?: string;
|
|
1120
|
+
/** Explicit ability to launch; defaults to the module's mainElement / first visible ability (project mode) or the installed bundle's main ability (bundle mode). */
|
|
1121
|
+
abilityName?: string;
|
|
1122
|
+
deviceSerial?: string;
|
|
469
1123
|
logger?: Logger;
|
|
470
1124
|
}
|
|
1125
|
+
/**
|
|
1126
|
+
* `aa start` exits 0 even when the launch is refused — a locked screen
|
|
1127
|
+
* (`Error Code:10106102`), a missing ability, a permission denial, etc. The failure
|
|
1128
|
+
* only shows up in its output. Returns the offending text when the output indicates a
|
|
1129
|
+
* failed launch, or null when it looks like a success.
|
|
1130
|
+
*/
|
|
1131
|
+
declare function detectAaStartFailure(output: string): string | null;
|
|
1132
|
+
/**
|
|
1133
|
+
* Parse the main ability of an installed bundle from `bm dump -n <bundle>`
|
|
1134
|
+
* output. Pure/testable. The output is a bundle-name prefix line followed by a
|
|
1135
|
+
* JSON blob; we take the entry module's `mainElementName` (fallback
|
|
1136
|
+
* `mainAbility`), or the first module that declares one. Returns null when the
|
|
1137
|
+
* bundle isn't installed or the output is unparseable.
|
|
1138
|
+
*/
|
|
1139
|
+
declare function parseMainAbilityFromBmDump(stdout: string): string | null;
|
|
471
1140
|
declare function launchApp(opts: LaunchAppOptions): Promise<void>;
|
|
472
1141
|
interface RunningProcess {
|
|
473
1142
|
pid: string;
|
|
@@ -484,6 +1153,30 @@ declare function listRunningProcesses(config: ConfigProvider, options?: {
|
|
|
484
1153
|
logger?: Logger;
|
|
485
1154
|
}): Promise<RunningProcess[] | string>;
|
|
486
1155
|
declare function findAppProcessId(config: ConfigProvider, projectDir: string, logger?: Logger): Promise<string>;
|
|
1156
|
+
interface BundleOptions {
|
|
1157
|
+
config: ConfigProvider;
|
|
1158
|
+
bundle: string;
|
|
1159
|
+
deviceSerial?: string;
|
|
1160
|
+
timeoutMs?: number;
|
|
1161
|
+
logger?: Logger;
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Non-throwing companion to {@link listRunningProcesses}: resolve a running
|
|
1165
|
+
* process for a bundle, or `null` when it isn't running. Suitable for "is X
|
|
1166
|
+
* running?" checks (e.g. the pre/post-install pid comparison in applyChanges).
|
|
1167
|
+
*
|
|
1168
|
+
* `pidof` matches the bundle's main (UIAbility) process. When that isn't found,
|
|
1169
|
+
* we fall back to `track-jpid` to also catch **extension-ability** processes,
|
|
1170
|
+
* which run under a separate process name `"<bundle>:<ext>"` (e.g. a
|
|
1171
|
+
* ServiceExtension, FormExtension, UIExtension or input method). Without this,
|
|
1172
|
+
* "verify the running process took the change" silently reported nothing for an
|
|
1173
|
+
* app whose only live process is an extension.
|
|
1174
|
+
*/
|
|
1175
|
+
declare function findRunningProcess(opts: BundleOptions): Promise<RunningProcess | null>;
|
|
1176
|
+
/** Uninstall an app by bundle name (`hdc uninstall <bundle>`). */
|
|
1177
|
+
declare function uninstallApp(opts: BundleOptions): Promise<void>;
|
|
1178
|
+
/** Force-stop an app (`hdc shell aa force-stop <bundle>`). */
|
|
1179
|
+
declare function forceStop(opts: BundleOptions): Promise<void>;
|
|
487
1180
|
|
|
488
1181
|
type HilogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL';
|
|
489
1182
|
/** A parsed line of `hdc shell hilog` output. */
|
|
@@ -512,11 +1205,16 @@ interface StreamHilogOptions {
|
|
|
512
1205
|
config: ConfigProvider;
|
|
513
1206
|
/** Restrict the stream to a single process id (passed as `-P <pid>`). */
|
|
514
1207
|
processId?: string;
|
|
1208
|
+
/** Filter by hilog domain, e.g. '0xD003900' (passed as `-D <domain>`). */
|
|
1209
|
+
domain?: string | number;
|
|
1210
|
+
/** Address a specific device (`-t <serial>`). */
|
|
1211
|
+
deviceSerial?: string;
|
|
515
1212
|
}
|
|
516
1213
|
/**
|
|
517
|
-
* Spawn `hdc shell hilog [-P <pid>]` and return the
|
|
518
|
-
* owns the stdout/stderr streams (typically wired
|
|
519
|
-
* is responsible for killing the process when
|
|
1214
|
+
* Spawn `hdc [-t serial] shell hilog [-P <pid>] [-D <domain>]` and return the
|
|
1215
|
+
* child process. The caller owns the stdout/stderr streams (typically wired
|
|
1216
|
+
* through `parseHilogLine`) and is responsible for killing the process when
|
|
1217
|
+
* streaming should stop.
|
|
520
1218
|
*/
|
|
521
1219
|
declare function streamHilog(opts: StreamHilogOptions): ChildProcessWithoutNullStreams;
|
|
522
1220
|
/**
|
|
@@ -525,6 +1223,61 @@ declare function streamHilog(opts: StreamHilogOptions): ChildProcessWithoutNullS
|
|
|
525
1223
|
* banners, blank lines, or partial chunks).
|
|
526
1224
|
*/
|
|
527
1225
|
declare function parseHilogLine(line: string): HilogEntry | null;
|
|
1226
|
+
/** Collapse consecutive duplicate entries (same level/tag/message), ignoring time/pid. */
|
|
1227
|
+
declare function dedupEntries(entries: HilogEntry[]): HilogEntry[];
|
|
1228
|
+
interface WaitForLogOptions {
|
|
1229
|
+
config: ConfigProvider;
|
|
1230
|
+
/** Tested against `"<tag>: <message>"` of each parsed line. */
|
|
1231
|
+
pattern: RegExp;
|
|
1232
|
+
timeoutMs: number;
|
|
1233
|
+
/** Restrict to a bundle's pid (resolved via pidof; re-resolved on each reconnect). */
|
|
1234
|
+
bundle?: string;
|
|
1235
|
+
domain?: string | number;
|
|
1236
|
+
deviceSerial?: string;
|
|
1237
|
+
abortSignal?: AbortSignal;
|
|
1238
|
+
logger?: Logger;
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* Resolve with the first hilog entry whose `"<tag>: <message>"` matches `pattern`.
|
|
1242
|
+
* The underlying stream is auto-respawned if it dies before the deadline, so the
|
|
1243
|
+
* wait survives a reboot mid-observation. Rejects on timeout (OniroError) or
|
|
1244
|
+
* abort (CancelledError).
|
|
1245
|
+
*/
|
|
1246
|
+
declare function waitForLog(opts: WaitForLogOptions): Promise<HilogEntry>;
|
|
1247
|
+
interface WatchLogOptions {
|
|
1248
|
+
config: ConfigProvider;
|
|
1249
|
+
pattern: RegExp;
|
|
1250
|
+
/** How long to collect matching entries. */
|
|
1251
|
+
durationMs: number;
|
|
1252
|
+
bundle?: string;
|
|
1253
|
+
domain?: string | number;
|
|
1254
|
+
deviceSerial?: string;
|
|
1255
|
+
/** Collapse consecutive duplicate lines. Default true. */
|
|
1256
|
+
dedup?: boolean;
|
|
1257
|
+
abortSignal?: AbortSignal;
|
|
1258
|
+
logger?: Logger;
|
|
1259
|
+
}
|
|
1260
|
+
/** Collect all hilog entries matching `pattern` for `durationMs`. Deduped by default. */
|
|
1261
|
+
declare function watchLog(opts: WatchLogOptions): Promise<HilogEntry[]>;
|
|
1262
|
+
interface DumpLogOptions {
|
|
1263
|
+
config: ConfigProvider;
|
|
1264
|
+
/** Cap the result to the last N lines (device-side `tail -n`). */
|
|
1265
|
+
lines?: number;
|
|
1266
|
+
/** Restrict to a bundle's running pid (no output if it isn't running). */
|
|
1267
|
+
bundle?: string;
|
|
1268
|
+
/** Extended-regex string applied device-side via `grep -E`. */
|
|
1269
|
+
grep?: string;
|
|
1270
|
+
domain?: string | number;
|
|
1271
|
+
deviceSerial?: string;
|
|
1272
|
+
timeoutMs?: number;
|
|
1273
|
+
logger?: Logger;
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* One-shot `hilog -x` dump, optionally filtered by domain, bundle pid, and a
|
|
1277
|
+
* grep regex, capped to the last `lines`. Mirrors the proven MCP get_logs
|
|
1278
|
+
* pipeline. Returns parsed entries.
|
|
1279
|
+
*/
|
|
1280
|
+
declare function dumpLog(opts: DumpLogOptions): Promise<HilogEntry[]>;
|
|
528
1281
|
|
|
529
1282
|
interface RunHvigorwOptions {
|
|
530
1283
|
config: ConfigProvider;
|
|
@@ -539,6 +1292,13 @@ interface RunHvigorwOptions {
|
|
|
539
1292
|
task?: string;
|
|
540
1293
|
/** Extra raw args appended after the standard ones. */
|
|
541
1294
|
extraArgs?: readonly string[];
|
|
1295
|
+
/**
|
|
1296
|
+
* Build modules in parallel. Default `true`. Pass `false` to add `--no-parallel`
|
|
1297
|
+
* for projects that require serial builds.
|
|
1298
|
+
*/
|
|
1299
|
+
parallel?: boolean;
|
|
1300
|
+
/** Abort the build; rejects with CancelledError and kills the hvigorw process. */
|
|
1301
|
+
abortSignal?: AbortSignal;
|
|
542
1302
|
logger?: Logger;
|
|
543
1303
|
/**
|
|
544
1304
|
* Optional callback for each stdout/stderr chunk, lets callers stream output
|
|
@@ -549,12 +1309,132 @@ interface RunHvigorwOptions {
|
|
|
549
1309
|
interface RunHvigorwResult {
|
|
550
1310
|
exitCode: number;
|
|
551
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Build the hvigorw argv. Pure (no I/O) so it is unit-testable. `--no-parallel`
|
|
1314
|
+
* is added ONLY when `parallel === false` — builds are parallel by default.
|
|
1315
|
+
*/
|
|
1316
|
+
declare function buildHvigorwArgs(opts: {
|
|
1317
|
+
task?: string;
|
|
1318
|
+
product?: string;
|
|
1319
|
+
module?: string;
|
|
1320
|
+
buildMode?: string;
|
|
1321
|
+
parallel?: boolean;
|
|
1322
|
+
extraArgs?: readonly string[];
|
|
1323
|
+
}): string[];
|
|
552
1324
|
/**
|
|
553
1325
|
* Run the project's `hvigorw` wrapper. Replaces the extension's vscode-tasks indirection
|
|
554
1326
|
* and the bash CLI's chained `clean` + `assembleHap` calls with a single direct spawn.
|
|
555
1327
|
*/
|
|
556
1328
|
declare function runHvigorw(opts: RunHvigorwOptions): Promise<RunHvigorwResult>;
|
|
557
1329
|
|
|
1330
|
+
interface ModuleHaps {
|
|
1331
|
+
signed: string[];
|
|
1332
|
+
unsigned: string[];
|
|
1333
|
+
}
|
|
1334
|
+
interface DiscoverHapsOptions {
|
|
1335
|
+
projectDir: string;
|
|
1336
|
+
/** Max directory recursion depth. Default 8. */
|
|
1337
|
+
maxDepth?: number;
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Walk a project's build outputs and group `*-signed.hap` / `*-unsigned.hap`
|
|
1341
|
+
* by build module name (parsed from the HAP filename). Skips `node_modules` /
|
|
1342
|
+
* `oh_modules` / `.git`. Ported from the proven MCP `findHaps`, extended with
|
|
1343
|
+
* per-module grouping so multi-module projects can install the right HAP.
|
|
1344
|
+
* Empty object when nothing is built.
|
|
1345
|
+
*/
|
|
1346
|
+
declare function discoverHaps(opts: DiscoverHapsOptions): Promise<Record<string, ModuleHaps>>;
|
|
1347
|
+
|
|
1348
|
+
interface RunOhpmOptions {
|
|
1349
|
+
config: ConfigProvider;
|
|
1350
|
+
projectDir: string;
|
|
1351
|
+
args: readonly string[];
|
|
1352
|
+
timeoutMs?: number;
|
|
1353
|
+
abortSignal?: AbortSignal;
|
|
1354
|
+
onOutput?: OutputSink;
|
|
1355
|
+
logger?: Logger;
|
|
1356
|
+
}
|
|
1357
|
+
/** Run `ohpm <args>` in the project directory. Resolves with the raw result (any exit code). */
|
|
1358
|
+
declare function runOhpm(opts: RunOhpmOptions): Promise<HdcExecResult>;
|
|
1359
|
+
/**
|
|
1360
|
+
* Install dependencies (`ohpm install --all`) only when `oh_modules/` is missing.
|
|
1361
|
+
* Returns `{ installed: true }` when it ran. Throws CommandFailedError if the
|
|
1362
|
+
* install ran and failed.
|
|
1363
|
+
*/
|
|
1364
|
+
declare function ensureOhModules(opts: {
|
|
1365
|
+
config: ConfigProvider;
|
|
1366
|
+
projectDir: string;
|
|
1367
|
+
abortSignal?: AbortSignal;
|
|
1368
|
+
onOutput?: OutputSink;
|
|
1369
|
+
logger?: Logger;
|
|
1370
|
+
}): Promise<{
|
|
1371
|
+
installed: boolean;
|
|
1372
|
+
}>;
|
|
1373
|
+
|
|
1374
|
+
interface CodelinterFinding {
|
|
1375
|
+
file: string;
|
|
1376
|
+
line: number;
|
|
1377
|
+
severity: string;
|
|
1378
|
+
/** Rule code/id when present in the output, else ''. */
|
|
1379
|
+
code: string;
|
|
1380
|
+
message: string;
|
|
1381
|
+
}
|
|
1382
|
+
interface CodelinterResult {
|
|
1383
|
+
/** codelinter process exit code. */
|
|
1384
|
+
code: number;
|
|
1385
|
+
findings: CodelinterFinding[];
|
|
1386
|
+
/** Combined stdout+stderr, for callers that want the raw report. */
|
|
1387
|
+
raw: string;
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Best-effort parser for codelinter output lines of the shape
|
|
1391
|
+
* `<file>:<line>[:<col>]: <severity>: <message> [<rule-code>]`. Lines that don't
|
|
1392
|
+
* match are ignored. Exported as a pure function so it is unit-testable.
|
|
1393
|
+
*/
|
|
1394
|
+
declare function parseCodelinterFindings(output: string): CodelinterFinding[];
|
|
1395
|
+
interface RunCodelinterOptions {
|
|
1396
|
+
config: ConfigProvider;
|
|
1397
|
+
projectDir: string;
|
|
1398
|
+
/** Files/globs to lint; when omitted, codelinter is run with no file args. */
|
|
1399
|
+
files?: readonly string[];
|
|
1400
|
+
timeoutMs?: number;
|
|
1401
|
+
abortSignal?: AbortSignal;
|
|
1402
|
+
logger?: Logger;
|
|
1403
|
+
}
|
|
1404
|
+
/** Run the OpenHarmony codelinter and return parsed findings + the raw report. */
|
|
1405
|
+
declare function runCodelinter(opts: RunCodelinterOptions): Promise<CodelinterResult>;
|
|
1406
|
+
|
|
1407
|
+
interface BuildHapOptions {
|
|
1408
|
+
config: ConfigProvider;
|
|
1409
|
+
projectDir: string;
|
|
1410
|
+
product?: string;
|
|
1411
|
+
module?: string;
|
|
1412
|
+
/** Forwarded as hvigor `buildMode` (e.g. release, debug). */
|
|
1413
|
+
mode?: string;
|
|
1414
|
+
/** hvigor task. Default `assembleHap`. */
|
|
1415
|
+
task?: string;
|
|
1416
|
+
/** Run `ohpm install --all` first when `oh_modules/` is missing. Default true. */
|
|
1417
|
+
autoInstallDeps?: boolean;
|
|
1418
|
+
/** Build modules in parallel. Default true (see runHvigorw). */
|
|
1419
|
+
parallel?: boolean;
|
|
1420
|
+
abortSignal?: AbortSignal;
|
|
1421
|
+
onOutput?: (chunk: string, stream: 'stdout' | 'stderr') => void;
|
|
1422
|
+
logger?: Logger;
|
|
1423
|
+
}
|
|
1424
|
+
interface BuildHapResult {
|
|
1425
|
+
exitCode: number;
|
|
1426
|
+
durationMs: number;
|
|
1427
|
+
/** Built HAPs grouped by module folder. */
|
|
1428
|
+
discoveredHaps: Record<string, ModuleHaps>;
|
|
1429
|
+
warnings: string[];
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* High-level build orchestration: ensure deps → run hvigorw → discover the
|
|
1433
|
+
* produced HAPs. The single call the CLI and MCP want; `runHvigorw` stays a raw
|
|
1434
|
+
* single-spawn primitive.
|
|
1435
|
+
*/
|
|
1436
|
+
declare function buildHap(opts: BuildHapOptions): Promise<BuildHapResult>;
|
|
1437
|
+
|
|
558
1438
|
/**
|
|
559
1439
|
* Conservative project-folder-name validator (no path separators, conservative charset).
|
|
560
1440
|
*/
|
|
@@ -610,6 +1490,55 @@ interface CreateScaffoldResult {
|
|
|
610
1490
|
*/
|
|
611
1491
|
declare function createScaffold(opts: CreateScaffoldOptions): Promise<CreateScaffoldResult>;
|
|
612
1492
|
|
|
1493
|
+
interface ProjectModule {
|
|
1494
|
+
name: string;
|
|
1495
|
+
/** Source path relative to the project root (e.g. `./entry`). */
|
|
1496
|
+
srcPath: string;
|
|
1497
|
+
/** Target names declared under the module (often empty). */
|
|
1498
|
+
targets: string[];
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Read the `modules[]` declared in `build-profile.json5` so callers can target a
|
|
1502
|
+
* specific module in a multi-module project.
|
|
1503
|
+
*/
|
|
1504
|
+
declare function listModules(opts: {
|
|
1505
|
+
projectDir: string;
|
|
1506
|
+
}): ProjectModule[];
|
|
1507
|
+
|
|
1508
|
+
interface AbilityInfo {
|
|
1509
|
+
name: string;
|
|
1510
|
+
type?: string;
|
|
1511
|
+
visible?: boolean;
|
|
1512
|
+
srcEntry?: string;
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Read all abilities declared in a module's `module.json5` `abilities[]`.
|
|
1516
|
+
* Defaults to the `entry` module folder.
|
|
1517
|
+
*/
|
|
1518
|
+
declare function listAbilities(opts: {
|
|
1519
|
+
projectDir: string;
|
|
1520
|
+
moduleName?: string;
|
|
1521
|
+
}): AbilityInfo[];
|
|
1522
|
+
|
|
1523
|
+
interface PrepareSigningOptions {
|
|
1524
|
+
config: ConfigProvider;
|
|
1525
|
+
projectDir: string;
|
|
1526
|
+
apl?: Apl;
|
|
1527
|
+
appFeature?: AppFeature;
|
|
1528
|
+
acls?: string[];
|
|
1529
|
+
passwords?: SigningPasswords;
|
|
1530
|
+
logger?: Logger;
|
|
1531
|
+
}
|
|
1532
|
+
interface PrepareSigningResult {
|
|
1533
|
+
source: 'present' | 'fresh';
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Ensure a project has signing material: a no-op when `signatures/` +
|
|
1537
|
+
* signingConfigs already exist ('present'), otherwise generate them via
|
|
1538
|
+
* {@link generateSigningConfigs} ('fresh', which needs java + the SDK).
|
|
1539
|
+
*/
|
|
1540
|
+
declare function prepareSigning(opts: PrepareSigningOptions): PrepareSigningResult;
|
|
1541
|
+
|
|
613
1542
|
declare function readJson5File<T>(filePath: string): T;
|
|
614
1543
|
/**
|
|
615
1544
|
* Write strict JSON content (quoted keys) to a `.json5` file. Keeps the file
|
|
@@ -619,6 +1548,127 @@ declare function writeJson5File(filePath: string, value: unknown): void;
|
|
|
619
1548
|
declare function readJsonFile<T>(filePath: string): T;
|
|
620
1549
|
declare function writeJsonFile(filePath: string, value: unknown): void;
|
|
621
1550
|
|
|
1551
|
+
interface HidumperOptions {
|
|
1552
|
+
config: ConfigProvider;
|
|
1553
|
+
deviceSerial?: string;
|
|
1554
|
+
timeoutMs?: number;
|
|
1555
|
+
logger?: Logger;
|
|
1556
|
+
}
|
|
1557
|
+
interface ScreenDump {
|
|
1558
|
+
width: number;
|
|
1559
|
+
height: number;
|
|
1560
|
+
/** Raw hidumper screen output. */
|
|
1561
|
+
raw: string;
|
|
1562
|
+
}
|
|
1563
|
+
/** `hidumper -s 10 -a screen` → parsed render resolution + raw text, or null. */
|
|
1564
|
+
declare function dumpScreen(opts: HidumperOptions): Promise<ScreenDump | null>;
|
|
1565
|
+
/** `hidumper -s WindowManagerService -a -a` — windows in z-order with surface presence. */
|
|
1566
|
+
declare function dumpWindow(opts: HidumperOptions): Promise<string>;
|
|
1567
|
+
/** `hidumper -s RenderService -a allInfo` — composition state / refresh rate. */
|
|
1568
|
+
declare function dumpRenderService(opts: HidumperOptions): Promise<string>;
|
|
1569
|
+
|
|
1570
|
+
interface DeviceFullInfo {
|
|
1571
|
+
serial: string;
|
|
1572
|
+
model?: string;
|
|
1573
|
+
manufacturer?: string;
|
|
1574
|
+
brand?: string;
|
|
1575
|
+
osFullName?: string;
|
|
1576
|
+
osReleaseType?: string;
|
|
1577
|
+
sdkApiVersion?: string;
|
|
1578
|
+
buildVersion?: string;
|
|
1579
|
+
display: {
|
|
1580
|
+
width: number;
|
|
1581
|
+
height: number;
|
|
1582
|
+
} | null;
|
|
1583
|
+
}
|
|
1584
|
+
interface GetDeviceInfoOptions {
|
|
1585
|
+
config: ConfigProvider;
|
|
1586
|
+
deviceSerial?: string;
|
|
1587
|
+
timeoutMs?: number;
|
|
1588
|
+
logger?: Logger;
|
|
1589
|
+
}
|
|
1590
|
+
/** Collate device properties (`param get` × N) and the display resolution. */
|
|
1591
|
+
declare function getDeviceInfo(opts: GetDeviceInfoOptions): Promise<DeviceFullInfo>;
|
|
1592
|
+
|
|
1593
|
+
interface HapAssetDiff {
|
|
1594
|
+
/** File paths present in the new HAP but not the installed one. */
|
|
1595
|
+
addedAssetPaths: string[];
|
|
1596
|
+
/** File paths present in the installed HAP but not the new one. */
|
|
1597
|
+
removedAssetPaths: string[];
|
|
1598
|
+
}
|
|
1599
|
+
/** Pure set-diff of two file-name listings, sorted. */
|
|
1600
|
+
declare function diffEntryNames(installed: Iterable<string>, next: Iterable<string>): HapAssetDiff;
|
|
1601
|
+
/**
|
|
1602
|
+
* Diff the file manifests of two HAP (zip) archives. Drives the ACE-extractor
|
|
1603
|
+
* cache-invalidation reboot decision in `applyChanges`: when the new HAP adds or
|
|
1604
|
+
* renames file paths vs the installed one, the path-keyed asset cache can serve
|
|
1605
|
+
* stale "GetAsset failed" errors until a reboot.
|
|
1606
|
+
*/
|
|
1607
|
+
declare function diffHapAssets(opts: {
|
|
1608
|
+
installedHap: string;
|
|
1609
|
+
newHap: string;
|
|
1610
|
+
}): Promise<HapAssetDiff>;
|
|
1611
|
+
|
|
1612
|
+
type InstallMethod = 'replace' | 'uninstall-install' | 'refuse';
|
|
1613
|
+
/**
|
|
1614
|
+
* P0-5a decision: how to install given whether `hdc install -r` reported a
|
|
1615
|
+
* sign-info-inconsistent error (9568332). System bundles are NOT silently
|
|
1616
|
+
* uninstalled (that can brick the device) unless explicitly allowed.
|
|
1617
|
+
*/
|
|
1618
|
+
declare function decideInstallMethod(s: {
|
|
1619
|
+
signInfoInconsistent: boolean;
|
|
1620
|
+
isSystemBundle: boolean;
|
|
1621
|
+
allowUninstall: boolean;
|
|
1622
|
+
}): InstallMethod;
|
|
1623
|
+
interface RebootDecision {
|
|
1624
|
+
reboot: boolean;
|
|
1625
|
+
reason: 'asset-cache' | 'pid-unchanged' | 'none';
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* P0-5b/c decision: whether to reboot after installing. Reboot when the HAP's
|
|
1629
|
+
* asset paths changed (ACE extractor cache is path-keyed and survives a process
|
|
1630
|
+
* kill), or when a persistent/system bundle's process didn't restart.
|
|
1631
|
+
*/
|
|
1632
|
+
declare function decideReboot(s: {
|
|
1633
|
+
assetsChanged: boolean;
|
|
1634
|
+
isSystemBundle: boolean;
|
|
1635
|
+
preInstallPid: number | null;
|
|
1636
|
+
postInstallPid: number | null;
|
|
1637
|
+
}): RebootDecision;
|
|
1638
|
+
interface ApplyChangesOptions {
|
|
1639
|
+
config: ConfigProvider;
|
|
1640
|
+
bundle: string;
|
|
1641
|
+
/** Explicit HAP path. If omitted, resolved from projectDir (+ module) via discoverHaps. */
|
|
1642
|
+
hapPath?: string;
|
|
1643
|
+
projectDir?: string;
|
|
1644
|
+
module?: string;
|
|
1645
|
+
/** Local path to the currently-installed HAP; enables the asset-cache diff/reboot. */
|
|
1646
|
+
installedHapPath?: string;
|
|
1647
|
+
/** Persistent/system bundle (e.g. systemui). Default false. */
|
|
1648
|
+
isSystemBundle?: boolean;
|
|
1649
|
+
/** Permit uninstalling a system bundle on sign-info mismatch (dangerous). Default false. */
|
|
1650
|
+
allowUninstall?: boolean;
|
|
1651
|
+
deviceSerial?: string;
|
|
1652
|
+
abortSignal?: AbortSignal;
|
|
1653
|
+
logger?: Logger;
|
|
1654
|
+
}
|
|
1655
|
+
interface ApplyChangesResult {
|
|
1656
|
+
method: 'replace' | 'uninstall-install' | 'reboot';
|
|
1657
|
+
preInstallPid: number | null;
|
|
1658
|
+
postInstallPid: number | null;
|
|
1659
|
+
replaced: boolean;
|
|
1660
|
+
/** True when an asset-path change forced the reboot. */
|
|
1661
|
+
cacheCleared: boolean;
|
|
1662
|
+
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Install a HAP and verify the running process took the change. Handles the
|
|
1665
|
+
* three failure modes the naive "install the most recent signed HAP" deploy
|
|
1666
|
+
* ignores: sign-info-inconsistent on `-r`, asset-cache invalidation, and a
|
|
1667
|
+
* persistent bundle that didn't restart. See {@link decideInstallMethod} /
|
|
1668
|
+
* {@link decideReboot} for the (pure, tested) branch logic.
|
|
1669
|
+
*/
|
|
1670
|
+
declare function applyChanges(opts: ApplyChangesOptions): Promise<ApplyChangesResult>;
|
|
1671
|
+
|
|
622
1672
|
declare const VERSION: string;
|
|
623
1673
|
|
|
624
|
-
export { ALL_SDKS, APL_VALUES, APP_FEATURE_VALUES, type Apl, type AppFeature, CancelledError, ChecksumMismatchError, CmdToolsNotInstalledError, type CmdToolsStatus, type ConfigKey, type ConfigProvider, type CreateScaffoldOptions, type CreateScaffoldResult, type DownloadOptions, type ExtractZipOptions, type GenerateSigningConfigsOptions, type HilogEntry, type HilogLevel, type InstallAppOptions, type InstallCmdToolsOptions, type InstallEmulatorOptions, type InstallSdkOptions, type LaunchAppOptions, type Logger, OHOS_URL_BASE, type OniroContext, OniroError, type OsFolder, type ProgressReporter, type ProgressUpdate, type Prompter, type RunHvigorwOptions, type RunHvigorwResult, type RunningProcess, type SdkArchiveInfo, type SdkInfo, SdkNotInstalledError, type SdkRelease, type SetHilogLevelOptions, type SigningKind, type StartEmulatorOptions, type StreamHilogOptions, type TemplateOption, UnsupportedPlatformError, VERSION, attemptHdcConnection, consoleLogger, createMaterial, createScaffold, decryptPwd, defaultContext, defaultPaths, detectProjectSdkVersion, detectSigningConfigNames, downloadAndInstallSdk, downloadFile, encryptPwd, extractTarball, extractZipWithProgress, findAppProcessId, findCmdToolsSourceDir, generateSigningConfigs, getBundleName, getCmdToolsBin, getCmdToolsDownloadUrl, getCmdToolsPath, getCmdToolsStatus, getEmulatorDir, getHdcPath, getHvigorwPath, getInstalledSdks, getKey, getMainAbility, getOhosBaseSdkHome, getOsFolder, getSdkFilename, getSdkRootDir, getSupportedSdksForUi, installApp, installCmdTools, installEmulator, isCmdToolsInstalled, isEmulatorInstalled, isValidBundleName, isValidProjectName, launchApp, listRunningProcesses, listTemplates, nonInteractivePrompter, noopLogger, noopProgress, parseHilogLine, pickSigningKind, readJson5File, readJsonFile, removeCmdTools, removeEmulator, removeSdk, runHvigorw, setHilogLevel, startEmulator, staticConfig, stopEmulator, streamHilog, validateTemplateLayout, verifySha256, writeJson5File, writeJsonFile };
|
|
1674
|
+
export { ALL_SDKS, APL_VALUES, APP_FEATURE_VALUES, type AbilityInfo, type Apl, type AppFeature, type ApplyChangesOptions, type ApplyChangesResult, type BuildHapOptions, type BuildHapResult, type BundleOptions, CancelledError, type CaptureBurstOptions, ChecksumMismatchError, CmdToolsNotInstalledError, type CmdToolsStatus, type CodelinterFinding, type CodelinterResult, CommandFailedError, type ConfigKey, type ConfigProvider, type CreateScaffoldOptions, type CreateScaffoldResult, type DeviceFullInfo, type DeviceInfo, type DiscoverHapsOptions, type DisplaySize, type DisplaySizeOptions, type DownloadOptions, type DumpLayoutOptions, type DumpLayoutResult, type DumpLogOptions, type ExtractZipOptions, type GenerateSigningConfigsOptions, type GestureUitestOptions, type GetDeviceInfoOptions, type HapAssetDiff, type HdcExecOptions, type HdcExecResult, type HdcShellOptions, type HidumperOptions, type HilogEntry, type HilogLevel, INSTALL_TMP_DIRNAME, type InputType, type InstallAppOptions, type InstallAppResult, type InstallCmdToolsOptions, type InstallEmulatorOptions, type InstallMethod, type InstallSdkOptions, type InstallTempDir, type InstallTempDirOptions, InsufficientSpaceError, type LaunchAppOptions, type LayoutNode, type Logger, type ModuleHaps, OHOS_URL_BASE, type OniroContext, OniroError, type OsFolder, type OutputSink, type ParamOptions, type PrepareSigningOptions, type PrepareSigningResult, type ProgressReporter, type ProgressUpdate, type ProjectModule, type Prompter, type RawLayoutNode, type RawTouchEvent, type RebootDecision, type RebootOptions, type RecvFileOptions, type RunCodelinterOptions, type RunHvigorwOptions, type RunHvigorwResult, type RunOhpmOptions, type RunProcessOptions, type RunningProcess, type ScreenDump, type Screenshot, type ScreenshotOptions, type SdkArchiveInfo, type SdkInfo, SdkNotInstalledError, type SdkRelease, type SendFileOptions, type SendGestureOptions, type SendInputOptions, type SendRawTouchOptions, type SetHilogLevelOptions, type SigningKind, type SigningPasswords, type StartEmulatorOptions, type StreamHilogOptions, TMP_DIR_HINT, type TemplateOption, UnsupportedPlatformError, VERSION, type WaitForBootOptions, type WaitForBundleOptions, type WaitForConditionOptions, type WaitForLogOptions, type WatchLogOptions, type Waypoint, applyChanges, attemptHdcConnection, buildGestureCommands, buildGestureUitestCommand, buildHap, buildHvigorwArgs, buildInputCommand, buildRawTouchCommand, captureBurst, consoleLogger, createInstallTempDir, createMaterial, createScaffold, createTempWorkDir, decideInstallMethod, decideReboot, decryptPwd, dedupEntries, defaultContext, defaultPaths, detectAaStartFailure, detectProjectSdkVersion, detectSigningConfigNames, diffEntryNames, diffHapAssets, discoverHaps, downloadAndInstallSdk, downloadFile, dumpLayout, dumpLog, dumpRenderService, dumpScreen, dumpWindow, encryptPwd, ensureFreeSpace, ensureOhModules, ensureOk, ensureRemoteOk, extractTarball, extractZipWithProgress, findAppProcessId, findCmdToolsSourceDir, findRunningProcess, forceStop, formatBytes, generateSigningConfigs, getBundleName, getCmdToolsBin, getCmdToolsDownloadUrl, getCmdToolsPath, getCmdToolsStatus, getDeviceInfo, getDisplaySize, getEmulatorDir, getFreeSpaceBytes, getHdcPath, getHvigorwPath, getInstalledSdks, getKey, getMainAbility, getOhosBaseSdkHome, getOhpmPath, getOsFolder, getSdkFilename, getSdkRootDir, getSupportedSdksForUi, hdcExec, installApp, installCmdTools, installEmulator, isCmdToolsInstalled, isEmulatorInstalled, isOutOfSpaceError, isRamBackedPath, isValidBundleName, isValidProjectName, launchApp, listAbilities, listDevices, listModules, listRunningProcesses, listTemplates, nonInteractivePrompter, noopLogger, noopProgress, paramGet, paramSet, parseBounds, parseCodelinterFindings, parseDeviceList, parseHilogLine, parseMainAbilityFromBmDump, parseRemoteExit, pickSigningKind, prepareSigning, pruneLayout, readJson5File, readJsonFile, reboot, recvFile, removeCmdTools, removeEmulator, removeSdk, removeTempWorkDir, resolveTmpRoot, runCodelinter, runHvigorw, runOhpm, runProcess, scopedLogger, selectDevice, sendFile, sendGesture, sendInput, sendRawTouch, setHilogLevel, shell, shellChecked, startEmulator, staticConfig, stopEmulator, streamHilog, takeScreenshot, toSpaceError, uninstallApp, validateTemplateLayout, verifySha256, waitForBoot, waitForBundle, waitForCondition, waitForLog, watchLog, waypointsToRawEvents, writeJson5File, writeJsonFile };
|