@oniroproject/oniro-app 0.18.0 → 0.19.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 +32 -1
- package/dist/oniro-app.js +232 -8
- package/dist/oniro-app.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -387,6 +387,35 @@ The SDK is `--sdk <dir>`, else `<sdk home>/<--api>`, else the one the project's
|
|
|
387
387
|
| `--no-other-sdks` | `show` only: on a miss, do not look in the other installed SDKs. |
|
|
388
388
|
| `--json` | `search`: `sdk` (`dir`, `api`, `version`, `source`), `query`, `total`, `hits` (the fields above as `name`, `qualifiedName`, `kind`, `kit`, `import`, `global`, `module`, `since`, `sinceText`, `deprecated`, `deprecatedSince`, `useInstead`, `syscap`, `systemApi`, `file`, `path`, `line`, `signature`, `doc`, `overloads`, `score`). `show`: `sdk`, `symbol`, `found`, `entries`, and on a miss `alsoIn` (`[{ api, since }]`) and `suggestions`. |
|
|
389
389
|
|
|
390
|
+
#### `docs sync` / `docs search` / `docs show` — read the OpenHarmony documentation
|
|
391
|
+
|
|
392
|
+
The application-development documentation of the OpenHarmony release matching the SDK (`en/application-dev` of [gitcode.com/openharmony/docs](https://gitcode.com/openharmony/docs)): usage guides (ArkUI components, navigation, state management, data storage, abilities), kit API prose, the business error codes each kit throws and platform behaviour (lifecycle, permissions, threads). `api search` says whether a symbol exists and with what signature; this says how it is used.
|
|
393
|
+
|
|
394
|
+
- `docs sync` clones the release's tree once: a partial, sparse clone without figures, about 100 MB (a plain clone of the tree is 2 GB), under `<sdkRootDir>/docs/<branch>` (`ONIRO_DOCS_DIR`). The branch comes from the SDK's version (`6.1.0.31` → `OpenHarmony-6.1-Release`, `5.1.0.107` → `OpenHarmony-5.1.0-Release`) or `--ref`. A second `sync` brings the clone up to date. Needs `git`.
|
|
395
|
+
- `docs search <query...>` ranks documents that contain every word (any word when none does) by where the words occur: title, headings, path, body; a camelCase or dotted identifier also matches by its parts (`NavPathStack` → nav, path, stack, weighing less). A document whose title is exactly a query word, or that holds the whole query in a title or heading, ranks higher; the generated API reference a little below the guides; system-API pages and tables of contents below everything. Each hit prints the path, the title, the matching sections with their line numbers and the first line. Exits 1 when nothing matches. The index is built in memory on first use (about 3 s for 5,000 documents) and answers in milliseconds.
|
|
396
|
+
- `docs show <path>` prints one document (a path `search` printed, relative to `en/application-dev`), or one section of it with `--heading` (a heading or a distinctive part of it, case-insensitive: from that heading to the next of the same or a higher level). Image lines and inline HTML are dropped; a long document is cut at `--lines` (default 250) with the list of its sections, so ask for a heading rather than the whole file. Exits 1 when the document or heading does not exist, suggesting close paths or the document's headings.
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
$ oniro-app docs search --api 23 relationalStore insert
|
|
400
|
+
reference/apis-arkdata/arkts-apis-data-relationalStore-RdbStore.md — Interface (RdbStore)
|
|
401
|
+
sections: "insert" (line 94), "insert10+" (line 178), "insertSync12+" (line 443), …
|
|
402
|
+
Provides APIs for managing data in an RDB store.
|
|
403
|
+
…
|
|
404
|
+
$ oniro-app docs show --api 23 reference/apis-arkdata/errorcode-data-rdb.md --heading 14800011
|
|
405
|
+
## 14800011 Database File Corrupted
|
|
406
|
+
…
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
| Flag | Description |
|
|
410
|
+
| --- | --- |
|
|
411
|
+
| `--api <level>` / `--sdk <dir>` / `--project <dir>` | The SDK whose release picks the docs, as for `api search`. |
|
|
412
|
+
| `--ref <branch>` | A docs branch or tag (`OpenHarmony-6.1-Release`, `master`) instead of the SDK-chosen one. |
|
|
413
|
+
| `--limit <n>` | `search` only: at most n hits (default 8). |
|
|
414
|
+
| `--section <dir>` | `search` only: only documents under this subtree (`ui`, `database`, `reference/errorcodes`, `application-models`). |
|
|
415
|
+
| `--heading <text>` | `show` only: only that section. |
|
|
416
|
+
| `--lines <n>` | `show` only: at most n lines (default 250). |
|
|
417
|
+
| `--json` | `sync`: `docs` (`ref`, `dir`, `tree`, `sdk`), `files`, `updated`, `commit`. `search`: `docs`, `query`, `terms`, `total`, `hits` (`path`, `title`, `score`, `headings` `[{ line, text }]`, `snippet`). `show`: `docs`, `found`, `path`, `text`, `truncated`, `lines`, `headings`; on a miss `error` and `suggestions`. |
|
|
418
|
+
|
|
390
419
|
#### `lint` — run the OpenHarmony codelinter
|
|
391
420
|
|
|
392
421
|
`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`, it exits 2: it skipped checks, so a clean report is not evidence of clean code. Its notices, and a hint when the flavour is the cause, go to stderr.
|
|
@@ -1005,10 +1034,12 @@ Tools (the inputs are the command's flags in camelCase, with the same defaults;
|
|
|
1005
1034
|
| `screens` | `screens --json` | `project` |
|
|
1006
1035
|
| `api_search` | `api search --json` | `query` (required), `kit`, `kind[]`, `lang`, `limit`, `deprecated`, `systemapi`, `api`, `sdk`, `project`, `rebuild` |
|
|
1007
1036
|
| `api_show` | `api show --json` | `symbol` (required), `kit`, `otherSdks`, `api`, `sdk`, `project`, `rebuild` |
|
|
1037
|
+
| `docs_search` | `docs search --json` | `query` (required), `limit`, `section`, `api`, `sdk`, `ref`, `project` |
|
|
1038
|
+
| `docs_show` | `docs show --json` | `path` (required), `heading`, `maxLines`, `api`, `sdk`, `ref`, `project` |
|
|
1008
1039
|
| `doctor` | `doctor --json` | `project`, `fix`, `device` (boolean, as `--no-device`), `serial`, `arktsCheck` |
|
|
1009
1040
|
| `devices` | `devices --json` | `long`; the array comes wrapped as `{ "devices": [...] }` |
|
|
1010
1041
|
|
|
1011
|
-
- **Errors.** A tool result has `isError: true` when the command would exit non-zero: a failed build, `check_arkts` with an error or one that could not run, a failed or incomplete test run, a failed smoke check, a `perf_trace` threshold exceeded or capture failed, an `api_show` miss or an `api_search` without hits, a failing `doctor` check, or a tool that threw (no device, a timeout, bad arguments). The JSON is still there to read. `logs_crash` is not an error when there was no crash; check `crashed`. JSON-RPC errors are kept for protocol problems (an unknown tool or method).
|
|
1042
|
+
- **Errors.** A tool result has `isError: true` when the command would exit non-zero: a failed build, `check_arkts` with an error or one that could not run, a failed or incomplete test run, a failed smoke check, a `perf_trace` threshold exceeded or capture failed, an `api_show` miss or an `api_search` without hits, a `docs_search` without hits, a `docs_show` of a missing document or heading, or either when the release's docs are not synced (the text says to run `docs sync`), a failing `doctor` check, or a tool that threw (no device, a timeout, bad arguments). The JSON is still there to read. `logs_crash` is not an error when there was no crash; check `crashed`. JSON-RPC errors are kept for protocol problems (an unknown tool or method).
|
|
1012
1043
|
- **Images.** `screenshot` returns the capture as an `image/jpeg` content block downscaled to `maxDim` (with `grid`, the 10x10 coordinate grid), plus its dimensions as JSON; `crop` and `target*` return a full-resolution crop, `contactSheet` the tiled burst, `diff` the comparison and the current screen. `output` also writes the image to a file (with `diff`, the full-resolution capture, usable as a later baseline).
|
|
1013
1044
|
- **Layouts.** `dump_layout` without `flat` or `summary` returns the whole tree; `flat` (text) is the cheap way to read a screen. `output` saves what is returned, so `{ "output": "before.json" }` then `{ "diff": "before.json" }` compares two moments.
|
|
1014
1045
|
|
package/dist/oniro-app.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/bin/oniro-app.ts
|
|
4
4
|
import { Command as Command11, CommanderError } from "commander";
|
|
5
|
-
import { OniroError as
|
|
5
|
+
import { OniroError as OniroError7 } from "@oniroproject/core";
|
|
6
6
|
|
|
7
7
|
// src/commands/sdk.ts
|
|
8
8
|
import * as fs from "fs";
|
|
@@ -80,7 +80,8 @@ var ENV_VAR_BY_KEY = {
|
|
|
80
80
|
harmonyosSdkPath: "ONIRO_HARMONYOS_SDK_PATH",
|
|
81
81
|
harmonyosAuthDir: "ONIRO_HARMONYOS_AUTH_DIR",
|
|
82
82
|
harmonyosSigningDir: "ONIRO_HARMONYOS_SIGNING_DIR",
|
|
83
|
-
cacheDir: "ONIRO_CACHE_DIR"
|
|
83
|
+
cacheDir: "ONIRO_CACHE_DIR",
|
|
84
|
+
docsDir: "ONIRO_DOCS_DIR"
|
|
84
85
|
};
|
|
85
86
|
function createEnvConfig(env = process.env) {
|
|
86
87
|
return {
|
|
@@ -3222,10 +3223,160 @@ function registerApiCommand(program) {
|
|
|
3222
3223
|
});
|
|
3223
3224
|
}
|
|
3224
3225
|
|
|
3226
|
+
// src/commands/docs.ts
|
|
3227
|
+
import {
|
|
3228
|
+
DocsIndex,
|
|
3229
|
+
docsDirFor,
|
|
3230
|
+
docsRefFor,
|
|
3231
|
+
docsTree,
|
|
3232
|
+
readSdkRelease,
|
|
3233
|
+
syncDocs,
|
|
3234
|
+
OniroError as OniroError5
|
|
3235
|
+
} from "@oniroproject/core";
|
|
3236
|
+
function selectDocs(opts) {
|
|
3237
|
+
const { config, logger } = getRuntime();
|
|
3238
|
+
if (opts.ref) return { ref: opts.ref, dir: docsDirFor(config, opts.ref) };
|
|
3239
|
+
const api = opts.api !== void 0 ? Number(opts.api) : void 0;
|
|
3240
|
+
let sel;
|
|
3241
|
+
try {
|
|
3242
|
+
sel = selectSdk(opts);
|
|
3243
|
+
} catch (err) {
|
|
3244
|
+
if (api === void 0 || !Number.isInteger(api) || api <= 0) throw err;
|
|
3245
|
+
const ref2 = docsRefFor({ api });
|
|
3246
|
+
logger.warn(`The API ${api} SDK is not installed; taking the ${ref2} docs for it.`);
|
|
3247
|
+
return { ref: ref2, dir: docsDirFor(config, ref2), sdk: { api } };
|
|
3248
|
+
}
|
|
3249
|
+
const release = readSdkRelease(sel.sdkDir);
|
|
3250
|
+
const ref = docsRefFor({ api: release.api ?? sel.api, version: release.version });
|
|
3251
|
+
return { ref, dir: docsDirFor(config, ref), sdk: { dir: sel.sdkDir, api: release.api ?? sel.api, version: release.version } };
|
|
3252
|
+
}
|
|
3253
|
+
function docsJson(sel, tree) {
|
|
3254
|
+
return { ref: sel.ref, dir: sel.dir, tree, sdk: sel.sdk };
|
|
3255
|
+
}
|
|
3256
|
+
function openDocs(sel) {
|
|
3257
|
+
const tree = docsTree(sel.dir);
|
|
3258
|
+
if (!tree) {
|
|
3259
|
+
const flag = sel.sdk?.api !== void 0 ? ` --api ${sel.sdk.api}` : sel.ref ? ` --ref ${sel.ref}` : "";
|
|
3260
|
+
throw new OniroError5(
|
|
3261
|
+
`The ${sel.ref} docs are not synced (no ${sel.dir}). Run \`oniro-app docs sync${flag}\` first (a partial clone of gitcode.com/openharmony/docs, about 100 MB).`
|
|
3262
|
+
);
|
|
3263
|
+
}
|
|
3264
|
+
return { tree, index: DocsIndex.load(tree) };
|
|
3265
|
+
}
|
|
3266
|
+
function runDocsSearch(query, opts) {
|
|
3267
|
+
const sel = selectDocs(opts);
|
|
3268
|
+
const { tree, index } = openDocs(sel);
|
|
3269
|
+
const limit = opts.limit !== void 0 ? Number(opts.limit) : void 0;
|
|
3270
|
+
if (limit !== void 0 && (!Number.isInteger(limit) || limit <= 0)) {
|
|
3271
|
+
throw new OniroError5(`--limit expects a positive number, got "${opts.limit}".`);
|
|
3272
|
+
}
|
|
3273
|
+
const result = index.search(query, { limit, section: opts.section });
|
|
3274
|
+
return { json: { docs: docsJson(sel, tree), ...result }, result, tree };
|
|
3275
|
+
}
|
|
3276
|
+
function runDocsShow(docPath, opts) {
|
|
3277
|
+
const sel = selectDocs(opts);
|
|
3278
|
+
const { tree, index } = openDocs(sel);
|
|
3279
|
+
const maxLines = opts.lines !== void 0 ? Number(opts.lines) : void 0;
|
|
3280
|
+
if (maxLines !== void 0 && (!Number.isInteger(maxLines) || maxLines <= 0)) {
|
|
3281
|
+
throw new OniroError5(`--lines expects a positive number, got "${opts.lines}".`);
|
|
3282
|
+
}
|
|
3283
|
+
const result = index.show(docPath, { heading: opts.heading, maxLines });
|
|
3284
|
+
return { json: { docs: docsJson(sel, tree), ...result }, result, tree };
|
|
3285
|
+
}
|
|
3286
|
+
async function runDocsSync(opts) {
|
|
3287
|
+
const { logger } = getRuntime();
|
|
3288
|
+
const sel = selectDocs(opts);
|
|
3289
|
+
const result = await syncDocs({ ref: sel.ref, dir: sel.dir, logger });
|
|
3290
|
+
const tree = docsTree(sel.dir);
|
|
3291
|
+
if (tree) DocsIndex.forget(tree);
|
|
3292
|
+
return { json: { docs: docsJson(sel, tree ?? sel.dir), sdk: sel.sdk, ...result }, result, sel };
|
|
3293
|
+
}
|
|
3294
|
+
function formatDocHit(h) {
|
|
3295
|
+
const lines = [`${h.path} \u2014 ${h.title}`];
|
|
3296
|
+
if (h.headings.length) lines.push(` sections: ${h.headings.map((x) => `"${x.text}" (line ${x.line})`).join(", ")}`);
|
|
3297
|
+
if (h.snippet) lines.push(` ${h.snippet}`);
|
|
3298
|
+
return lines.join("\n");
|
|
3299
|
+
}
|
|
3300
|
+
function registerDocsCommand(program) {
|
|
3301
|
+
const docs = program.command("docs").description(
|
|
3302
|
+
"Search the OpenHarmony application-development documentation (gitcode.com/openharmony/docs, `en/application-dev`) of the release matching the SDK: usage guides, kit API prose, business error codes and platform behaviour, which the SDK typings behind `api search` do not say. `docs sync` clones the release's tree once (a partial, sparse clone without figures, about 100 MB) under <sdkRootDir>/docs (ONIRO_DOCS_DIR)."
|
|
3303
|
+
);
|
|
3304
|
+
const docsOptions = (cmd) => cmd.option(
|
|
3305
|
+
"--api <level>",
|
|
3306
|
+
"The SDK API level whose release picks the docs. Default: the project's compileSdkVersion (from the current directory or --project), else the newest installed SDK."
|
|
3307
|
+
).option("--sdk <dir>", "An SDK API directory (holding ets/) whose version picks the docs.").option("--project <dir>", "The project whose compileSdkVersion picks the SDK (default: the current directory).").option("--ref <branch>", "A docs branch or tag (`OpenHarmony-6.1-Release`, `master`) instead of the SDK-chosen one.");
|
|
3308
|
+
docsOptions(
|
|
3309
|
+
docs.command("sync").description(
|
|
3310
|
+
"Clone the docs of the release matching the SDK (6.1.0.x \u2192 OpenHarmony-6.1-Release), or bring an existing clone up to date. Needs git."
|
|
3311
|
+
)
|
|
3312
|
+
).option("--json", "Print JSON: docs (ref, dir, tree, sdk), files, updated, commit.").action(async (opts) => {
|
|
3313
|
+
const { json, result, sel } = await runDocsSync(opts);
|
|
3314
|
+
if (opts.json) process.stdout.write(`${JSON.stringify(json, null, 2)}
|
|
3315
|
+
`);
|
|
3316
|
+
else {
|
|
3317
|
+
process.stdout.write(
|
|
3318
|
+
`${result.updated ? "Updated" : "Cloned"} the ${sel.ref} docs${result.commit ? ` (${result.commit})` : ""}: ${result.files} documents in ${result.dir}
|
|
3319
|
+
`
|
|
3320
|
+
);
|
|
3321
|
+
}
|
|
3322
|
+
});
|
|
3323
|
+
docsOptions(
|
|
3324
|
+
docs.command("search <query...>").description(
|
|
3325
|
+
"Ranked search: documents containing every word (any word when none does), scored by where the words occur (title, headings, path, body); a camelCase or dotted identifier also matches by its parts. Each hit names the sections that match, to read with `docs show`. Exits 1 when nothing matches."
|
|
3326
|
+
)
|
|
3327
|
+
).option("--limit <n>", "At most n hits.", "8").option("--section <dir>", "Only documents under this subtree: `ui`, `database`, `reference/errorcodes`, `application-models`.").option("--json", "Print JSON: docs (ref, dir, tree, sdk), query, terms, total, hits (path, title, score, headings, snippet).").action((words, opts) => {
|
|
3328
|
+
const { json, result, tree } = runDocsSearch(words.join(" "), opts);
|
|
3329
|
+
if (opts.json) {
|
|
3330
|
+
process.stdout.write(`${JSON.stringify(json, null, 2)}
|
|
3331
|
+
`);
|
|
3332
|
+
} else {
|
|
3333
|
+
for (const h of result.hits) process.stdout.write(`${formatDocHit(h)}
|
|
3334
|
+
|
|
3335
|
+
`);
|
|
3336
|
+
const shown = result.hits.length < result.total ? `${result.hits.length} of ${result.total}` : `${result.total}`;
|
|
3337
|
+
process.stdout.write(
|
|
3338
|
+
result.total ? `${shown} document${result.total === 1 ? "" : "s"} match; paths are relative to ${tree}.
|
|
3339
|
+
` : "No document matches; try fewer or different words (component or kit names, decorators, an error code).\n"
|
|
3340
|
+
);
|
|
3341
|
+
}
|
|
3342
|
+
process.exitCode = result.total ? 0 : 1;
|
|
3343
|
+
});
|
|
3344
|
+
docsOptions(
|
|
3345
|
+
docs.command("show <path>").description(
|
|
3346
|
+
"One document (a path `docs search` printed, relative to en/application-dev), or one section of it by heading. Images and inline HTML are dropped; long documents are cut at --lines with a list of their sections. Exits 1 when the document or heading does not exist, suggesting close paths or the headings."
|
|
3347
|
+
)
|
|
3348
|
+
).option("--heading <text>", "A heading (or a distinctive part of it, case-insensitive): only that section.").option("--lines <n>", "At most n lines (default 250).").option(
|
|
3349
|
+
"--json",
|
|
3350
|
+
"Print JSON: docs (ref, dir, tree, sdk), found, path, text, truncated, lines, headings; on a miss error and suggestions."
|
|
3351
|
+
).action((docPath, opts) => {
|
|
3352
|
+
const { json, result } = runDocsShow(docPath, opts);
|
|
3353
|
+
if (opts.json) {
|
|
3354
|
+
process.stdout.write(`${JSON.stringify(json, null, 2)}
|
|
3355
|
+
`);
|
|
3356
|
+
} else if (result.found) {
|
|
3357
|
+
process.stdout.write(`${result.text}
|
|
3358
|
+
`);
|
|
3359
|
+
if (!opts.heading && result.headings.length) {
|
|
3360
|
+
process.stdout.write(`
|
|
3361
|
+
[sections: ${result.headings.slice(0, 40).map((h) => h.text).join(" | ")}]
|
|
3362
|
+
`);
|
|
3363
|
+
}
|
|
3364
|
+
} else {
|
|
3365
|
+
process.stdout.write(`${result.error}
|
|
3366
|
+
`);
|
|
3367
|
+
if (result.suggestions.length) {
|
|
3368
|
+
process.stdout.write(` ${opts.heading ? "headings" : "close paths"}: ${result.suggestions.join(" | ")}
|
|
3369
|
+
`);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
process.exitCode = result.found ? 0 : 1;
|
|
3373
|
+
});
|
|
3374
|
+
}
|
|
3375
|
+
|
|
3225
3376
|
// src/commands/serve.ts
|
|
3226
3377
|
import * as fs10 from "fs";
|
|
3227
3378
|
import * as path19 from "path";
|
|
3228
|
-
import { OniroError as
|
|
3379
|
+
import { OniroError as OniroError6 } from "@oniroproject/core";
|
|
3229
3380
|
|
|
3230
3381
|
// src/mcp/protocol.ts
|
|
3231
3382
|
import * as readline2 from "readline";
|
|
@@ -4488,6 +4639,76 @@ var apiShow = {
|
|
|
4488
4639
|
return jsonResult(run.json, !run.found);
|
|
4489
4640
|
}
|
|
4490
4641
|
};
|
|
4642
|
+
var DOCS_PROPS = {
|
|
4643
|
+
api: int("The SDK API level whose release picks the docs (default: the project's compileSdkVersion, else the newest installed SDK)."),
|
|
4644
|
+
sdk: str("An SDK API directory (holding ets/) whose version picks the docs."),
|
|
4645
|
+
ref: str("A docs branch or tag (`OpenHarmony-6.1-Release`, `master`) instead of the SDK-chosen one."),
|
|
4646
|
+
...PROJECT
|
|
4647
|
+
};
|
|
4648
|
+
function docsOpts(a, ctx) {
|
|
4649
|
+
return {
|
|
4650
|
+
api: a.api !== void 0 ? String(a.api) : void 0,
|
|
4651
|
+
sdk: pathArg(a, "sdk", ctx),
|
|
4652
|
+
ref: a.ref,
|
|
4653
|
+
project: projectOf(a, ctx)
|
|
4654
|
+
};
|
|
4655
|
+
}
|
|
4656
|
+
var docsSearch = {
|
|
4657
|
+
name: "docs_search",
|
|
4658
|
+
title: "Search the OpenHarmony docs",
|
|
4659
|
+
description: "Ranked search of the OpenHarmony application-development documentation of the release matching the SDK (`oniro-app docs search --json`): usage guides (ArkUI components, navigation, state management, data storage, abilities), kit API prose, business error codes and platform behaviour, which the SDK typings behind api_search do not say. Documents containing every word rank by where the words occur (title, headings, path, body); each hit names the matching sections, to read with docs_show. Use domain words (a component, kit or decorator name, an error code), not sentences. Returns docs (ref, dir, tree, sdk), query, terms, total, hits (path, title, score, headings [{line, text}], snippet). isError when nothing matches, or when the docs are not synced (`oniro-app docs sync`).",
|
|
4660
|
+
inputSchema: object(
|
|
4661
|
+
{
|
|
4662
|
+
query: str('The search words, e.g. "LazyForEach reuse", "relationalStore insert", "14800011".'),
|
|
4663
|
+
limit: int("At most n hits.", { minimum: 1, maximum: 30, default: 8 }),
|
|
4664
|
+
section: str("Only documents under this subtree: `ui`, `database`, `reference/errorcodes`, `application-models`."),
|
|
4665
|
+
...DOCS_PROPS
|
|
4666
|
+
},
|
|
4667
|
+
["query"]
|
|
4668
|
+
),
|
|
4669
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
4670
|
+
changesDevice: false,
|
|
4671
|
+
async call(a, ctx) {
|
|
4672
|
+
try {
|
|
4673
|
+
const run = runDocsSearch(a.query, {
|
|
4674
|
+
...docsOpts(a, ctx),
|
|
4675
|
+
limit: a.limit !== void 0 ? String(a.limit) : void 0,
|
|
4676
|
+
section: a.section
|
|
4677
|
+
});
|
|
4678
|
+
return jsonResult(run.json, run.result.total === 0);
|
|
4679
|
+
} catch (err) {
|
|
4680
|
+
return errorResult(message(err));
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
};
|
|
4684
|
+
var docsShow = {
|
|
4685
|
+
name: "docs_show",
|
|
4686
|
+
title: "Read one OpenHarmony doc",
|
|
4687
|
+
description: "One documentation file (a path docs_search returned, relative to en/application-dev), or one section of it by heading (`oniro-app docs show --json`). Images and inline HTML are dropped; a long document is cut at maxLines with the list of its sections, so ask for a heading rather than the whole file. Returns docs, found, path, text, truncated, lines, headings; isError with suggestions (close paths, or the headings when the heading did not match).",
|
|
4688
|
+
inputSchema: object(
|
|
4689
|
+
{
|
|
4690
|
+
path: str("The document path, e.g. `ui/arkts-navigation-jump.md`."),
|
|
4691
|
+
heading: str("A heading (or a distinctive part of it, case-insensitive): only that section."),
|
|
4692
|
+
maxLines: int("At most n lines.", { minimum: 20, maximum: 1200, default: 250 }),
|
|
4693
|
+
...DOCS_PROPS
|
|
4694
|
+
},
|
|
4695
|
+
["path"]
|
|
4696
|
+
),
|
|
4697
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
4698
|
+
changesDevice: false,
|
|
4699
|
+
async call(a, ctx) {
|
|
4700
|
+
try {
|
|
4701
|
+
const run = runDocsShow(a.path, {
|
|
4702
|
+
...docsOpts(a, ctx),
|
|
4703
|
+
heading: a.heading,
|
|
4704
|
+
lines: a.maxLines !== void 0 ? String(a.maxLines) : void 0
|
|
4705
|
+
});
|
|
4706
|
+
return jsonResult(run.json, !run.result.found);
|
|
4707
|
+
} catch (err) {
|
|
4708
|
+
return errorResult(message(err));
|
|
4709
|
+
}
|
|
4710
|
+
}
|
|
4711
|
+
};
|
|
4491
4712
|
var doctor = {
|
|
4492
4713
|
name: "doctor",
|
|
4493
4714
|
title: "Check the toolchain",
|
|
@@ -4552,6 +4773,8 @@ var ALL_TOOLS = [
|
|
|
4552
4773
|
screens,
|
|
4553
4774
|
apiSearch,
|
|
4554
4775
|
apiShow,
|
|
4776
|
+
docsSearch,
|
|
4777
|
+
docsShow,
|
|
4555
4778
|
doctor,
|
|
4556
4779
|
devices
|
|
4557
4780
|
];
|
|
@@ -4568,7 +4791,7 @@ function selectTools(names, readOnly) {
|
|
|
4568
4791
|
function parseToolList(raw) {
|
|
4569
4792
|
if (raw === void 0) return void 0;
|
|
4570
4793
|
const names = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
4571
|
-
if (!names.length) throw new
|
|
4794
|
+
if (!names.length) throw new OniroError6("--tools needs at least one tool name.");
|
|
4572
4795
|
return names;
|
|
4573
4796
|
}
|
|
4574
4797
|
function instructions(ctx, toolCount) {
|
|
@@ -4581,9 +4804,9 @@ function registerServeCommand(program) {
|
|
|
4581
4804
|
).allowExcessArguments(false).option("--project <dir>", "Project the tools work on unless a call names another (default: the current directory).").option("--device <serial>", "Device the tools target unless a call names another (default: the only connected one).").option("--tools <list>", `Expose only these tools, comma-separated (of ${TOOL_NAMES.join(", ")}).`).option("--read-only", "Leave out the tools that change the device: apply, launch, input, test.").action(async (opts) => {
|
|
4582
4805
|
const { logger } = getRuntime();
|
|
4583
4806
|
const projectDir = path19.resolve(opts.project ?? process.cwd());
|
|
4584
|
-
if (!fs10.existsSync(projectDir)) throw new
|
|
4807
|
+
if (!fs10.existsSync(projectDir)) throw new OniroError6(`--project ${projectDir} does not exist.`);
|
|
4585
4808
|
const tools = selectTools(parseToolList(opts.tools), !!opts.readOnly);
|
|
4586
|
-
if (!tools.length) throw new
|
|
4809
|
+
if (!tools.length) throw new OniroError6("No tool left to serve: --read-only removed every tool --tools named.");
|
|
4587
4810
|
const context = { projectDir, deviceSerial: opts.device };
|
|
4588
4811
|
const server = new McpServer({
|
|
4589
4812
|
name: "oniro-app",
|
|
@@ -4728,7 +4951,7 @@ function registerReplayCommand(program) {
|
|
|
4728
4951
|
}
|
|
4729
4952
|
|
|
4730
4953
|
// src/bin/oniro-app.ts
|
|
4731
|
-
var CLI_VERSION = "0.
|
|
4954
|
+
var CLI_VERSION = "0.19.0";
|
|
4732
4955
|
function buildProgram() {
|
|
4733
4956
|
const program = new Command11().name("oniro-app").description(
|
|
4734
4957
|
"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."
|
|
@@ -4754,6 +4977,7 @@ function buildProgram() {
|
|
|
4754
4977
|
registerDoctorCommand(program);
|
|
4755
4978
|
registerScreensCommand(program);
|
|
4756
4979
|
registerApiCommand(program);
|
|
4980
|
+
registerDocsCommand(program);
|
|
4757
4981
|
registerTestCommand(program);
|
|
4758
4982
|
registerInputCommand(program);
|
|
4759
4983
|
registerRecordCommand(program);
|
|
@@ -4773,7 +4997,7 @@ async function main() {
|
|
|
4773
4997
|
process.exitCode = err.exitCode;
|
|
4774
4998
|
return;
|
|
4775
4999
|
}
|
|
4776
|
-
const message2 = err instanceof
|
|
5000
|
+
const message2 = err instanceof OniroError7 ? err.message : err instanceof Error ? err.message : String(err);
|
|
4777
5001
|
const stack = process.env.ONIRO_DEBUG === "1" && err instanceof Error && err.stack ? `${err.stack}
|
|
4778
5002
|
` : "";
|
|
4779
5003
|
process.stderr.write(`[error] ${message2}
|