@harmonyos-arkts/opencode-plugin 0.0.20-beta → 0.0.21

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +161 -196
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  - **HarmonyOS设计专家**:为HarmonyOS应用和原子化服务创建详细的PRD设计文档
9
9
  - **HarmonyOS开发专家**:根据设计文档遵循HarmonyOS规范实现功能
10
10
  - **HarmonyOS构建**:使用harmonyos-hvigor技能构建项目并确保编译成功
11
- - **HarmonyOS文档查询**:通过 `harmony-doc-search` 搜索华为官方开发者文档(关键词越精简越准确),通过 `harmony-doc-view` 查看文档全文(支持分页)
11
+ - **HarmonyOS文档查询**:通过 `harmony-doc` 工具搜索和查看华为开发者文档(含官方文档与社区内容),支持关键词搜索和分页查看全文
12
12
 
13
13
  ## 快速开始
14
14
 
package/dist/index.js CHANGED
@@ -31599,8 +31599,7 @@ var HM_BUILD = `
31599
31599
  4. Repeat at least 3 times
31600
31600
  5. If still failing after 3 attempts, report the remaining errors to the user and ask for guidance
31601
31601
  - If the build succeeds:
31602
- 1. Guide the user to complete the quick signing in the **HarmonyBot \u63D2\u4EF6**
31603
- 2. Path: **\u63D2\u4EF6** \u53F3\u4E0A\u89D2 ** \u2192\u300C\u8BBE\u7F6E \u2014\u2014 \u5173\u8054\u5E94\u7528 \u2014\u2014 \u5E94\u7528\u7B7E\u540D\u300D** \u2192 \u5B8C\u6210**\u5FEB\u901F\u7B7E\u540D**\u3002
31602
+ 1. Guide the user to complete signature setup in **\u8BBE\u7F6E** at the top-right corner of the **HarmonyOS Dev Assistant\u63D2\u4EF6**
31604
31603
  - Only after a successful build should the development cycle be considered complete
31605
31604
  `;
31606
31605
  var HM_MULTI_DEVICE = `
@@ -31913,8 +31912,6 @@ function createHmAgent() {
31913
31912
  doom_loop: "ask",
31914
31913
  "skillSearch": "allow",
31915
31914
  ascf_build: "deny",
31916
- "harmony-doc-search": "allow",
31917
- "harmony-doc-view": "allow",
31918
31915
  skill: {
31919
31916
  "*": "deny",
31920
31917
  "harmonyos-atomic-dev": "allow",
@@ -31946,9 +31943,7 @@ function createDesignAgent() {
31946
31943
  "*": "deny",
31947
31944
  "harmonyos-prd-design": "allow"
31948
31945
  },
31949
- "skillSearch": "deny",
31950
- "harmony-doc-search": "deny",
31951
- "harmony-doc-view": "deny"
31946
+ "skillSearch": "deny"
31952
31947
  },
31953
31948
  metadata: void 0
31954
31949
  };
@@ -31971,8 +31966,6 @@ function createHmDevelopmentAgent() {
31971
31966
  temperature: 0.3,
31972
31967
  permission: {
31973
31968
  "skillSearch": "allow",
31974
- "harmony-doc-search": "allow",
31975
- "harmony-doc-view": "allow",
31976
31969
  skill: {
31977
31970
  "*": "deny",
31978
31971
  "harmonyos-atomic-dev": "allow",
@@ -44875,12 +44868,10 @@ async function updateEtsCache(sessionManager, sessionID, directory) {
44875
44868
  var CHECK_ETS_TEMPLATE_MODES = /* @__PURE__ */ new Set(["atomic", "application"]);
44876
44869
  function createHmTemplateTool(managers) {
44877
44870
  return tool({
44878
- description: "Create an empty HarmonyOS project template. Supports three modes: 'application' (full app), 'module' (sub-module), 'atomic' (atomic service). Defaults to the current working directory unless the user specifies a different directory.",
44871
+ description: "Create an empty HarmonyOS project template. Supports three modes: 'application' (full app), 'module' (sub-module), 'atomic' (atomic service). Defaults to the current working directory unless the user specifies a different directory.\n\nParameters:\n- filePath: Absolute path of the target directory where the template will be created. Defaults to the current working directory if not specified.\n- mode: Template type: 'application' (\u5E94\u7528), 'module' (\u6A21\u5757), or 'atomic' (\u5143\u670D\u52A1).",
44879
44872
  args: {
44880
- filePath: tool.schema.string().describe(
44881
- "Absolute path of the target directory where the template will be created. Defaults to the current working directory if not specified."
44882
- ),
44883
- mode: tool.schema.string().describe("Template type: 'application' (\u5E94\u7528), 'module' (\u6A21\u5757), or 'atomic' (\u5143\u670D\u52A1).")
44873
+ filePath: tool.schema.string(),
44874
+ mode: tool.schema.string()
44884
44875
  },
44885
44876
  execute: async (args, context) => {
44886
44877
  try {
@@ -45384,117 +45375,6 @@ function convert_search_result(searchResults, prefix) {
45384
45375
  });
45385
45376
  }
45386
45377
 
45387
- // src/tools/skill-search/skill-search-tool.ts
45388
- function skillSearchTool(_managers) {
45389
- return tool({
45390
- description: "Search for relevant documents within the harmonyos-atomic-dev skill directory by keywords. Returns the top K most relevant document snippets from the skill directory, ranked by keyword match frequency. Results include experience_file_path (best practices), ets_file_path (code examples), and sdk_file_path (SDK API info). QUERY TIPS: Decompose your intent into short space-separated keywords for best results. Include: 1) Kit or component name (e.g. ScanKit, AdsKit, ShareKit), 2) specific API or method names (e.g. scanBarcode, loadAd, ShareController), 3) feature keywords (e.g. \u626B\u7801, \u5E7F\u544A\u52A0\u8F7D, \u5206\u4EAB). Example: 'ScanKit \u626B\u7801 scanBarcode startScanForResult' instead of '\u5E2E\u6211\u5B9E\u73B0\u4E00\u4E2A\u626B\u7801\u529F\u80FD'.",
45391
- args: {
45392
- skill_path: tool.schema.string().describe(
45393
- "Absolute path to the harmonyos-atomic-dev skill directory. IMPORTANT: this path should not contain any prefix or suffix like 'file://' or 'SKILL.md'."
45394
- ),
45395
- query: tool.schema.string().describe(
45396
- "A decomposed requirement or intent describing what you want to find, broken down into searchable keywords separated by spaces."
45397
- ),
45398
- topK: tool.schema.number().describe("Maximum number of top-ranked documents to return. Actual results may be fewer depending on query relevance.").min(1).max(3).default(3)
45399
- },
45400
- execute: async (args, context) => {
45401
- try {
45402
- const results = await searchSkill(args.skill_path, args.query, args.topK);
45403
- if (results.length === 0) {
45404
- return "No relative items found in the skill directory.";
45405
- }
45406
- const info = results.map((r) => {
45407
- const lines = [];
45408
- lines.push(`score ${r.score.toFixed(4)}`);
45409
- if (r.experience_file_path) lines.push(`- experience path: ${r.experience_file_path}`);
45410
- if (r.ets_file_path) lines.push(`- sample code path: ${r.ets_file_path}`);
45411
- if (r.sdk_file_path) lines.push(`- sdk info path: ${r.sdk_file_path}`);
45412
- return lines.join("\n");
45413
- }).join("\n\n");
45414
- return `## Results
45415
-
45416
- ${info}`;
45417
- } catch (e) {
45418
- return `Error: ${e instanceof Error ? e.message : String(e)}`;
45419
- }
45420
- }
45421
- });
45422
- }
45423
-
45424
- // src/tools/html-preview/html-preview-tool.ts
45425
- import { access } from "fs/promises";
45426
- import path7 from "path";
45427
- import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
45428
- var PROTOTYPE_HTML_FILENAME = "prototype.html";
45429
- function toFileUrl(filePath) {
45430
- return pathToFileURL(path7.resolve(filePath)).href;
45431
- }
45432
- async function fileExists(filePath) {
45433
- try {
45434
- await access(filePath);
45435
- return true;
45436
- } catch {
45437
- return false;
45438
- }
45439
- }
45440
- function resolvePrototypePath(directory, input) {
45441
- const trimmed = input.trim();
45442
- if (!trimmed) {
45443
- throw new Error("filePath is required");
45444
- }
45445
- if (trimmed.startsWith("file://")) {
45446
- return fileURLToPath2(trimmed);
45447
- }
45448
- return path7.isAbsolute(trimmed) ? trimmed : path7.resolve(directory, trimmed);
45449
- }
45450
- async function resolvePrototypePreview(directory, filePathInput) {
45451
- const filePath = resolvePrototypePath(directory, filePathInput);
45452
- if (!await fileExists(filePath)) {
45453
- throw new Error(
45454
- `Prototype HTML not found: ${filePath}. Pass the exact local path where ${PROTOTYPE_HTML_FILENAME} was written.`
45455
- );
45456
- }
45457
- return { url: toFileUrl(filePath), filePath };
45458
- }
45459
- function htmlPreviewTool(_managers) {
45460
- return tool({
45461
- description: "Send the UX prototype preview to the frontend. Call this immediately after writing prototype.html. You MUST pass filePath with the exact local path of the written file so the frontend can locate and preview it.",
45462
- args: {
45463
- filePath: tool.schema.string().describe(
45464
- "Local path to prototype.html. Use the same path from the write step, e.g. prototype.html, /Users/yanqing/coding/your-project/prototype.html, or file:///.../prototype.html."
45465
- ),
45466
- title: tool.schema.optional(tool.schema.string().describe("Title shown in the preview panel."))
45467
- },
45468
- execute: async (args, context) => {
45469
- try {
45470
- log("[html_preview]", { filePath: args.filePath, title: args.title });
45471
- const { url: url3, filePath } = await resolvePrototypePreview(context.directory, args.filePath);
45472
- const title = args.title?.trim() || "Prototype Preview";
45473
- const metadata = {
45474
- url: url3,
45475
- filePath,
45476
- fileName: path7.basename(filePath),
45477
- title
45478
- };
45479
- context.metadata({
45480
- title,
45481
- metadata: {
45482
- htmlPreview: metadata
45483
- }
45484
- });
45485
- return [
45486
- "Prototype preview sent to frontend.",
45487
- `Title: ${title}`,
45488
- `Local path: ${filePath}`,
45489
- `Preview URL: ${url3}`
45490
- ].join("\n");
45491
- } catch (e) {
45492
- return `Error: ${e instanceof Error ? e.message : String(e)}`;
45493
- }
45494
- }
45495
- });
45496
- }
45497
-
45498
45378
  // src/tools/harmony-doc/api-client.ts
45499
45379
  var BASE_URL = "https://svc-drcn.developer.huawei.com/community/servlet";
45500
45380
  var HEADERS = {
@@ -45697,6 +45577,157 @@ function formatUpdateTime(utcTimeStr) {
45697
45577
  return `${y}-${m}-${d} ${h}:${min}`;
45698
45578
  }
45699
45579
 
45580
+ // src/tools/skill-search/skill-search-tool.ts
45581
+ function skillSearchTool(managers) {
45582
+ return tool({
45583
+ description: "Search HarmonyOS development knowledge across BOTH local skill documents AND official Huawei documentation. Returns two sections: (1) Local Skill Results \u2014 file paths to curated code examples, best practices, and SDK API info from the harmonyos-atomic-dev skill directory; (2) Official Documentation \u2014 search results from developer.huawei.com with titles, URLs, breadcrumbs, and excerpts. Use this tool for any HarmonyOS API, component, Kit, or development pattern lookup. After reviewing results, read local skill files for code patterns and use harmony-doc-view to read full official documents by URL. IMPORTANT: This tool already searches official documentation \u2014 do NOT also call harmony-doc-view for the same purpose. Only use harmony-doc-view to read a specific document page from the URLs listed below. Each scenario only supports ONE tool call. Do NOT call this tool multiple times.\n\nParameters:\n- skill_path: The COMPLETE absolute filesystem path to the harmonyos-atomic-dev skill directory (e.g. '/home/user/.opencode/skills/harmonyos-atomic-dev'). Do NOT pass just the skill name 'harmonyos-atomic-dev' \u2014 you MUST resolve and provide the full absolute path. Do NOT include any prefix like 'file://' or suffix like 'SKILL.md' or 'index.json'.\n- query: A decomposed requirement or intent describing what you want to find, broken down into searchable keywords separated by spaces. QUERY TIPS: For best results, decompose your intent into short space-separated keywords instead of long sentences. Include: 1) Kit or component name (e.g. ScanKit, AdsKit, ShareKit), 2) specific API or method names (e.g. scanBarcode, loadAd, ShareController), 3) feature keywords (e.g. \u626B\u7801, \u5E7F\u544A\u52A0\u8F7D, \u5206\u4EAB). Example: 'ScanKit \u626B\u7801 scanBarcode startScanForResult' instead of '\u5E2E\u6211\u5B9E\u73B0\u4E00\u4E2A\u626B\u7801\u529F\u80FD'.\n- topK: Maximum number of top-ranked documents to return (1-3, default 3). Actual results may be fewer depending on query relevance.",
45584
+ args: {
45585
+ skill_path: tool.schema.string(),
45586
+ query: tool.schema.string(),
45587
+ topK: tool.schema.number().min(1).max(3).default(3)
45588
+ },
45589
+ execute: async (args, context) => {
45590
+ const [localResults, docResults] = await Promise.all([
45591
+ searchSkill(args.skill_path, args.query, args.topK).catch(
45592
+ (e) => new Error(`Local search failed: ${e instanceof Error ? e.message : String(e)}`)
45593
+ ),
45594
+ searchDocs(args.query, 5).catch(
45595
+ (e) => new Error(`Doc search failed: ${e instanceof Error ? e.message : String(e)}`)
45596
+ )
45597
+ ]);
45598
+ const parts = [];
45599
+ if (localResults instanceof Error) {
45600
+ parts.push(`## Local Skill Results
45601
+
45602
+ ${localResults.message}`);
45603
+ } else if (localResults.length === 0) {
45604
+ parts.push("## Local Skill Results\n\nNo matching skill documents found.");
45605
+ } else {
45606
+ const localInfo = localResults.map((r) => {
45607
+ const lines = [];
45608
+ lines.push(`score ${r.score.toFixed(4)}`);
45609
+ if (r.experience_file_path) lines.push(`- experience path: ${r.experience_file_path}`);
45610
+ if (r.ets_file_path) lines.push(`- sample code path: ${r.ets_file_path}`);
45611
+ if (r.sdk_file_path) lines.push(`- sdk info path: ${r.sdk_file_path}`);
45612
+ return lines.join("\n");
45613
+ }).join("\n\n");
45614
+ parts.push(`## Local Skill Results
45615
+
45616
+ ${localInfo}`);
45617
+ }
45618
+ if (docResults instanceof Error) {
45619
+ parts.push(`## Official Documentation
45620
+
45621
+ ${docResults.message}`);
45622
+ } else if (docResults.length === 0) {
45623
+ parts.push("## Official Documentation\n\nNo matching official documents found.");
45624
+ } else {
45625
+ const docInfo = docResults.map((r, i) => {
45626
+ const lines = [];
45627
+ let title = r.title;
45628
+ if (r.subsection && r.subsection !== r.title) {
45629
+ title += ` #${r.subsection}`;
45630
+ }
45631
+ lines.push(`${i + 1}. **${title}**`);
45632
+ let displayUrl = r.url;
45633
+ if (r.anchorId) {
45634
+ displayUrl += `#${r.anchorId}`;
45635
+ }
45636
+ lines.push(` URL: ${displayUrl}`);
45637
+ if (r.excerpt) {
45638
+ const suffix = r.excerptTruncated ? "..." : "";
45639
+ lines.push(` ${r.excerpt}${suffix}`);
45640
+ }
45641
+ if (r.breadcrumb.length > 0) {
45642
+ lines.push(` \u6765\u81EA: ${r.breadcrumb.join(" > ")}`);
45643
+ }
45644
+ return lines.join("\n");
45645
+ }).join("\n\n");
45646
+ parts.push(
45647
+ `## Official Documentation
45648
+
45649
+ ${docInfo}
45650
+
45651
+ Use harmony-doc-view with a URL above to read any official document in full.`
45652
+ );
45653
+ }
45654
+ return parts.join("\n\n");
45655
+ }
45656
+ });
45657
+ }
45658
+
45659
+ // src/tools/html-preview/html-preview-tool.ts
45660
+ import { access } from "fs/promises";
45661
+ import path7 from "path";
45662
+ import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
45663
+ var PROTOTYPE_HTML_FILENAME = "prototype.html";
45664
+ function toFileUrl(filePath) {
45665
+ return pathToFileURL(path7.resolve(filePath)).href;
45666
+ }
45667
+ async function fileExists(filePath) {
45668
+ try {
45669
+ await access(filePath);
45670
+ return true;
45671
+ } catch {
45672
+ return false;
45673
+ }
45674
+ }
45675
+ function resolvePrototypePath(directory, input) {
45676
+ const trimmed = input.trim();
45677
+ if (!trimmed) {
45678
+ throw new Error("filePath is required");
45679
+ }
45680
+ if (trimmed.startsWith("file://")) {
45681
+ return fileURLToPath2(trimmed);
45682
+ }
45683
+ return path7.isAbsolute(trimmed) ? trimmed : path7.resolve(directory, trimmed);
45684
+ }
45685
+ async function resolvePrototypePreview(directory, filePathInput) {
45686
+ const filePath = resolvePrototypePath(directory, filePathInput);
45687
+ if (!await fileExists(filePath)) {
45688
+ throw new Error(
45689
+ `Prototype HTML not found: ${filePath}. Pass the exact local path where ${PROTOTYPE_HTML_FILENAME} was written.`
45690
+ );
45691
+ }
45692
+ return { url: toFileUrl(filePath), filePath };
45693
+ }
45694
+ function htmlPreviewTool(_managers) {
45695
+ return tool({
45696
+ description: "Send the UX prototype preview to the frontend. Call this immediately after writing prototype.html. You MUST pass filePath with the exact local path of the written file so the frontend can locate and preview it.\n\nParameters:\n- filePath: Local path to prototype.html. Use the same path from the write step, e.g. prototype.html, /Users/yanqing/coding/your-project/prototype.html, or file:///.../prototype.html.\n- title: (optional) Title shown in the preview panel.",
45697
+ args: {
45698
+ filePath: tool.schema.string(),
45699
+ title: tool.schema.optional(tool.schema.string())
45700
+ },
45701
+ execute: async (args, context) => {
45702
+ try {
45703
+ log("[html_preview]", { filePath: args.filePath, title: args.title });
45704
+ const { url: url3, filePath } = await resolvePrototypePreview(context.directory, args.filePath);
45705
+ const title = args.title?.trim() || "Prototype Preview";
45706
+ const metadata = {
45707
+ url: url3,
45708
+ filePath,
45709
+ fileName: path7.basename(filePath),
45710
+ title
45711
+ };
45712
+ context.metadata({
45713
+ title,
45714
+ metadata: {
45715
+ htmlPreview: metadata
45716
+ }
45717
+ });
45718
+ return [
45719
+ "Prototype preview sent to frontend.",
45720
+ `Title: ${title}`,
45721
+ `Local path: ${filePath}`,
45722
+ `Preview URL: ${url3}`
45723
+ ].join("\n");
45724
+ } catch (e) {
45725
+ return `Error: ${e instanceof Error ? e.message : String(e)}`;
45726
+ }
45727
+ }
45728
+ });
45729
+ }
45730
+
45700
45731
  // node_modules/turndown/lib/turndown.es.js
45701
45732
  function extend3(destination) {
45702
45733
  for (var i = 1; i < arguments.length; i++) {
@@ -46747,7 +46778,7 @@ function cleanupMarkdown(md) {
46747
46778
  return out.trim();
46748
46779
  }
46749
46780
 
46750
- // src/tools/harmony-doc/harmony-doc-view-tool.ts
46781
+ // src/tools/harmony-doc/harmony-doc-tool.ts
46751
46782
  var docCache = /* @__PURE__ */ new Map();
46752
46783
  var CACHE_TTL = 10 * 60 * 1e3;
46753
46784
  function getCached(objectId) {
@@ -46764,10 +46795,10 @@ function setCache(objectId, doc, markdown, breadcrumb) {
46764
46795
  }
46765
46796
  function harmonyDocViewTool(_managers) {
46766
46797
  return tool({
46767
- description: "View a HarmonyOS official documentation page by URL with full Markdown content and pagination. Use this tool to read official API references, guides, and best practices from developer.huawei.com. Typically used with URLs obtained from harmony-doc-search results. Supports pagination for long documents \u2014 use the 'page' parameter to continue reading.",
46798
+ description: "View a HarmonyOS official documentation page by URL with full Markdown content and pagination. Use this tool to read official API references, guides, and best practices from developer.huawei.com. Typically used with URLs obtained from skillSearch's Official Documentation results. Supports pagination for long documents \u2014 use the 'page' parameter to continue reading.\n\nParameters:\n- url: Full URL of the document to view. Must be a developer.huawei.com URL, typically from skillSearch results.\n- page: Page number for long documents. Starts at 1. Default is 1.",
46768
46799
  args: {
46769
- url: tool.schema.string().describe("Full URL of the document to view. Must be a developer.huawei.com URL."),
46770
- page: tool.schema.number().describe("Page number for long documents. Starts at 1.").min(1).default(1)
46800
+ url: tool.schema.string(),
46801
+ page: tool.schema.number().min(1).default(1)
46771
46802
  },
46772
46803
  execute: async (args, _context) => {
46773
46804
  return executeView(args.url, args.page);
@@ -46865,67 +46896,13 @@ Source: ${url3}
46865
46896
  }
46866
46897
  }
46867
46898
 
46868
- // src/tools/harmony-doc/harmony-doc-search-tool.ts
46869
- var DEFAULT_SEARCH_COUNT = 5;
46870
- function harmonyDocSearchTool(_managers) {
46871
- return tool({
46872
- description: "Search official HarmonyOS documentation from developer.huawei.com. This tool requires network access and takes several seconds to respond. Covers any HarmonyOS-related knowledge: API references, Kit capabilities, ArkUI components, ArkTS syntax, development guides, best practices, error codes, migration guides, sample code references. IMPORTANT: Use concise keywords for best results \u2014 fewer words = more precise matches. Example: 'ScanKit scanBarcode' instead of 'how to implement barcode scanning with ScanKit'. After reviewing results, use harmony-doc-view to read any document in full by URL.",
46873
- args: {
46874
- keyword: tool.schema.string().describe(
46875
- "Concise search keyword for official HarmonyOS documentation. Keep it short and specific \u2014 prefer 1-3 keywords over long sentences. Supports any HarmonyOS-related query: Kit/Component names (ScanKit, AdsKit, List, Column), API names (scanBarcode, ShareController, @State, @Prop), ArkTS syntax (@Entry, @Builder, @Extend), feature keywords (\u626B\u7801, \u5E7F\u544A, \u5206\u4EAB, \u52A8\u753B, \u7F51\u7EDC\u8BF7\u6C42), error codes, migration topics, or any development concept."
46876
- )
46877
- },
46878
- execute: async (args, _context) => {
46879
- const docResults = await searchDocs(
46880
- args.keyword,
46881
- DEFAULT_SEARCH_COUNT
46882
- ).catch(
46883
- (e) => new Error(
46884
- `Doc search failed: ${e instanceof Error ? e.message : String(e)}`
46885
- )
46886
- );
46887
- if (docResults instanceof Error) {
46888
- return docResults.message;
46889
- }
46890
- if (docResults.length === 0) {
46891
- return `No matching official documents found for "${args.keyword}".`;
46892
- }
46893
- const docInfo = docResults.map((r, i) => {
46894
- const lines = [];
46895
- let title = r.title;
46896
- if (r.subsection && r.subsection !== r.title) {
46897
- title += ` #${r.subsection}`;
46898
- }
46899
- lines.push(`${i + 1}. **${title}**`);
46900
- let displayUrl = r.url;
46901
- if (r.anchorId) {
46902
- displayUrl += `#${r.anchorId}`;
46903
- }
46904
- lines.push(` URL: ${displayUrl}`);
46905
- if (r.excerpt) {
46906
- const suffix = r.excerptTruncated ? "..." : "";
46907
- lines.push(` ${r.excerpt}${suffix}`);
46908
- }
46909
- if (r.breadcrumb.length > 0) {
46910
- lines.push(` \u6765\u81EA: ${r.breadcrumb.join(" > ")}`);
46911
- }
46912
- return lines.join("\n");
46913
- }).join("\n\n");
46914
- return `${docInfo}
46915
-
46916
- Use harmony-doc-view with a URL above to read any official document in full.`;
46917
- }
46918
- });
46919
- }
46920
-
46921
46899
  // src/tools/builtin.ts
46922
46900
  function createBuiltinTools(managers) {
46923
46901
  return {
46924
46902
  createHmTemplate: createHmTemplateTool(managers),
46925
46903
  skillSearch: skillSearchTool(managers),
46926
46904
  html_preview: htmlPreviewTool(managers),
46927
- "harmony-doc-view": harmonyDocViewTool(managers),
46928
- "harmony-doc-search": harmonyDocSearchTool(managers)
46905
+ "harmony-doc-view": harmonyDocViewTool(managers)
46929
46906
  };
46930
46907
  }
46931
46908
 
@@ -47546,7 +47523,6 @@ function createToolHooks(sessionManager, projectDir) {
47546
47523
  injectAiCodeChange(input, output);
47547
47524
  await injectHtmlPreview(input, output, projectDir);
47548
47525
  await updateEtsCount(sessionManager, projectDir, input);
47549
- markCompactAfterHtmlPreview(input, sessionManager);
47550
47526
  }
47551
47527
  };
47552
47528
  }
@@ -47636,17 +47612,6 @@ function injectAiCodeChange(input, output) {
47636
47612
  log("aiCodeChange after hook error", { tool: input.tool, error: String(e) });
47637
47613
  }
47638
47614
  }
47639
- function markCompactAfterHtmlPreview(input, sessionManager) {
47640
- if (input.tool !== "html_preview") return;
47641
- const sessionID = input.sessionID;
47642
- if (!sessionID) return;
47643
- let session = sessionManager.get(sessionID);
47644
- if (!session) {
47645
- session = sessionManager.create(sessionID);
47646
- }
47647
- session.data.set("compactAfterPreviewActive", true);
47648
- log("Activated persistent context compaction after html_preview", { sessionID });
47649
- }
47650
47615
 
47651
47616
  // src/commands/env-check.ts
47652
47617
  import { execSync } from "child_process";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@harmonyos-arkts/opencode-plugin",
4
- "version": "0.0.20-beta",
4
+ "version": "0.0.21",
5
5
  "description": "HarmonyOS Full-Lifecycle Development Assistant. Specialized in the complete development lifecycle of HarmonyOS applications, including project creation, UI development, state management, network requests, data storage, permission requests, performance optimization, testing, and release.",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "ArkTs"
31
31
  ],
32
32
  "dependencies": {
33
- "@opencode-ai/sdk": "1.15.1",
33
+ "@opencode-ai/sdk": "latest",
34
34
  "diff": "7.0.0",
35
35
  "env-paths": "4.0.0",
36
36
  "jsonc-parser": "3.3.1",