@harmonyos-arkts/opencode-plugin 0.0.6-beta → 0.0.7
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/dist/index.js +206 -158
- package/dist/templates/application/README.md +52 -0
- package/dist/templates/atomic/README.md +62 -0
- package/dist/templates/module/README.md +42 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -14860,7 +14860,7 @@ var HM_DEVELOP = `
|
|
|
14860
14860
|
### Development Phase
|
|
14861
14861
|
- Use the \`harmonyos-atomic-dev\` skill to implement features according to the design document for harmonyos atomic service
|
|
14862
14862
|
- Use the \`harmonyos-atomic-dev\` skill to fix issues and modify function in current projects
|
|
14863
|
-
- Use the createHmTemplate tool to create empty applicaiton\u3001module\u3001atomic
|
|
14863
|
+
- Use the createHmTemplate tool to create empty applicaiton\u3001module\u3001atomic. After creation, use parallel Read tool calls to read the template's README.md and key files of the current project simultaneously \u2014 do NOT use glob/grep to explore the template.
|
|
14864
14864
|
- Use the \`.harmonyos/\` file (*.md\u3001*.html) as references to generate
|
|
14865
14865
|
- After completing development, you MUST proceed to the Build phase
|
|
14866
14866
|
- **NO EXCEPTIONS**: Code must be built successfully before marking development as complete
|
|
@@ -14885,22 +14885,118 @@ var HM_BUILD = `
|
|
|
14885
14885
|
5. If still failing after 3 attempts, report the remaining errors to the user and ask for guidance
|
|
14886
14886
|
- Only after a successful build should the development cycle be considered complete
|
|
14887
14887
|
`;
|
|
14888
|
-
var HM_ASCF = `
|
|
14889
|
-
### ASCF Phase
|
|
14890
|
-
- HM_ASCF is the default active environment. Treat all requests as ASCF-context tasks unless the user explicitly asks to switch domain.
|
|
14891
|
-
- Skill routing is mandatory and must be explicit before execution. Never handle ASCF tasks without selecting one of the ASCF skills first.
|
|
14892
|
-
- Use \`harmonyos-atomic-ascf-convert\` for mini-program to HarmonyOS Atomic Service conversion (migration, API mapping, directory and component adaptation, conversion implementation).
|
|
14893
|
-
- Use \`harmonyos-ascf-knowledge\` for ASCF development guidance, technical Q&A, issue localization, and troubleshooting in existing ASCF projects.
|
|
14894
|
-
- For mixed requests, execute in two stages: (1) conversion via \`harmonyos-atomic-ascf-convert\`, then (2) engineering verification and issue diagnosis via \`harmonyos-ascf-knowledge\`.
|
|
14895
|
-
- If the request is "how to", "why it fails", "where the issue is", or "how to fix", always prioritize \`harmonyos-ascf-knowledge\`.
|
|
14896
|
-
- If a selected skill returns insufficient context, immediately continue with the other ASCF skill as fallback, then merge results into a single ASCF-oriented answer.
|
|
14897
|
-
`;
|
|
14898
14888
|
var HM_ONE2MANY = `
|
|
14899
14889
|
### One-to-Many Adaptation Phase
|
|
14900
14890
|
- Use the \`harmonyos-one2many-adapt\` skill to adapt the HarmonyOS application for multiple device types (phone, tablet, foldable, 2-in-1, wearable, TV)
|
|
14901
14891
|
- After completing adaptation, you MUST proceed to the Build phase
|
|
14902
14892
|
- **NO EXCEPTIONS**: Code must be built successfully before marking adaptation as complete
|
|
14903
14893
|
`;
|
|
14894
|
+
var HM_PLAN = `
|
|
14895
|
+
### Plan Phase
|
|
14896
|
+
You are a **planning specialist** for HarmonyOS projects. Your sole responsibility is to ANALYZE, PLAN, and DOCUMENT.
|
|
14897
|
+
|
|
14898
|
+
**CRITICAL RULES (you MUST follow these):**
|
|
14899
|
+
1. You MUST follow ALL steps below in strict order. Do not skip any step.
|
|
14900
|
+
2. You MUST NOT write any implementation code or create/edit source files (except the plan document).
|
|
14901
|
+
3. You MUST write the final plan to \`.harmonyos/plan.md\`.
|
|
14902
|
+
4. After outputting the plan, STOP and wait for user/approver feedback. Do NOT proceed to development yourself.
|
|
14903
|
+
|
|
14904
|
+
---
|
|
14905
|
+
|
|
14906
|
+
**Step 1: Explore the Codebase**
|
|
14907
|
+
|
|
14908
|
+
Thoroughly explore the existing project to understand:
|
|
14909
|
+
- Directory structure and file organization (use Glob)
|
|
14910
|
+
- Architecture patterns \u2014 look for @ComponentV2/@ObservedV2, MVVM, state management singletons
|
|
14911
|
+
- Page routing setup (main_pages.json, route_map.json)
|
|
14912
|
+
- Existing models, stores, and data flow
|
|
14913
|
+
- Any existing features similar to what's being requested
|
|
14914
|
+
- module.json5 for permissions and ability configuration
|
|
14915
|
+
- Entry point (EntryAbility) and initial page loading
|
|
14916
|
+
|
|
14917
|
+
If \`.harmonyos/codebase.md\` exists, read it first for cached analysis.
|
|
14918
|
+
|
|
14919
|
+
**Step 2: Analyze Requirements**
|
|
14920
|
+
|
|
14921
|
+
Break down the user's request into:
|
|
14922
|
+
- Core features and sub-features
|
|
14923
|
+
- Dependencies between tasks (what must be done before what \u2014 use explicit "depends on Step N" markers)
|
|
14924
|
+
- Technical constraints (HarmonyOS NEXT API availability, Kit compatibility, permission requirements)
|
|
14925
|
+
- Impact analysis: which existing files need modification vs which are new files
|
|
14926
|
+
|
|
14927
|
+
Output a dependency-ordered task list.
|
|
14928
|
+
|
|
14929
|
+
**Step 3: Create the Development Plan**
|
|
14930
|
+
|
|
14931
|
+
Write a structured plan to \`.harmonyos/plan.md\` using this template:
|
|
14932
|
+
|
|
14933
|
+
\`\`\`markdown
|
|
14934
|
+
# Development Plan: [Feature Name]
|
|
14935
|
+
|
|
14936
|
+
## Overview
|
|
14937
|
+
[1-2 sentence summary of what will be implemented]
|
|
14938
|
+
|
|
14939
|
+
## Current Architecture Summary
|
|
14940
|
+
[Brief description of the relevant existing code that will be affected]
|
|
14941
|
+
|
|
14942
|
+
## Implementation Steps
|
|
14943
|
+
|
|
14944
|
+
### Step 1: [Clear Action Title]
|
|
14945
|
+
- **Objective**: [What this step accomplishes]
|
|
14946
|
+
- **Files to create**: [Full paths of new files, or "None"]
|
|
14947
|
+
- **Files to modify**: [Full paths of existing files to change, or "None"]
|
|
14948
|
+
- **Key changes**:
|
|
14949
|
+
- [Specific code changes: new classes, methods, UI components]
|
|
14950
|
+
- [APIs or Kits to use]
|
|
14951
|
+
- [State management approach]
|
|
14952
|
+
- [Configuration or permission updates]
|
|
14953
|
+
- **Acceptance criteria**: [How to verify this step is correctly completed]
|
|
14954
|
+
|
|
14955
|
+
### Step 2: [Clear Action Title]
|
|
14956
|
+
[Same structure, with "depends on Step 1" if applicable]
|
|
14957
|
+
...
|
|
14958
|
+
|
|
14959
|
+
## Risk & Considerations
|
|
14960
|
+
- [Potential issues, edge cases, or breaking changes to existing functionality]
|
|
14961
|
+
\`\`\`
|
|
14962
|
+
|
|
14963
|
+
**Step 4: Present and Review**
|
|
14964
|
+
|
|
14965
|
+
Output the plan content to the user in your response. Then conclude with:
|
|
14966
|
+
|
|
14967
|
+
> Plan saved to \`.harmonyos/plan.md\`. Please review and confirm, or suggest adjustments before implementation begins.
|
|
14968
|
+
|
|
14969
|
+
**STOP HERE. Do NOT proceed to implementation. The main agent or user will handle the next phase.**
|
|
14970
|
+
|
|
14971
|
+
---
|
|
14972
|
+
|
|
14973
|
+
**Granularity Guidelines:**
|
|
14974
|
+
- Simple tasks (1-2 files changed): 2-3 high-level steps
|
|
14975
|
+
- Medium tasks (3-5 files): 4-6 steps, one major file change per step
|
|
14976
|
+
- Complex tasks (6+ files or architectural changes): Fine-grained steps with explicit dependency chains
|
|
14977
|
+
- Each step MUST be independently verifiable
|
|
14978
|
+
- Group related changes that must be deployed together into the same step
|
|
14979
|
+
|
|
14980
|
+
**Plan Output Example (for reference):**
|
|
14981
|
+
|
|
14982
|
+
### Step 1: Add UserStore Model
|
|
14983
|
+
- **Objective**: Create shared user authentication state management
|
|
14984
|
+
- **Files to create**: entry/src/main/ets/model/UserStore.ets
|
|
14985
|
+
- **Files to modify**: None
|
|
14986
|
+
- **Key changes**:
|
|
14987
|
+
- Create UserInfo interface and UserStore singleton with @ObservedV2/@Trace
|
|
14988
|
+
- Add loginWithHuaweiID() method using @kit.AccountKit authentication
|
|
14989
|
+
- Add logout() method
|
|
14990
|
+
- **Acceptance criteria**: UserStore exports getInstance(), isLoggedIn is reactive
|
|
14991
|
+
|
|
14992
|
+
### Step 2: Create Splash Page with Countdown
|
|
14993
|
+
- **Objective**: Add splash screen that navigates based on login state
|
|
14994
|
+
- **Files to create**: entry/src/main/ets/pages/SplashPage.ets
|
|
14995
|
+
- **Files to modify**: entry/src/main/resources/base/profile/main_pages.json, entry/src/main/ets/entryability/EntryAbility.ets
|
|
14996
|
+
- **Key changes**:
|
|
14997
|
+
- ... (depends on Step 1)
|
|
14998
|
+
- **Acceptance criteria**: App starts on SplashPage, countdown works, routes correctly
|
|
14999
|
+
`;
|
|
14904
15000
|
function buildPlanPrompt(type) {
|
|
14905
15001
|
switch (type) {
|
|
14906
15002
|
case "dev":
|
|
@@ -14909,10 +15005,10 @@ function buildPlanPrompt(type) {
|
|
|
14909
15005
|
return HM_DESIGN;
|
|
14910
15006
|
case "build":
|
|
14911
15007
|
return HM_BUILD;
|
|
14912
|
-
case "ascf":
|
|
14913
|
-
return HM_ASCF;
|
|
14914
15008
|
case "one2many":
|
|
14915
15009
|
return HM_ONE2MANY;
|
|
15010
|
+
case "plan":
|
|
15011
|
+
return HM_PLAN;
|
|
14916
15012
|
case "all":
|
|
14917
15013
|
return buildAllAgentPrompt();
|
|
14918
15014
|
default:
|
|
@@ -14920,40 +15016,16 @@ function buildPlanPrompt(type) {
|
|
|
14920
15016
|
}
|
|
14921
15017
|
}
|
|
14922
15018
|
function buildAllAgentPrompt() {
|
|
14923
|
-
return `All HarmonyOS development tasks can be broadly categorized into three main phases: Design, Development, Build
|
|
15019
|
+
return `All HarmonyOS development tasks can be broadly categorized into three main phases: Design, Development, Build. Each phase has its own set of best practices and workflows to ensure efficient and successful project completion.
|
|
14924
15020
|
${HM_DESIGN}
|
|
14925
15021
|
${HM_DEVELOP}
|
|
14926
15022
|
${HM_BUILD}
|
|
14927
|
-
${HM_ASCF}
|
|
14928
15023
|
|
|
14929
15024
|
Follow these workflows:
|
|
14930
15025
|
- **New project (greenfield)**: PRD Design \u2192 Development \u2192 Build.
|
|
14931
|
-
- **Incremental development (complex)**:
|
|
15026
|
+
- **Incremental development (complex)**: Use Plan Agent to list a plan \u2192 Discuss plan details with the user \u2192 Development \u2192 Build.
|
|
14932
15027
|
- **Incremental development (simple)**: Development \u2192 Build directly.
|
|
14933
|
-
|
|
14934
|
-
}
|
|
14935
|
-
function buildHmExploreSubAgentPrompt() {
|
|
14936
|
-
return `
|
|
14937
|
-
You are a HarmonyOS project file search specialist. You excel at thoroughly navigating and exploring codebases.
|
|
14938
|
-
|
|
14939
|
-
Your strengths:
|
|
14940
|
-
- Rapidly finding files using glob patterns
|
|
14941
|
-
- Searching code and text with powerful regex patterns
|
|
14942
|
-
- Reading and analyzing file contents
|
|
14943
|
-
|
|
14944
|
-
Guidelines:
|
|
14945
|
-
- Use Glob for broad file pattern matching
|
|
14946
|
-
- Use Grep for searching file contents with regex
|
|
14947
|
-
- Use Read when you know the specific file path you need to read
|
|
14948
|
-
- Use Bash for file operations like copying, moving, or listing directory contents
|
|
14949
|
-
- Adapt your search approach based on the thoroughness level specified by the caller
|
|
14950
|
-
- Return file paths as absolute paths in your final response
|
|
14951
|
-
- For clear communication, avoid using emojis
|
|
14952
|
-
- Create '\`.harmonyos/codebase.md\`' to write your findings, and you can also read '\`.harmonyos/codebase.md\`' if this existed
|
|
14953
|
-
- Do not create any files except '\`.harmonyos/codebase.md\`', or run bash commands that modify the user's system state in any way
|
|
14954
|
-
|
|
14955
|
-
Complete the user's search request efficiently and report your findings clearly.
|
|
14956
|
-
`;
|
|
15028
|
+
`;
|
|
14957
15029
|
}
|
|
14958
15030
|
function buildHmAgentPrompt(type) {
|
|
14959
15031
|
return `You are HarmonyOS Dev Assistant(HDACode), an expert coding agent specialized in HarmonyOS development.
|
|
@@ -15097,9 +15169,6 @@ function createHmAgent() {
|
|
|
15097
15169
|
prompt: buildHmAgentPrompt("all"),
|
|
15098
15170
|
temperature: 0.3,
|
|
15099
15171
|
permission: {
|
|
15100
|
-
"task": {
|
|
15101
|
-
"explore": "deny"
|
|
15102
|
-
},
|
|
15103
15172
|
"skillSearch": "deny"
|
|
15104
15173
|
},
|
|
15105
15174
|
metadata: void 0
|
|
@@ -15134,13 +15203,6 @@ function createDesignAgent() {
|
|
|
15134
15203
|
}
|
|
15135
15204
|
|
|
15136
15205
|
// src/agents/dev-agent.ts
|
|
15137
|
-
function getHmExploreSubAgentDescription() {
|
|
15138
|
-
return `
|
|
15139
|
-
Fast agent specialized for exploring codebases.
|
|
15140
|
-
Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?").
|
|
15141
|
-
When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.
|
|
15142
|
-
`;
|
|
15143
|
-
}
|
|
15144
15206
|
function getHmDevDescription() {
|
|
15145
15207
|
return `
|
|
15146
15208
|
HarmonyOS Development
|
|
@@ -15155,72 +15217,12 @@ function createHmDevelopmentAgent() {
|
|
|
15155
15217
|
prompt: buildHmAgentPrompt("dev"),
|
|
15156
15218
|
temperature: 0.3,
|
|
15157
15219
|
permission: {
|
|
15158
|
-
"task": {
|
|
15159
|
-
"explore": "deny"
|
|
15160
|
-
},
|
|
15161
15220
|
"skillSearch": "allow"
|
|
15162
15221
|
},
|
|
15163
15222
|
metadata: void 0
|
|
15164
15223
|
};
|
|
15165
15224
|
return agent;
|
|
15166
15225
|
}
|
|
15167
|
-
function createHmExploreSubAgent() {
|
|
15168
|
-
const agent = {
|
|
15169
|
-
id: "harmonyos-explore",
|
|
15170
|
-
name: "harmonyos-explore",
|
|
15171
|
-
description: getHmExploreSubAgentDescription(),
|
|
15172
|
-
mode: "subagent",
|
|
15173
|
-
prompt: buildHmExploreSubAgentPrompt(),
|
|
15174
|
-
temperature: 0.1,
|
|
15175
|
-
permission: {
|
|
15176
|
-
"*": "deny",
|
|
15177
|
-
"grep": "allow",
|
|
15178
|
-
"glob": "allow",
|
|
15179
|
-
"list": "allow",
|
|
15180
|
-
"bash": "allow",
|
|
15181
|
-
"read": "allow",
|
|
15182
|
-
"edit": {
|
|
15183
|
-
"*.harmonyos/codebase.md": "allow"
|
|
15184
|
-
},
|
|
15185
|
-
"write": {
|
|
15186
|
-
"*.harmonyos/codebase.md": "allow"
|
|
15187
|
-
}
|
|
15188
|
-
},
|
|
15189
|
-
metadata: void 0
|
|
15190
|
-
};
|
|
15191
|
-
return agent;
|
|
15192
|
-
}
|
|
15193
|
-
|
|
15194
|
-
// src/agents/ascf-agent.ts
|
|
15195
|
-
function getHmAscfDescription() {
|
|
15196
|
-
return `
|
|
15197
|
-
HarmonyOS ASCF assistant for mini-program conversion, ASCF development Q&A, and issue troubleshooting
|
|
15198
|
-
`;
|
|
15199
|
-
}
|
|
15200
|
-
function createAscfAgent() {
|
|
15201
|
-
const agent = {
|
|
15202
|
-
id: "harmonyos-ascf",
|
|
15203
|
-
name: "harmonyos-ascf",
|
|
15204
|
-
description: getHmAscfDescription(),
|
|
15205
|
-
mode: "primary",
|
|
15206
|
-
prompt: buildHmAgentPrompt("ascf"),
|
|
15207
|
-
temperature: 0.6,
|
|
15208
|
-
permission: {
|
|
15209
|
-
"skill": {
|
|
15210
|
-
"*": "deny",
|
|
15211
|
-
"harmonyos-atomic-ascf-convert": "allow",
|
|
15212
|
-
"harmonyos-ascf-knowledge": "allow",
|
|
15213
|
-
"huawei-payment-integration": "allow",
|
|
15214
|
-
"harmonyos-atomic-service-filing": "allow",
|
|
15215
|
-
"harmony-emulator-debugging": "allow",
|
|
15216
|
-
"harmonyos-atomic-ascf-release": "allow"
|
|
15217
|
-
},
|
|
15218
|
-
"skillSearch": "deny"
|
|
15219
|
-
},
|
|
15220
|
-
metadata: void 0
|
|
15221
|
-
};
|
|
15222
|
-
return agent;
|
|
15223
|
-
}
|
|
15224
15226
|
|
|
15225
15227
|
// src/agents/one2many-agent.ts
|
|
15226
15228
|
function getHmOne2ManyDescription() {
|
|
@@ -15251,9 +15253,7 @@ var AgentRegistry = class {
|
|
|
15251
15253
|
this.register(createHmAgent());
|
|
15252
15254
|
this.register(createDesignAgent());
|
|
15253
15255
|
this.register(createHmDevelopmentAgent());
|
|
15254
|
-
this.register(createAscfAgent());
|
|
15255
15256
|
this.register(createOne2ManyAgent());
|
|
15256
|
-
this.register(createHmExploreSubAgent());
|
|
15257
15257
|
}
|
|
15258
15258
|
register(agent) {
|
|
15259
15259
|
this.agents.set(agent.id, agent);
|
|
@@ -15385,22 +15385,7 @@ var AgentManager = class {
|
|
|
15385
15385
|
}
|
|
15386
15386
|
};
|
|
15387
15387
|
|
|
15388
|
-
// src/shared/ets-counter.ts
|
|
15389
|
-
import { readdir, readFile as readFile2, stat } from "fs/promises";
|
|
15390
|
-
import { join as join2, extname } from "path";
|
|
15391
|
-
async function countEtsLines(projectDir) {
|
|
15392
|
-
const files = [];
|
|
15393
|
-
const totalLines = files.reduce((sum, f) => sum + f.lines, 0);
|
|
15394
|
-
return {
|
|
15395
|
-
fileCount: files.length,
|
|
15396
|
-
totalLines,
|
|
15397
|
-
files,
|
|
15398
|
-
timestamp: Date.now()
|
|
15399
|
-
};
|
|
15400
|
-
}
|
|
15401
|
-
|
|
15402
15388
|
// src/managers/config-handler.ts
|
|
15403
|
-
var EXPLORE_ETS_THRESHOLD = 2e3;
|
|
15404
15389
|
function mergePermission(target, source) {
|
|
15405
15390
|
if (!target) return source;
|
|
15406
15391
|
const result = { ...target };
|
|
@@ -15415,27 +15400,11 @@ function mergePermission(target, source) {
|
|
|
15415
15400
|
}
|
|
15416
15401
|
return result;
|
|
15417
15402
|
}
|
|
15418
|
-
function createConfigHandler(_pluginConfig, agent,
|
|
15403
|
+
function createConfigHandler(_pluginConfig, agent, _projectDir) {
|
|
15419
15404
|
return async (config3) => {
|
|
15420
|
-
let exploreEnabled = true;
|
|
15421
|
-
try {
|
|
15422
|
-
const stats = await countEtsLines(projectDir);
|
|
15423
|
-
exploreEnabled = stats.totalLines >= EXPLORE_ETS_THRESHOLD;
|
|
15424
|
-
log("ETS count for explore agent", {
|
|
15425
|
-
totalLines: stats.totalLines,
|
|
15426
|
-
fileCount: stats.fileCount,
|
|
15427
|
-
enabled: exploreEnabled
|
|
15428
|
-
});
|
|
15429
|
-
} catch (err) {
|
|
15430
|
-
log("Failed to count ETS lines, enabling explore by default", { error: String(err) });
|
|
15431
|
-
}
|
|
15432
15405
|
const pluginAgents = agent.record();
|
|
15433
15406
|
if (config3.agent) {
|
|
15434
15407
|
for (const [id, pluginAgentConfig] of Object.entries(pluginAgents)) {
|
|
15435
|
-
if (id === "harmonyos-explore" && !exploreEnabled) {
|
|
15436
|
-
log("Skipping harmonyos-explore agent (insufficient .ets files)");
|
|
15437
|
-
continue;
|
|
15438
|
-
}
|
|
15439
15408
|
if (config3.agent[id]) {
|
|
15440
15409
|
const merged = { ...config3.agent[id], ...pluginAgentConfig };
|
|
15441
15410
|
if (config3.agent[id].permission && pluginAgentConfig.permission) {
|
|
@@ -28038,6 +28007,86 @@ async function downloadTemplate(mode, filePath) {
|
|
|
28038
28007
|
}
|
|
28039
28008
|
}
|
|
28040
28009
|
|
|
28010
|
+
// src/shared/ets-counter.ts
|
|
28011
|
+
import { readdir, readFile as readFile2, stat } from "fs/promises";
|
|
28012
|
+
import { join as join2, extname } from "path";
|
|
28013
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
28014
|
+
"node_modules",
|
|
28015
|
+
".preview",
|
|
28016
|
+
"build",
|
|
28017
|
+
".cxx",
|
|
28018
|
+
".gradle",
|
|
28019
|
+
"oh_modules",
|
|
28020
|
+
".hvigor",
|
|
28021
|
+
"entry/build"
|
|
28022
|
+
]);
|
|
28023
|
+
var HM_PROJECT_INDICATORS = ["build-profile.json5", "oh-package.json5"];
|
|
28024
|
+
var MAX_CONTENT_READ_FILES = 500;
|
|
28025
|
+
var ESTIMATED_LINES_PER_FILE = 100;
|
|
28026
|
+
async function isHarmonyOSProject(dir) {
|
|
28027
|
+
for (const indicator of HM_PROJECT_INDICATORS) {
|
|
28028
|
+
try {
|
|
28029
|
+
await stat(join2(dir, indicator));
|
|
28030
|
+
return true;
|
|
28031
|
+
} catch {
|
|
28032
|
+
}
|
|
28033
|
+
}
|
|
28034
|
+
return false;
|
|
28035
|
+
}
|
|
28036
|
+
async function collectEtsFilePaths(dir, results) {
|
|
28037
|
+
let entries;
|
|
28038
|
+
try {
|
|
28039
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
28040
|
+
} catch {
|
|
28041
|
+
return;
|
|
28042
|
+
}
|
|
28043
|
+
for (const entry of entries) {
|
|
28044
|
+
if (entry.isDirectory()) {
|
|
28045
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
28046
|
+
if (entry.name.startsWith(".") && entry.name !== ".ets") continue;
|
|
28047
|
+
await collectEtsFilePaths(join2(dir, entry.name), results);
|
|
28048
|
+
} else if (extname(entry.name) === ".ets") {
|
|
28049
|
+
results.push(join2(dir, entry.name));
|
|
28050
|
+
}
|
|
28051
|
+
}
|
|
28052
|
+
}
|
|
28053
|
+
async function countEtsLines(projectDir) {
|
|
28054
|
+
const startTime = Date.now();
|
|
28055
|
+
if (!await isHarmonyOSProject(projectDir)) {
|
|
28056
|
+
log("ets.count.skipped", { projectDir, elapsed: Date.now() - startTime });
|
|
28057
|
+
return { fileCount: 0, totalLines: 0, files: [], timestamp: Date.now() };
|
|
28058
|
+
}
|
|
28059
|
+
const filePaths = [];
|
|
28060
|
+
await collectEtsFilePaths(projectDir, filePaths);
|
|
28061
|
+
const fileCount = filePaths.length;
|
|
28062
|
+
if (fileCount > MAX_CONTENT_READ_FILES) {
|
|
28063
|
+
const elapsed2 = Date.now() - startTime;
|
|
28064
|
+
log("ets.count.estimated", { fileCount, estimatedLines: fileCount * ESTIMATED_LINES_PER_FILE, elapsed: elapsed2 });
|
|
28065
|
+
return {
|
|
28066
|
+
fileCount,
|
|
28067
|
+
totalLines: fileCount * ESTIMATED_LINES_PER_FILE,
|
|
28068
|
+
files: [],
|
|
28069
|
+
timestamp: Date.now()
|
|
28070
|
+
};
|
|
28071
|
+
}
|
|
28072
|
+
const files = [];
|
|
28073
|
+
for (const filePath of filePaths) {
|
|
28074
|
+
try {
|
|
28075
|
+
const content = await readFile2(filePath, "utf-8");
|
|
28076
|
+
files.push({ path: filePath, lines: content.split("\n").length });
|
|
28077
|
+
} catch {
|
|
28078
|
+
}
|
|
28079
|
+
}
|
|
28080
|
+
const elapsed = Date.now() - startTime;
|
|
28081
|
+
log("ets.count.precise", { fileCount, totalLines: files.reduce((sum, f) => sum + f.lines, 0), elapsed });
|
|
28082
|
+
return {
|
|
28083
|
+
fileCount,
|
|
28084
|
+
totalLines: files.reduce((sum, f) => sum + f.lines, 0),
|
|
28085
|
+
files,
|
|
28086
|
+
timestamp: Date.now()
|
|
28087
|
+
};
|
|
28088
|
+
}
|
|
28089
|
+
|
|
28041
28090
|
// src/tools/create-template/ets-check.ts
|
|
28042
28091
|
async function checkEtsExists(directory) {
|
|
28043
28092
|
try {
|
|
@@ -28090,12 +28139,11 @@ function createHmTemplateTool(managers) {
|
|
|
28090
28139
|
}
|
|
28091
28140
|
|
|
28092
28141
|
// src/tools/skill-search/skill-search-tool.ts
|
|
28093
|
-
import { homedir as
|
|
28142
|
+
import { homedir as homedir2 } from "node:os";
|
|
28094
28143
|
import { join as join4 } from "node:path";
|
|
28095
28144
|
|
|
28096
28145
|
// src/tools/skill-search/search-skill.ts
|
|
28097
28146
|
import { readFileSync } from "node:fs";
|
|
28098
|
-
import { homedir as homedir2 } from "node:os";
|
|
28099
28147
|
import { join as join3 } from "node:path";
|
|
28100
28148
|
|
|
28101
28149
|
// src/tools/skill-search/tokenizer.ts
|
|
@@ -28278,7 +28326,6 @@ var filter_default = [
|
|
|
28278
28326
|
];
|
|
28279
28327
|
|
|
28280
28328
|
// src/tools/skill-search/search-skill.ts
|
|
28281
|
-
var DEFAULT_SKILL_PATH = join3(homedir2(), ".config", "opencode", "skills", "harmonyos-atomic-dev");
|
|
28282
28329
|
var cachedEntries = null;
|
|
28283
28330
|
var cachedIndexableEntries = null;
|
|
28284
28331
|
var cachedFilters = null;
|
|
@@ -28300,10 +28347,9 @@ function loadAndCache(resolvedPath) {
|
|
|
28300
28347
|
return true;
|
|
28301
28348
|
}
|
|
28302
28349
|
function searchSkill(skill_path, query, topK = 5) {
|
|
28303
|
-
const resolvedPath = skill_path?.trim() || DEFAULT_SKILL_PATH;
|
|
28304
28350
|
if (!cachedEntries) {
|
|
28305
28351
|
try {
|
|
28306
|
-
if (!loadAndCache(
|
|
28352
|
+
if (!loadAndCache(skill_path?.trim())) return [];
|
|
28307
28353
|
} catch {
|
|
28308
28354
|
return [];
|
|
28309
28355
|
}
|
|
@@ -28314,9 +28360,7 @@ function searchSkill(skill_path, query, topK = 5) {
|
|
|
28314
28360
|
if (idx !== -1) {
|
|
28315
28361
|
preFiltered.push({
|
|
28316
28362
|
ets_file_path: "",
|
|
28317
|
-
experience_file_path: entry.path
|
|
28318
|
-
summary: entry.summary,
|
|
28319
|
-
range: 0
|
|
28363
|
+
experience_file_path: entry.path
|
|
28320
28364
|
});
|
|
28321
28365
|
query = (query.slice(0, idx) + query.slice(idx + category.length)).trim();
|
|
28322
28366
|
}
|
|
@@ -28338,9 +28382,7 @@ function convert_search_result(searchResults) {
|
|
|
28338
28382
|
);
|
|
28339
28383
|
return {
|
|
28340
28384
|
ets_file_path: entry.path,
|
|
28341
|
-
experience_file_path: experience?.path ?? ""
|
|
28342
|
-
summary: entry.summary,
|
|
28343
|
-
range: rank + 1
|
|
28385
|
+
experience_file_path: experience?.path ?? ""
|
|
28344
28386
|
};
|
|
28345
28387
|
});
|
|
28346
28388
|
}
|
|
@@ -28348,9 +28390,9 @@ function convert_search_result(searchResults) {
|
|
|
28348
28390
|
// src/tools/skill-search/skill-search-tool.ts
|
|
28349
28391
|
function skillSearchTool(managers) {
|
|
28350
28392
|
return tool({
|
|
28351
|
-
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. Use this tool instead of Glob/Grep when you need to find specific knowledge or documentation within harmonyos-atomic-dev skill. It scans all files under the given skill_path and returns the most relevant matches based on your query keywords. The results include ets_file_path (path to the ETS code examples), experience_file_path (path to the matching experience document best practices), summary (document summary), and range (relevance rank 1 = most relevant)\
|
|
28393
|
+
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. Use this tool instead of Glob/Grep when you need to find specific knowledge or documentation within harmonyos-atomic-dev skill. It scans all files under the given skill_path and returns the most relevant matches based on your query keywords. The results include ets_file_path (path to the ETS code examples), experience_file_path (path to the matching experience document best practices), summary (document summary), and range (relevance rank 1 = most relevant). 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'.",
|
|
28352
28394
|
args: {
|
|
28353
|
-
skill_path: tool.schema.string("Absolute path to the skill directory to search within. Default path may not contains harmonyos-atomic-dev skill").default(join4(
|
|
28395
|
+
skill_path: tool.schema.string("Absolute path to the skill directory to search within. Default path may not contains harmonyos-atomic-dev skill").default(join4(homedir2(), ".config", "opencode", "skills", "harmonyos-atomic-dev")),
|
|
28354
28396
|
query: tool.schema.string("A decomposed requirement or intent describing what you want to find, broken down into searchable keywords separated by spaces."),
|
|
28355
28397
|
topK: tool.schema.number("Maximum number of top-ranked documents to return. Actual results may be fewer depending on query relevance.").min(1).max(5).default(5)
|
|
28356
28398
|
},
|
|
@@ -28360,7 +28402,13 @@ function skillSearchTool(managers) {
|
|
|
28360
28402
|
if (results.length === 0) {
|
|
28361
28403
|
return "No relative items found in the skill directory.";
|
|
28362
28404
|
}
|
|
28363
|
-
return
|
|
28405
|
+
return results.map((r) => {
|
|
28406
|
+
if (r.ets_file_path) {
|
|
28407
|
+
return `${r.experience_file_path}
|
|
28408
|
+
\u793A\u4F8B\u6587\u4EF6\uFF1A${r.ets_file_path}`;
|
|
28409
|
+
}
|
|
28410
|
+
return r.experience_file_path;
|
|
28411
|
+
}).join("\n\n");
|
|
28364
28412
|
} catch (e) {
|
|
28365
28413
|
return `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
28366
28414
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# HarmonyOS Application Template
|
|
2
|
+
|
|
3
|
+
HarmonyOS 标准应用工程模板,基于 Stage 模型,适用于开发完整的 HarmonyOS 应用程序。
|
|
4
|
+
|
|
5
|
+
## 目录结构
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
application/
|
|
9
|
+
├── AppScope/ # 应用全局配置
|
|
10
|
+
│ ├── app.json5 # 应用包名、版本号、图标等全局信息
|
|
11
|
+
│ └── resources/ # 应用级资源(图标、字符串)
|
|
12
|
+
├── entry/ # 主模块(Entry Module)
|
|
13
|
+
│ ├── src/
|
|
14
|
+
│ │ ├── main/
|
|
15
|
+
│ │ │ ├── ets/
|
|
16
|
+
│ │ │ │ ├── entryability/ # UIAbility 入口
|
|
17
|
+
│ │ │ │ ├── entrybackupability/# 备份恢复 ExtensionAbility
|
|
18
|
+
│ │ │ │ └── pages/ # 页面(Index.ets)
|
|
19
|
+
│ │ │ ├── resources/ # 模块资源(字符串、颜色、图片、配置)
|
|
20
|
+
│ │ │ └── module.json5 # 模块配置(Ability、页面路由)
|
|
21
|
+
│ │ ├── ohosTest/ # 仪器化测试
|
|
22
|
+
│ │ └── test/ # 本地单元测试
|
|
23
|
+
│ ├── build-profile.json5 # 模块级构建配置
|
|
24
|
+
│ ├── oh-package.json5 # 模块依赖声明
|
|
25
|
+
│ └── hvigorfile.ts # Hvigor 构建脚本
|
|
26
|
+
├── hvigor/ # Hvigor 构建引擎配置
|
|
27
|
+
├── build-profile.json5 # 工程级构建配置(签名、SDK 版本、模块列表)
|
|
28
|
+
├── oh-package.json5 # 工程级依赖声明
|
|
29
|
+
├── hvigorfile.ts # 工程级 Hvigor 脚本
|
|
30
|
+
└── code-linter.json5 # 代码检查配置
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 关键配置
|
|
34
|
+
|
|
35
|
+
| 配置项 | 值 |
|
|
36
|
+
|--------|-----|
|
|
37
|
+
| bundleName | `com.example.app` |
|
|
38
|
+
| module type | `entry` |
|
|
39
|
+
| targetSdkVersion | `6.0.1(21)` |
|
|
40
|
+
| runtimeOS | `HarmonyOS` |
|
|
41
|
+
| installationFree | `false` |
|
|
42
|
+
|
|
43
|
+
## 使用场景
|
|
44
|
+
|
|
45
|
+
- 创建一个新的 HarmonyOS 标准应用工程
|
|
46
|
+
- 包含完整的 UIAbility 生命周期管理
|
|
47
|
+
- 内置备份恢复能力(EntryBackupAbility)
|
|
48
|
+
- 适合需要独立安装和分发的应用
|
|
49
|
+
|
|
50
|
+
## 使用方式
|
|
51
|
+
|
|
52
|
+
此模板由 `createHmTemplate` 工具自动下载和解压,作为 HarmonyOS 应用开发的初始工程骨架。
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# HarmonyOS Atomic Service Template
|
|
2
|
+
|
|
3
|
+
HarmonyOS 元服务(Atomic Service)工程模板,基于 Stage 模型,适用于开发免安装的轻量化服务。
|
|
4
|
+
|
|
5
|
+
## 目录结构
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
atomic/
|
|
9
|
+
├── AppScope/ # 应用全局配置
|
|
10
|
+
│ ├── app.json5 # 应用包名、版本号(bundleType: "atomicService")
|
|
11
|
+
│ └── resources/ # 应用级资源(图标、字符串)
|
|
12
|
+
├── entry/ # 主模块(Entry Module)
|
|
13
|
+
│ ├── src/
|
|
14
|
+
│ │ ├── main/
|
|
15
|
+
│ │ │ ├── ets/
|
|
16
|
+
│ │ │ │ ├── entryability/ # UIAbility 入口
|
|
17
|
+
│ │ │ │ └── pages/ # 页面(Index.ets)
|
|
18
|
+
│ │ │ ├── resources/ # 模块资源(字符串、颜色、图片、配置)
|
|
19
|
+
│ │ │ └── module.json5 # 模块配置(Ability、页面路由)
|
|
20
|
+
│ │ ├── ohosTest/ # 仪器化测试
|
|
21
|
+
│ │ ├── test/ # 本地单元测试
|
|
22
|
+
│ │ └── mock/ # Mock 配置
|
|
23
|
+
│ ├── build-profile.json5 # 模块级构建配置
|
|
24
|
+
│ ├── oh-package.json5 # 模块依赖声明
|
|
25
|
+
│ └── hvigorfile.ts # Hvigor 构建脚本
|
|
26
|
+
├── hvigor/ # Hvigor 构建引擎配置
|
|
27
|
+
├── build-profile.json5 # 工程级构建配置(签名、SDK 版本、模块列表)
|
|
28
|
+
├── oh-package.json5 # 工程级依赖声明
|
|
29
|
+
├── hvigorfile.ts # 工程级 Hvigor 脚本
|
|
30
|
+
└── code-linter.json5 # 代码检查配置
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 关键配置
|
|
34
|
+
|
|
35
|
+
| 配置项 | 值 |
|
|
36
|
+
|--------|-----|
|
|
37
|
+
| bundleName | `com.atomicservice.example` |
|
|
38
|
+
| bundleType | `atomicService` |
|
|
39
|
+
| module type | `entry` |
|
|
40
|
+
| targetSdkVersion | `6.0.1(21)` |
|
|
41
|
+
| runtimeOS | `HarmonyOS` |
|
|
42
|
+
| installationFree | `true` |
|
|
43
|
+
|
|
44
|
+
## 与 Application 模板的区别
|
|
45
|
+
|
|
46
|
+
| 特性 | Application | Atomic Service |
|
|
47
|
+
|------|-------------|----------------|
|
|
48
|
+
| bundleType | 默认(app) | `atomicService` |
|
|
49
|
+
| installationFree | `false` | `true` |
|
|
50
|
+
| 备份能力 | 包含 EntryBackupAbility | 不包含 |
|
|
51
|
+
| 图标资源 | layered_image | app_icon |
|
|
52
|
+
| 免安装 | 不支持 | 支持 |
|
|
53
|
+
|
|
54
|
+
## 使用场景
|
|
55
|
+
|
|
56
|
+
- 开发免安装的元服务(Atomic Service)
|
|
57
|
+
- 适用于服务卡片、快捷服务、轻量级功能入口
|
|
58
|
+
- 通过 HarmonyOS 服务分发平台进行分发
|
|
59
|
+
|
|
60
|
+
## 使用方式
|
|
61
|
+
|
|
62
|
+
此模板由 `createHmTemplate` 工具自动下载和解压,作为 HarmonyOS 元服务开发的初始工程骨架。
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# HarmonyOS Module Template
|
|
2
|
+
|
|
3
|
+
HarmonyOS HAR(HarmonyOS Archive)库模块模板,用于开发可复用的共享库模块。
|
|
4
|
+
|
|
5
|
+
## 目录结构
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
module/
|
|
9
|
+
├── src/
|
|
10
|
+
│ ├── main/
|
|
11
|
+
│ │ ├── ets/
|
|
12
|
+
│ │ │ └── components/ # 导出的组件(MainPage.ets)
|
|
13
|
+
│ │ ├── resources/ # 模块资源(字符串、浮点数)
|
|
14
|
+
│ │ └── module.json5 # 模块配置(type: "har")
|
|
15
|
+
│ ├── ohosTest/ # 仪器化测试
|
|
16
|
+
│ └── test/ # 本地单元测试
|
|
17
|
+
├── Index.ets # 库模块导出入口
|
|
18
|
+
├── build-profile.json5 # 模块级构建配置
|
|
19
|
+
├── oh-package.json5 # 模块依赖声明
|
|
20
|
+
├── hvigorfile.ts # Hvigor 构建脚本
|
|
21
|
+
├── consumer-rules.txt # 混淆消费者规则
|
|
22
|
+
└── obfuscation-rules.txt # 混淆规则
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 关键配置
|
|
26
|
+
|
|
27
|
+
| 配置项 | 值 |
|
|
28
|
+
|--------|-----|
|
|
29
|
+
| module name | `library` |
|
|
30
|
+
| module type | `har` |
|
|
31
|
+
| deviceTypes | `["phone"]` |
|
|
32
|
+
| apiType | `stageMode` |
|
|
33
|
+
|
|
34
|
+
## 使用场景
|
|
35
|
+
|
|
36
|
+
- 创建一个可复用的 HAR 共享库
|
|
37
|
+
- 封装通用组件、工具类或业务逻辑供多个模块引用
|
|
38
|
+
- 通过 `oh-package.json5` 管理依赖,支持混淆配置
|
|
39
|
+
|
|
40
|
+
## 使用方式
|
|
41
|
+
|
|
42
|
+
此模板由 `createHmTemplate` 工具自动下载和解压,用于在现有 HarmonyOS 工程中添加新的 HAR 库模块。将模板内容复制到工程目录下并在 `build-profile.json5` 的 `modules` 中注册即可。
|
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.
|
|
4
|
+
"version": "0.0.7",
|
|
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",
|
|
@@ -48,4 +48,4 @@
|
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=18.0.0"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|