fix: move skill directories to repo root and update AGENTS.md structure diagram

This commit is contained in:
cheliangzhao
2026-02-10 20:04:27 +08:00
parent 2378b310a5
commit a984e27246
13 changed files with 113 additions and 145 deletions

258
AGENTS.md
View File

@@ -1,115 +1,126 @@
# AGENTS.md - OpenCode Skills Repository # AGENTS.md - OpenCode Skills Repository
This repository contains AI coding agent skills for HarmonyOS/ArkTS development. Skills teach AI assistants how to build, deploy, and develop HarmonyOS applications. AI coding agent skills for HarmonyOS/ArkTS development. This is a **documentation-only** repo -- no build system for the repo itself. The skills teach agents how to build, deploy, and develop HarmonyOS apps.
## Repository Structure ## Repository Structure
``` ```
skills/ arkts-development/ # ArkTS/ArkUI development skill
├── arkts-development/ # ArkTS/ArkUI development skill ├── SKILL.md # Main skill definition (loaded by agent)
│ ├── SKILL.md # Main skill definition ├── assets/*.ets # Code templates
│ ├── assets/ # Code templates (.ets files) └── references/*.md # API docs, migration guide, patterns
│ └── references/ # API docs, migration guide, patterns harmonyos-build-deploy/ # Build & deploy skill
── harmonyos-build-deploy/ # Build & deploy skill ── SKILL.md # Main skill definition (loaded by agent)
├── SKILL.md # Main skill definition └── references/*.md # Device installation guide
└── references/ # Device installation guide
``` ```
## Build/Lint/Test Commands ## Build / Lint / Test Commands
This is a documentation repository - no build system for the repo itself. However, the skills document these HarmonyOS CLI tools: These commands apply to **HarmonyOS projects** that the skills describe, not this repo.
### Build Commands (hvigorw) ### Build (hvigorw)
```bash ```bash
# Incremental build (default for development) hvigorw assembleApp --mode project -p product=default -p buildMode=release --no-daemon # Full app
hvigorw assembleApp --mode project -p product=default -p buildMode=release --no-daemon hvigorw assembleHap -p module=entry@default --mode module -p buildMode=release --no-daemon # Single module (faster)
hvigorw clean --no-daemon # Clean artifacts
# Clean build hvigorw --sync -p product=default -p buildMode=release --no-daemon # Sync after config change
hvigorw clean --no-daemon
hvigorw assembleApp --mode project -p product=default -p buildMode=release --no-daemon
# Build single module (faster iteration)
hvigorw assembleHap -p module=entry@default --mode module -p buildMode=release --no-daemon
# Run tests
hvigorw onDeviceTest -p module=entry -p coverage=true # On-device test
hvigorw test -p module=entry # Local test
``` ```
### Package Manager (ohpm) ### Test
```bash ```bash
ohpm install --all # Install all dependencies # Run all tests for a module (on-device)
ohpm clean && ohpm cache clean # Deep clean hvigorw onDeviceTest -p module=entry -p coverage=true --no-daemon
# Run all tests for a module (local / host-side)
hvigorw test -p module=entry --no-daemon
# Run a single test suite or single test (on-device) -- use -p testParam
hvigorw onDeviceTest -p module=entry -p testParam="{\"unittest\":\"TestClassName\"}" --no-daemon
hvigorw onDeviceTest -p module=entry -p testParam="{\"unittest\":\"TestClassName#testMethodName\"}" --no-daemon
``` ```
### Code Linter (codelinter) ### Dependencies (ohpm)
```bash ```bash
codelinter # Check current project ohpm install --all # Install all deps
codelinter --fix # Check and auto-fix ohpm clean && ohpm cache clean # Deep clean
codelinter -f json -o report.json # JSON output
codelinter -i # Incremental (Git changes only)
codelinter --exit-on error,warn # CI/CD with exit codes
``` ```
### Device Commands (hdc) ### Lint (codelinter)
```bash ```bash
hdc list targets # List devices (returns UDID) codelinter # Check project
hdc -t <UDID> file send <local> <remote> # Push files codelinter --fix # Auto-fix
hdc -t <UDID> shell "bm install -p <path>" # Install app codelinter -i # Incremental (git changes only)
hdc -t <UDID> shell "aa start -a EntryAbility -b <bundleName>" # Launch app codelinter --exit-on error,warn # CI mode (non-zero exit on issues)
codelinter -f json -o report.json # JSON report
```
### Device (hdc)
```bash
hdc list targets # List devices (returns UDID)
hdc -t <UDID> file send <local_path> <device_path> # Push files
hdc -t <UDID> shell "bm install -p <dir>" # Install app
hdc -t <UDID> shell "aa start -a EntryAbility -b <bundleName>" # Launch app
``` ```
## Code Style Guidelines ## Code Style Guidelines
### ArkTS Language Constraints ### ArkTS Language Constraints
ArkTS is stricter than TypeScript. These are prohibited: ArkTS is stricter than TypeScript. These features are **prohibited**:
| Prohibited | Use Instead | | Prohibited | Use Instead |
|------------|-------------| |-------------------------|------------------------------------|
| `any`, `unknown` | Explicit types, interfaces | | `any`, `unknown` | Explicit types, interfaces |
| `var` | `let`, `const` | | `var` | `let`, `const` |
| Dynamic property `obj['key']` | Fixed object structure | | `obj['key']` (dynamic) | Fixed object structure |
| `for...in`, `delete`, `with` | `for...of`, array methods | | `for...in` | `for...of`, array methods |
| `#privateField` | `private` keyword | | `delete`, `with` | Optional properties, explicit refs |
| Structural typing | Explicit `implements`/`extends` | | `#privateField` | `private` keyword |
| Structural typing | Explicit `implements` / `extends` |
| `eval()`, `Function()` | Arrow functions, static code |
### Naming Conventions ### Naming Conventions
| Element | Convention | Example | | Element | Convention | Example |
|---------|------------|---------| |-----------------------|-----------------|-----------------------------|
| Components (struct) | PascalCase | `HomePage`, `UserCard` | | Components (struct) | PascalCase | `HomePage`, `UserCard` |
| Methods | camelCase | `loadData()`, `handleClick()` | | Interfaces | PascalCase | `UserInfo`, `ApiResponse` |
| Properties/Variables | camelCase | `isLoading`, `userName` | | Methods / Functions | camelCase | `loadData()`, `handleClick` |
| Interfaces | PascalCase | `UserInfo`, `ApiResponse` | | Properties / Variables| camelCase | `isLoading`, `userName` |
| Constants | camelCase or UPPER_SNAKE | `maxRetries`, `API_URL` | | Constants | camelCase or UPPER_SNAKE | `maxRetries`, `API_URL` |
| Files (skill docs) | kebab-case | `api-reference.md` | | Skill directories | kebab-case | `arkts-development` |
| Skill directories | kebab-case | `arkts-development` | | Filenames (docs) | kebab-case | `api-reference.md` |
### Type Annotations ### Type Annotations
Always use explicit type annotations: Always use **explicit** type annotations on declarations, parameters, and return types:
```typescript ```typescript
// Required: Explicit types on declarations
@State isLoading: boolean = false; @State isLoading: boolean = false;
@State items: ItemType[] = []; @State items: ItemType[] = [];
// Required: Return types on methods
async loadData(): Promise<void> { } async loadData(): Promise<void> { }
navigateToDetail(item: ItemType): void { } navigateToDetail(item: ItemType): void { }
// Required: Parameter types
ForEach(this.items, (item: ItemType) => { ... }, (item: ItemType) => item.id) ForEach(this.items, (item: ItemType) => { ... }, (item: ItemType) => item.id)
``` ```
### Imports
Use HarmonyOS Kit-style imports:
```typescript
import { router } from '@kit.ArkUI';
import { http } from '@kit.NetworkKit';
import { preferences } from '@kit.ArkData';
```
### Component Structure ### Component Structure
Follow this standard component layout: Follow this ordering inside every `@Component` struct:
```typescript ```typescript
@Entry @Entry
@@ -118,23 +129,21 @@ struct ComponentName {
// 1. State decorators // 1. State decorators
@State isLoading: boolean = false; @State isLoading: boolean = false;
@State errorMessage: string = ''; @State errorMessage: string = '';
// 2. Lifecycle
// 2. Lifecycle methods
aboutToAppear(): void { this.loadData(); } aboutToAppear(): void { this.loadData(); }
aboutToDisappear(): void { /* cleanup */ } aboutToDisappear(): void { /* cleanup */ }
// 3. Business methods // 3. Business methods
async loadData(): Promise<void> { } async loadData(): Promise<void> { }
// 4. @Builder methods (reusable UI blocks)
// 4. Builder methods (reusable UI blocks)
@Builder ItemCard(item: ItemType) { } @Builder ItemCard(item: ItemType) { }
// 5. build() -- always last
// 5. Build method (always last)
build() { } build() { }
} }
``` ```
### Error Handling Pattern ### Error Handling
Wrap async work in try/catch/finally with loading state:
```typescript ```typescript
async loadData(): Promise<void> { async loadData(): Promise<void> {
@@ -149,81 +158,40 @@ async loadData(): Promise<void> {
} }
``` ```
### Import Style ### ForEach -- always provide types and a key generator
Use HarmonyOS Kit imports:
```typescript
import { router } from '@kit.ArkUI';
import { http } from '@kit.NetworkKit';
import { preferences } from '@kit.ArkData';
```
## Skill File Format
Each skill follows this structure:
```markdown
---
name: skill-name
description: Detailed description for AI agent matching
---
# Skill Title
## Quick Start / Quick Reference
## Main Content Sections
## Troubleshooting
## Reference Files
```
### YAML Frontmatter
Required fields:
- `name`: kebab-case identifier matching directory name
- `description`: Detailed description for AI agent matching (trigger keywords)
## Documentation Conventions
- Use tables for command references and parameters
- Include code blocks with language specifiers (`typescript`, `bash`)
- Cross-reference related skills and reference files
- Use bilingual content (Chinese/English) for HarmonyOS context
- Structure: Quick Reference first, then detailed sections
## File Organization
- Main skill definition: `SKILL.md` (uppercase)
- Code templates: `assets/*.ets`
- Reference documentation: `references/*.md`
- All filenames: kebab-case
## Common Patterns
### State Management Decorators
| Decorator | Direction | Usage |
|-----------|-----------|-------|
| `@State` | Internal | Component's own mutable state |
| `@Prop` | Parent → Child | One-way binding (child copy) |
| `@Link` | Parent ↔ Child | Two-way binding (pass with `$var`) |
| `@Provide/@Consume` | Ancestor → Descendant | Cross-level state sharing |
### Layout Components
```typescript
Column({ space: 10 }) { } // Vertical layout
Row({ space: 10 }) { } // Horizontal layout
Stack() { } // Overlay layout
List({ space: 10 }) { } // Scrollable list
```
### ForEach Pattern
Always provide explicit types and key generator:
```typescript ```typescript
ForEach(this.items, (item: ItemType) => { ForEach(this.items, (item: ItemType) => {
ListItem() { Text(item.title) } ListItem() { Text(item.title) }
}, (item: ItemType) => item.id) // Key generator for efficient updates }, (item: ItemType) => item.id)
``` ```
## Skill File Format
Every skill directory contains a `SKILL.md` with YAML frontmatter:
```markdown
---
name: skill-name # kebab-case, matches directory name
description: ... # Detailed description for agent matching
---
# Skill Title
## Quick Start / Quick Reference
## Detailed Sections
## Troubleshooting
## Reference Files
```
### File Organization Rules
- Main definition: `SKILL.md` (uppercase)
- Code templates: `assets/*.ets`
- Reference docs: `references/*.md`
- All filenames: **kebab-case**
## Documentation Conventions
- Use **tables** for command references and parameter lists.
- Use **fenced code blocks** with language specifiers (`typescript`, `bash`).
- Structure content as: Quick Reference first, then detailed sections.
- Cross-reference related skills and reference files by relative path.